Initial commit; kernel source import

This commit is contained in:
Nathan
2025-04-06 23:50:55 -05:00
commit 25c6d769f4
45093 changed files with 18199410 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
GCOV_PROFILE := y
ccflags-y += -Idrivers/video/tegra/host
nvhost-host1x-objs = \
host1x.o
obj-$(CONFIG_TEGRA_GRHOST) += nvhost-host1x.o

View File

@@ -0,0 +1,859 @@
/*
* drivers/video/tegra/host/dev.c
*
* Tegra Graphics Host Driver Entrypoint
*
* Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
*
* 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 <linux/slab.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/file.h>
#include <linux/clk.h>
#include <linux/hrtimer.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/tegra-soc.h>
#include "dev.h"
#include <trace/events/nvhost.h>
#include <linux/nvhost.h>
#include <linux/nvhost_ioctl.h>
#include <linux/platform_data/tegra_pm_domains.h>
#include "debug.h"
#include "bus_client.h"
#include "nvhost_acm.h"
#include "nvhost_channel.h"
#include "nvhost_job.h"
#include "nvhost_memmgr.h"
#ifdef CONFIG_TEGRA_GRHOST_SYNC
#include "nvhost_sync.h"
#endif
#include "nvhost_scale.h"
#include "chip_support.h"
#include "t114/t114.h"
#include "t124/t124.h"
#define DRIVER_NAME "host1x"
static const char *num_syncpts_name = "num_pts";
static const char *num_mutexes_name = "num_mlocks";
static const char *num_waitbases_name = "num_bases";
static const char *gather_filter_enabled_name = "gather_filter_enabled";
struct nvhost_master *nvhost;
struct nvhost_ctrl_userctx {
struct nvhost_master *dev;
u32 *mod_locks;
};
struct nvhost_capability_node {
struct kobj_attribute attr;
struct nvhost_master *host;
int (*func)(struct nvhost_syncpt *sp);
};
static int nvhost_ctrlrelease(struct inode *inode, struct file *filp)
{
struct nvhost_ctrl_userctx *priv = filp->private_data;
int i;
trace_nvhost_ctrlrelease(priv->dev->dev->name);
filp->private_data = NULL;
if (priv->mod_locks[0])
nvhost_module_idle(priv->dev->dev);
for (i = 1; i < nvhost_syncpt_nb_mlocks(&priv->dev->syncpt); i++)
if (priv->mod_locks[i])
nvhost_mutex_unlock(&priv->dev->syncpt, i);
kfree(priv->mod_locks);
kfree(priv);
return 0;
}
static int nvhost_ctrlopen(struct inode *inode, struct file *filp)
{
struct nvhost_master *host =
container_of(inode->i_cdev, struct nvhost_master, cdev);
struct nvhost_ctrl_userctx *priv;
u32 *mod_locks;
trace_nvhost_ctrlopen(host->dev->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
mod_locks = kzalloc(sizeof(u32)
* nvhost_syncpt_nb_mlocks(&host->syncpt),
GFP_KERNEL);
if (!(priv && mod_locks)) {
kfree(priv);
kfree(mod_locks);
return -ENOMEM;
}
priv->dev = host;
priv->mod_locks = mod_locks;
filp->private_data = priv;
return 0;
}
static int nvhost_ioctl_ctrl_syncpt_read(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_syncpt_read_args *args)
{
if (args->id >= nvhost_syncpt_nb_pts(&ctx->dev->syncpt))
return -EINVAL;
args->value = nvhost_syncpt_read(&ctx->dev->syncpt, args->id);
trace_nvhost_ioctl_ctrl_syncpt_read(args->id, args->value);
return 0;
}
static int nvhost_ioctl_ctrl_syncpt_incr(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_syncpt_incr_args *args)
{
if (args->id >= nvhost_syncpt_nb_pts(&ctx->dev->syncpt))
return -EINVAL;
trace_nvhost_ioctl_ctrl_syncpt_incr(args->id);
nvhost_syncpt_incr(&ctx->dev->syncpt, args->id);
return 0;
}
static int nvhost_ioctl_ctrl_syncpt_waitex(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_syncpt_waitex_args *args)
{
u32 timeout;
int err;
if (args->id >= nvhost_syncpt_nb_pts(&ctx->dev->syncpt))
return -EINVAL;
if (args->timeout == NVHOST_NO_TIMEOUT)
/*
* FIXME: MAX_SCHEDULE_TIMEOUT is ulong which can be bigger
* than u32 so we should fix nvhost_syncpt_wait_timeout to
* take ulong not u32.
*/
timeout = (u32)MAX_SCHEDULE_TIMEOUT;
else
timeout = (u32)msecs_to_jiffies(args->timeout);
err = nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id,
args->thresh, timeout, &args->value,
NULL, true);
trace_nvhost_ioctl_ctrl_syncpt_wait(args->id, args->thresh,
args->timeout, args->value, err);
return err;
}
static int nvhost_ioctl_ctrl_syncpt_waitmex(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_syncpt_waitmex_args *args)
{
ulong timeout;
int err;
struct timespec ts;
if (args->id >= nvhost_syncpt_nb_pts(&ctx->dev->syncpt))
return -EINVAL;
if (args->timeout == NVHOST_NO_TIMEOUT)
timeout = MAX_SCHEDULE_TIMEOUT;
else
timeout = (u32)msecs_to_jiffies(args->timeout);
err = nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id,
args->thresh, timeout, &args->value,
&ts, true);
args->tv_sec = ts.tv_sec;
args->tv_nsec = ts.tv_nsec;
trace_nvhost_ioctl_ctrl_syncpt_wait(args->id, args->thresh,
args->timeout, args->value, err);
return err;
}
static int nvhost_ioctl_ctrl_sync_fence_create(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_sync_fence_create_args *args)
{
#ifdef CONFIG_TEGRA_GRHOST_SYNC
int err;
int i;
struct nvhost_ctrl_sync_fence_info *pts;
char name[32];
const char __user *args_name =
(const char __user *)(uintptr_t)args->name;
const void __user *args_pts =
(const void __user *)(uintptr_t)args->pts;
if (args_name) {
if (strncpy_from_user(name, args_name, sizeof(name)) < 0)
return -EFAULT;
name[sizeof(name) - 1] = '\0';
} else {
name[0] = '\0';
}
pts = kmalloc_array(args->num_pts, sizeof(*pts), GFP_KERNEL);
if (!pts)
return -ENOMEM;
/* Multiplication overflow would have errored in kmalloc_array */
if (copy_from_user(pts, args_pts, sizeof(*pts) * args->num_pts)) {
err = -EFAULT;
goto out;
}
for (i = 0; i < args->num_pts; i++) {
if (pts[i].id >= nvhost_syncpt_nb_pts(&ctx->dev->syncpt) &&
pts[i].id != NVSYNCPT_INVALID) {
err = -EINVAL;
goto out;
}
}
err = nvhost_sync_create_fence(&ctx->dev->syncpt, pts, args->num_pts,
name, &args->fence_fd);
out:
kfree(pts);
return err;
#else
return -EINVAL;
#endif
}
static int nvhost_ioctl_ctrl_module_mutex(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_module_mutex_args *args)
{
int err = 0;
if (args->id >= nvhost_syncpt_nb_mlocks(&ctx->dev->syncpt) ||
args->lock > 1)
return -EINVAL;
trace_nvhost_ioctl_ctrl_module_mutex(args->lock, args->id);
if (args->lock && !ctx->mod_locks[args->id]) {
if (args->id == 0)
nvhost_module_busy(ctx->dev->dev);
else
err = nvhost_mutex_try_lock(&ctx->dev->syncpt,
args->id);
if (!err)
ctx->mod_locks[args->id] = 1;
} else if (!args->lock && ctx->mod_locks[args->id]) {
if (args->id == 0)
nvhost_module_idle(ctx->dev->dev);
else
nvhost_mutex_unlock(&ctx->dev->syncpt, args->id);
ctx->mod_locks[args->id] = 0;
}
return err;
}
static int nvhost_ioctl_ctrl_module_regrdwr(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_module_regrdwr_args *args)
{
u32 num_offsets = args->num_offsets;
u32 __user *offsets = (u32 *)(uintptr_t)args->offsets;
u32 __user *values = (u32 *)(uintptr_t)args->values;
u32 *vals;
u32 *p1;
int remaining;
int err;
struct platform_device *ndev;
trace_nvhost_ioctl_ctrl_module_regrdwr(args->id,
args->num_offsets, args->write);
/* Check that there is something to read and that block size is
* u32 aligned */
if (num_offsets == 0 || args->block_size & 3)
return -EINVAL;
ndev = nvhost_device_list_match_by_id(args->id);
if (!ndev)
return -ENODEV;
remaining = args->block_size >> 2;
vals = kmalloc(num_offsets * args->block_size,
GFP_KERNEL);
if (!vals)
return -ENOMEM;
p1 = vals;
if (args->write) {
if (copy_from_user((char *)vals, (char *)values,
num_offsets * args->block_size)) {
kfree(vals);
return -EFAULT;
}
while (num_offsets--) {
u32 offs;
if (get_user(offs, offsets)) {
kfree(vals);
return -EFAULT;
}
offsets++;
err = nvhost_write_module_regs(ndev,
offs, remaining, p1);
if (err) {
kfree(vals);
return err;
}
p1 += remaining;
}
kfree(vals);
} else {
while (num_offsets--) {
u32 offs;
if (get_user(offs, offsets)) {
kfree(vals);
return -EFAULT;
}
offsets++;
err = nvhost_read_module_regs(ndev,
offs, remaining, p1);
if (err) {
kfree(vals);
return err;
}
p1 += remaining;
}
if (copy_to_user((char *)values, (char *)vals,
args->num_offsets * args->block_size)) {
kfree(vals);
return -EFAULT;
}
kfree(vals);
}
return 0;
}
static int nvhost_ioctl_ctrl_get_version(struct nvhost_ctrl_userctx *ctx,
struct nvhost_get_param_args *args)
{
args->value = NVHOST_SUBMIT_VERSION_MAX_SUPPORTED;
return 0;
}
static int nvhost_ioctl_ctrl_syncpt_read_max(struct nvhost_ctrl_userctx *ctx,
struct nvhost_ctrl_syncpt_read_args *args)
{
if (args->id >= nvhost_syncpt_nb_pts(&ctx->dev->syncpt))
return -EINVAL;
args->value = nvhost_syncpt_read_max(&ctx->dev->syncpt, args->id);
return 0;
}
static long nvhost_ctrlctl(struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct nvhost_ctrl_userctx *priv = filp->private_data;
u8 buf[NVHOST_IOCTL_CTRL_MAX_ARG_SIZE];
int err = 0;
if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) ||
(_IOC_NR(cmd) == 0) ||
(_IOC_NR(cmd) > NVHOST_IOCTL_CTRL_LAST) ||
(_IOC_SIZE(cmd) > NVHOST_IOCTL_CTRL_MAX_ARG_SIZE))
return -EFAULT;
if (_IOC_DIR(cmd) & _IOC_WRITE) {
if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd)))
return -EFAULT;
}
switch (cmd) {
case NVHOST_IOCTL_CTRL_SYNCPT_READ:
err = nvhost_ioctl_ctrl_syncpt_read(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_SYNCPT_INCR:
err = nvhost_ioctl_ctrl_syncpt_incr(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_SYNCPT_WAIT:
err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_SYNC_FENCE_CREATE:
err = nvhost_ioctl_ctrl_sync_fence_create(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_MODULE_MUTEX:
err = nvhost_ioctl_ctrl_module_mutex(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_MODULE_REGRDWR:
err = nvhost_ioctl_ctrl_module_regrdwr(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_SYNCPT_WAITEX:
err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_GET_VERSION:
err = nvhost_ioctl_ctrl_get_version(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_SYNCPT_READ_MAX:
err = nvhost_ioctl_ctrl_syncpt_read_max(priv, (void *)buf);
break;
case NVHOST_IOCTL_CTRL_SYNCPT_WAITMEX:
err = nvhost_ioctl_ctrl_syncpt_waitmex(priv, (void *)buf);
break;
default:
err = -ENOTTY;
break;
}
if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ))
err = copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd));
return err;
}
static const struct file_operations nvhost_ctrlops = {
.owner = THIS_MODULE,
.release = nvhost_ctrlrelease,
.open = nvhost_ctrlopen,
.unlocked_ioctl = nvhost_ctrlctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = nvhost_ctrlctl,
#endif
};
#ifdef CONFIG_PM
static int power_on_host(struct platform_device *dev)
{
struct nvhost_master *host = nvhost_get_private_data(dev);
nvhost_syncpt_reset(&host->syncpt);
return 0;
}
static int power_off_host(struct platform_device *dev)
{
struct nvhost_master *host = nvhost_get_private_data(dev);
nvhost_syncpt_save(&host->syncpt);
return 0;
}
static void clock_on_host(struct platform_device *dev)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
struct nvhost_master *host = nvhost_get_private_data(dev);
nvhost_intr_start(&host->intr, clk_get_rate(pdata->clk[0]));
}
static int clock_off_host(struct platform_device *dev)
{
struct nvhost_master *host = nvhost_get_private_data(dev);
nvhost_intr_stop(&host->intr);
return 0;
}
#endif
static int nvhost_gather_filter_enabled(struct nvhost_syncpt *sp)
{
return 0;
}
static ssize_t nvhost_syncpt_capability_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct nvhost_capability_node *node =
container_of(attr, struct nvhost_capability_node, attr);
return snprintf(buf, PAGE_SIZE, "%u\n",
node->func(&node->host->syncpt));
}
static inline int nvhost_set_sysfs_capability_node(
struct nvhost_master *host, const char *name,
struct nvhost_capability_node *node,
int (*func)(struct nvhost_syncpt *sp))
{
node->attr.attr.name = name;
node->attr.attr.mode = S_IRUGO;
node->attr.show = nvhost_syncpt_capability_show;
node->func = func;
node->host = host;
return sysfs_create_file(host->caps_kobj, &node->attr.attr);
}
static int nvhost_user_init(struct nvhost_master *host)
{
int err, devno;
host->nvhost_class = class_create(THIS_MODULE, IFACE_NAME);
if (IS_ERR(host->nvhost_class)) {
err = PTR_ERR(host->nvhost_class);
dev_err(&host->dev->dev, "failed to create class\n");
goto fail;
}
err = alloc_chrdev_region(&devno, 0, 1, IFACE_NAME);
if (err < 0) {
dev_err(&host->dev->dev, "failed to reserve chrdev region\n");
goto fail;
}
cdev_init(&host->cdev, &nvhost_ctrlops);
host->cdev.owner = THIS_MODULE;
err = cdev_add(&host->cdev, devno, 1);
if (err < 0)
goto fail;
host->ctrl = device_create(host->nvhost_class, NULL, devno, NULL,
IFACE_NAME "-ctrl");
if (IS_ERR(host->ctrl)) {
err = PTR_ERR(host->ctrl);
dev_err(&host->dev->dev, "failed to create ctrl device\n");
goto fail;
}
host->caps_nodes = devm_kzalloc(&host->dev->dev,
sizeof(struct nvhost_capability_node) * 4, GFP_KERNEL);
if (!host->caps_nodes) {
err = -ENOMEM;
goto fail;
}
host->caps_kobj = kobject_create_and_add("capabilities",
&host->dev->dev.kobj);
if (!host->caps_kobj) {
err = -EIO;
goto fail;
}
if (nvhost_set_sysfs_capability_node(host, num_syncpts_name,
host->caps_nodes, &nvhost_syncpt_nb_pts)) {
err = -EIO;
goto fail;
}
if (nvhost_set_sysfs_capability_node(host, num_waitbases_name,
host->caps_nodes + 1, &nvhost_syncpt_nb_bases)) {
err = -EIO;
goto fail;
}
if (nvhost_set_sysfs_capability_node(host, num_mutexes_name,
host->caps_nodes + 2, &nvhost_syncpt_nb_mlocks)) {
err = -EIO;
goto fail;
}
if (nvhost_set_sysfs_capability_node(host,
gather_filter_enabled_name, host->caps_nodes + 3,
nvhost_gather_filter_enabled)) {
err = -EIO;
goto fail;
}
return 0;
fail:
return err;
}
struct nvhost_channel *nvhost_alloc_channel(struct platform_device *dev)
{
return host_device_op().alloc_nvhost_channel(dev);
}
void nvhost_free_channel(struct nvhost_channel *ch)
{
host_device_op().free_nvhost_channel(ch);
}
static void nvhost_free_resources(struct nvhost_master *host)
{
kfree(host->intr.syncpt);
host->intr.syncpt = 0;
}
static int nvhost_alloc_resources(struct nvhost_master *host)
{
int err;
err = nvhost_init_chip_support(host);
if (err)
return err;
host->intr.syncpt = kzalloc(sizeof(struct nvhost_intr_syncpt) *
nvhost_syncpt_nb_pts(&host->syncpt),
GFP_KERNEL);
if (!host->intr.syncpt) {
/* frees happen in the support removal phase */
return -ENOMEM;
}
return 0;
}
static struct of_device_id tegra_host1x_of_match[] = {
#ifdef TEGRA_11X_OR_HIGHER_CONFIG
{ .compatible = "nvidia,tegra114-host1x",
.data = (struct nvhost_device_data *)&t11_host1x_info },
#endif
#ifdef TEGRA_12X_OR_HIGHER_CONFIG
{ .compatible = "nvidia,tegra124-host1x",
.data = (struct nvhost_device_data *)&t124_host1x_info },
#endif
{ },
};
void nvhost_host1x_update_clk(struct platform_device *pdev)
{
struct nvhost_device_data *pdata = NULL;
struct nvhost_device_profile *profile;
/* There are only two chips which need this workaround, so hardcode */
#ifdef CONFIG_ARCH_TEGRA_114_SOC
if (of_machine_is_compatible("nvidia,tegra114"))
pdata = &t11_gr3d_info;
#endif
if (!pdata)
return;
profile = pdata->power_profile;
if (profile && profile->actmon)
actmon_op().update_sample_period(profile->actmon);
}
int nvhost_host1x_finalize_poweron(struct platform_device *dev)
{
return power_on_host(dev);
}
int nvhost_host1x_prepare_poweroff(struct platform_device *dev)
{
return power_off_host(dev);
}
static int nvhost_probe(struct platform_device *dev)
{
struct nvhost_master *host;
struct resource *regs;
int syncpt_irq, generic_irq;
int err;
struct nvhost_device_data *pdata = NULL;
if (dev->dev.of_node) {
const struct of_device_id *match;
match = of_match_device(tegra_host1x_of_match, &dev->dev);
if (match)
pdata = (struct nvhost_device_data *)match->data;
} else
pdata = (struct nvhost_device_data *)dev->dev.platform_data;
WARN_ON(!pdata);
if (!pdata) {
dev_info(&dev->dev, "no platform data\n");
return -ENODATA;
}
regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&dev->dev, "missing host1x regs\n");
return -ENXIO;
}
syncpt_irq = platform_get_irq(dev, 0);
if (IS_ERR_VALUE(syncpt_irq)) {
dev_err(&dev->dev, "missing syncpt irq\n");
return -ENXIO;
}
generic_irq = platform_get_irq(dev, 1);
if (IS_ERR_VALUE(generic_irq)) {
dev_err(&dev->dev, "missing generic irq\n");
return -ENXIO;
}
host = devm_kzalloc(&dev->dev, sizeof(*host), GFP_KERNEL);
if (!host)
return -ENOMEM;
nvhost = host;
host->dev = dev;
mutex_init(&pdata->lock);
/* Copy host1x parameters. The private_data gets replaced
* by nvhost_master later */
memcpy(&host->info, pdata->private_data,
sizeof(struct host1x_device_info));
pdata->pdev = dev;
/* set common host1x device data */
platform_set_drvdata(dev, pdata);
/* set private host1x device data */
nvhost_set_private_data(dev, host);
host->aperture = devm_request_and_ioremap(&dev->dev, regs);
if (!host->aperture) {
err = -ENXIO;
goto fail;
}
err = nvhost_alloc_resources(host);
if (err) {
dev_err(&dev->dev, "failed to init chip support\n");
goto fail;
}
host->memmgr = nvhost_memmgr_alloc_mgr();
if (!host->memmgr) {
dev_err(&dev->dev, "unable to create nvmap client\n");
err = -EIO;
goto fail;
}
err = nvhost_syncpt_init(dev, &host->syncpt);
if (err)
goto fail;
err = nvhost_intr_init(&host->intr, generic_irq, syncpt_irq);
if (err)
goto fail;
err = nvhost_user_init(host);
if (err)
goto fail;
err = nvhost_module_init(dev);
if (err)
goto fail;
#ifdef CONFIG_PM_GENERIC_DOMAINS
pdata->pd.name = "tegra-host1x";
err = nvhost_module_add_domain(&pdata->pd, dev);
#endif
nvhost_module_busy(dev);
nvhost_syncpt_reset(&host->syncpt);
nvhost_intr_start(&host->intr, clk_get_rate(pdata->clk[0]));
nvhost_device_list_init();
pdata->nvhost_timeout_default =
CONFIG_TEGRA_GRHOST_DEFAULT_TIMEOUT;
nvhost_debug_init(host);
nvhost_module_idle(dev);
dev_info(&dev->dev, "initialized\n");
return 0;
fail:
nvhost_free_resources(host);
if (host->memmgr)
nvhost_memmgr_put_mgr(host->memmgr);
kfree(host);
return err;
}
static int __exit nvhost_remove(struct platform_device *dev)
{
struct nvhost_master *host = nvhost_get_private_data(dev);
nvhost_intr_deinit(&host->intr);
nvhost_syncpt_deinit(&host->syncpt);
nvhost_free_resources(host);
#ifdef CONFIG_PM_RUNTIME
pm_runtime_put(&dev->dev);
pm_runtime_disable(&dev->dev);
#else
nvhost_module_disable_clk(&dev->dev);
#endif
return 0;
}
#ifdef CONFIG_PM
static int nvhost_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct nvhost_master *host = nvhost_get_private_data(pdev);
int ret = 0;
nvhost_module_enable_clk(dev);
power_off_host(pdev);
clock_off_host(pdev);
nvhost_module_disable_clk(dev);
ret = nvhost_module_suspend(&host->dev->dev);
dev_info(dev, "suspend status: %d\n", ret);
return ret;
}
static int nvhost_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
nvhost_module_enable_clk(dev);
clock_on_host(pdev);
power_on_host(pdev);
nvhost_module_disable_clk(dev);
dev_info(dev, "resuming\n");
return 0;
}
static const struct dev_pm_ops host1x_pm_ops = {
.suspend = nvhost_suspend,
.resume = nvhost_resume,
};
#endif /* CONFIG_PM */
static struct platform_driver platform_driver = {
.probe = nvhost_probe,
.remove = __exit_p(nvhost_remove),
.driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
#ifdef CONFIG_PM
.pm = &host1x_pm_ops,
#endif
#ifdef CONFIG_OF
.of_match_table = tegra_host1x_of_match,
#endif
},
};
static int __init nvhost_mod_init(void)
{
return platform_driver_register(&platform_driver);
}
static void __exit nvhost_mod_exit(void)
{
platform_driver_unregister(&platform_driver);
}
/* host1x master device needs nvmap to be instantiated first.
* nvmap is instantiated via fs_initcall.
* Hence instantiate host1x master device using rootfs_initcall
* which is one level after fs_initcall. */
rootfs_initcall(nvhost_mod_init);
module_exit(nvhost_mod_exit);

View File

@@ -0,0 +1,114 @@
/*
* drivers/video/tegra/host/host1x/host1x.h
*
* Tegra Graphics Host Driver Entrypoint
*
* Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
*
* 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 __NVHOST_HOST1X_H
#define __NVHOST_HOST1X_H
#include <linux/cdev.h>
#include <linux/nvhost.h>
#include "nvhost_syncpt.h"
#include "nvhost_intr.h"
#define TRACE_MAX_LENGTH 128U
#define IFACE_NAME "nvhost"
struct nvhost_channel;
struct mem_mgr;
struct host1x_device_info {
int nb_channels; /* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
int nb_bases; /* host1x: num syncpoints supported */
u64 client_managed; /* host1x: client managed syncpts */
int nb_mlocks; /* host1x: number of mlocks */
const char **syncpt_names; /* names of sync points */
};
struct nvhost_master {
void __iomem *aperture;
void __iomem *sync_aperture;
struct class *nvhost_class;
struct cdev cdev;
struct device *ctrl;
struct nvhost_syncpt syncpt;
struct mem_mgr *memmgr;
struct nvhost_intr intr;
struct platform_device *dev;
atomic_t clientid;
struct host1x_device_info info;
struct kobject *caps_kobj;
struct nvhost_capability_node *caps_nodes;
};
extern struct nvhost_master *nvhost;
void nvhost_debug_init(struct nvhost_master *master);
void nvhost_device_debug_init(struct platform_device *dev);
void nvhost_device_debug_deinit(struct platform_device *dev);
void nvhost_debug_dump(struct nvhost_master *master);
int nvhost_host1x_finalize_poweron(struct platform_device *dev);
int nvhost_host1x_prepare_poweroff(struct platform_device *dev);
struct nvhost_channel *nvhost_alloc_channel(struct platform_device *dev);
void nvhost_free_channel(struct nvhost_channel *ch);
extern pid_t nvhost_debug_null_kickoff_pid;
static inline void *nvhost_get_private_data(struct platform_device *_dev)
{
struct nvhost_device_data *pdata =
(struct nvhost_device_data *)platform_get_drvdata(_dev);
BUG_ON(!pdata);
return pdata ? pdata->private_data : NULL;
}
static inline void nvhost_set_private_data(struct platform_device *_dev,
void *priv_data)
{
struct nvhost_device_data *pdata =
(struct nvhost_device_data *)platform_get_drvdata(_dev);
WARN_ON(!pdata);
pdata->private_data = priv_data;
}
static inline struct nvhost_master *nvhost_get_host(
struct platform_device *_dev)
{
struct platform_device *pdev;
if (_dev->dev.parent && _dev->dev.parent != &platform_bus) {
pdev = to_platform_device(_dev->dev.parent);
return nvhost_get_private_data(pdev);
} else
return nvhost_get_private_data(_dev);
}
static inline struct platform_device *nvhost_get_parent(
struct platform_device *_dev)
{
return (_dev->dev.parent && _dev->dev.parent != &platform_bus)
? to_platform_device(_dev->dev.parent) : NULL;
}
void nvhost_host1x_update_clk(struct platform_device *pdev);
#endif

View File

@@ -0,0 +1,153 @@
/*
* drivers/video/tegra/host/host1x/host1x01_hardware.h
*
* Tegra Graphics Host Register Offsets for T20/T30
*
* Copyright (c) 2010-2012 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 __NVHOST_HOST1X01_HARDWARE_H
#define __NVHOST_HOST1X01_HARDWARE_H
#include <linux/types.h>
#include <linux/bitops.h>
#include "hw_host1x01_channel.h"
#include "hw_host1x01_sync.h"
#include "hw_host1x01_uclass.h"
/* channel registers */
#define NV_HOST1X_CHANNEL_MAP_SIZE_BYTES 16384
#define NV_HOST1X_SYNC_MLOCK_NUM 16
/* sync registers */
#define HOST1X_CHANNEL_SYNC_REG_BASE 0x3000
#define NV_HOST1X_NB_MLOCKS 16
static inline u32 nvhost_class_host_wait_syncpt(
unsigned indx, unsigned threshold)
{
return host1x_uclass_wait_syncpt_indx_f(indx)
| host1x_uclass_wait_syncpt_thresh_f(threshold);
}
static inline u32 nvhost_class_host_load_syncpt_base(
unsigned indx, unsigned threshold)
{
return host1x_uclass_load_syncpt_base_base_indx_f(indx)
| host1x_uclass_load_syncpt_base_value_f(threshold);
}
static inline u32 nvhost_class_host_wait_syncpt_base(
unsigned indx, unsigned base_indx, unsigned offset)
{
return host1x_uclass_wait_syncpt_base_indx_f(indx)
| host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_wait_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt_base(
unsigned base_indx, unsigned offset)
{
return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_incr_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt(
unsigned cond, unsigned indx)
{
return host1x_uclass_incr_syncpt_cond_f(cond)
| host1x_uclass_incr_syncpt_indx_f(indx);
}
static inline u32 nvhost_class_host_indoff_reg_write(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indbe_f(0xf)
| host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset);
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
static inline u32 nvhost_class_host_indoff_reg_read(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset)
| host1x_uclass_indoff_rwn_read_v();
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
/* cdma opcodes */
static inline u32 nvhost_opcode_setclass(
unsigned class_id, unsigned offset, unsigned mask)
{
return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
}
static inline u32 nvhost_opcode_incr(unsigned offset, unsigned count)
{
return (1 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_nonincr(unsigned offset, unsigned count)
{
return (2 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_mask(unsigned offset, unsigned mask)
{
return (3 << 28) | (offset << 16) | mask;
}
static inline u32 nvhost_opcode_imm(unsigned offset, unsigned value)
{
return (4 << 28) | (offset << 16) | value;
}
static inline u32 nvhost_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
{
return nvhost_opcode_imm(host1x_uclass_incr_syncpt_r(),
nvhost_class_host_incr_syncpt(cond, indx));
}
static inline u32 nvhost_opcode_restart(unsigned address)
{
return (5 << 28) | (address >> 4);
}
static inline u32 nvhost_opcode_gather(unsigned count)
{
return (6 << 28) | count;
}
static inline u32 nvhost_opcode_gather_insert(unsigned offset, unsigned incr,
unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | (incr << 14) | count;
}
#define NVHOST_OPCODE_NOOP nvhost_opcode_nonincr(0, 0)
static inline u32 nvhost_mask2(unsigned x, unsigned y)
{
return 1 | (1 << (y - x));
}
#endif

View File

@@ -0,0 +1,153 @@
/*
* drivers/video/tegra/host/host1x/host1x01_hardware.h
*
* Tegra Graphics Host Register Offsets for T20/T30
*
* Copyright (c) 2010-2012 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 __NVHOST_HOST1X02_HARDWARE_H
#define __NVHOST_HOST1X02_HARDWARE_H
#include <linux/types.h>
#include <linux/bitops.h>
#include "hw_host1x02_channel.h"
#include "hw_host1x02_sync.h"
#include "hw_host1x02_uclass.h"
/* channel registers */
#define NV_HOST1X_CHANNEL_MAP_SIZE_BYTES 16384
#define NV_HOST1X_SYNC_MLOCK_NUM 16
/* sync registers */
#define HOST1X_CHANNEL_SYNC_REG_BASE 0x3000
#define NV_HOST1X_NB_MLOCKS 16
static inline u32 nvhost_class_host_wait_syncpt(
unsigned indx, unsigned threshold)
{
return host1x_uclass_wait_syncpt_indx_f(indx)
| host1x_uclass_wait_syncpt_thresh_f(threshold);
}
static inline u32 nvhost_class_host_load_syncpt_base(
unsigned indx, unsigned threshold)
{
return host1x_uclass_load_syncpt_base_base_indx_f(indx)
| host1x_uclass_load_syncpt_base_value_f(threshold);
}
static inline u32 nvhost_class_host_wait_syncpt_base(
unsigned indx, unsigned base_indx, unsigned offset)
{
return host1x_uclass_wait_syncpt_base_indx_f(indx)
| host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_wait_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt_base(
unsigned base_indx, unsigned offset)
{
return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_incr_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt(
unsigned cond, unsigned indx)
{
return host1x_uclass_incr_syncpt_cond_f(cond)
| host1x_uclass_incr_syncpt_indx_f(indx);
}
static inline u32 nvhost_class_host_indoff_reg_write(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indbe_f(0xf)
| host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset);
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
static inline u32 nvhost_class_host_indoff_reg_read(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset)
| host1x_uclass_indoff_rwn_read_v();
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
/* cdma opcodes */
static inline u32 nvhost_opcode_setclass(
unsigned class_id, unsigned offset, unsigned mask)
{
return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
}
static inline u32 nvhost_opcode_incr(unsigned offset, unsigned count)
{
return (1 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_nonincr(unsigned offset, unsigned count)
{
return (2 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_mask(unsigned offset, unsigned mask)
{
return (3 << 28) | (offset << 16) | mask;
}
static inline u32 nvhost_opcode_imm(unsigned offset, unsigned value)
{
return (4 << 28) | (offset << 16) | value;
}
static inline u32 nvhost_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
{
return nvhost_opcode_imm(host1x_uclass_incr_syncpt_r(),
nvhost_class_host_incr_syncpt(cond, indx));
}
static inline u32 nvhost_opcode_restart(unsigned address)
{
return (5 << 28) | (address >> 4);
}
static inline u32 nvhost_opcode_gather(unsigned count)
{
return (6 << 28) | count;
}
static inline u32 nvhost_opcode_gather_insert(unsigned offset, unsigned incr,
unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | (incr << 14) | count;
}
#define NVHOST_OPCODE_NOOP nvhost_opcode_nonincr(0, 0)
static inline u32 nvhost_mask2(unsigned x, unsigned y)
{
return 1 | (1 << (y - x));
}
#endif

View File

@@ -0,0 +1,169 @@
/*
* drivers/video/tegra/host/host1x/host1x03_hardware.h
*
* Tegra Graphics Host Register Offsets for T20/T30
*
* Copyright (c) 2012 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 __NVHOST_HOST1X03_HARDWARE_H
#define __NVHOST_HOST1X03_HARDWARE_H
#include <linux/types.h>
#include <linux/bitops.h>
#include "hw_host1x03_channel.h"
#include "hw_host1x03_sync.h"
#include "hw_host1x03_uclass.h"
/* channel registers */
#define NV_HOST1X_CHANNEL_MAP_SIZE_BYTES 16384
#define NV_HOST1X_SYNC_MLOCK_NUM 16
/* sync registers */
#define HOST1X_CHANNEL_SYNC_REG_BASE 0x2100
#define NV_HOST1X_NB_MLOCKS 16
static inline u32 nvhost_class_host_wait_syncpt(
unsigned indx, unsigned threshold)
{
return (indx << 24) | (threshold & 0xffffff);
}
static inline u32 nvhost_class_host_load_syncpt_base(
unsigned indx, unsigned threshold)
{
return host1x_uclass_wait_syncpt_indx_f(indx)
| host1x_uclass_wait_syncpt_thresh_f(threshold);
}
static inline u32 nvhost_class_host_wait_syncpt_base(
unsigned indx, unsigned base_indx, unsigned offset)
{
return host1x_uclass_wait_syncpt_base_indx_f(indx)
| host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_wait_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt_base(
unsigned base_indx, unsigned offset)
{
return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_incr_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt(
unsigned cond, unsigned indx)
{
return host1x_uclass_incr_syncpt_cond_f(cond)
| host1x_uclass_incr_syncpt_indx_f(indx);
}
enum {
NV_HOST_MODULE_HOST1X = 0,
NV_HOST_MODULE_MPE = 1,
NV_HOST_MODULE_GR3D = 6
};
static inline u32 nvhost_class_host_indoff_reg_write(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indbe_f(0xf)
| host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset);
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
static inline u32 nvhost_class_host_indoff_reg_read(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset)
| host1x_uclass_indoff_rwn_read_v();
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
/* cdma opcodes */
static inline u32 nvhost_opcode_setclass(
unsigned class_id, unsigned offset, unsigned mask)
{
return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
}
static inline u32 nvhost_opcode_incr(unsigned offset, unsigned count)
{
return (1 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_nonincr(unsigned offset, unsigned count)
{
return (2 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_mask(unsigned offset, unsigned mask)
{
return (3 << 28) | (offset << 16) | mask;
}
static inline u32 nvhost_opcode_imm(unsigned offset, unsigned value)
{
return (4 << 28) | (offset << 16) | value;
}
static inline u32 nvhost_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
{
return nvhost_opcode_imm(host1x_uclass_incr_syncpt_r(),
nvhost_class_host_incr_syncpt(cond, indx));
}
static inline u32 nvhost_opcode_restart(unsigned address)
{
return (5 << 28) | (address >> 4);
}
static inline u32 nvhost_opcode_gather(unsigned count)
{
return (6 << 28) | count;
}
static inline u32 nvhost_opcode_gather_nonincr(unsigned offset, unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | count;
}
static inline u32 nvhost_opcode_gather_incr(unsigned offset, unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
}
static inline u32 nvhost_opcode_gather_insert(unsigned offset, unsigned incr,
unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | (incr << 14) | count;
}
#define NVHOST_OPCODE_NOOP nvhost_opcode_nonincr(0, 0)
static inline u32 nvhost_mask2(unsigned x, unsigned y)
{
return 1 | (1 << (y - x));
}
#endif

View File

@@ -0,0 +1,50 @@
/*
* Tegra Graphics Host Actmon
*
* Copyright (c) 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_ACTMON_H
#define __HOST1X_ACTMON_H
struct dentry;
enum init_e {
ACTMON_OFF = 0,
ACTMON_READY = 1,
ACTMON_SLEEP = 2
};
struct host1x_actmon {
/* Set to 1 if actmon has been initialized */
enum init_e init;
struct nvhost_master *host;
void __iomem *regs;
struct clk *clk;
/* Counters for debug usage */
int above_wmark;
int below_wmark;
/* Store actmon period. clks_per_sample can be used even when host1x is
* not active. */
long usecs_per_sample;
long clks_per_sample;
int k;
};
#endif

View File

@@ -0,0 +1,521 @@
/*
* Tegra Graphics Host Actmon support for T114
*
* 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 <linux/nvhost.h>
#include <linux/io.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include "dev.h"
#include "chip_support.h"
#include "host1x_actmon.h"
/*
* host1x_actmon_update_sample_period_safe(host)
*
* This function updates frequency specific values on actmon using the current
* host1x frequency. The function should be called only when host1x is active.
*
* Actmon takes samples 3d activity every clock cycle. If 3d is active,
* the internal counter is increased by one. Depending on value of
* host1x_sync_actmon_status_gr3d_mon_act_f(x), these internal values
* grow either to 255 (1) or 65535 (0). After growing up to this value,
* the actual counter is increased by one.
*
* Each period takes a number of counter increments. If we wish a period
* to be a known time, we get the number of counter increments by:
*
* f_{host}
* clks = --------- * t_{sample_period}.
* 256
*
* This is used as a base value for determining a proper value for raw sample
* period value.
*/
static void host1x_actmon_update_sample_period_safe(
struct host1x_actmon *actmon)
{
struct nvhost_master *host = actmon->host;
void __iomem *sync_regs = host->sync_aperture;
long freq_mhz, clks_per_sample;
struct nvhost_device_data *pdata = platform_get_drvdata(host->dev);
/* We use MHz and us instead of Hz and s due to numerical limitations */
freq_mhz = clk_get_rate(pdata->clk[0]) / 1000000;
clks_per_sample = (freq_mhz * actmon->usecs_per_sample) / 256;
actmon->clks_per_sample = clks_per_sample;
writel(host1x_sync_actmon_status_sample_period_f(clks_per_sample)
| host1x_sync_actmon_status_status_source_f(
host1x_sync_actmon_status_status_source_usec_v()),
sync_regs + host1x_sync_actmon_status_r());
}
static int host1x_actmon_init(struct host1x_actmon *actmon)
{
struct nvhost_master *host = actmon->host;
void __iomem *sync_regs = host->sync_aperture;
u32 val;
unsigned long timeout = jiffies + msecs_to_jiffies(25);
if (actmon->init == ACTMON_READY)
return 0;
nvhost_module_busy(host->dev);
if (actmon->init == ACTMON_OFF) {
actmon->usecs_per_sample = 160;
actmon->above_wmark = 0;
actmon->below_wmark = 0;
actmon->k = 6;
}
/* Initialize average */
writel(0, sync_regs + host1x_sync_actmon_init_avg_r());
/* Default count weight - 1 for per unit actmons */
writel(1, sync_regs + host1x_sync_actmon_count_weight_r());
/* Wait for actmon to be disabled */
do {
val = readl(sync_regs + host1x_sync_actmon_status_r());
} while (!time_after(jiffies, timeout) &&
val & host1x_sync_actmon_status_gr3d_mon_act_f(1));
WARN_ON(time_after(jiffies, timeout));
/* Write (normalised) sample period. */
host1x_actmon_update_sample_period_safe(actmon);
/* Clear interrupt status */
writel(0xffffffff, sync_regs + host1x_sync_actmon_intr_status_r());
val = readl(sync_regs + host1x_sync_actmon_ctrl_r());
/* Enable periodic mode */
val |= host1x_sync_actmon_ctrl_enb_periodic_f(1);
/* Moving avg IIR filter window size 2^6=128 */
val |= host1x_sync_actmon_ctrl_k_val_f(actmon->k);
/* Enable ACTMON */
val |= host1x_sync_actmon_ctrl_enb_f(1);
writel(val, sync_regs + host1x_sync_actmon_ctrl_r());
actmon->init = ACTMON_READY;
nvhost_module_idle(host->dev);
return 0;
}
static void host1x_actmon_deinit(struct host1x_actmon *actmon)
{
struct nvhost_master *host = actmon->host;
void __iomem *sync_regs = host->sync_aperture;
u32 val;
if (actmon->init != ACTMON_READY)
return;
nvhost_module_busy(host->dev);
/* Disable actmon */
val = readl(sync_regs + host1x_sync_actmon_ctrl_r());
val &= ~host1x_sync_actmon_ctrl_enb_m();
val &= ~host1x_sync_actmon_ctrl_enb_periodic_m();
val &= ~host1x_sync_actmon_ctrl_avg_above_wmark_en_m();
val &= ~host1x_sync_actmon_ctrl_avg_below_wmark_en_m();
writel(val, sync_regs + host1x_sync_actmon_ctrl_r());
/* Write sample period */
writel(host1x_sync_actmon_status_sample_period_f(0)
| host1x_sync_actmon_status_status_source_f(
host1x_sync_actmon_status_status_source_usec_v()),
sync_regs + host1x_sync_actmon_status_r());
/* Clear interrupt status */
writel(0xffffffff, sync_regs + host1x_sync_actmon_intr_status_r());
actmon->init = ACTMON_SLEEP;
nvhost_module_idle(host->dev);
}
static int host1x_actmon_avg(struct host1x_actmon *actmon, u32 *val)
{
struct nvhost_master *host = actmon->host;
void __iomem *sync_regs = host->sync_aperture;
if (actmon->init != ACTMON_READY) {
*val = 0;
return 0;
}
nvhost_module_busy(host->dev);
*val = readl(sync_regs + host1x_sync_actmon_avg_count_r());
nvhost_module_idle(host->dev);
rmb();
return 0;
}
static int host1x_actmon_avg_norm(struct host1x_actmon *actmon, u32 *avg)
{
struct nvhost_master *host = actmon->host;
void __iomem *sync_regs = host->sync_aperture;
long val;
if (actmon->init != ACTMON_READY) {
*avg = 0;
return 0;
}
nvhost_module_busy(host->dev);
/* Read load from hardware */
val = readl(sync_regs + host1x_sync_actmon_avg_count_r());
/* Undocumented feature: AVG value is not scaled. */
*avg = (val * 1000) / ((1 + actmon->clks_per_sample) * 256);
nvhost_module_idle(host->dev);
rmb();
return 0;
}
static int host1x_actmon_above_wmark_count(struct host1x_actmon *actmon)
{
return actmon->above_wmark;
}
static int host1x_actmon_below_wmark_count(struct host1x_actmon *actmon)
{
return actmon->below_wmark;
}
static void host1x_actmon_update_sample_period(struct host1x_actmon *actmon)
{
void __iomem *sync_regs = actmon->host->sync_aperture;
long old_clks_per_sample;
long ratio, avg;
u32 val;
unsigned long timeout = jiffies + msecs_to_jiffies(25);
/* No sense to update actmon if actmon is inactive */
if (actmon->init != ACTMON_READY)
return;
nvhost_module_busy(actmon->host->dev);
/* Disable actmon */
val = readl(sync_regs + host1x_sync_actmon_ctrl_r());
val &= ~host1x_sync_actmon_ctrl_enb_m();
val &= ~host1x_sync_actmon_ctrl_enb_periodic_m();
writel(val, sync_regs + host1x_sync_actmon_ctrl_r());
/* Calculate ratio between old and new clks_per_sample */
old_clks_per_sample = actmon->clks_per_sample;
host1x_actmon_update_sample_period_safe(actmon);
ratio = (actmon->clks_per_sample * 1000) / old_clks_per_sample;
/* Scale the avg to match new clock */
avg = readl(sync_regs + host1x_sync_actmon_avg_count_r());
avg *= ratio;
avg /= 1000;
writel(avg, sync_regs + host1x_sync_actmon_init_avg_r());
/* Wait for actmon to be disabled */
do {
val = readl(sync_regs + host1x_sync_actmon_status_r());
} while (!time_after(jiffies, timeout) &&
val & host1x_sync_actmon_status_gr3d_mon_act_f(1));
/* Re-enable actmon - this will latch the init value to avg reg */
val |= host1x_sync_actmon_ctrl_enb_m();
val |= host1x_sync_actmon_ctrl_enb_periodic_m();
writel(val, sync_regs + host1x_sync_actmon_ctrl_r());
nvhost_module_idle(actmon->host->dev);
}
static void host1x_actmon_set_sample_period_norm(struct host1x_actmon *actmon,
long usecs)
{
actmon->usecs_per_sample = usecs;
host1x_actmon_update_sample_period(actmon);
}
static void host1x_actmon_set_k(struct host1x_actmon *actmon, u32 k)
{
void __iomem *sync_regs = actmon->host->sync_aperture;
long val;
actmon->k = k;
val = readl(sync_regs + host1x_sync_actmon_ctrl_r());
val &= ~(host1x_sync_actmon_ctrl_k_val_m());
val |= host1x_sync_actmon_ctrl_k_val_f(actmon->k);
writel(val, sync_regs + host1x_sync_actmon_ctrl_r());
}
static u32 host1x_actmon_get_k(struct host1x_actmon *actmon)
{
return actmon->k;
}
static long host1x_actmon_get_sample_period(struct host1x_actmon *actmon)
{
return actmon->clks_per_sample;
}
static long host1x_actmon_get_sample_period_norm(struct host1x_actmon *actmon)
{
return actmon->usecs_per_sample;
}
/*
* Debugfs functions
*/
static int actmon_below_wmark_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
seq_printf(s, "%d\n", host1x_actmon_below_wmark_count(actmon));
return 0;
}
static int actmon_below_wmark_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_below_wmark_show, inode->i_private);
}
static const struct file_operations actmon_below_wmark_fops = {
.open = actmon_below_wmark_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_above_wmark_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
seq_printf(s, "%d\n", host1x_actmon_above_wmark_count(actmon));
return 0;
}
static int actmon_above_wmark_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_above_wmark_show, inode->i_private);
}
static const struct file_operations actmon_above_wmark_fops = {
.open = actmon_above_wmark_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_avg_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
u32 avg;
int err;
err = host1x_actmon_avg(actmon, &avg);
if (!err)
seq_printf(s, "%d\n", avg);
return err;
}
static int actmon_avg_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_avg_show, inode->i_private);
}
static const struct file_operations actmon_avg_fops = {
.open = actmon_avg_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_avg_norm_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
u32 avg;
int err;
err = host1x_actmon_avg_norm(actmon, &avg);
if (!err)
seq_printf(s, "%d\n", avg);
return err;
}
static int actmon_avg_norm_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_avg_norm_show, inode->i_private);
}
static const struct file_operations actmon_avg_norm_fops = {
.open = actmon_avg_norm_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_sample_period_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
long period = host1x_actmon_get_sample_period(actmon);
seq_printf(s, "%ld\n", period);
return 0;
}
static int actmon_sample_period_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_sample_period_show, inode->i_private);
}
static const struct file_operations actmon_sample_period_fops = {
.open = actmon_sample_period_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_sample_period_norm_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
long period = host1x_actmon_get_sample_period_norm(actmon);
seq_printf(s, "%ld\n", period);
return 0;
}
static int actmon_sample_period_norm_open(struct inode *inode,
struct file *file)
{
return single_open(file, actmon_sample_period_norm_show,
inode->i_private);
}
static ssize_t actmon_sample_period_norm_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct seq_file *s = file->private_data;
struct host1x_actmon *actmon = s->private;
char buffer[40];
int buf_size;
unsigned long period;
memset(buffer, 0, sizeof(buffer));
buf_size = min(count, (sizeof(buffer)-1));
if (copy_from_user(buffer, user_buf, buf_size))
return -EFAULT;
if (kstrtoul(buffer, 10, &period))
return -EINVAL;
host1x_actmon_set_sample_period_norm(actmon, period);
return count;
}
static const struct file_operations actmon_sample_period_norm_fops = {
.open = actmon_sample_period_norm_open,
.read = seq_read,
.write = actmon_sample_period_norm_write,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_k_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
long period = host1x_actmon_get_k(actmon);
seq_printf(s, "%ld\n", period);
return 0;
}
static int actmon_k_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_k_show, inode->i_private);
}
static ssize_t actmon_k_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct seq_file *s = file->private_data;
struct host1x_actmon *actmon = s->private;
char buffer[40];
int buf_size;
unsigned long k;
memset(buffer, 0, sizeof(buffer));
buf_size = min(count, (sizeof(buffer)-1));
if (copy_from_user(buffer, user_buf, buf_size))
return -EFAULT;
if (kstrtoul(buffer, 10, &k))
return -EINVAL;
host1x_actmon_set_k(actmon, k);
return count;
}
static const struct file_operations actmon_k_fops = {
.open = actmon_k_open,
.read = seq_read,
.write = actmon_k_write,
.llseek = seq_lseek,
.release = single_release,
};
static void host1x_actmon_debug_init(struct host1x_actmon *actmon,
struct dentry *de)
{
BUG_ON(!actmon);
debugfs_create_file("actmon_k", S_IRUGO, de,
actmon, &actmon_k_fops);
debugfs_create_file("actmon_sample_period", S_IRUGO, de,
actmon, &actmon_sample_period_fops);
debugfs_create_file("actmon_sample_period_norm", S_IRUGO, de,
actmon, &actmon_sample_period_norm_fops);
debugfs_create_file("actmon_avg_norm", S_IRUGO, de,
actmon, &actmon_avg_norm_fops);
debugfs_create_file("actmon_avg", S_IRUGO, de,
actmon, &actmon_avg_fops);
debugfs_create_file("actmon_above_wmark", S_IRUGO, de,
actmon, &actmon_above_wmark_fops);
debugfs_create_file("actmon_below_wmark", S_IRUGO, de,
actmon, &actmon_below_wmark_fops);
}
static const struct nvhost_actmon_ops host1x_actmon_ops = {
.init = host1x_actmon_init,
.deinit = host1x_actmon_deinit,
.read_avg = host1x_actmon_avg,
.above_wmark_count = host1x_actmon_above_wmark_count,
.below_wmark_count = host1x_actmon_below_wmark_count,
.read_avg_norm = host1x_actmon_avg_norm,
.update_sample_period = host1x_actmon_update_sample_period,
.set_sample_period_norm = host1x_actmon_set_sample_period_norm,
.get_sample_period_norm = host1x_actmon_get_sample_period_norm,
.get_sample_period = host1x_actmon_get_sample_period,
.get_k = host1x_actmon_get_k,
.set_k = host1x_actmon_set_k,
.debug_init = host1x_actmon_debug_init,
};

View File

@@ -0,0 +1,540 @@
/*
* Tegra Graphics Host Actmon support for T124
*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* 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 <linux/nvhost.h>
#include <linux/io.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include "dev.h"
#include "chip_support.h"
#include "host1x/host1x_actmon.h"
void actmon_writel(struct host1x_actmon *actmon, u32 val, u32 reg)
{
nvhost_dbg(dbg_reg, " r=0x%x v=0x%x", reg, val);
writel(val, actmon->regs + reg);
}
u32 actmon_readl(struct host1x_actmon *actmon, u32 reg)
{
u32 val = readl(actmon->regs + reg);
nvhost_dbg(dbg_reg, " r=0x%x v=0x%x", reg, val);
return val;
}
/*
* actmon_update_sample_period_safe(host)
*
* This function updates frequency specific values on actmon using the current
* actmon frequency. The function should be called only when host1x is active.
*
*/
static void actmon_update_sample_period_safe(struct host1x_actmon *actmon)
{
long freq_mhz, clks_per_sample;
u32 val;
/* We use MHz and us instead of Hz and s due to numerical limitations */
freq_mhz = clk_get_rate(actmon->clk) / 1000000;
clks_per_sample = freq_mhz * actmon->usecs_per_sample;
actmon->clks_per_sample = clks_per_sample;
val = actmon_readl(actmon, actmon_ctrl_r());
val &= ~actmon_ctrl_sample_period_m();
val |= actmon_ctrl_sample_period_f(clks_per_sample);
actmon_writel(actmon, val, actmon_ctrl_r());
/* AVG value depends on sample period => clear it */
actmon_writel(actmon, 0, actmon_init_avg_r());
}
static int host1x_actmon_init(struct host1x_actmon *actmon)
{
struct platform_device *pdev = actmon->host->dev;
struct nvhost_device_data *pdata =
(struct nvhost_device_data *)platform_get_drvdata(pdev);
u32 val;
if (actmon->init == ACTMON_READY)
return 0;
if (actmon->init == ACTMON_OFF) {
actmon->usecs_per_sample = 10;
actmon->above_wmark = 0;
actmon->below_wmark = 0;
actmon->k = 1;
}
actmon->clk = pdata->clk[1];
if (!actmon->clk)
return -ENODEV;
nvhost_module_busy(actmon->host->dev);
/* Clear average and control registers */
actmon_writel(actmon, 0, actmon_init_avg_r());
actmon_writel(actmon, 0, actmon_ctrl_r());
/* Write (normalised) sample period. */
actmon_update_sample_period_safe(actmon);
/* Clear interrupt status */
actmon_writel(actmon, 0xffffffff, actmon_intr_status_r());
val = actmon_readl(actmon, actmon_ctrl_r());
val |= actmon_ctrl_enb_periodic_f(1);
val |= actmon_ctrl_k_val_f(actmon->k);
val |= actmon_ctrl_actmon_enable_f(1);
actmon_writel(actmon, val, actmon_ctrl_r());
nvhost_module_idle(actmon->host->dev);
actmon->init = ACTMON_READY;
return 0;
}
static void host1x_actmon_deinit(struct host1x_actmon *actmon)
{
if (actmon->init != ACTMON_READY)
return;
actmon->init = ACTMON_SLEEP;
/* Disable actmon and clear interrupt status */
nvhost_module_busy(actmon->host->dev);
actmon_writel(actmon, 0, actmon_ctrl_r());
actmon_writel(actmon, 0xffffffff, actmon_intr_status_r());
nvhost_module_idle(actmon->host->dev);
}
static int host1x_actmon_avg(struct host1x_actmon *actmon, u32 *val)
{
if (actmon->init != ACTMON_READY) {
*val = 0;
return 0;
}
nvhost_module_busy(actmon->host->dev);
*val = actmon_readl(actmon, actmon_avg_count_r());
nvhost_module_idle(actmon->host->dev);
rmb();
return 0;
}
static int host1x_actmon_avg_norm(struct host1x_actmon *actmon, u32 *avg)
{
long val;
if (!(actmon->init == ACTMON_READY && actmon->clks_per_sample > 0)) {
*avg = 0;
return 0;
}
/* Read load from hardware */
nvhost_module_busy(actmon->host->dev);
val = actmon_readl(actmon, actmon_avg_count_r());
nvhost_module_idle(actmon->host->dev);
rmb();
*avg = (val * 1000) / actmon->clks_per_sample;
return 0;
}
static int host1x_actmon_count(struct host1x_actmon *actmon, u32 *val)
{
if (actmon->init != ACTMON_READY) {
*val = 0;
return 0;
}
/* Read load from hardware */
nvhost_module_busy(actmon->host->dev);
*val = actmon_readl(actmon, actmon_count_r());
nvhost_module_idle(actmon->host->dev);
rmb();
return 0;
}
static int host1x_actmon_count_norm(struct host1x_actmon *actmon, u32 *avg)
{
long val;
if (actmon->init != ACTMON_READY) {
*avg = 0;
return 0;
}
/* Read load from hardware */
nvhost_module_busy(actmon->host->dev);
val = actmon_readl(actmon, actmon_count_r());
nvhost_module_idle(actmon->host->dev);
rmb();
*avg = (val * 1000) / actmon->clks_per_sample;
return 0;
}
static int host1x_actmon_above_wmark_count(struct host1x_actmon *actmon)
{
return actmon->above_wmark;
}
static int host1x_actmon_below_wmark_count(struct host1x_actmon *actmon)
{
return actmon->below_wmark;
}
static void host1x_actmon_update_sample_period(struct host1x_actmon *actmon)
{
/* No sense to update actmon if actmon is inactive */
if (actmon->init != ACTMON_READY)
return;
nvhost_module_busy(actmon->host->dev);
actmon_update_sample_period_safe(actmon);
nvhost_module_idle(actmon->host->dev);
}
static void host1x_actmon_set_sample_period_norm(struct host1x_actmon *actmon,
long usecs)
{
actmon->usecs_per_sample = usecs;
host1x_actmon_update_sample_period(actmon);
}
static void host1x_actmon_set_k(struct host1x_actmon *actmon, u32 k)
{
long val;
actmon->k = k;
nvhost_module_busy(actmon->host->dev);
val = actmon_readl(actmon, actmon_ctrl_r());
val &= ~(actmon_ctrl_k_val_m());
val |= actmon_ctrl_k_val_f(actmon->k);
actmon_writel(actmon, val, actmon_ctrl_r());
nvhost_module_idle(actmon->host->dev);
}
static u32 host1x_actmon_get_k(struct host1x_actmon *actmon)
{
return actmon->k;
}
static long host1x_actmon_get_sample_period(struct host1x_actmon *actmon)
{
return actmon->clks_per_sample;
}
static long host1x_actmon_get_sample_period_norm(struct host1x_actmon *actmon)
{
return actmon->usecs_per_sample;
}
static int actmon_below_wmark_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
seq_printf(s, "%d\n", host1x_actmon_below_wmark_count(actmon));
return 0;
}
static int actmon_below_wmark_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_below_wmark_show, inode->i_private);
}
static const struct file_operations actmon_below_wmark_fops = {
.open = actmon_below_wmark_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_above_wmark_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
seq_printf(s, "%d\n", host1x_actmon_above_wmark_count(actmon));
return 0;
}
static int actmon_above_wmark_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_above_wmark_show, inode->i_private);
}
static const struct file_operations actmon_above_wmark_fops = {
.open = actmon_above_wmark_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_avg_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
u32 avg;
int err;
err = host1x_actmon_avg(actmon, &avg);
if (!err)
seq_printf(s, "%d\n", avg);
return err;
}
static int actmon_avg_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_avg_show, inode->i_private);
}
static const struct file_operations actmon_avg_fops = {
.open = actmon_avg_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_avg_norm_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
u32 avg;
int err;
err = host1x_actmon_avg_norm(actmon, &avg);
if (!err)
seq_printf(s, "%d\n", avg);
return err;
}
static int actmon_avg_norm_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_avg_norm_show, inode->i_private);
}
static const struct file_operations actmon_avg_norm_fops = {
.open = actmon_avg_norm_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_count_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
u32 avg;
int err;
err = host1x_actmon_count(actmon, &avg);
if (!err)
seq_printf(s, "%d\n", avg);
return err;
}
static int actmon_count_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_count_show, inode->i_private);
}
static const struct file_operations actmon_count_fops = {
.open = actmon_count_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_count_norm_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
u32 avg;
int err;
err = host1x_actmon_count_norm(actmon, &avg);
if (!err)
seq_printf(s, "%d\n", avg);
return err;
}
static int actmon_count_norm_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_count_norm_show, inode->i_private);
}
static const struct file_operations actmon_count_norm_fops = {
.open = actmon_count_norm_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_sample_period_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
long period = host1x_actmon_get_sample_period(actmon);
seq_printf(s, "%ld\n", period);
return 0;
}
static int actmon_sample_period_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_sample_period_show, inode->i_private);
}
static const struct file_operations actmon_sample_period_fops = {
.open = actmon_sample_period_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_sample_period_norm_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
long period = host1x_actmon_get_sample_period_norm(actmon);
seq_printf(s, "%ld\n", period);
return 0;
}
static int actmon_sample_period_norm_open(struct inode *inode,
struct file *file)
{
return single_open(file, actmon_sample_period_norm_show,
inode->i_private);
}
static ssize_t actmon_sample_period_norm_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct seq_file *s = file->private_data;
struct host1x_actmon *actmon = s->private;
char buffer[40];
int buf_size;
unsigned long period;
memset(buffer, 0, sizeof(buffer));
buf_size = min(count, (sizeof(buffer)-1));
if (copy_from_user(buffer, user_buf, buf_size))
return -EFAULT;
if (kstrtoul(buffer, 10, &period))
return -EINVAL;
host1x_actmon_set_sample_period_norm(actmon, period);
return count;
}
static const struct file_operations actmon_sample_period_norm_fops = {
.open = actmon_sample_period_norm_open,
.read = seq_read,
.write = actmon_sample_period_norm_write,
.llseek = seq_lseek,
.release = single_release,
};
static int actmon_k_show(struct seq_file *s, void *unused)
{
struct host1x_actmon *actmon = s->private;
long period = host1x_actmon_get_k(actmon);
seq_printf(s, "%ld\n", period);
return 0;
}
static int actmon_k_open(struct inode *inode, struct file *file)
{
return single_open(file, actmon_k_show, inode->i_private);
}
static ssize_t actmon_k_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct seq_file *s = file->private_data;
struct host1x_actmon *actmon = s->private;
char buffer[40];
int buf_size;
unsigned long k;
memset(buffer, 0, sizeof(buffer));
buf_size = min(count, (sizeof(buffer)-1));
if (copy_from_user(buffer, user_buf, buf_size))
return -EFAULT;
if (kstrtoul(buffer, 10, &k))
return -EINVAL;
host1x_actmon_set_k(actmon, k);
return count;
}
static const struct file_operations actmon_k_fops = {
.open = actmon_k_open,
.read = seq_read,
.write = actmon_k_write,
.llseek = seq_lseek,
.release = single_release,
};
static void host1x_actmon_debug_init(struct host1x_actmon *actmon,
struct dentry *de)
{
BUG_ON(!actmon);
debugfs_create_file("actmon_k", S_IRUGO, de,
actmon, &actmon_k_fops);
debugfs_create_file("actmon_sample_period", S_IRUGO, de,
actmon, &actmon_sample_period_fops);
debugfs_create_file("actmon_sample_period_norm", S_IRUGO, de,
actmon, &actmon_sample_period_norm_fops);
debugfs_create_file("actmon_avg_norm", S_IRUGO, de,
actmon, &actmon_avg_norm_fops);
debugfs_create_file("actmon_avg", S_IRUGO, de,
actmon, &actmon_avg_fops);
debugfs_create_file("actmon_count", S_IRUGO, de,
actmon, &actmon_count_fops);
debugfs_create_file("actmon_count_norm", S_IRUGO, de,
actmon, &actmon_count_norm_fops);
debugfs_create_file("actmon_above_wmark", S_IRUGO, de,
actmon, &actmon_above_wmark_fops);
debugfs_create_file("actmon_below_wmark", S_IRUGO, de,
actmon, &actmon_below_wmark_fops);
}
static const struct nvhost_actmon_ops host1x_actmon_ops = {
.init = host1x_actmon_init,
.deinit = host1x_actmon_deinit,
.read_avg = host1x_actmon_avg,
.above_wmark_count = host1x_actmon_above_wmark_count,
.below_wmark_count = host1x_actmon_below_wmark_count,
.read_avg_norm = host1x_actmon_avg_norm,
.update_sample_period = host1x_actmon_update_sample_period,
.set_sample_period_norm = host1x_actmon_set_sample_period_norm,
.get_sample_period_norm = host1x_actmon_get_sample_period_norm,
.get_sample_period = host1x_actmon_get_sample_period,
.get_k = host1x_actmon_get_k,
.set_k = host1x_actmon_set_k,
.debug_init = host1x_actmon_debug_init,
};

View File

@@ -0,0 +1,586 @@
/*
* drivers/video/tegra/host/host1x/host1x_cdma.c
*
* Tegra Graphics Host Command DMA
*
* Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
*
* 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 <linux/slab.h>
#include <linux/scatterlist.h>
#include "nvhost_acm.h"
#include "nvhost_cdma.h"
#include "nvhost_channel.h"
#include "debug.h"
#include "dev.h"
#include "class_ids.h"
#include "chip_support.h"
#include "nvhost_job.h"
#include "host1x_cdma.h"
static inline u32 host1x_channel_dmactrl(int stop, int get_rst, int init_get)
{
return host1x_channel_dmactrl_dmastop_f(stop)
| host1x_channel_dmactrl_dmagetrst_f(get_rst)
| host1x_channel_dmactrl_dmainitget_f(init_get);
}
static void cdma_timeout_handler(struct work_struct *work);
/*
* 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 == cur
* means that the push buffer is full, not empty.
*/
/**
* Reset to empty push buffer
*/
static void push_buffer_reset(struct push_buffer *pb)
{
pb->fence = PUSH_BUFFER_SIZE - 8;
pb->cur = 0;
}
/**
* Init push buffer resources
*/
static void push_buffer_destroy(struct push_buffer *pb);
static int push_buffer_init(struct push_buffer *pb)
{
struct nvhost_cdma *cdma = pb_to_cdma(pb);
int err = 0;
pb->mapped = NULL;
pb->dma_addr = 0;
pb->client_handle = NULL;
cdma_pb_op().reset(pb);
/* allocate the pushbuffer memory */
pb->mapped = dma_alloc_writecombine(&cdma_to_dev(cdma)->dev->dev,
PUSH_BUFFER_SIZE + 4,
&pb->dma_addr,
GFP_KERNEL);
if (!pb->mapped) {
err = -ENOMEM;
pb->mapped = NULL;
goto fail;
}
/* memory for storing nvmap client and handles for each opcode pair */
pb->client_handle = kzalloc(NVHOST_GATHER_QUEUE_SIZE *
sizeof(struct mem_mgr_handle),
GFP_KERNEL);
if (!pb->client_handle) {
err = -ENOMEM;
goto fail;
}
/* put the restart at the end of pushbuffer memory */
*(pb->mapped + (PUSH_BUFFER_SIZE >> 2)) =
nvhost_opcode_restart(pb->dma_addr);
return 0;
fail:
push_buffer_destroy(pb);
return err;
}
/**
* Clean up push buffer resources
*/
static void push_buffer_destroy(struct push_buffer *pb)
{
struct nvhost_cdma *cdma = pb_to_cdma(pb);
if (pb->mapped)
dma_free_writecombine(&cdma_to_dev(cdma)->dev->dev,
PUSH_BUFFER_SIZE + 4,
pb->mapped,
pb->dma_addr);
kfree(pb->client_handle);
pb->mapped = NULL;
pb->dma_addr = 0;
pb->client_handle = 0;
}
/**
* Push two words to the push buffer
* Caller must ensure push buffer is not full
*/
static void push_buffer_push_to(struct push_buffer *pb,
struct mem_mgr *client, struct mem_handle *handle,
u32 op1, u32 op2)
{
u32 cur = pb->cur;
u32 *p = (u32 *)((uintptr_t)pb->mapped + cur);
u32 cur_nvmap = (cur/8) & (NVHOST_GATHER_QUEUE_SIZE - 1);
WARN_ON(cur == pb->fence);
*(p++) = op1;
*(p++) = op2;
pb->client_handle[cur_nvmap].client = client;
pb->client_handle[cur_nvmap].handle = handle;
pb->cur = (cur + 8) & (PUSH_BUFFER_SIZE - 1);
}
static void _push_buffer_push_to(struct push_buffer *pb,
dma_addr_t iova,
u32 op1, u32 op2)
{
u32 cur = pb->cur;
u32 *p = (u32 *)((uintptr_t)pb->mapped + cur);
u32 cur_nvmap = (cur/8) & (NVHOST_GATHER_QUEUE_SIZE - 1);
WARN_ON(cur == pb->fence);
*(p++) = op1;
*(p++) = op2;
pb->client_handle[cur_nvmap].iova = iova;
pb->cur = (cur + 8) & (PUSH_BUFFER_SIZE - 1);
}
/**
* Pop a number of two word slots from the push buffer
* Caller must ensure push buffer is not empty
*/
static void push_buffer_pop_from(struct push_buffer *pb,
unsigned int slots)
{
/* Clear the nvmap references for old items from pb */
unsigned int i;
u32 fence_nvmap = pb->fence/8;
for (i = 0; i < slots; i++) {
int cur_fence_nvmap = (fence_nvmap+i)
& (NVHOST_GATHER_QUEUE_SIZE - 1);
struct mem_mgr_handle *h = &pb->client_handle[cur_fence_nvmap];
h->client = NULL;
h->handle = NULL;
h->iova = 0;
}
/* Advance the next write position */
pb->fence = (pb->fence + slots * 8) & (PUSH_BUFFER_SIZE - 1);
}
/**
* Return the number of two word slots free in the push buffer
*/
static u32 push_buffer_space(struct push_buffer *pb)
{
return ((pb->fence - pb->cur) & (PUSH_BUFFER_SIZE - 1)) / 8;
}
static u32 push_buffer_putptr(struct push_buffer *pb)
{
return pb->dma_addr + pb->cur;
}
/*
* The syncpt incr buffer is filled with methods to increment syncpts, which
* is later GATHER-ed into the mainline PB. It's used when a timed out context
* is interleaved with other work, so needs to inline the syncpt increments
* to maintain the count (but otherwise does no work).
*/
/**
* Init timeout resources
*/
static int cdma_timeout_init(struct nvhost_cdma *cdma,
u32 syncpt_id)
{
if (syncpt_id == NVSYNCPT_INVALID)
return -EINVAL;
INIT_DELAYED_WORK(&cdma->timeout.wq, cdma_timeout_handler);
cdma->timeout.initialized = true;
return 0;
}
/**
* Clean up timeout resources
*/
static void cdma_timeout_destroy(struct nvhost_cdma *cdma)
{
if (cdma->timeout.initialized)
cancel_delayed_work(&cdma->timeout.wq);
cdma->timeout.initialized = false;
}
/**
* Increment timedout buffer's syncpt via CPU.
*/
static void cdma_timeout_pb_cleanup(struct nvhost_cdma *cdma, u32 getptr,
u32 nr_slots)
{
struct nvhost_master *dev = cdma_to_dev(cdma);
struct push_buffer *pb = &cdma->push_buffer;
u32 getidx;
/* NOP all the PB slots */
getidx = getptr - pb->dma_addr;
while (nr_slots--) {
u32 *p = (u32 *)((uintptr_t)pb->mapped + getidx);
*(p++) = NVHOST_OPCODE_NOOP;
*(p++) = NVHOST_OPCODE_NOOP;
dev_dbg(&dev->dev->dev, "%s: NOP at 0x%llx\n",
__func__, (u64)(pb->dma_addr + getidx));
getidx = (getidx + 8) & (PUSH_BUFFER_SIZE - 1);
}
wmb();
}
/**
* Start channel DMA
*/
static void cdma_start(struct nvhost_cdma *cdma)
{
void __iomem *chan_regs = cdma_to_channel(cdma)->aperture;
if (cdma->running)
return;
cdma->last_put = cdma_pb_op().putptr(&cdma->push_buffer);
writel(host1x_channel_dmactrl(true, false, false),
chan_regs + host1x_channel_dmactrl_r());
/* set base, put, end pointer (all of memory) */
writel(0, chan_regs + host1x_channel_dmastart_r());
writel(cdma->last_put, chan_regs + host1x_channel_dmaput_r());
writel(0xFFFFFFFF, chan_regs + host1x_channel_dmaend_r());
/* reset GET */
writel(host1x_channel_dmactrl(true, true, true),
chan_regs + host1x_channel_dmactrl_r());
/* prevent using setclass inside gathers */
nvhost_channel_init_gather_filter(cdma_to_channel(cdma));
/* start the command DMA */
writel(host1x_channel_dmactrl(false, false, false),
chan_regs + host1x_channel_dmactrl_r());
cdma->running = true;
}
/**
* Similar to cdma_start(), but rather than starting from an idle
* state (where DMA GET is set to DMA PUT), on a timeout we restore
* DMA GET from an explicit value (so DMA may again be pending).
*/
static void cdma_timeout_restart(struct nvhost_cdma *cdma, u32 getptr)
{
struct nvhost_master *dev = cdma_to_dev(cdma);
void __iomem *chan_regs = cdma_to_channel(cdma)->aperture;
if (cdma->running)
return;
cdma->last_put = cdma_pb_op().putptr(&cdma->push_buffer);
writel(host1x_channel_dmactrl(true, false, false),
chan_regs + host1x_channel_dmactrl_r());
/* set base, end pointer (all of memory) */
writel(0, chan_regs + host1x_channel_dmastart_r());
writel(0xFFFFFFFF, chan_regs + host1x_channel_dmaend_r());
/* set GET, by loading the value in PUT (then reset GET) */
writel(getptr, chan_regs + host1x_channel_dmaput_r());
writel(host1x_channel_dmactrl(true, true, true),
chan_regs + host1x_channel_dmactrl_r());
dev_dbg(&dev->dev->dev,
"%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n",
__func__,
readl(chan_regs + host1x_channel_dmaget_r()),
readl(chan_regs + host1x_channel_dmaput_r()),
cdma->last_put);
/* deassert GET reset and set PUT */
writel(host1x_channel_dmactrl(true, false, false),
chan_regs + host1x_channel_dmactrl_r());
writel(cdma->last_put, chan_regs + host1x_channel_dmaput_r());
/* reinitialise gather filter for the channel */
nvhost_channel_init_gather_filter(cdma_to_channel(cdma));
/* start the command DMA */
writel(host1x_channel_dmactrl(false, false, false),
chan_regs + host1x_channel_dmactrl_r());
cdma->running = true;
}
/**
* Kick channel DMA into action by writing its PUT offset (if it has changed)
*/
static void cdma_kick(struct nvhost_cdma *cdma)
{
u32 put;
put = cdma_pb_op().putptr(&cdma->push_buffer);
if (put != cdma->last_put) {
void __iomem *chan_regs = cdma_to_channel(cdma)->aperture;
writel(put, chan_regs + host1x_channel_dmaput_r());
cdma->last_put = put;
}
}
static void cdma_stop(struct nvhost_cdma *cdma)
{
void __iomem *chan_regs = cdma_to_channel(cdma)->aperture;
mutex_lock(&cdma->lock);
if (cdma->running) {
nvhost_cdma_wait_locked(cdma, CDMA_EVENT_SYNC_QUEUE_EMPTY);
writel(host1x_channel_dmactrl(true, false, false),
chan_regs + host1x_channel_dmactrl_r());
cdma->running = false;
}
mutex_unlock(&cdma->lock);
}
/**
* Stops both channel's command processor and CDMA immediately.
* Also, tears down the channel and resets corresponding module.
*/
static void cdma_timeout_teardown_begin(struct nvhost_cdma *cdma)
{
struct nvhost_master *dev = cdma_to_dev(cdma);
struct nvhost_channel *ch = cdma_to_channel(cdma);
u32 cmdproc_stop;
if (cdma->torndown && !cdma->running) {
dev_warn(&dev->dev->dev, "Already torn down\n");
return;
}
dev_dbg(&dev->dev->dev,
"begin channel teardown (channel id %d)\n", ch->chid);
cmdproc_stop = readl(dev->sync_aperture + host1x_sync_cmdproc_stop_r());
cmdproc_stop |= BIT(ch->chid);
writel(cmdproc_stop, dev->sync_aperture + host1x_sync_cmdproc_stop_r());
dev_dbg(&dev->dev->dev,
"%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n",
__func__,
readl(ch->aperture + host1x_channel_dmaget_r()),
readl(ch->aperture + host1x_channel_dmaput_r()),
cdma->last_put);
writel(host1x_channel_dmactrl(true, false, false),
ch->aperture + host1x_channel_dmactrl_r());
writel(BIT(ch->chid), dev->sync_aperture + host1x_sync_ch_teardown_r());
nvhost_module_reset(ch->dev);
cdma->running = false;
cdma->torndown = true;
}
static void cdma_timeout_release_mlocks(struct nvhost_cdma *cdma)
{
struct nvhost_master *dev = cdma_to_dev(cdma);
struct nvhost_syncpt *syncpt = &dev->syncpt;
unsigned int chid = cdma_to_channel(cdma)->chid;
int i;
for (i = 0; i < nvhost_syncpt_nb_mlocks(syncpt); i++) {
unsigned int owner;
bool ch_own, cpu_own;
syncpt_op().mutex_owner(syncpt, i, &cpu_own, &ch_own, &owner);
if (!(ch_own && owner == chid))
continue;
syncpt_op().mutex_unlock(&dev->syncpt, i);
dev_dbg(&dev->dev->dev, "released mlock %d\n", i);
}
}
static void cdma_timeout_teardown_end(struct nvhost_cdma *cdma, u32 getptr)
{
struct nvhost_master *dev = cdma_to_dev(cdma);
struct nvhost_channel *ch = cdma_to_channel(cdma);
u32 cmdproc_stop;
dev_dbg(&dev->dev->dev,
"end channel teardown (id %d, DMAGET restart = 0x%x)\n",
ch->chid, getptr);
cmdproc_stop = readl(dev->sync_aperture + host1x_sync_cmdproc_stop_r());
cmdproc_stop &= ~(BIT(ch->chid));
writel(cmdproc_stop, dev->sync_aperture + host1x_sync_cmdproc_stop_r());
cdma_timeout_release_mlocks(cdma);
cdma->torndown = false;
cdma_timeout_restart(cdma, getptr);
}
static bool cdma_check_dependencies(struct nvhost_cdma *cdma)
{
struct nvhost_channel *ch = cdma_to_channel(cdma);
struct nvhost_master *dev = cdma_to_dev(cdma);
u32 cbstat = readl(dev->sync_aperture +
host1x_sync_cbstat_0_r() + 4 * ch->chid);
u32 cbread = readl(dev->sync_aperture +
host1x_sync_cbread0_r() + 4 * ch->chid);
u32 waiting = cbstat & 0x00010008;
u32 syncpt_id = cbread >> 24;
int i;
if (!waiting)
return false;
for (i = 0; i < cdma->timeout.num_syncpts; ++i)
if (cdma->timeout.sp[i].id == syncpt_id)
return false;
return true;
}
/**
* If this timeout fires, it indicates the current sync_queue entry has
* exceeded its TTL and the userctx should be timed out and remaining
* submits already issued cleaned up (future submits return an error).
*/
static void cdma_timeout_handler(struct work_struct *work)
{
struct nvhost_cdma *cdma;
struct nvhost_master *dev;
struct nvhost_syncpt *sp;
struct nvhost_channel *ch;
int ret;
bool completed;
int i;
u32 syncpt_val;
u32 prev_cmdproc, cmdproc_stop;
cdma = container_of(to_delayed_work(work), struct nvhost_cdma,
timeout.wq);
dev = cdma_to_dev(cdma);
sp = &dev->syncpt;
ch = cdma_to_channel(cdma);
ret = mutex_trylock(&cdma->lock);
if (!ret) {
schedule_delayed_work(&cdma->timeout.wq, msecs_to_jiffies(10));
return;
}
if (nvhost_debug_force_timeout_dump ||
cdma->timeout.timeout_debug_dump)
nvhost_debug_dump_locked(cdma_to_dev(cdma), ch->chid);
/* is this submit dependent with submits on other channels? */
if (cdma->timeout.allow_dependency && cdma_check_dependencies(cdma)) {
dev_dbg(&dev->dev->dev,
"cdma_timeout: timeout handler rescheduled\n");
cdma->timeout.allow_dependency = false;
schedule_delayed_work(&cdma->timeout.wq,
msecs_to_jiffies(cdma->timeout.timeout));
mutex_unlock(&cdma->lock);
return;
}
if (!cdma->timeout.clientid) {
dev_dbg(&dev->dev->dev,
"cdma_timeout: expired, but has no clientid\n");
mutex_unlock(&cdma->lock);
return;
}
/* stop processing to get a clean snapshot */
prev_cmdproc = readl(dev->sync_aperture + host1x_sync_cmdproc_stop_r());
cmdproc_stop = prev_cmdproc | BIT(ch->chid);
writel(cmdproc_stop, dev->sync_aperture + host1x_sync_cmdproc_stop_r());
dev_dbg(&dev->dev->dev, "cdma_timeout: cmdproc was 0x%x is 0x%x\n",
prev_cmdproc, cmdproc_stop);
completed = true;
for (i = 0; completed && i < cdma->timeout.num_syncpts; ++i) {
syncpt_val = nvhost_syncpt_update_min(&dev->syncpt,
cdma->timeout.sp[i].id);
if (!nvhost_syncpt_is_expired(&dev->syncpt,
cdma->timeout.sp[i].id, cdma->timeout.sp[i].fence))
completed = false;
}
/* has buffer actually completed? */
if (completed) {
dev_dbg(&dev->dev->dev,
"cdma_timeout: expired, but buffer had completed\n");
/* restore */
cmdproc_stop = prev_cmdproc & ~(BIT(ch->chid));
writel(cmdproc_stop,
dev->sync_aperture + host1x_sync_cmdproc_stop_r());
mutex_unlock(&cdma->lock);
return;
}
for (i = 0; i < cdma->timeout.num_syncpts; ++i) {
syncpt_val = nvhost_syncpt_read_min(&dev->syncpt,
cdma->timeout.sp[i].id);
dev_warn(&dev->dev->dev,
"%s: timeout: %d (%s) ctx 0x%p, HW thresh %d, done %d\n",
__func__, cdma->timeout.sp[i].id,
syncpt_op().name(sp, cdma->timeout.sp[i].id),
cdma->timeout.ctx, syncpt_val,
cdma->timeout.sp[i].fence);
}
/* stop HW, resetting channel/module */
cdma_op().timeout_teardown_begin(cdma);
nvhost_cdma_update_sync_queue(cdma, sp, ch->dev);
mutex_unlock(&cdma->lock);
}
static const struct nvhost_cdma_ops host1x_cdma_ops = {
.start = cdma_start,
.stop = cdma_stop,
.kick = cdma_kick,
.timeout_init = cdma_timeout_init,
.timeout_destroy = cdma_timeout_destroy,
.timeout_teardown_begin = cdma_timeout_teardown_begin,
.timeout_teardown_end = cdma_timeout_teardown_end,
.timeout_pb_cleanup = cdma_timeout_pb_cleanup,
};
static const struct nvhost_pushbuffer_ops host1x_pushbuffer_ops = {
.reset = push_buffer_reset,
.init = push_buffer_init,
.destroy = push_buffer_destroy,
.push_to = push_buffer_push_to,
._push_to = _push_buffer_push_to,
.pop_from = push_buffer_pop_from,
.space = push_buffer_space,
.putptr = push_buffer_putptr,
};

View File

@@ -0,0 +1,35 @@
/*
* drivers/video/tegra/host/host1x/host1x_cdma.h
*
* Tegra Graphics Host Command DMA
*
* Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
*
* 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 __NVHOST_HOST1X_HOST1X_CDMA_H
#define __NVHOST_HOST1X_HOST1X_CDMA_H
/* Number of gathers we allow to be queued up per channel. Must be a
* power of two. Currently sized such that pushbuffer is 4KB (512*8B). */
#define NVHOST_GATHER_QUEUE_SIZE 512
/* 8 bytes per slot. (This number does not include the final RESTART.) */
#define PUSH_BUFFER_SIZE (NVHOST_GATHER_QUEUE_SIZE * 8)
/* 4K page containing GATHERed methods to increment channel syncpts
* and replaces the original timed out contexts GATHER slots */
#define SYNCPT_INCR_BUFFER_SIZE_WORDS (4096 / sizeof(u32))
#endif

View File

@@ -0,0 +1,473 @@
/*
* drivers/video/tegra/host/host1x/channel_host1x.c
*
* Tegra Graphics Host Channel
*
* Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved.
*
* 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 "nvhost_channel.h"
#include "dev.h"
#include "class_ids.h"
#include "nvhost_acm.h"
#include "nvhost_job.h"
#include "nvhost_hwctx.h"
#include <trace/events/nvhost.h>
#include <linux/slab.h>
#include "nvhost_hwctx.h"
#include "nvhost_intr.h"
#include "class_ids.h"
static void sync_waitbases(struct nvhost_channel *ch, u32 syncpt_val)
{
unsigned long waitbase;
struct nvhost_device_data *pdata = platform_get_drvdata(ch->dev);
if (pdata->waitbasesync) {
waitbase = pdata->waitbases[0];
nvhost_cdma_push(&ch->cdma,
nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
host1x_uclass_load_syncpt_base_r(),
1),
nvhost_class_host_load_syncpt_base(waitbase,
syncpt_val));
}
}
static void serialize(struct nvhost_job *job)
{
struct nvhost_channel *ch = job->ch;
struct nvhost_syncpt *sp = &nvhost_get_host(ch->dev)->syncpt;
struct nvhost_device_data *pdata = platform_get_drvdata(ch->dev);
int i;
if (!job->serialize && !pdata->serialize)
return;
/*
* Force serialization by inserting a host wait for the
* previous job to finish before this one can commence.
*
* NOTE! This cannot be packed because otherwise we might
* overwrite the RESTART opcode at the end of the push
* buffer.
*/
for (i = 0; i < job->num_syncpts; ++i) {
u32 id = job->sp[i].id;
u32 max = nvhost_syncpt_read_max(sp, id);
nvhost_cdma_push(&ch->cdma,
nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
host1x_uclass_wait_syncpt_r(), 1),
nvhost_class_host_wait_syncpt(id, max));
}
}
static bool ctxsave_needed(struct nvhost_job *job, struct nvhost_hwctx *cur_ctx)
{
struct nvhost_channel *ch = job->ch;
if (!cur_ctx || ch->cur_ctx == job->hwctx ||
ch->cur_ctx->has_timedout ||
!ch->cur_ctx->h->save_push)
return false;
else
return true;
}
static void submit_ctxsave(struct nvhost_job *job, struct nvhost_hwctx *cur_ctx)
{
struct nvhost_master *host = nvhost_get_host(job->ch->dev);
struct nvhost_channel *ch = job->ch;
u32 syncval;
/* Is a save needed? */
if (!ctxsave_needed(job, cur_ctx))
return;
/* Adjust the syncpoint max */
job->sp[job->hwctx_syncpt_idx].incrs +=
cur_ctx->save_incrs;
syncval = nvhost_syncpt_incr_max(&host->syncpt,
job->sp[job->hwctx_syncpt_idx].id,
cur_ctx->save_incrs);
/* Send the save to channel */
cur_ctx->valid = true;
cur_ctx->h->save_push(cur_ctx, &ch->cdma);
nvhost_job_get_hwctx(job, cur_ctx);
trace_nvhost_channel_context_save(ch->dev->name, cur_ctx);
}
static void submit_ctxrestore(struct nvhost_job *job)
{
struct nvhost_master *host = nvhost_get_host(job->ch->dev);
struct nvhost_channel *ch = job->ch;
u32 syncval;
struct nvhost_hwctx *ctx = job->hwctx;
/* First check if we have a valid context to restore */
if (ch->cur_ctx == job->hwctx || !job->hwctx ||
!job->hwctx->valid ||
!ctx->h->restore_push)
return;
/* Increment syncpt max */
job->sp[job->hwctx_syncpt_idx].incrs += ctx->restore_incrs;
syncval = nvhost_syncpt_incr_max(&host->syncpt,
job->sp[job->hwctx_syncpt_idx].id,
ctx->restore_incrs);
/* Send restore buffer to channel */
ctx->h->restore_push(ctx, &ch->cdma);
trace_nvhost_channel_context_restore(ch->dev->name, ctx);
}
static void submit_nullkickoff(struct nvhost_job *job, u32 user_syncpt_incrs)
{
struct nvhost_channel *ch = job->ch;
int incr, i;
u32 op_incr;
struct nvhost_device_data *pdata = platform_get_drvdata(ch->dev);
/* push increments that correspond to nulled out commands */
for (i = 0; i < job->num_syncpts; ++i) {
u32 incrs = (i == job->hwctx_syncpt_idx) ?
user_syncpt_incrs : job->sp[i].incrs;
op_incr = nvhost_opcode_imm_incr_syncpt(
host1x_uclass_incr_syncpt_cond_op_done_v(),
job->sp[i].id);
for (incr = 0; incr < (incrs >> 1); incr++)
nvhost_cdma_push(&ch->cdma, op_incr, op_incr);
if (incrs & 1)
nvhost_cdma_push(&ch->cdma, op_incr,
NVHOST_OPCODE_NOOP);
}
/* for 3d, waitbase needs to be incremented after each submit */
if (pdata->class == NV_GRAPHICS_3D_CLASS_ID) {
u32 waitbase = job->hwctx->h->waitbase;
nvhost_cdma_push(&ch->cdma,
nvhost_opcode_setclass(
NV_HOST1X_CLASS_ID,
host1x_uclass_incr_syncpt_base_r(),
1),
nvhost_class_host_incr_syncpt_base(
waitbase,
job->sp[job->hwctx_syncpt_idx].incrs));
}
}
static inline u32 gather_regnum(u32 word)
{
return (word >> 16) & 0xfff;
}
static inline u32 gather_type(u32 word)
{
return (word >> 28) & 1;
}
static inline u32 gather_count(u32 word)
{
return word & 0x3fff;
}
static void submit_gathers(struct nvhost_job *job)
{
u32 class_id = 0;
int i;
void *cpuva;
/* push user gathers */
for (i = 0; i < job->num_gathers; i++) {
struct nvhost_job_gather *g = &job->gathers[i];
u32 op1;
u32 op2;
if (g->class_id != class_id) {
nvhost_cdma_push(&job->ch->cdma,
nvhost_opcode_setclass(g->class_id, 0, 0),
NVHOST_OPCODE_NOOP);
class_id = g->class_id;
}
/* If register is specified, add a gather with incr/nonincr.
* This allows writing large amounts of data directly from
* memory to a register. */
if (gather_regnum(g->words))
op1 = nvhost_opcode_gather_insert(
gather_regnum(g->words),
gather_type(g->words),
gather_count(g->words));
else
op1 = nvhost_opcode_gather(g->words);
op2 = job->gathers[i].mem_base + g->offset;
cpuva = dma_buf_vmap(g->buf);
_nvhost_cdma_push_gather(&job->ch->cdma,
cpuva,
job->gathers[i].mem_base,
g->offset,
op1, op2);
if (cpuva)
dma_buf_vunmap(g->buf, cpuva);
}
}
static int host1x_channel_submit(struct nvhost_job *job)
{
struct nvhost_channel *ch = job->ch;
struct nvhost_syncpt *sp = &nvhost_get_host(job->ch->dev)->syncpt;
u32 user_syncpt_incrs;
u32 prev_max = 0;
int err, i;
void *completed_waiters[job->num_syncpts];
struct nvhost_job_syncpt *hwctx_sp = job->sp + job->hwctx_syncpt_idx;
memset(completed_waiters, 0, sizeof(void *) * job->num_syncpts);
/* Bail out on timed out contexts */
if (job->hwctx && job->hwctx->has_timedout)
return -ETIMEDOUT;
/* Turn on the client module and host1x */
for (i = 0; i < job->num_syncpts; ++i)
nvhost_module_busy(ch->dev);
/* before error checks, return current max */
prev_max = hwctx_sp->fence = nvhost_syncpt_read_max(sp, hwctx_sp->id);
/* get submit lock */
err = mutex_lock_interruptible(&ch->submitlock);
if (err) {
nvhost_module_idle_mult(ch->dev, job->num_syncpts);
goto error;
}
for (i = 0; i < job->num_syncpts; ++i) {
completed_waiters[i] = nvhost_intr_alloc_waiter();
if (!completed_waiters[i]) {
nvhost_module_idle_mult(ch->dev, job->num_syncpts);
mutex_unlock(&ch->submitlock);
err = -ENOMEM;
goto error;
}
if (nvhost_intr_has_pending_jobs(
&nvhost_get_host(ch->dev)->intr, job->sp[i].id, ch))
dev_warn(&ch->dev->dev,
"%s: cross-channel dependencies on syncpt %d\n",
__func__, job->sp[i].id);
}
/* begin a CDMA submit */
err = nvhost_cdma_begin(&ch->cdma, job);
if (err) {
mutex_unlock(&ch->submitlock);
nvhost_module_idle_mult(ch->dev, job->num_syncpts);
goto error;
}
serialize(job);
/* submit_ctxsave() and submit_ctxrestore() use the channel syncpt */
user_syncpt_incrs = hwctx_sp->incrs;
submit_ctxsave(job, ch->cur_ctx);
submit_ctxrestore(job);
ch->cur_ctx = job->hwctx;
/* determine fences for all syncpoints */
for (i = 0; i < job->num_syncpts; ++i) {
u32 incrs = (i == job->hwctx_syncpt_idx) ?
user_syncpt_incrs :
job->sp[i].incrs;
/* create a valid max for client managed syncpoints */
if (nvhost_syncpt_client_managed(sp, job->sp[i].id)) {
u32 min = nvhost_syncpt_read(sp, job->sp[i].id);
if (min)
dev_warn(&job->ch->dev->dev,
"converting an active unmanaged syncpoint %d to managed\n",
job->sp[i].id);
nvhost_syncpt_set_max(sp, job->sp[i].id, min);
nvhost_syncpt_set_manager(sp, job->sp[i].id, false);
}
job->sp[i].fence =
nvhost_syncpt_incr_max(sp, job->sp[i].id, incrs);
}
if (job->null_kickoff)
submit_nullkickoff(job, user_syncpt_incrs);
else
submit_gathers(job);
sync_waitbases(ch, hwctx_sp->fence);
/* end CDMA submit & stash pinned hMems into sync queue */
nvhost_cdma_end(&ch->cdma, job);
trace_nvhost_channel_submitted(ch->dev->name, prev_max,
hwctx_sp->fence);
for (i = 0; i < job->num_syncpts; ++i) {
/* schedule a submit complete interrupt */
err = nvhost_intr_add_action(&nvhost_get_host(ch->dev)->intr,
job->sp[i].id, job->sp[i].fence,
NVHOST_INTR_ACTION_SUBMIT_COMPLETE, ch,
completed_waiters[i],
NULL);
WARN(err, "Failed to set submit complete interrupt");
}
mutex_unlock(&ch->submitlock);
return 0;
error:
for (i = 0; i < job->num_syncpts; ++i)
kfree(completed_waiters[i]);
return err;
}
static int host1x_save_context(struct nvhost_channel *ch)
{
struct nvhost_hwctx *hwctx_to_save;
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
u32 syncpt_incrs, syncpt_val;
int err = 0;
void *ref;
void *wakeup_waiter = NULL;
struct nvhost_job *job;
u32 syncpt_id, waitbase;
wakeup_waiter = nvhost_intr_alloc_waiter();
if (!wakeup_waiter) {
err = -ENOMEM;
goto done;
}
nvhost_module_busy(nvhost_get_parent(ch->dev));
mutex_lock(&ch->submitlock);
hwctx_to_save = ch->cur_ctx;
if (!hwctx_to_save) {
mutex_unlock(&ch->submitlock);
goto done;
}
job = nvhost_job_alloc(ch, hwctx_to_save, 0, 0, 0, 1);
if (!job) {
err = -ENOMEM;
mutex_unlock(&ch->submitlock);
goto done;
}
hwctx_to_save->valid = true;
ch->cur_ctx = NULL;
syncpt_id = hwctx_to_save->h->syncpt;
waitbase = hwctx_to_save->h->waitbase;
syncpt_incrs = hwctx_to_save->save_incrs;
syncpt_val = nvhost_syncpt_incr_max(&nvhost_get_host(ch->dev)->syncpt,
syncpt_id, syncpt_incrs);
job->hwctx_syncpt_idx = 0;
job->sp->id = syncpt_id;
job->sp->waitbase = waitbase;
job->sp->incrs = syncpt_incrs;
job->sp->fence = syncpt_val;
job->num_syncpts = 1;
err = nvhost_cdma_begin(&ch->cdma, job);
if (err) {
mutex_unlock(&ch->submitlock);
goto done;
}
hwctx_to_save->h->save_push(hwctx_to_save, &ch->cdma);
nvhost_cdma_end(&ch->cdma, job);
nvhost_job_put(job);
job = NULL;
err = nvhost_intr_add_action(&nvhost_get_host(ch->dev)->intr,
syncpt_id, syncpt_val,
NVHOST_INTR_ACTION_WAKEUP, &wq,
wakeup_waiter,
&ref);
wakeup_waiter = NULL;
WARN(err, "Failed to set wakeup interrupt");
wait_event(wq,
nvhost_syncpt_is_expired(&nvhost_get_host(ch->dev)->syncpt,
syncpt_id, syncpt_val));
nvhost_intr_put_ref(&nvhost_get_host(ch->dev)->intr, syncpt_id, ref);
nvhost_cdma_update(&ch->cdma);
mutex_unlock(&ch->submitlock);
nvhost_module_idle(nvhost_get_parent(ch->dev));
done:
kfree(wakeup_waiter);
return err;
}
static inline void __iomem *host1x_channel_aperture(void __iomem *p, int ndx)
{
p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
return p;
}
static inline int hwctx_handler_init(struct nvhost_channel *ch)
{
int err = 0;
struct nvhost_device_data *pdata = platform_get_drvdata(ch->dev);
u32 syncpt = pdata->syncpts[0];
u32 waitbase = pdata->waitbases[0];
if (pdata->alloc_hwctx_handler) {
ch->ctxhandler = pdata->alloc_hwctx_handler(syncpt,
waitbase, ch);
if (!ch->ctxhandler)
err = -ENOMEM;
}
return err;
}
static int host1x_channel_init(struct nvhost_channel *ch,
struct nvhost_master *dev, int index)
{
ch->chid = index;
mutex_init(&ch->reflock);
mutex_init(&ch->submitlock);
ch->aperture = host1x_channel_aperture(dev->aperture, index);
return hwctx_handler_init(ch);
}
static const struct nvhost_channel_ops host1x_channel_ops = {
.init = host1x_channel_init,
.submit = host1x_channel_submit,
.save_context = host1x_save_context,
};

View File

@@ -0,0 +1,257 @@
/*
* drivers/video/tegra/host/host1x/host1x_debug.c
*
* Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com>
*
* Copyright (c) 2011-2014, NVIDIA Corporation. All rights reserved.
*
* 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 <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/io.h>
#include "dev.h"
#include "debug.h"
#include "nvhost_cdma.h"
#include "nvhost_channel.h"
#include "nvhost_job.h"
#include "chip_support.h"
#include "nvhost_memmgr.h"
#define NVHOST_DEBUG_MAX_PAGE_OFFSET 102400
enum {
NVHOST_DBG_STATE_CMD = 0,
NVHOST_DBG_STATE_DATA = 1,
NVHOST_DBG_STATE_GATHER = 2
};
static void do_show_channel_gather(struct output *o,
phys_addr_t phys_addr,
u32 words, struct nvhost_cdma *cdma,
phys_addr_t pin_addr, u32 *map_addr)
{
/* Map dmaget cursor to corresponding nvmap_handle */
u32 offset;
int state, i;
offset = phys_addr - pin_addr;
/*
* Sometimes we're given different hardware address to the same
* page - in these cases the offset will get an invalid number and
* we just have to bail out.
*/
if (offset > NVHOST_DEBUG_MAX_PAGE_OFFSET) {
nvhost_debug_output(o, "[address mismatch]\n");
} else {
/* GATHER buffer starts always with commands */
state = NVHOST_DBG_STATE_CMD;
for (i = 0; i < words; i++)
nvhost_debug_output(o,
"%08x ", *(map_addr + offset/4 + i));
nvhost_debug_output(o, "\n");
}
}
static void show_channel_gathers(struct output *o, struct nvhost_cdma *cdma)
{
struct nvhost_job *job;
int i;
if (list_empty(&cdma->sync_queue)) {
nvhost_debug_output(o, "The CDMA sync queue is empty.\n");
return;
}
job = list_first_entry(&cdma->sync_queue, struct nvhost_job, list);
nvhost_debug_output(o, "\n%p: JOB, syncpt_id=%d, syncpt_val=%d,"
" first_get=%08x, timeout=%d, ctx=%p,"
" num_slots=%d\n",
job,
job->sp ? job->sp->id : -1,
job->sp ? job->sp->fence : -1,
job->first_get,
job->timeout,
job->hwctx,
job->num_slots);
for (i = 0; i < job->num_gathers; i++) {
struct nvhost_job_gather *g = &job->gathers[i];
u32 *mapped = dma_buf_vmap(g->buf);
if (!mapped) {
nvhost_debug_output(o, "[could not mmap]\n");
continue;
}
nvhost_debug_output(o,
" GATHER at %08x+%04x, %d words\n",
g->mem_base, g->offset, g->words);
do_show_channel_gather(o, g->mem_base + g->offset,
g->words, cdma, g->mem_base, mapped);
dma_buf_vunmap(g->buf, mapped);
}
}
static void t20_debug_show_channel_cdma(struct nvhost_master *m,
struct nvhost_channel *ch, struct output *o, int chid)
{
struct nvhost_channel *channel = ch;
struct nvhost_cdma *cdma = &channel->cdma;
u32 dmaput, dmaget, dmactrl;
u32 cbstat, cbread, cmdstat;
u32 val, base, baseval;
dmaput = readl(channel->aperture + host1x_channel_dmaput_r());
dmaget = readl(channel->aperture + host1x_channel_dmaget_r());
dmactrl = readl(channel->aperture + host1x_channel_dmactrl_r());
cbread = readl(m->sync_aperture + host1x_sync_cbread0_r() + 4 * chid);
cbstat = readl(m->sync_aperture + host1x_sync_cbstat_0_r() + 4 * chid);
cmdstat = readl(m->sync_aperture + host1x_sync_cmdproc_stat_r());
#ifdef CONFIG_PM_RUNTIME
nvhost_debug_output(o, "%d-%s (%d): ", chid,
channel->dev->name,
atomic_read(&channel->dev->dev.power.usage_count));
#else
nvhost_debug_output(o, "%d-%s: ", chid, channel->dev->name);
#endif
if (host1x_channel_dmactrl_dmastop_v(dmactrl)
|| !channel->cdma.push_buffer.mapped) {
nvhost_debug_output(o, "inactive\n\n");
return;
}
if (cmdstat & BIT(chid))
nvhost_debug_output(o, "bad opcode observed, ");
switch (cbstat) {
case 0x00010008:
nvhost_debug_output(o, "waiting on syncpt %d val %d\n",
cbread >> 24, cbread & 0xffffff);
break;
case 0x00010009:
base = (cbread >> 16) & 0xff;
baseval = readl(m->sync_aperture +
host1x_sync_syncpt_base_0_r() + 4 * base);
val = cbread & 0xffff;
nvhost_debug_output(o, "waiting on syncpt %d val %d "
"(base %d = %d; offset = %d)\n",
cbread >> 24, baseval + val,
base, baseval, val);
break;
default:
nvhost_debug_output(o,
"active class %02x, offset %04x, val %08x\n",
host1x_sync_cbstat_0_cbclass0_v(cbstat),
host1x_sync_cbstat_0_cboffset0_v(cbstat),
cbread);
break;
}
nvhost_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n",
dmaput, dmaget, dmactrl);
nvhost_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat);
show_channel_gathers(o, cdma);
nvhost_debug_output(o, "\n");
}
static void t20_debug_show_channel_fifo(struct nvhost_master *m,
struct nvhost_channel *ch, struct output *o, int chid)
{
u32 val, rd_ptr, wr_ptr, start, end, max = 64;
struct nvhost_channel *channel = ch;
nvhost_debug_output(o, "%d: fifo:\n", chid);
writel(host1x_sync_cfpeek_ctrl_cfpeek_ena_f(1)
| host1x_sync_cfpeek_ctrl_cfpeek_channr_f(chid),
m->sync_aperture + host1x_sync_cfpeek_ctrl_r());
wmb();
val = readl(channel->aperture + host1x_channel_fifostat_r());
if (host1x_channel_fifostat_cfempty_v(val)) {
writel(0x0, m->sync_aperture + host1x_sync_cfpeek_ctrl_r());
nvhost_debug_output(o, "FIFOSTAT %08x\n[empty]\n",
val);
return;
}
val = readl(m->sync_aperture + host1x_sync_cfpeek_ptrs_r());
rd_ptr = host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(val);
wr_ptr = host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(val);
val = readl(m->sync_aperture + host1x_sync_cf0_setup_r() + 4 * chid);
start = host1x_sync_cf0_setup_cf0_base_v(val);
end = host1x_sync_cf0_setup_cf0_limit_v(val);
nvhost_debug_output(o, "FIFOSTAT %08x, %03x - %03x, RD %03x, WR %03x\n",
val, start, end, rd_ptr, wr_ptr);
do {
writel(host1x_sync_cfpeek_ctrl_cfpeek_ena_f(1)
| host1x_sync_cfpeek_ctrl_cfpeek_channr_f(chid)
| host1x_sync_cfpeek_ctrl_cfpeek_addr_f(rd_ptr),
m->sync_aperture + host1x_sync_cfpeek_ctrl_r());
wmb();
val = readl(m->sync_aperture + host1x_sync_cfpeek_read_r());
rmb();
nvhost_debug_output(o, "%08x ", val);
if (rd_ptr == end)
rd_ptr = start;
else
rd_ptr++;
max--;
} while (max && rd_ptr != wr_ptr);
nvhost_debug_output(o, "\n");
writel(0x0, m->sync_aperture + host1x_sync_cfpeek_ctrl_r());
}
static void t20_debug_show_mlocks(struct nvhost_master *m, struct output *o)
{
u32 __iomem *mlo_regs = m->sync_aperture +
host1x_sync_mlock_owner_0_r();
int i;
nvhost_debug_output(o, "---- mlocks ----\n");
for (i = 0; i < NV_HOST1X_NB_MLOCKS; i++) {
u32 owner = readl(mlo_regs + i);
if (host1x_sync_mlock_owner_0_mlock_ch_owns_0_v(owner))
nvhost_debug_output(o, "%d: locked by channel %d\n",
i,
host1x_sync_mlock_owner_0_mlock_owner_chid_0_v(
owner));
else if (host1x_sync_mlock_owner_0_mlock_cpu_owns_0_v(owner))
nvhost_debug_output(o, "%d: locked by cpu\n", i);
}
nvhost_debug_output(o, "\n");
}
static const struct nvhost_debug_ops host1x_debug_ops = {
.show_channel_cdma = t20_debug_show_channel_cdma,
.show_channel_fifo = t20_debug_show_channel_fifo,
.show_mlocks = t20_debug_show_mlocks,
};

View File

@@ -0,0 +1,59 @@
/*
* drivers/video/tegra/host/host1x/host1x_hwctx.h
*
* Tegra Graphics Host HOST1X Hardware Context Interface
*
* 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 as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __NVHOST_HOST1X_HWCTX_H
#define __NVHOST_HOST1X_HWCTX_H
#include <linux/kref.h>
#include "nvhost_hwctx.h"
struct nvhost_hwctx_handler;
struct nvhost_channel;
struct sg_table;
#define to_host1x_hwctx_handler(handler) \
container_of((handler), struct host1x_hwctx_handler, h)
#define to_host1x_hwctx(h) container_of((h), struct host1x_hwctx, hwctx)
#define host1x_hwctx_handler(_hwctx) to_host1x_hwctx_handler((_hwctx)->hwctx.h)
struct host1x_hwctx {
struct nvhost_hwctx hwctx;
u32 restore_size;
u32 *cpuva;
dma_addr_t iova;
bool mem_flag;
};
struct host1x_hwctx_handler {
struct nvhost_hwctx_handler h;
u32 restore_size;
u32 restore_incrs;
u32 save_incrs;
u32 save_slots;
u32 save_size;
u32 *cpuva;
dma_addr_t iova;
};
#endif

View File

@@ -0,0 +1,308 @@
/*
* drivers/video/tegra/host/host1x/host1x_intr.c
*
* Tegra Graphics Host Interrupt Management
*
* Copyright (C) 2010 Google, Inc.
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
*
* 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 <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/ktime.h>
#include "nvhost_intr.h"
#include "dev.h"
/* Spacing between sync registers */
#define REGISTER_STRIDE 4
#define INT_HOST1X_MPCORE_SYNCPT 97
static void t20_intr_syncpt_intr_ack(struct nvhost_intr_syncpt *syncpt,
bool disable_intr);
static void t20_intr_enable_syncpt_intr(struct nvhost_intr *intr, u32 id);
static void t20_intr_set_syncpt_threshold(struct nvhost_intr *intr,
u32 id, u32 thresh);
static void syncpt_thresh_cascade_fn(struct work_struct *work)
{
struct nvhost_intr_syncpt *sp =
container_of(work, struct nvhost_intr_syncpt, work);
nvhost_syncpt_thresh_fn(sp);
}
static irqreturn_t syncpt_thresh_cascade_isr(int irq, void *dev_id)
{
struct nvhost_master *dev = dev_id;
void __iomem *sync_regs = dev->sync_aperture;
struct nvhost_intr *intr = &dev->intr;
unsigned long reg;
int i, id;
for (i = 0; i < DIV_ROUND_UP(dev->info.nb_pts, 32); i++) {
reg = readl(sync_regs +
host1x_sync_syncpt_thresh_cpu0_int_status_r() +
i * REGISTER_STRIDE);
for_each_set_bit(id, &reg, 32) {
struct nvhost_intr_syncpt *sp;
int sp_id = i * 32 + id;
if (unlikely(sp_id >= dev->info.nb_pts)) {
dev_err(&dev->dev->dev, "%s(): syncpoint id %d is beyond the number of syncpoints (%d)\n",
__func__, sp_id, dev->info.nb_pts);
goto out;
}
sp = intr->syncpt + sp_id;
ktime_get_ts(&sp->isr_recv);
/* handle syncpoint 0 increments immediately */
if (sp_id == 0) {
dev_warn(&dev->dev->dev, "%s(): syncpoint id 0 incremented\n",
__func__);
nvhost_syncpt_patch_check(&dev->syncpt);
t20_intr_syncpt_intr_ack(sp, false);
} else {
t20_intr_syncpt_intr_ack(sp, true);
queue_work(intr->wq, &sp->work);
}
}
}
out:
return IRQ_HANDLED;
}
static void t20_intr_init_host_sync(struct nvhost_intr *intr)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
int i, err;
intr_op().disable_all_syncpt_intrs(intr);
for (i = 0; i < dev->info.nb_pts; i++)
INIT_WORK(&intr->syncpt[i].work, syncpt_thresh_cascade_fn);
err = request_irq(intr->syncpt_irq,
syncpt_thresh_cascade_isr,
IRQF_SHARED, "host_syncpt", dev);
if (err)
BUG();
/* increase the auto-ack timout to the maximum value. 2d will hang
* otherwise on ap20.
*/
writel(0xff, sync_regs + host1x_sync_ctxsw_timeout_cfg_r());
/* enable syncpoint 0 interrupt */
t20_intr_set_syncpt_threshold(intr, 0, 1);
t20_intr_enable_syncpt_intr(intr, 0);
}
static void t20_intr_set_host_clocks_per_usec(struct nvhost_intr *intr, u32 cpm)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
/* write microsecond clock register */
writel(cpm, sync_regs + host1x_sync_usec_clk_r());
/* set the ip_busy_timeout */
writel(cpm * 500000, sync_regs + host1x_sync_ip_busy_timeout_r());
}
static void t20_intr_set_syncpt_threshold(struct nvhost_intr *intr,
u32 id, u32 thresh)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
writel(thresh, sync_regs +
(host1x_sync_syncpt_int_thresh_0_r() + id * REGISTER_STRIDE));
}
static void t20_intr_enable_syncpt_intr(struct nvhost_intr *intr, u32 id)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
writel(bit_mask(id), sync_regs +
host1x_sync_syncpt_thresh_int_enable_cpu0_r() +
bit_word(id) * REGISTER_STRIDE);
}
static void t20_intr_disable_syncpt_intr(struct nvhost_intr *intr, u32 id)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
writel(bit_mask(id), sync_regs +
host1x_sync_syncpt_thresh_int_disable_r() +
bit_word(id) * REGISTER_STRIDE);
/* clear status for both cpu's */
writel(bit_mask(id), sync_regs +
host1x_sync_syncpt_thresh_cpu0_int_status_r() +
bit_word(id) * REGISTER_STRIDE);
writel(bit_mask(id), sync_regs +
host1x_sync_syncpt_thresh_cpu1_int_status_r() +
bit_word(id) * REGISTER_STRIDE);
}
static void t20_intr_disable_all_syncpt_intrs(struct nvhost_intr *intr)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
u32 reg;
for (reg = 0; reg < bit_word(dev->info.nb_pts) * REGISTER_STRIDE;
reg += REGISTER_STRIDE) {
/* disable interrupts for both cpu's */
writel(0xffffffffu, sync_regs +
host1x_sync_syncpt_thresh_int_disable_r() +
reg);
/* clear status for both cpu's */
writel(0xffffffffu, sync_regs +
host1x_sync_syncpt_thresh_cpu0_int_status_r() + reg);
writel(0xffffffffu, sync_regs +
host1x_sync_syncpt_thresh_cpu1_int_status_r() + reg);
}
}
/*
* Acknowledge that the syncpoint interrupt is handled. If disable_intr is set,
* the syncpoint interrupt is also disabled.
*/
static void t20_intr_syncpt_intr_ack(struct nvhost_intr_syncpt *syncpt,
bool disable_intr)
{
unsigned int id = syncpt->id;
struct nvhost_intr *intr = intr_syncpt_to_intr(syncpt);
void __iomem *sync_regs = intr_to_dev(intr)->sync_aperture;
u32 reg = bit_word(id) * REGISTER_STRIDE;
if (disable_intr)
writel(bit_mask(id), sync_regs +
host1x_sync_syncpt_thresh_int_disable_r() + reg);
writel(bit_mask(id), sync_regs +
host1x_sync_syncpt_thresh_cpu0_int_status_r() + reg);
}
/**
* Host general interrupt service function
* Handles read / write failures
*/
static irqreturn_t t20_intr_host1x_isr(int irq, void *dev_id)
{
struct nvhost_intr *intr = dev_id;
void __iomem *sync_regs = intr_to_dev(intr)->sync_aperture;
u32 stat;
u32 ext_stat;
u32 addr;
unsigned long intstat;
intstat = readl(sync_regs + host1x_sync_intstatus_r());
intr->intstatus = intstat;
/* Handle host1x interrupt in ISR */
stat = readl(sync_regs + host1x_sync_hintstatus_r());
ext_stat = readl(sync_regs + host1x_sync_hintstatus_ext_r());
if (host1x_sync_hintstatus_ext_ip_read_int_v(ext_stat)) {
addr = readl(sync_regs + host1x_sync_ip_read_timeout_addr_r());
pr_err("Host read timeout at address %x\n", addr);
}
if (host1x_sync_hintstatus_ext_ip_write_int_v(ext_stat)) {
addr = readl(sync_regs + host1x_sync_ip_write_timeout_addr_r());
pr_err("Host write timeout at address %x\n", addr);
}
writel(ext_stat, sync_regs + host1x_sync_hintstatus_ext_r());
writel(stat, sync_regs + host1x_sync_hintstatus_r());
writel(intstat, sync_regs + host1x_sync_intstatus_r());
return IRQ_HANDLED;
}
static int t20_intr_request_host_general_irq(struct nvhost_intr *intr)
{
void __iomem *sync_regs = intr_to_dev(intr)->sync_aperture;
int err;
/* master disable for general (not syncpt) host interrupts */
writel(0, sync_regs + host1x_sync_intmask_r());
/* clear status & extstatus */
writel(0xfffffffful, sync_regs + host1x_sync_hintstatus_ext_r());
writel(0xfffffffful, sync_regs + host1x_sync_hintstatus_r());
err = request_irq(intr->general_irq, t20_intr_host1x_isr,
0, "host_status", intr);
if (err)
return err;
/* enable extra interrupt sources IP_READ_INT and IP_WRITE_INT */
writel(BIT(30) | BIT(31), sync_regs + host1x_sync_hintmask_ext_r());
/* enable extra interrupt sources */
writel(BIT(31), sync_regs + host1x_sync_hintmask_r());
/* enable host module interrupt to CPU0 */
writel(BIT(0), sync_regs + host1x_sync_intc0mask_r());
/* master enable for general (not syncpt) host interrupts */
writel(BIT(0), sync_regs + host1x_sync_intmask_r());
return err;
}
static void t20_intr_free_host_general_irq(struct nvhost_intr *intr)
{
void __iomem *sync_regs = intr_to_dev(intr)->sync_aperture;
/* master disable for general (not syncpt) host interrupts */
writel(0, sync_regs + host1x_sync_intmask_r());
free_irq(intr->general_irq, intr);
}
static int t20_free_syncpt_irq(struct nvhost_intr *intr)
{
struct nvhost_master *dev = intr_to_dev(intr);
/* disable syncpoint 0 interrupt */
t20_intr_disable_syncpt_intr(intr, 0);
free_irq(INT_HOST1X_MPCORE_SYNCPT, dev);
flush_workqueue(intr->wq);
return 0;
}
static const struct nvhost_intr_ops host1x_intr_ops = {
.init_host_sync = t20_intr_init_host_sync,
.set_host_clocks_per_usec = t20_intr_set_host_clocks_per_usec,
.set_syncpt_threshold = t20_intr_set_syncpt_threshold,
.enable_syncpt_intr = t20_intr_enable_syncpt_intr,
.disable_syncpt_intr = t20_intr_disable_syncpt_intr,
.disable_all_syncpt_intrs = t20_intr_disable_all_syncpt_intrs,
.request_host_general_irq = t20_intr_request_host_general_irq,
.free_host_general_irq = t20_intr_free_host_general_irq,
.free_syncpt_irq = t20_free_syncpt_irq,
};

View File

@@ -0,0 +1,191 @@
/*
* drivers/video/tegra/host/host1x/host1x_syncpt.c
*
* Tegra Graphics Host Syncpoints for HOST1X
*
* 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 <linux/nvhost_ioctl.h>
#include <linux/io.h>
#include <trace/events/nvhost.h>
#include "nvhost_syncpt.h"
#include "nvhost_acm.h"
#include "host1x.h"
#include "chip_support.h"
/**
* Write the current syncpoint value back to hw.
*/
static void t20_syncpt_reset(struct nvhost_syncpt *sp, u32 id)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
int min = nvhost_syncpt_read_min(sp, id);
writel(min, dev->sync_aperture + (host1x_sync_syncpt_0_r() + id * 4));
}
/**
* Write the current waitbase value back to hw.
*/
static void t20_syncpt_reset_wait_base(struct nvhost_syncpt *sp, u32 id)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
writel(sp->base_val[id],
dev->sync_aperture + (host1x_sync_syncpt_base_0_r() + id * 4));
}
/**
* Read waitbase value from hw.
*/
static void t20_syncpt_read_wait_base(struct nvhost_syncpt *sp, u32 id)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
sp->base_val[id] = readl(dev->sync_aperture +
(host1x_sync_syncpt_base_0_r() + id * 4));
}
/**
* Updates the last value read from hardware.
* (was nvhost_syncpt_update_min)
*/
static u32 t20_syncpt_update_min(struct nvhost_syncpt *sp, u32 id)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
void __iomem *sync_regs = dev->sync_aperture;
u32 old, live;
do {
old = nvhost_syncpt_read_min(sp, id);
live = readl(sync_regs + (host1x_sync_syncpt_0_r() + id * 4));
} while ((u32)atomic_cmpxchg(&sp->min_val[id], old, live) != old);
return live;
}
/**
* Write a cpu syncpoint increment to the hardware, without touching
* the cache. Caller is responsible for host being powered.
*/
static void t20_syncpt_cpu_incr(struct nvhost_syncpt *sp, u32 id)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
u32 reg_offset = id / 32;
if (!nvhost_syncpt_client_managed(sp, id)
&& nvhost_syncpt_min_eq_max(sp, id)) {
dev_err(&syncpt_to_dev(sp)->dev->dev,
"Trying to increment syncpoint id %d beyond max\n",
id);
nvhost_debug_dump(syncpt_to_dev(sp));
return;
}
writel(bit_mask(id), dev->sync_aperture +
host1x_sync_syncpt_cpu_incr_r() + reg_offset * 4);
}
/* remove a wait pointed to by patch_addr */
static int host1x_syncpt_patch_wait(struct nvhost_syncpt *sp,
void *patch_addr)
{
u32 override = nvhost_class_host_wait_syncpt(
NVSYNCPT_GRAPHICS_HOST, 0);
__raw_writel(override, patch_addr);
return 0;
}
static const char *t20_syncpt_name(struct nvhost_syncpt *sp, u32 id)
{
struct host1x_device_info *info = &syncpt_to_dev(sp)->info;
const char *name = NULL;
if (id < info->nb_pts)
name = info->syncpt_names[id];
return name ? name : "";
}
static void t20_syncpt_debug(struct nvhost_syncpt *sp)
{
u32 i;
for (i = 0; i < nvhost_syncpt_nb_pts(sp); i++) {
u32 max = nvhost_syncpt_read_max(sp, i);
u32 min = nvhost_syncpt_update_min(sp, i);
if (!max && !min)
continue;
dev_info(&syncpt_to_dev(sp)->dev->dev,
"id %d (%s) min %d max %d\n",
i, syncpt_op().name(sp, i),
min, max);
}
for (i = 0; i < nvhost_syncpt_nb_bases(sp); i++) {
u32 base_val;
t20_syncpt_read_wait_base(sp, i);
base_val = sp->base_val[i];
if (base_val)
dev_info(&syncpt_to_dev(sp)->dev->dev,
"waitbase id %d val %d\n",
i, base_val);
}
}
static int syncpt_mutex_try_lock(struct nvhost_syncpt *sp,
unsigned int idx)
{
void __iomem *sync_regs = syncpt_to_dev(sp)->sync_aperture;
/* mlock registers returns 0 when the lock is aquired.
* writing 0 clears the lock. */
return !!readl(sync_regs + (host1x_sync_mlock_0_r() + idx * 4));
}
static void syncpt_mutex_unlock(struct nvhost_syncpt *sp,
unsigned int idx)
{
void __iomem *sync_regs = syncpt_to_dev(sp)->sync_aperture;
writel(0, sync_regs + (host1x_sync_mlock_0_r() + idx * 4));
}
static void syncpt_mutex_owner(struct nvhost_syncpt *sp,
unsigned int idx,
bool *cpu, bool *ch,
unsigned int *chid)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
u32 __iomem *mlo_regs = dev->sync_aperture +
host1x_sync_mlock_owner_0_r();
u32 owner = readl(mlo_regs + idx);
*chid = host1x_sync_mlock_owner_0_mlock_owner_chid_0_v(owner);
*cpu = host1x_sync_mlock_owner_0_mlock_cpu_owns_0_v(owner);
*ch = host1x_sync_mlock_owner_0_mlock_ch_owns_0_v(owner);
}
static const struct nvhost_syncpt_ops host1x_syncpt_ops = {
.reset = t20_syncpt_reset,
.reset_wait_base = t20_syncpt_reset_wait_base,
.read_wait_base = t20_syncpt_read_wait_base,
.update_min = t20_syncpt_update_min,
.cpu_incr = t20_syncpt_cpu_incr,
.patch_wait = host1x_syncpt_patch_wait,
.debug = t20_syncpt_debug,
.name = t20_syncpt_name,
.mutex_try_lock = syncpt_mutex_try_lock,
.mutex_unlock = syncpt_mutex_unlock,
.mutex_owner = syncpt_mutex_owner,
};

View File

@@ -0,0 +1,228 @@
/*
* drivers/video/tegra/host/host1x/host1x_counter.c
*
* Tegra Graphics Host Counter support
*
* Copyright (c) 2012, 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 <linux/nvhost.h>
#include <linux/io.h>
#include <linux/debugfs.h>
#include "dev.h"
#include "chip_support.h"
static void host1x_tickctrl_debug_init(struct platform_device *dev);
static int host1x_tickctrl_init_channel(struct platform_device *dev)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
void __iomem *regs = pdata->channel->aperture;
nvhost_module_busy(nvhost_get_parent(dev));
/* Initialize counter */
writel(0, regs + host1x_channel_tickcount_hi_r());
writel(0, regs + host1x_channel_tickcount_lo_r());
writel(0, regs + host1x_channel_stallcount_hi_r());
writel(0, regs + host1x_channel_stallcount_lo_r());
writel(0, regs + host1x_channel_xfercount_hi_r());
writel(0, regs + host1x_channel_xfercount_lo_r());
writel(host1x_channel_channelctrl_enabletickcnt_f(1),
regs + host1x_channel_channelctrl_r());
writel(host1x_channel_stallctrl_enable_channel_stall_f(1),
regs + host1x_channel_stallctrl_r());
writel(host1x_channel_xferctrl_enable_channel_xfer_f(1),
regs + host1x_channel_xferctrl_r());
nvhost_module_idle(nvhost_get_parent(dev));
host1x_tickctrl_debug_init(dev);
return 0;
}
static void host1x_tickctrl_deinit_channel(struct platform_device *dev)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
void __iomem *regs = pdata->channel->aperture;
nvhost_module_busy(nvhost_get_parent(dev));
writel(host1x_channel_stallctrl_enable_channel_stall_f(0),
regs + host1x_channel_stallctrl_r());
writel(host1x_channel_xferctrl_enable_channel_xfer_f(0),
regs + host1x_channel_xferctrl_r());
writel(host1x_channel_channelctrl_enabletickcnt_f(0),
regs + host1x_channel_channelctrl_r());
nvhost_module_idle(nvhost_get_parent(dev));
}
static u64 readl64(void __iomem *reg_hi, void __iomem *reg_lo)
{
u32 hi, lo, hi2;
do {
hi = readl(reg_hi);
lo = readl(reg_lo);
rmb();
hi2 = readl(reg_hi);
} while (hi2 != hi);
return ((u64)hi << 32) | (u64)lo;
}
static int host1x_tickctrl_tickcount(struct platform_device *dev, u64 *val)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
void __iomem *regs = pdata->channel->aperture;
nvhost_module_busy(nvhost_get_parent(dev));
*val = readl64(regs + host1x_channel_tickcount_hi_r(),
regs + host1x_channel_tickcount_lo_r());
rmb();
nvhost_module_idle(nvhost_get_parent(dev));
return 0;
}
static int host1x_tickctrl_stallcount(struct platform_device *dev, u64 *val)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
void __iomem *regs = pdata->channel->aperture;
nvhost_module_busy(nvhost_get_parent(dev));
*val = readl64(regs + host1x_channel_stallcount_hi_r(),
regs + host1x_channel_stallcount_lo_r());
rmb();
nvhost_module_idle(nvhost_get_parent(dev));
return 0;
}
static int host1x_tickctrl_xfercount(struct platform_device *dev, u64 *val)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
void __iomem *regs = pdata->channel->aperture;
nvhost_module_busy(nvhost_get_parent(dev));
*val = readl64(regs + host1x_channel_xfercount_hi_r(),
regs + host1x_channel_xfercount_lo_r());
rmb();
nvhost_module_idle(nvhost_get_parent(dev));
return 0;
}
static int tickcount_show(struct seq_file *s, void *unused)
{
struct platform_device *dev = s->private;
u64 cnt;
int err;
err = tickctrl_op().tickcount(dev, &cnt);
if (!err)
seq_printf(s, "%lld\n", cnt);
return err;
}
static int tickcount_open(struct inode *inode, struct file *file)
{
if (!tickctrl_op().tickcount)
return -ENODEV;
return single_open(file, tickcount_show, inode->i_private);
}
static const struct file_operations tickcount_fops = {
.open = tickcount_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int stallcount_show(struct seq_file *s, void *unused)
{
struct platform_device *dev = s->private;
u64 cnt;
int err;
err = tickctrl_op().stallcount(dev, &cnt);
if (!err)
seq_printf(s, "%lld\n", cnt);
return err;
}
static int stallcount_open(struct inode *inode, struct file *file)
{
if (!tickctrl_op().stallcount)
return -ENODEV;
return single_open(file, stallcount_show, inode->i_private);
}
static const struct file_operations stallcount_fops = {
.open = stallcount_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int xfercount_show(struct seq_file *s, void *unused)
{
struct platform_device *dev = s->private;
u64 cnt;
int err;
err = tickctrl_op().xfercount(dev, &cnt);
if (!err)
seq_printf(s, "%lld\n", cnt);
return err;
}
static int xfercount_open(struct inode *inode, struct file *file)
{
if (!tickctrl_op().xfercount)
return -ENODEV;
return single_open(file, xfercount_show, inode->i_private);
}
static const struct file_operations xfercount_fops = {
.open = xfercount_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static void host1x_tickctrl_debug_init(struct platform_device *dev)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
debugfs_create_file("stallcount", S_IRUGO, pdata->debugfs, dev,
&stallcount_fops);
debugfs_create_file("xfercount", S_IRUGO, pdata->debugfs, dev,
&xfercount_fops);
debugfs_create_file("tickcount", S_IRUGO, pdata->debugfs, dev,
&tickcount_fops);
}
static const struct nvhost_tickctrl_ops host1x_tickctrl_ops = {
.init_channel = host1x_tickctrl_init_channel,
.deinit_channel = host1x_tickctrl_deinit_channel,
.tickcount = host1x_tickctrl_tickcount,
.stallcount = host1x_tickctrl_stallcount,
.xfercount = host1x_tickctrl_xfercount,
};

View File

@@ -0,0 +1,182 @@
/*
* drivers/video/tegra/host/host1x/hw_host1x01_channel.h
*
* Copyright (c) 2012, 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/>.
*
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef __hw_host1x01_channel_h__
#define __hw_host1x01_channel_h__
/*This file is autogenerated. Do not edit. */
static inline u32 host1x_channel_fifostat_r(void)
{
return 0x0;
}
static inline u32 host1x_channel_fifostat_cfempty_s(void)
{
return 1;
}
static inline u32 host1x_channel_fifostat_cfempty_f(u32 v)
{
return (v & 0x1) << 10;
}
static inline u32 host1x_channel_fifostat_cfempty_m(void)
{
return 0x1 << 10;
}
static inline u32 host1x_channel_fifostat_cfempty_v(u32 r)
{
return (r >> 10) & 0x1;
}
static inline u32 host1x_channel_fifostat_cfempty_notempty_v(void)
{
return 0;
}
static inline u32 host1x_channel_fifostat_cfempty_empty_v(void)
{
return 1;
}
static inline u32 host1x_channel_fifostat_outfentries_s(void)
{
return 5;
}
static inline u32 host1x_channel_fifostat_outfentries_f(u32 v)
{
return (v & 0x1f) << 24;
}
static inline u32 host1x_channel_fifostat_outfentries_m(void)
{
return 0x1f << 24;
}
static inline u32 host1x_channel_fifostat_outfentries_v(u32 r)
{
return (r >> 24) & 0x1f;
}
static inline u32 host1x_channel_inddata_r(void)
{
return 0xc;
}
static inline u32 host1x_channel_dmastart_r(void)
{
return 0x14;
}
static inline u32 host1x_channel_dmaput_r(void)
{
return 0x18;
}
static inline u32 host1x_channel_dmaget_r(void)
{
return 0x1c;
}
static inline u32 host1x_channel_dmaend_r(void)
{
return 0x20;
}
static inline u32 host1x_channel_dmactrl_r(void)
{
return 0x24;
}
static inline u32 host1x_channel_dmactrl_dmastop_s(void)
{
return 1;
}
static inline u32 host1x_channel_dmactrl_dmastop_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_dmactrl_dmastop_m(void)
{
return 0x1 << 0;
}
static inline u32 host1x_channel_dmactrl_dmastop_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_channel_dmactrl_dmastop_run_v(void)
{
return 0;
}
static inline u32 host1x_channel_dmactrl_dmastop_stop_v(void)
{
return 1;
}
static inline u32 host1x_channel_dmactrl_dmagetrst_s(void)
{
return 1;
}
static inline u32 host1x_channel_dmactrl_dmagetrst_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_channel_dmactrl_dmagetrst_m(void)
{
return 0x1 << 1;
}
static inline u32 host1x_channel_dmactrl_dmagetrst_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_channel_dmactrl_dmainitget_s(void)
{
return 1;
}
static inline u32 host1x_channel_dmactrl_dmainitget_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_channel_dmactrl_dmainitget_m(void)
{
return 0x1 << 2;
}
static inline u32 host1x_channel_dmactrl_dmainitget_v(u32 r)
{
return (r >> 2) & 0x1;
}
#endif /* __hw_host1x01_channel_h__ */

View File

@@ -0,0 +1,890 @@
/*
* drivers/video/tegra/host/host1x/hw_host1x01_sync.h
*
* Copyright (c) 2012, 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/>.
*
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef __hw_host1x01_sync_h__
#define __hw_host1x01_sync_h__
/*This file is autogenerated. Do not edit. */
static inline u32 host1x_sync_intstatus_r(void)
{
return 0x0;
}
static inline u32 host1x_sync_intmask_r(void)
{
return 0x4;
}
static inline u32 host1x_sync_intc0mask_r(void)
{
return 0x8;
}
static inline u32 host1x_sync_hintstatus_r(void)
{
return 0x20;
}
static inline u32 host1x_sync_hintmask_r(void)
{
return 0x24;
}
static inline u32 host1x_sync_hintstatus_ext_r(void)
{
return 0x28;
}
static inline u32 host1x_sync_hintstatus_ext_ip_read_int_s(void)
{
return 1;
}
static inline u32 host1x_sync_hintstatus_ext_ip_read_int_f(u32 v)
{
return (v & 0x1) << 30;
}
static inline u32 host1x_sync_hintstatus_ext_ip_read_int_m(void)
{
return 0x1 << 30;
}
static inline u32 host1x_sync_hintstatus_ext_ip_read_int_v(u32 r)
{
return (r >> 30) & 0x1;
}
static inline u32 host1x_sync_hintstatus_ext_ip_write_int_s(void)
{
return 1;
}
static inline u32 host1x_sync_hintstatus_ext_ip_write_int_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 host1x_sync_hintstatus_ext_ip_write_int_m(void)
{
return 0x1 << 31;
}
static inline u32 host1x_sync_hintstatus_ext_ip_write_int_v(u32 r)
{
return (r >> 31) & 0x1;
}
static inline u32 host1x_sync_hintmask_ext_r(void)
{
return 0x2c;
}
static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(void)
{
return 0x40;
}
static inline u32 host1x_sync_syncpt_thresh_cpu1_int_status_r(void)
{
return 0x48;
}
static inline u32 host1x_sync_syncpt_thresh_int_disable_r(void)
{
return 0x60;
}
static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(void)
{
return 0x68;
}
static inline u32 host1x_sync_cf0_setup_r(void)
{
return 0x80;
}
static inline u32 host1x_sync_cf0_setup_cf0_base_s(void)
{
return 9;
}
static inline u32 host1x_sync_cf0_setup_cf0_base_f(u32 v)
{
return (v & 0x1ff) << 0;
}
static inline u32 host1x_sync_cf0_setup_cf0_base_m(void)
{
return 0x1ff << 0;
}
static inline u32 host1x_sync_cf0_setup_cf0_base_v(u32 r)
{
return (r >> 0) & 0x1ff;
}
static inline u32 host1x_sync_cf0_setup_cf0_limit_s(void)
{
return 9;
}
static inline u32 host1x_sync_cf0_setup_cf0_limit_f(u32 v)
{
return (v & 0x1ff) << 16;
}
static inline u32 host1x_sync_cf0_setup_cf0_limit_m(void)
{
return 0x1ff << 16;
}
static inline u32 host1x_sync_cf0_setup_cf0_limit_v(u32 r)
{
return (r >> 16) & 0x1ff;
}
static inline u32 host1x_sync_cmdproc_stat_r(void)
{
return 0xa8;
}
static inline u32 host1x_sync_cmdproc_stop_r(void)
{
return 0xac;
}
static inline u32 host1x_sync_ch_teardown_r(void)
{
return 0xb0;
}
static inline u32 host1x_sync_ch_teardown_ch0_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch0_teardown_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_sync_ch_teardown_ch0_teardown_m(void)
{
return 0x1 << 0;
}
static inline u32 host1x_sync_ch_teardown_ch0_teardown_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch0_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch0_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch1_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch1_teardown_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_sync_ch_teardown_ch1_teardown_m(void)
{
return 0x1 << 1;
}
static inline u32 host1x_sync_ch_teardown_ch1_teardown_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch1_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch1_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch2_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch2_teardown_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_sync_ch_teardown_ch2_teardown_m(void)
{
return 0x1 << 2;
}
static inline u32 host1x_sync_ch_teardown_ch2_teardown_v(u32 r)
{
return (r >> 2) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch2_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch2_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch3_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch3_teardown_f(u32 v)
{
return (v & 0x1) << 3;
}
static inline u32 host1x_sync_ch_teardown_ch3_teardown_m(void)
{
return 0x1 << 3;
}
static inline u32 host1x_sync_ch_teardown_ch3_teardown_v(u32 r)
{
return (r >> 3) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch3_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch3_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch4_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch4_teardown_f(u32 v)
{
return (v & 0x1) << 4;
}
static inline u32 host1x_sync_ch_teardown_ch4_teardown_m(void)
{
return 0x1 << 4;
}
static inline u32 host1x_sync_ch_teardown_ch4_teardown_v(u32 r)
{
return (r >> 4) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch4_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch4_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch5_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch5_teardown_f(u32 v)
{
return (v & 0x1) << 5;
}
static inline u32 host1x_sync_ch_teardown_ch5_teardown_m(void)
{
return 0x1 << 5;
}
static inline u32 host1x_sync_ch_teardown_ch5_teardown_v(u32 r)
{
return (r >> 5) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch5_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch5_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch6_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch6_teardown_f(u32 v)
{
return (v & 0x1) << 6;
}
static inline u32 host1x_sync_ch_teardown_ch6_teardown_m(void)
{
return 0x1 << 6;
}
static inline u32 host1x_sync_ch_teardown_ch6_teardown_v(u32 r)
{
return (r >> 6) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch6_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch6_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch7_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_ch_teardown_ch7_teardown_f(u32 v)
{
return (v & 0x1) << 7;
}
static inline u32 host1x_sync_ch_teardown_ch7_teardown_m(void)
{
return 0x1 << 7;
}
static inline u32 host1x_sync_ch_teardown_ch7_teardown_v(u32 r)
{
return (r >> 7) & 0x1;
}
static inline u32 host1x_sync_ch_teardown_ch7_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_ch_teardown_ch7_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_r(void)
{
return 0xb4;
}
static inline u32 host1x_sync_mod_teardown_display_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_display_teardown_f(u32 v)
{
return (v & 0x1) << 8;
}
static inline u32 host1x_sync_mod_teardown_display_teardown_m(void)
{
return 0x1 << 8;
}
static inline u32 host1x_sync_mod_teardown_display_teardown_v(u32 r)
{
return (r >> 8) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_display_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_display_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_displayb_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_displayb_teardown_f(u32 v)
{
return (v & 0x1) << 9;
}
static inline u32 host1x_sync_mod_teardown_displayb_teardown_m(void)
{
return 0x1 << 9;
}
static inline u32 host1x_sync_mod_teardown_displayb_teardown_v(u32 r)
{
return (r >> 9) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_displayb_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_displayb_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_f(u32 v)
{
return (v & 0x1) << 3;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_m(void)
{
return 0x1 << 3;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_v(u32 r)
{
return (r >> 3) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_gr3d_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_gr3d_teardown_f(u32 v)
{
return (v & 0x1) << 6;
}
static inline u32 host1x_sync_mod_teardown_gr3d_teardown_m(void)
{
return 0x1 << 6;
}
static inline u32 host1x_sync_mod_teardown_gr3d_teardown_v(u32 r)
{
return (r >> 6) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_gr3d_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_gr3d_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_isp_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_isp_teardown_f(u32 v)
{
return (v & 0x1) << 4;
}
static inline u32 host1x_sync_mod_teardown_isp_teardown_m(void)
{
return 0x1 << 4;
}
static inline u32 host1x_sync_mod_teardown_isp_teardown_v(u32 r)
{
return (r >> 4) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_isp_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_isp_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_mpe_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_mpe_teardown_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_sync_mod_teardown_mpe_teardown_m(void)
{
return 0x1 << 1;
}
static inline u32 host1x_sync_mod_teardown_mpe_teardown_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_mpe_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_mpe_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_tvo_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_tvo_teardown_f(u32 v)
{
return (v & 0x1) << 11;
}
static inline u32 host1x_sync_mod_teardown_tvo_teardown_m(void)
{
return 0x1 << 11;
}
static inline u32 host1x_sync_mod_teardown_tvo_teardown_v(u32 r)
{
return (r >> 11) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_tvo_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_tvo_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_dsi_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_dsi_teardown_f(u32 v)
{
return (v & 0x1) << 12;
}
static inline u32 host1x_sync_mod_teardown_dsi_teardown_m(void)
{
return 0x1 << 12;
}
static inline u32 host1x_sync_mod_teardown_dsi_teardown_v(u32 r)
{
return (r >> 12) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_dsi_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_dsi_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_hdmi_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_hdmi_teardown_f(u32 v)
{
return (v & 0x1) << 10;
}
static inline u32 host1x_sync_mod_teardown_hdmi_teardown_m(void)
{
return 0x1 << 10;
}
static inline u32 host1x_sync_mod_teardown_hdmi_teardown_v(u32 r)
{
return (r >> 10) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_hdmi_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_hdmi_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_vi_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_vi_teardown_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_sync_mod_teardown_vi_teardown_m(void)
{
return 0x1 << 2;
}
static inline u32 host1x_sync_mod_teardown_vi_teardown_v(u32 r)
{
return (r >> 2) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_vi_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_vi_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_f(u32 v)
{
return (v & 0x1) << 5;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_m(void)
{
return 0x1 << 5;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_v(u32 r)
{
return (r >> 5) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_dsib_teardown_s(void)
{
return 1;
}
static inline u32 host1x_sync_mod_teardown_dsib_teardown_f(u32 v)
{
return (v & 0x1) << 16;
}
static inline u32 host1x_sync_mod_teardown_dsib_teardown_m(void)
{
return 0x1 << 16;
}
static inline u32 host1x_sync_mod_teardown_dsib_teardown_v(u32 r)
{
return (r >> 16) & 0x1;
}
static inline u32 host1x_sync_mod_teardown_dsib_teardown_no_action_v(void)
{
return 0;
}
static inline u32 host1x_sync_mod_teardown_dsib_teardown_teardown_v(void)
{
return 1;
}
static inline u32 host1x_sync_usec_clk_r(void)
{
return 0x1a4;
}
static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
{
return 0x1a8;
}
static inline u32 host1x_sync_ip_busy_timeout_r(void)
{
return 0x1bc;
}
static inline u32 host1x_sync_ip_read_timeout_addr_r(void)
{
return 0x1c0;
}
static inline u32 host1x_sync_ip_write_timeout_addr_r(void)
{
return 0x1c4;
}
static inline u32 host1x_sync_mlock_0_r(void)
{
return 0x2c0;
}
static inline u32 host1x_sync_mlock_owner_0_r(void)
{
return 0x340;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_owner_chid_0_s(void)
{
return 4;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_owner_chid_0_f(u32 v)
{
return (v & 0xf) << 8;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_owner_chid_0_m(void)
{
return 0xf << 8;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_owner_chid_0_v(u32 r)
{
return (r >> 8) & 0xf;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_cpu_owns_0_s(void)
{
return 1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_cpu_owns_0_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_cpu_owns_0_m(void)
{
return 0x1 << 1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_cpu_owns_0_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_ch_owns_0_s(void)
{
return 1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_ch_owns_0_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_ch_owns_0_m(void)
{
return 0x1 << 0;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_ch_owns_0_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_sync_syncpt_0_r(void)
{
return 0x400;
}
static inline u32 host1x_sync_syncpt_int_thresh_0_r(void)
{
return 0x500;
}
static inline u32 host1x_sync_syncpt_base_0_r(void)
{
return 0x600;
}
static inline u32 host1x_sync_syncpt_cpu_incr_r(void)
{
return 0x700;
}
static inline u32 host1x_sync_cbread0_r(void)
{
return 0x720;
}
static inline u32 host1x_sync_cfpeek_ctrl_r(void)
{
return 0x74c;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_s(void)
{
return 9;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_f(u32 v)
{
return (v & 0x1ff) << 0;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_m(void)
{
return 0x1ff << 0;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_v(u32 r)
{
return (r >> 0) & 0x1ff;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_s(void)
{
return 3;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_f(u32 v)
{
return (v & 0x7) << 16;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_m(void)
{
return 0x7 << 16;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_v(u32 r)
{
return (r >> 16) & 0x7;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_ena_s(void)
{
return 1;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_ena_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_ena_m(void)
{
return 0x1 << 31;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_ena_v(u32 r)
{
return (r >> 31) & 0x1;
}
static inline u32 host1x_sync_cfpeek_read_r(void)
{
return 0x750;
}
static inline u32 host1x_sync_cfpeek_ptrs_r(void)
{
return 0x754;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_s(void)
{
return 9;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_f(u32 v)
{
return (v & 0x1ff) << 0;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_m(void)
{
return 0x1ff << 0;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(u32 r)
{
return (r >> 0) & 0x1ff;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_s(void)
{
return 9;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_f(u32 v)
{
return (v & 0x1ff) << 16;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_m(void)
{
return 0x1ff << 16;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(u32 r)
{
return (r >> 16) & 0x1ff;
}
static inline u32 host1x_sync_cbstat_0_r(void)
{
return 0x758;
}
static inline u32 host1x_sync_cbstat_0_cboffset0_s(void)
{
return 16;
}
static inline u32 host1x_sync_cbstat_0_cboffset0_f(u32 v)
{
return (v & 0xffff) << 0;
}
static inline u32 host1x_sync_cbstat_0_cboffset0_m(void)
{
return 0xffff << 0;
}
static inline u32 host1x_sync_cbstat_0_cboffset0_v(u32 r)
{
return (r >> 0) & 0xffff;
}
static inline u32 host1x_sync_cbstat_0_cbclass0_s(void)
{
return 10;
}
static inline u32 host1x_sync_cbstat_0_cbclass0_f(u32 v)
{
return (v & 0x3ff) << 16;
}
static inline u32 host1x_sync_cbstat_0_cbclass0_m(void)
{
return 0x3ff << 16;
}
static inline u32 host1x_sync_cbstat_0_cbclass0_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
#endif /* __hw_host1x01_sync_h__ */

View File

@@ -0,0 +1,474 @@
/*
* drivers/video/tegra/host/host1x/hw_host1x01_uclass.h
*
* Copyright (c) 2012, 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/>.
*
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef __hw_host1x01_uclass_h__
#define __hw_host1x01_uclass_h__
/*This file is autogenerated. Do not edit. */
static inline u32 host1x_uclass_incr_syncpt_r(void)
{
return 0x0;
}
static inline u32 host1x_uclass_incr_syncpt_cond_s(void)
{
return 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
{
return (v & 0xff) << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_m(void)
{
return 0xff << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_v(u32 r)
{
return (r >> 8) & 0xff;
}
static inline u32 host1x_uclass_incr_syncpt_cond_immediate_v(void)
{
return 0;
}
static inline u32 host1x_uclass_incr_syncpt_cond_op_done_v(void)
{
return 1;
}
static inline u32 host1x_uclass_incr_syncpt_cond_rd_done_v(void)
{
return 2;
}
static inline u32 host1x_uclass_incr_syncpt_cond_reg_wr_safe_v(void)
{
return 3;
}
static inline u32 host1x_uclass_incr_syncpt_indx_s(void)
{
return 8;
}
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 0;
}
static inline u32 host1x_uclass_incr_syncpt_indx_m(void)
{
return 0xff << 0;
}
static inline u32 host1x_uclass_incr_syncpt_indx_v(u32 r)
{
return (r >> 0) & 0xff;
}
static inline u32 host1x_uclass_wait_syncpt_r(void)
{
return 0x8;
}
static inline u32 host1x_uclass_wait_syncpt_indx_s(void)
{
return 8;
}
static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_indx_m(void)
{
return 0xff << 24;
}
static inline u32 host1x_uclass_wait_syncpt_indx_v(u32 r)
{
return (r >> 24) & 0xff;
}
static inline u32 host1x_uclass_wait_syncpt_thresh_s(void)
{
return 24;
}
static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_thresh_m(void)
{
return 0xffffff << 0;
}
static inline u32 host1x_uclass_wait_syncpt_thresh_v(u32 r)
{
return (r >> 0) & 0xffffff;
}
static inline u32 host1x_uclass_wait_syncpt_base_r(void)
{
return 0x9;
}
static inline u32 host1x_uclass_wait_syncpt_base_indx_s(void)
{
return 8;
}
static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_base_indx_m(void)
{
return 0xff << 24;
}
static inline u32 host1x_uclass_wait_syncpt_base_indx_v(u32 r)
{
return (r >> 24) & 0xff;
}
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_s(void)
{
return 8;
}
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 16;
}
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_m(void)
{
return 0xff << 16;
}
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_v(u32 r)
{
return (r >> 16) & 0xff;
}
static inline u32 host1x_uclass_wait_syncpt_base_offset_s(void)
{
return 16;
}
static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
{
return (v & 0xffff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_base_offset_m(void)
{
return 0xffff << 0;
}
static inline u32 host1x_uclass_wait_syncpt_base_offset_v(u32 r)
{
return (r >> 0) & 0xffff;
}
static inline u32 host1x_uclass_load_syncpt_base_r(void)
{
return 0xb;
}
static inline u32 host1x_uclass_load_syncpt_base_base_indx_s(void)
{
return 8;
}
static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_load_syncpt_base_base_indx_m(void)
{
return 0xff << 24;
}
static inline u32 host1x_uclass_load_syncpt_base_base_indx_v(u32 r)
{
return (r >> 24) & 0xff;
}
static inline u32 host1x_uclass_load_syncpt_base_value_s(void)
{
return 24;
}
static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_load_syncpt_base_value_m(void)
{
return 0xffffff << 0;
}
static inline u32 host1x_uclass_load_syncpt_base_value_v(u32 r)
{
return (r >> 0) & 0xffffff;
}
static inline u32 host1x_uclass_incr_syncpt_base_r(void)
{
return 0xc;
}
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_s(void)
{
return 8;
}
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_m(void)
{
return 0xff << 24;
}
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_v(u32 r)
{
return (r >> 24) & 0xff;
}
static inline u32 host1x_uclass_incr_syncpt_base_offset_s(void)
{
return 24;
}
static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_incr_syncpt_base_offset_m(void)
{
return 0xffffff << 0;
}
static inline u32 host1x_uclass_incr_syncpt_base_offset_v(u32 r)
{
return (r >> 0) & 0xffffff;
}
static inline u32 host1x_uclass_indoff_r(void)
{
return 0x2d;
}
static inline u32 host1x_uclass_indoff_indbe_s(void)
{
return 4;
}
static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
{
return (v & 0xf) << 28;
}
static inline u32 host1x_uclass_indoff_indbe_m(void)
{
return 0xf << 28;
}
static inline u32 host1x_uclass_indoff_indbe_v(u32 r)
{
return (r >> 28) & 0xf;
}
static inline u32 host1x_uclass_indoff_autoinc_s(void)
{
return 1;
}
static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
{
return (v & 0x1) << 27;
}
static inline u32 host1x_uclass_indoff_autoinc_m(void)
{
return 0x1 << 27;
}
static inline u32 host1x_uclass_indoff_autoinc_v(u32 r)
{
return (r >> 27) & 0x1;
}
static inline u32 host1x_uclass_indoff_spool_s(void)
{
return 1;
}
static inline u32 host1x_uclass_indoff_spool_f(u32 v)
{
return (v & 0x1) << 26;
}
static inline u32 host1x_uclass_indoff_spool_m(void)
{
return 0x1 << 26;
}
static inline u32 host1x_uclass_indoff_spool_v(u32 r)
{
return (r >> 26) & 0x1;
}
static inline u32 host1x_uclass_indoff_indoffset_s(void)
{
return 24;
}
static inline u32 host1x_uclass_indoff_indoffset_f(u32 v)
{
return (v & 0xffffff) << 2;
}
static inline u32 host1x_uclass_indoff_indoffset_m(void)
{
return 0xffffff << 2;
}
static inline u32 host1x_uclass_indoff_indoffset_v(u32 r)
{
return (r >> 2) & 0xffffff;
}
static inline u32 host1x_uclass_indoff_indmodid_s(void)
{
return 8;
}
static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
{
return (v & 0xff) << 18;
}
static inline u32 host1x_uclass_indoff_indmodid_m(void)
{
return 0xff << 18;
}
static inline u32 host1x_uclass_indoff_indmodid_v(u32 r)
{
return (r >> 18) & 0xff;
}
static inline u32 host1x_uclass_indoff_indmodid_host1x_v(void)
{
return 0;
}
static inline u32 host1x_uclass_indoff_indmodid_mpe_v(void)
{
return 1;
}
static inline u32 host1x_uclass_indoff_indmodid_vi_v(void)
{
return 2;
}
static inline u32 host1x_uclass_indoff_indmodid_epp_v(void)
{
return 3;
}
static inline u32 host1x_uclass_indoff_indmodid_isp_v(void)
{
return 4;
}
static inline u32 host1x_uclass_indoff_indmodid_gr2d_v(void)
{
return 5;
}
static inline u32 host1x_uclass_indoff_indmodid_gr3d_v(void)
{
return 6;
}
static inline u32 host1x_uclass_indoff_indmodid_display_v(void)
{
return 8;
}
static inline u32 host1x_uclass_indoff_indmodid_tvo_v(void)
{
return 11;
}
static inline u32 host1x_uclass_indoff_indmodid_displayb_v(void)
{
return 9;
}
static inline u32 host1x_uclass_indoff_indmodid_dsi_v(void)
{
return 12;
}
static inline u32 host1x_uclass_indoff_indmodid_hdmi_v(void)
{
return 10;
}
static inline u32 host1x_uclass_indoff_indmodid_dsib_v(void)
{
return 16;
}
static inline u32 host1x_uclass_indoff_indroffset_s(void)
{
return 16;
}
static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
{
return (v & 0xffff) << 2;
}
static inline u32 host1x_uclass_indoff_indroffset_m(void)
{
return 0xffff << 2;
}
static inline u32 host1x_uclass_indoff_indroffset_v(u32 r)
{
return (r >> 2) & 0xffff;
}
static inline u32 host1x_uclass_indoff_acctype_s(void)
{
return 1;
}
static inline u32 host1x_uclass_indoff_acctype_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_uclass_indoff_acctype_m(void)
{
return 0x1 << 1;
}
static inline u32 host1x_uclass_indoff_acctype_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_uclass_indoff_acctype_reg_v(void)
{
return 0;
}
static inline u32 host1x_uclass_indoff_acctype_fb_v(void)
{
return 1;
}
static inline u32 host1x_uclass_indoff_rwn_s(void)
{
return 1;
}
static inline u32 host1x_uclass_indoff_rwn_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_uclass_indoff_rwn_m(void)
{
return 0x1 << 0;
}
static inline u32 host1x_uclass_indoff_rwn_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_uclass_indoff_rwn_write_v(void)
{
return 0;
}
static inline u32 host1x_uclass_indoff_rwn_read_v(void)
{
return 1;
}
static inline u32 host1x_uclass_inddata_r(void)
{
return 0x2e;
}
#endif /* __hw_host1x01_uclass_h__ */

View File

@@ -0,0 +1,153 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x02_channel_h_
#define _hw_host1x02_channel_h_
static inline u32 host1x_channel_fifostat_r(void)
{
return 0x0;
}
static inline u32 host1x_channel_fifostat_cfempty_v(u32 r)
{
return (r >> 11) & 0x1;
}
static inline u32 host1x_channel_fifostat_outfentries_v(u32 r)
{
return (r >> 24) & 0x1f;
}
static inline u32 host1x_channel_inddata_r(void)
{
return 0xc;
}
static inline u32 host1x_channel_dmastart_r(void)
{
return 0x14;
}
static inline u32 host1x_channel_dmaput_r(void)
{
return 0x18;
}
static inline u32 host1x_channel_dmaget_r(void)
{
return 0x1c;
}
static inline u32 host1x_channel_dmaend_r(void)
{
return 0x20;
}
static inline u32 host1x_channel_dmactrl_r(void)
{
return 0x24;
}
static inline u32 host1x_channel_dmactrl_dmastop_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_dmactrl_dmastop_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_channel_dmactrl_dmagetrst_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_channel_dmactrl_dmainitget_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_channel_tickcount_hi_r(void)
{
return 0x90;
}
static inline u32 host1x_channel_tickcount_lo_r(void)
{
return 0x94;
}
static inline u32 host1x_channel_channelctrl_r(void)
{
return 0x98;
}
static inline u32 host1x_channel_channelctrl_enabletickcnt_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_stallctrl_r(void)
{
return 0xa0;
}
static inline u32 host1x_channel_stallctrl_enable_channel_stall_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_stallcount_hi_r(void)
{
return 0xa4;
}
static inline u32 host1x_channel_stallcount_lo_r(void)
{
return 0xa8;
}
static inline u32 host1x_channel_xferctrl_r(void)
{
return 0xac;
}
static inline u32 host1x_channel_xferctrl_enable_channel_xfer_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_xfercount_hi_r(void)
{
return 0xb0;
}
static inline u32 host1x_channel_xfercount_lo_r(void)
{
return 0xb4;
}
#endif

View File

@@ -0,0 +1,325 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x02_sync_h_
#define _hw_host1x02_sync_h_
static inline u32 host1x_sync_intstatus_r(void)
{
return 0x0;
}
static inline u32 host1x_sync_intmask_r(void)
{
return 0x4;
}
static inline u32 host1x_sync_intc0mask_r(void)
{
return 0x8;
}
static inline u32 host1x_sync_hintstatus_r(void)
{
return 0x20;
}
static inline u32 host1x_sync_hintmask_r(void)
{
return 0x24;
}
static inline u32 host1x_sync_hintstatus_ext_r(void)
{
return 0x28;
}
static inline u32 host1x_sync_hintstatus_ext_ip_read_int_v(u32 r)
{
return (r >> 30) & 0x1;
}
static inline u32 host1x_sync_hintstatus_ext_ip_write_int_v(u32 r)
{
return (r >> 31) & 0x1;
}
static inline u32 host1x_sync_hintmask_ext_r(void)
{
return 0x2c;
}
static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(void)
{
return 0x40;
}
static inline u32 host1x_sync_syncpt_thresh_cpu1_int_status_r(void)
{
return 0x48;
}
static inline u32 host1x_sync_syncpt_thresh_int_disable_r(void)
{
return 0x60;
}
static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(void)
{
return 0x68;
}
static inline u32 host1x_sync_cf0_setup_r(void)
{
return 0x80;
}
static inline u32 host1x_sync_cf0_setup_cf0_base_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cf0_setup_cf0_limit_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_cmdproc_stat_r(void)
{
return 0xa8;
}
static inline u32 host1x_sync_cmdproc_stop_r(void)
{
return 0xac;
}
static inline u32 host1x_sync_ch_teardown_r(void)
{
return 0xb0;
}
static inline u32 host1x_sync_mod_teardown_r(void)
{
return 0xb4;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_f(u32 v)
{
return (v & 0x1) << 3;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_f(u32 v)
{
return (v & 0x1) << 5;
}
static inline u32 host1x_sync_usec_clk_r(void)
{
return 0x1a4;
}
static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
{
return 0x1a8;
}
static inline u32 host1x_sync_ip_busy_timeout_r(void)
{
return 0x1bc;
}
static inline u32 host1x_sync_ip_read_timeout_addr_r(void)
{
return 0x1c0;
}
static inline u32 host1x_sync_ip_write_timeout_addr_r(void)
{
return 0x1c4;
}
static inline u32 host1x_sync_mlock_0_r(void)
{
return 0x2c0;
}
static inline u32 host1x_sync_mlock_owner_0_r(void)
{
return 0x340;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_owner_chid_0_v(u32 r)
{
return (r >> 8) & 0xf;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_cpu_owns_0_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_ch_owns_0_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_sync_syncpt_0_r(void)
{
return 0x400;
}
static inline u32 host1x_sync_syncpt_int_thresh_0_r(void)
{
return 0x500;
}
static inline u32 host1x_sync_syncpt_base_0_r(void)
{
return 0x600;
}
static inline u32 host1x_sync_syncpt_cpu_incr_r(void)
{
return 0x700;
}
static inline u32 host1x_sync_cbread0_r(void)
{
return 0x720;
}
static inline u32 host1x_sync_cfpeek_ctrl_r(void)
{
return 0x74c;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_f(u32 v)
{
return (v & 0x3ff) << 0;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_f(u32 v)
{
return (v & 0xf) << 16;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_v(u32 r)
{
return (r >> 16) & 0xf;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_ena_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 host1x_sync_cfpeek_read_r(void)
{
return 0x750;
}
static inline u32 host1x_sync_cfpeek_ptrs_r(void)
{
return 0x754;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_cbstat_0_r(void)
{
return 0x758;
}
static inline u32 host1x_sync_cbstat_0_cboffset0_v(u32 r)
{
return (r >> 0) & 0xffff;
}
static inline u32 host1x_sync_cbstat_0_cbclass0_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_actmon_ctrl_r(void)
{
return 0x9d0;
}
static inline u32 host1x_sync_actmon_ctrl_enb_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 host1x_sync_actmon_ctrl_enb_m(void)
{
return 0x1 << 31;
}
static inline u32 host1x_sync_actmon_ctrl_avg_above_wmark_en_m(void)
{
return 0x1 << 21;
}
static inline u32 host1x_sync_actmon_ctrl_avg_below_wmark_en_m(void)
{
return 0x1 << 20;
}
static inline u32 host1x_sync_actmon_ctrl_enb_periodic_f(u32 v)
{
return (v & 0x1) << 18;
}
static inline u32 host1x_sync_actmon_ctrl_enb_periodic_m(void)
{
return 0x1 << 18;
}
static inline u32 host1x_sync_actmon_ctrl_k_val_f(u32 v)
{
return (v & 0x7) << 10;
}
static inline u32 host1x_sync_actmon_ctrl_k_val_m(void)
{
return 0x7 << 10;
}
static inline u32 host1x_sync_actmon_init_avg_r(void)
{
return 0x9dc;
}
static inline u32 host1x_sync_actmon_count_weight_r(void)
{
return 0x9e8;
}
static inline u32 host1x_sync_actmon_avg_count_r(void)
{
return 0x9f0;
}
static inline u32 host1x_sync_actmon_status_r(void)
{
return 0x9f4;
}
static inline u32 host1x_sync_actmon_status_sample_period_f(u32 v)
{
return (v & 0xff) << 3;
}
static inline u32 host1x_sync_actmon_status_status_source_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_sync_actmon_status_status_source_usec_v(void)
{
return 0x00000001;
}
static inline u32 host1x_sync_actmon_status_gr3d_mon_act_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_sync_actmon_intr_status_r(void)
{
return 0x9f8;
}
#endif

View File

@@ -0,0 +1,165 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x02_uclass_h_
#define _hw_host1x02_uclass_h_
static inline u32 host1x_uclass_incr_syncpt_r(void)
{
return 0x0;
}
static inline u32 host1x_uclass_incr_syncpt_cond_s(void)
{
return 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
{
return (v & 0xff) << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_m(void)
{
return 0xff << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_v(u32 r)
{
return (r >> 8) & 0xff;
}
static inline u32 host1x_uclass_incr_syncpt_cond_op_done_v(void)
{
return 0x00000001;
}
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_r(void)
{
return 0x8;
}
static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_base_r(void)
{
return 0x9;
}
static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 16;
}
static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
{
return (v & 0xffff) << 0;
}
static inline u32 host1x_uclass_load_syncpt_base_r(void)
{
return 0xb;
}
static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_incr_syncpt_base_r(void)
{
return 0xc;
}
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_indoff_r(void)
{
return 0x2d;
}
static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
{
return (v & 0xf) << 28;
}
static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
{
return (v & 0x1) << 27;
}
static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
{
return (v & 0xff) << 18;
}
static inline u32 host1x_uclass_indoff_indmodid_gr3d_v(void)
{
return 0x00000006;
}
static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
{
return (v & 0xffff) << 2;
}
static inline u32 host1x_uclass_indoff_rwn_read_v(void)
{
return 0x00000001;
}
static inline u32 host1x_uclass_inddata_r(void)
{
return 0x2e;
}
#endif

View File

@@ -0,0 +1,153 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x03_channel_h_
#define _hw_host1x03_channel_h_
static inline u32 host1x_channel_fifostat_r(void)
{
return 0x0;
}
static inline u32 host1x_channel_fifostat_cfempty_v(u32 r)
{
return (r >> 11) & 0x1;
}
static inline u32 host1x_channel_fifostat_outfentries_v(u32 r)
{
return (r >> 24) & 0x1f;
}
static inline u32 host1x_channel_inddata_r(void)
{
return 0xc;
}
static inline u32 host1x_channel_dmastart_r(void)
{
return 0x14;
}
static inline u32 host1x_channel_dmaput_r(void)
{
return 0x18;
}
static inline u32 host1x_channel_dmaget_r(void)
{
return 0x1c;
}
static inline u32 host1x_channel_dmaend_r(void)
{
return 0x20;
}
static inline u32 host1x_channel_dmactrl_r(void)
{
return 0x24;
}
static inline u32 host1x_channel_dmactrl_dmastop_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_dmactrl_dmastop_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_channel_dmactrl_dmagetrst_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_channel_dmactrl_dmainitget_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_channel_tickcount_hi_r(void)
{
return 0x90;
}
static inline u32 host1x_channel_tickcount_lo_r(void)
{
return 0x94;
}
static inline u32 host1x_channel_channelctrl_r(void)
{
return 0x98;
}
static inline u32 host1x_channel_channelctrl_enabletickcnt_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_stallctrl_r(void)
{
return 0xa0;
}
static inline u32 host1x_channel_stallctrl_enable_channel_stall_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_stallcount_hi_r(void)
{
return 0xa4;
}
static inline u32 host1x_channel_stallcount_lo_r(void)
{
return 0xa8;
}
static inline u32 host1x_channel_xferctrl_r(void)
{
return 0xac;
}
static inline u32 host1x_channel_xferctrl_enable_channel_xfer_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_xfercount_hi_r(void)
{
return 0xb0;
}
static inline u32 host1x_channel_xfercount_lo_r(void)
{
return 0xb4;
}
#endif

View File

@@ -0,0 +1,325 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x03_sync_h_
#define _hw_host1x03_sync_h_
static inline u32 host1x_sync_intstatus_r(void)
{
return 0x0;
}
static inline u32 host1x_sync_intmask_r(void)
{
return 0x4;
}
static inline u32 host1x_sync_intc0mask_r(void)
{
return 0x8;
}
static inline u32 host1x_sync_hintstatus_r(void)
{
return 0x20;
}
static inline u32 host1x_sync_hintmask_r(void)
{
return 0x24;
}
static inline u32 host1x_sync_hintstatus_ext_r(void)
{
return 0x28;
}
static inline u32 host1x_sync_hintstatus_ext_ip_read_int_v(u32 r)
{
return (r >> 30) & 0x1;
}
static inline u32 host1x_sync_hintstatus_ext_ip_write_int_v(u32 r)
{
return (r >> 31) & 0x1;
}
static inline u32 host1x_sync_hintmask_ext_r(void)
{
return 0x2c;
}
static inline u32 host1x_sync_cmdproc_stat_r(void)
{
return 0xa8;
}
static inline u32 host1x_sync_cmdproc_stop_r(void)
{
return 0xac;
}
static inline u32 host1x_sync_ch_teardown_r(void)
{
return 0xb0;
}
static inline u32 host1x_sync_mod_teardown_r(void)
{
return 0xb4;
}
static inline u32 host1x_sync_mod_teardown_epp_teardown_f(u32 v)
{
return (v & 0x1) << 3;
}
static inline u32 host1x_sync_mod_teardown_gr2d_teardown_f(u32 v)
{
return (v & 0x1) << 5;
}
static inline u32 host1x_sync_usec_clk_r(void)
{
return 0x1a4;
}
static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
{
return 0x1a8;
}
static inline u32 host1x_sync_ip_busy_timeout_r(void)
{
return 0x1bc;
}
static inline u32 host1x_sync_ip_read_timeout_addr_r(void)
{
return 0x1c0;
}
static inline u32 host1x_sync_ip_write_timeout_addr_r(void)
{
return 0x1c4;
}
static inline u32 host1x_sync_mlock_0_r(void)
{
return 0x2c0;
}
static inline u32 host1x_sync_mlock_owner_0_r(void)
{
return 0x340;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_owner_chid_0_v(u32 r)
{
return (r >> 8) & 0xf;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_cpu_owns_0_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_ch_owns_0_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_sync_syncpt_base_0_r(void)
{
return 0x600;
}
static inline u32 host1x_sync_cfpeek_ctrl_r(void)
{
return 0x74c;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_f(u32 v)
{
return (v & 0x3ff) << 0;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_f(u32 v)
{
return (v & 0xf) << 16;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_v(u32 r)
{
return (r >> 16) & 0xf;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_ena_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 host1x_sync_cfpeek_read_r(void)
{
return 0x750;
}
static inline u32 host1x_sync_cfpeek_ptrs_r(void)
{
return 0x754;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_actmon_ctrl_r(void)
{
return 0x9d0;
}
static inline u32 host1x_sync_actmon_ctrl_enb_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 host1x_sync_actmon_ctrl_enb_m(void)
{
return 0x1 << 31;
}
static inline u32 host1x_sync_actmon_ctrl_avg_above_wmark_en_m(void)
{
return 0x1 << 21;
}
static inline u32 host1x_sync_actmon_ctrl_avg_below_wmark_en_m(void)
{
return 0x1 << 20;
}
static inline u32 host1x_sync_actmon_ctrl_enb_periodic_f(u32 v)
{
return (v & 0x1) << 18;
}
static inline u32 host1x_sync_actmon_ctrl_enb_periodic_m(void)
{
return 0x1 << 18;
}
static inline u32 host1x_sync_actmon_ctrl_k_val_f(u32 v)
{
return (v & 0x7) << 10;
}
static inline u32 host1x_sync_actmon_ctrl_k_val_m(void)
{
return 0x7 << 10;
}
static inline u32 host1x_sync_actmon_init_avg_r(void)
{
return 0x9dc;
}
static inline u32 host1x_sync_actmon_count_weight_r(void)
{
return 0x9e8;
}
static inline u32 host1x_sync_actmon_avg_count_r(void)
{
return 0x9f0;
}
static inline u32 host1x_sync_actmon_status_r(void)
{
return 0x9f4;
}
static inline u32 host1x_sync_actmon_status_sample_period_f(u32 v)
{
return (v & 0xff) << 3;
}
static inline u32 host1x_sync_actmon_status_status_source_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_sync_actmon_status_status_source_usec_v(void)
{
return 0x00000001;
}
static inline u32 host1x_sync_actmon_status_gr3d_mon_act_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_sync_actmon_intr_status_r(void)
{
return 0x9f8;
}
static inline u32 host1x_sync_cf0_setup_r(void)
{
return 0xc00;
}
static inline u32 host1x_sync_cf0_setup_cf0_base_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cf0_setup_cf0_limit_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_cbread0_r(void)
{
return 0xc80;
}
static inline u32 host1x_sync_cbstat_0_r(void)
{
return 0xcc0;
}
static inline u32 host1x_sync_cbstat_0_cboffset0_v(u32 r)
{
return (r >> 0) & 0xffff;
}
static inline u32 host1x_sync_cbstat_0_cbclass0_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(void)
{
return 0xe80;
}
static inline u32 host1x_sync_syncpt_thresh_cpu1_int_status_r(void)
{
return 0xea0;
}
static inline u32 host1x_sync_syncpt_thresh_int_disable_r(void)
{
return 0xf00;
}
static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(void)
{
return 0xf20;
}
static inline u32 host1x_sync_syncpt_cpu_incr_r(void)
{
return 0xf60;
}
static inline u32 host1x_sync_syncpt_0_r(void)
{
return 0xf80;
}
static inline u32 host1x_sync_syncpt_int_thresh_0_r(void)
{
return 0x1380;
}
#endif

View File

@@ -0,0 +1,165 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x03_uclass_h_
#define _hw_host1x03_uclass_h_
static inline u32 host1x_uclass_incr_syncpt_r(void)
{
return 0x0;
}
static inline u32 host1x_uclass_incr_syncpt_cond_s(void)
{
return 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
{
return (v & 0xff) << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_m(void)
{
return 0xff << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_v(u32 r)
{
return (r >> 8) & 0xff;
}
static inline u32 host1x_uclass_incr_syncpt_cond_op_done_v(void)
{
return 0x00000001;
}
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_r(void)
{
return 0x8;
}
static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_base_r(void)
{
return 0x9;
}
static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 16;
}
static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
{
return (v & 0xffff) << 0;
}
static inline u32 host1x_uclass_load_syncpt_base_r(void)
{
return 0xb;
}
static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_incr_syncpt_base_r(void)
{
return 0xc;
}
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_indoff_r(void)
{
return 0x2d;
}
static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
{
return (v & 0xf) << 28;
}
static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
{
return (v & 0x1) << 27;
}
static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
{
return (v & 0xff) << 18;
}
static inline u32 host1x_uclass_indoff_indmodid_gr3d_v(void)
{
return 0x00000006;
}
static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
{
return (v & 0xffff) << 2;
}
static inline u32 host1x_uclass_indoff_rwn_read_v(void)
{
return 0x00000001;
}
static inline u32 host1x_uclass_inddata_r(void)
{
return 0x2e;
}
#endif

View File

@@ -0,0 +1,97 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x04_actmon_h_
#define _hw_host1x04_actmon_h_
static inline u32 actmon_ctrl_r(void)
{
return 0x0;
}
static inline u32 actmon_ctrl_actmon_enable_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 actmon_ctrl_enb_periodic_f(u32 v)
{
return (v & 0x1) << 13;
}
static inline u32 actmon_ctrl_k_val_f(u32 v)
{
return (v & 0x7) << 10;
}
static inline u32 actmon_ctrl_k_val_m(void)
{
return 0x7 << 10;
}
static inline u32 actmon_ctrl_sample_period_f(u32 v)
{
return (v & 0xff) << 0;
}
static inline u32 actmon_ctrl_sample_period_m(void)
{
return 0xff << 0;
}
static inline u32 actmon_init_avg_r(void)
{
return 0x14;
}
static inline u32 actmon_count_r(void)
{
return 0x18;
}
static inline u32 actmon_avg_count_r(void)
{
return 0x1c;
}
static inline u32 actmon_intr_status_r(void)
{
return 0x20;
}
#endif

View File

@@ -0,0 +1,141 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x04_channel_h_
#define _hw_host1x04_channel_h_
static inline u32 host1x_channel_fifostat_r(void)
{
return 0x0;
}
static inline u32 host1x_channel_fifostat_cfempty_v(u32 r)
{
return (r >> 11) & 0x1;
}
static inline u32 host1x_channel_fifostat_outfentries_v(u32 r)
{
return (r >> 24) & 0x1f;
}
static inline u32 host1x_channel_inddata_r(void)
{
return 0xc;
}
static inline u32 host1x_channel_dmastart_r(void)
{
return 0x14;
}
static inline u32 host1x_channel_dmaput_r(void)
{
return 0x18;
}
static inline u32 host1x_channel_dmaget_r(void)
{
return 0x1c;
}
static inline u32 host1x_channel_dmaend_r(void)
{
return 0x20;
}
static inline u32 host1x_channel_dmactrl_r(void)
{
return 0x24;
}
static inline u32 host1x_channel_dmactrl_dmastop_f(u32 v)
{
return (v & 0x1) << 0;
}
static inline u32 host1x_channel_dmactrl_dmastop_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_channel_dmactrl_dmagetrst_f(u32 v)
{
return (v & 0x1) << 1;
}
static inline u32 host1x_channel_dmactrl_dmainitget_f(u32 v)
{
return (v & 0x1) << 2;
}
static inline u32 host1x_channel_channelctrl_r(void)
{
return 0x98;
}
static inline u32 host1x_channel_stallcount_hi_r(void)
{
return 0xa4;
}
static inline u32 host1x_channel_stallcount_lo_r(void)
{
return 0xa8;
}
static inline u32 host1x_channel_stallctrl_r(void)
{
return 0xa0;
}
static inline u32 host1x_channel_tickcount_hi_r(void)
{
return 0x90;
}
static inline u32 host1x_channel_tickcount_lo_r(void)
{
return 0x94;
}
static inline u32 host1x_channel_xfercount_hi_r(void)
{
return 0xb0;
}
static inline u32 host1x_channel_xfercount_lo_r(void)
{
return 0xb4;
}
static inline u32 host1x_channel_xferctrl_r(void)
{
return 0xac;
}
#endif

View File

@@ -0,0 +1,245 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x04_sync_h_
#define _hw_host1x04_sync_h_
static inline u32 host1x_sync_intstatus_r(void)
{
return 0x0;
}
static inline u32 host1x_sync_intmask_r(void)
{
return 0x4;
}
static inline u32 host1x_sync_intc0mask_r(void)
{
return 0x8;
}
static inline u32 host1x_sync_hintstatus_r(void)
{
return 0x20;
}
static inline u32 host1x_sync_hintmask_r(void)
{
return 0x24;
}
static inline u32 host1x_sync_hintstatus_ext_r(void)
{
return 0x28;
}
static inline u32 host1x_sync_hintstatus_ext_ip_read_int_v(u32 r)
{
return (r >> 30) & 0x1;
}
static inline u32 host1x_sync_hintstatus_ext_ip_write_int_v(u32 r)
{
return (r >> 31) & 0x1;
}
static inline u32 host1x_sync_hintmask_ext_r(void)
{
return 0x2c;
}
static inline u32 host1x_sync_cmdproc_stat_r(void)
{
return 0xa8;
}
static inline u32 host1x_sync_cmdproc_stop_r(void)
{
return 0xac;
}
static inline u32 host1x_sync_ch_teardown_r(void)
{
return 0xb0;
}
static inline u32 host1x_sync_mod_teardown_r(void)
{
return 0xb4;
}
static inline u32 host1x_sync_usec_clk_r(void)
{
return 0x1a4;
}
static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
{
return 0x1a8;
}
static inline u32 host1x_sync_ip_busy_timeout_r(void)
{
return 0x1bc;
}
static inline u32 host1x_sync_ip_read_timeout_addr_r(void)
{
return 0x1c0;
}
static inline u32 host1x_sync_ip_write_timeout_addr_r(void)
{
return 0x1c4;
}
static inline u32 host1x_sync_mlock_0_r(void)
{
return 0x2c0;
}
static inline u32 host1x_sync_mlock_owner_0_r(void)
{
return 0x340;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_owner_chid_0_v(u32 r)
{
return (r >> 8) & 0xf;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_cpu_owns_0_v(u32 r)
{
return (r >> 1) & 0x1;
}
static inline u32 host1x_sync_mlock_owner_0_mlock_ch_owns_0_v(u32 r)
{
return (r >> 0) & 0x1;
}
static inline u32 host1x_sync_syncpt_base_0_r(void)
{
return 0x600;
}
static inline u32 host1x_sync_cfpeek_ctrl_r(void)
{
return 0x74c;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_f(u32 v)
{
return (v & 0x3ff) << 0;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_addr_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_f(u32 v)
{
return (v & 0xf) << 16;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_channr_v(u32 r)
{
return (r >> 16) & 0xf;
}
static inline u32 host1x_sync_cfpeek_ctrl_cfpeek_ena_f(u32 v)
{
return (v & 0x1) << 31;
}
static inline u32 host1x_sync_cfpeek_read_r(void)
{
return 0x750;
}
static inline u32 host1x_sync_cfpeek_ptrs_r(void)
{
return 0x754;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_cf0_setup_r(void)
{
return 0xc00;
}
static inline u32 host1x_sync_cf0_setup_cf0_base_v(u32 r)
{
return (r >> 0) & 0x3ff;
}
static inline u32 host1x_sync_cf0_setup_cf0_limit_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_cbread0_r(void)
{
return 0xc80;
}
static inline u32 host1x_sync_cbstat_0_r(void)
{
return 0xcc0;
}
static inline u32 host1x_sync_cbstat_0_cbclass0_v(u32 r)
{
return (r >> 16) & 0x3ff;
}
static inline u32 host1x_sync_cbstat_0_cboffset0_v(u32 r)
{
return (r >> 0) & 0xffff;
}
static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(void)
{
return 0xe80;
}
static inline u32 host1x_sync_syncpt_thresh_cpu1_int_status_r(void)
{
return 0xea0;
}
static inline u32 host1x_sync_syncpt_thresh_int_disable_r(void)
{
return 0xf00;
}
static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(void)
{
return 0xf20;
}
static inline u32 host1x_sync_syncpt_cpu_incr_r(void)
{
return 0xf60;
}
static inline u32 host1x_sync_syncpt_0_r(void)
{
return 0xf80;
}
static inline u32 host1x_sync_syncpt_int_thresh_0_r(void)
{
return 0x1380;
}
#endif

View File

@@ -0,0 +1,149 @@
/*
* 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 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/>.
*/
/*
* Function naming determines intended use:
*
* <x>_r(void) : Returns the offset for register <x>.
*
* <x>_o(void) : Returns the offset for element <x>.
*
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
*
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
*
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
* and masked to place it at field <y> of register <x>. This value
* can be |'d with others to produce a full register value for
* register <x>.
*
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
* value can be ~'d and then &'d to clear the value of field <y> for
* register <x>.
*
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
* to place it at field <y> of register <x>. This value can be |'d
* with others to produce a full register value for <x>.
*
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
* <x> value 'r' after being shifted to place its LSB at bit 0.
* This value is suitable for direct comparison with other unshifted
* values appropriate for use in field <y> of register <x>.
*
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
* field <y> of register <x>. This value is suitable for direct
* comparison with unshifted values appropriate for use in field <y>
* of register <x>.
*/
#ifndef _hw_host1x04_uclass_h_
#define _hw_host1x04_uclass_h_
static inline u32 host1x_uclass_incr_syncpt_r(void)
{
return 0x0;
}
static inline u32 host1x_uclass_incr_syncpt_cond_s(void)
{
return 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
{
return (v & 0xff) << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_m(void)
{
return 0xff << 8;
}
static inline u32 host1x_uclass_incr_syncpt_cond_v(u32 r)
{
return (r >> 8) & 0xff;
}
static inline u32 host1x_uclass_incr_syncpt_cond_op_done_v(void)
{
return 0x00000001;
}
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 0;
}
static inline u32 host1x_uclass_incr_syncpt_base_r(void)
{
return 0xc;
}
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_base_r(void)
{
return 0x9;
}
static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 16;
}
static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
{
return (v & 0xffff) << 0;
}
static inline u32 host1x_uclass_load_syncpt_base_r(void)
{
return 0xb;
}
static inline u32 host1x_uclass_wait_syncpt_r(void)
{
return 0x8;
}
static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
{
return (v & 0xff) << 24;
}
static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
{
return (v & 0xffffff) << 0;
}
static inline u32 host1x_uclass_indoff_r(void)
{
return 0x2d;
}
static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
{
return (v & 0xf) << 28;
}
static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
{
return (v & 0x1) << 27;
}
static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
{
return (v & 0xff) << 18;
}
static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
{
return (v & 0xffff) << 2;
}
static inline u32 host1x_uclass_indoff_rwn_read_v(void)
{
return 0x00000001;
}
#endif