summaryrefslogtreecommitdiff
path: root/drivers/video/tegra
diff options
context:
space:
mode:
authorVandana Salve <vsalve@nvidia.com>2011-10-18 18:34:02 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:49:29 -0800
commite7a4d6233d300b607bcc1a9153fc0ea69ce65547 (patch)
treea51a67b41bf65ce85213e5be5d9867aeaa22791d /drivers/video/tegra
parentfd46ce8f4be0adfa61272185c1fd9a4ac15eac98 (diff)
nvhost: Add host module clock functionality for T20/T30
This includes Get/Set clock rate functionality. Removed the abstraction and added functionality for T20 and T30 into nvhost_acm file Bug 887263 Change-Id: I2e8ad3d96fcc3711f99f9aa42150e7d4588910fa Reviewed-on: http://git-master/r/58654 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: Vandana Salve <vsalve@nvidia.com> Tested-by: Vandana Salve <vsalve@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Rebase-Id: R5aebeda335d753d23b0e8704dea949ccf0f7303e
Diffstat (limited to 'drivers/video/tegra')
-rw-r--r--drivers/video/tegra/host/chip_support.h9
-rw-r--r--drivers/video/tegra/host/nvhost_acm.c102
-rw-r--r--drivers/video/tegra/host/nvhost_acm.h1
-rw-r--r--drivers/video/tegra/host/t30/Makefile1
-rw-r--r--drivers/video/tegra/host/t30/acm_t30.c142
-rw-r--r--drivers/video/tegra/host/t30/t30.c3
-rw-r--r--drivers/video/tegra/host/t30/t30.h1
7 files changed, 89 insertions, 170 deletions
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h
index 04ff6951770a..8932552a29a4 100644
--- a/drivers/video/tegra/host/chip_support.h
+++ b/drivers/video/tegra/host/chip_support.h
@@ -154,15 +154,6 @@ struct nvhost_chip_support {
unsigned int idx);
} cpuaccess;
- struct {
- int (*add_client)(struct nvhost_module *mod, void *priv);
- void (*remove_client)(struct nvhost_module *mod, void *priv);
- int (*get_rate)(struct nvhost_module *mod,
- unsigned long *rate,
- int index);
- int (*set_rate)(struct nvhost_module *mod, void *priv,
- unsigned long rate, int index);
- } acm;
};
diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c
index ed950a562be7..e4ff2d51a325 100644
--- a/drivers/video/tegra/host/nvhost_acm.c
+++ b/drivers/video/tegra/host/nvhost_acm.c
@@ -36,6 +36,15 @@
#define POWERGATE_DELAY 10
#define MAX_DEVID_LENGTH 16
+DEFINE_MUTEX(client_list_lock);
+
+struct nvhost_module_client {
+ struct list_head node;
+ unsigned long rate[NVHOST_MODULE_MAX_CLOCKS];
+ void *priv;
+};
+
+
void nvhost_module_reset(struct device *dev, struct nvhost_module *mod)
{
dev_dbg(dev,
@@ -182,36 +191,103 @@ int nvhost_module_get_rate(struct nvhost_master *host,
struct nvhost_module *mod, unsigned long *rate,
int index)
{
- int ret = -EINVAL;
- if (host_acm_op(host).get_rate)
- ret = host_acm_op(host).get_rate(mod, rate, index);
- return ret;
+ struct clk *c;
+
+ c = mod->clk[index];
+ if (IS_ERR_OR_NULL(c))
+ return -EINVAL;
+
+ /* Need to enable client to get correct rate */
+ nvhost_module_busy(mod);
+ *rate = clk_get_rate(c);
+ nvhost_module_idle(mod);
+ return 0;
+
+}
+
+static int nvhost_module_update_rate(struct nvhost_module *mod, int index)
+{
+ unsigned long rate = 0;
+ struct nvhost_module_client *m;
+
+ if (!mod->clk[index])
+ return -EINVAL;
+
+ list_for_each_entry(m, &mod->client_list, node) {
+ rate = max(m->rate[index], rate);
+ }
+ if (!rate)
+ rate = clk_round_rate(mod->clk[index],
+ mod->desc->clocks[index].default_rate);
+
+ return clk_set_rate(mod->clk[index], rate);
}
int nvhost_module_set_rate(struct nvhost_master *host,
struct nvhost_module *mod, void *priv,
unsigned long rate, int index)
{
- int ret = -EINVAL;
- if (host_acm_op(host).set_rate)
- ret = host_acm_op(host).set_rate(mod, priv, rate, index);
+ struct nvhost_module_client *m;
+ int ret;
+
+ mutex_lock(&client_list_lock);
+ list_for_each_entry(m, &mod->client_list, node) {
+ if (m->priv == priv) {
+ rate = clk_round_rate(mod->clk[index], rate);
+ m->rate[index] = rate;
+ break;
+ }
+ }
+ ret = nvhost_module_update_rate(mod, index);
+ mutex_unlock(&client_list_lock);
return ret;
+
}
int nvhost_module_add_client(struct nvhost_master *host,
struct nvhost_module *mod, void *priv)
{
- int ret = 0;
- if (host_acm_op(host).add_client)
- ret = host_acm_op(host).add_client(mod, priv);
- return ret;
+ int i;
+ unsigned long rate;
+ struct nvhost_module_client *client;
+
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
+ if (!client)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&client->node);
+ client->priv = priv;
+
+ for (i = 0; i < mod->num_clks; i++) {
+ rate = clk_round_rate(mod->clk[i],
+ mod->desc->clocks[i].default_rate);
+ client->rate[i] = rate;
+ }
+ mutex_lock(&client_list_lock);
+ list_add_tail(&client->node, &mod->client_list);
+ mutex_unlock(&client_list_lock);
+ return 0;
}
void nvhost_module_remove_client(struct nvhost_master *host,
struct nvhost_module *mod, void *priv)
{
- if (host_acm_op(host).remove_client)
- host_acm_op(host).remove_client(mod, priv);
+ int i;
+ struct nvhost_module_client *m;
+
+ mutex_lock(&client_list_lock);
+ list_for_each_entry(m, &mod->client_list, node) {
+ if (priv == m->priv) {
+ list_del(&m->node);
+ break;
+ }
+ }
+ if (m) {
+ kfree(m);
+ for (i = 0; i < mod->num_clks; i++)
+ nvhost_module_update_rate(mod, i);
+ }
+ mutex_unlock(&client_list_lock);
}
int nvhost_module_init(struct nvhost_module *mod, const char *name,
diff --git a/drivers/video/tegra/host/nvhost_acm.h b/drivers/video/tegra/host/nvhost_acm.h
index 251e1bce6651..34ad622618cc 100644
--- a/drivers/video/tegra/host/nvhost_acm.h
+++ b/drivers/video/tegra/host/nvhost_acm.h
@@ -94,7 +94,6 @@ int nvhost_module_set_rate(struct nvhost_master *host,
struct nvhost_module *mod, void *priv,
unsigned long rate, int index);
-#define host_acm_op(host) (host->op.acm)
static inline bool nvhost_module_powered(struct nvhost_module *mod)
{
diff --git a/drivers/video/tegra/host/t30/Makefile b/drivers/video/tegra/host/t30/Makefile
index 7e77d8af701c..5229b2e21456 100644
--- a/drivers/video/tegra/host/t30/Makefile
+++ b/drivers/video/tegra/host/t30/Makefile
@@ -3,7 +3,6 @@ nvhost-t30-objs = \
channel_t30.o \
scale3d.o \
debug_t30.o \
- acm_t30.o \
3dctx_t30.o
obj-$(CONFIG_TEGRA_GRHOST) += nvhost-t30.o
diff --git a/drivers/video/tegra/host/t30/acm_t30.c b/drivers/video/tegra/host/t30/acm_t30.c
deleted file mode 100644
index f209e6043fb4..000000000000
--- a/drivers/video/tegra/host/t30/acm_t30.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * drivers/video/tegra/host/t30/acm_t30.c
- *
- * Tegra Graphics Host Power Management for Tegra3
- *
- * Copyright (c) 2010-2011, NVIDIA Corporation.
- *
- * 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.
- */
-
-#include <linux/slab.h>
-#include <linux/err.h>
-#include "../dev.h"
-#include "../chip_support.h"
-#include "../nvhost_acm.h"
-#include "t30.h"
-DEFINE_MUTEX(client_list_lock);
-
-struct nvhost_module_client {
- struct list_head node;
- unsigned long rate[NVHOST_MODULE_MAX_CLOCKS];
- void *priv;
-};
-
-int t30_acm_get_rate(struct nvhost_module *mod, unsigned long *rate,
- int index)
-{
- struct clk *c;
-
- c = mod->clk[index];
- if (IS_ERR_OR_NULL(c))
- return -EINVAL;
-
- /* Need to enable client to get correct rate */
- nvhost_module_busy(mod);
- *rate = clk_get_rate(c);
- nvhost_module_idle(mod);
- return 0;
-}
-
-static int t30_acm_update_rate(struct nvhost_module *mod, int index)
-{
- unsigned long rate = 0;
- struct nvhost_module_client *m;
-
- if (!mod->clk[index])
- return -EINVAL;
-
- list_for_each_entry(m, &mod->client_list, node) {
- rate = max(m->rate[index], rate);
- }
- if (!rate)
- rate = clk_round_rate(mod->clk[index],
- mod->desc->clocks[index].default_rate);
-
- return clk_set_rate(mod->clk[index], rate);
-}
-
-int t30_acm_set_rate(struct nvhost_module *mod, void *priv,
- unsigned long rate, int index)
-{
- struct nvhost_module_client *m;
- int ret;
-
- mutex_lock(&client_list_lock);
- list_for_each_entry(m, &mod->client_list, node) {
- if (m->priv == priv) {
- rate = clk_round_rate(mod->clk[index], rate);
- m->rate[index] = rate;
- break;
- }
- }
- ret = t30_acm_update_rate(mod, index);
- mutex_unlock(&client_list_lock);
- return ret;
-}
-
-int t30_acm_add_client(struct nvhost_module *mod, void *priv)
-{
- int i;
- unsigned long rate;
- struct nvhost_module_client *client;
-
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&client->node);
- client->priv = priv;
-
- for (i = 0; i < mod->num_clks; i++) {
- rate = clk_round_rate(mod->clk[i],
- mod->desc->clocks[i].default_rate);
- client->rate[i] = rate;
- }
- mutex_lock(&client_list_lock);
- list_add_tail(&client->node, &mod->client_list);
- mutex_unlock(&client_list_lock);
- return 0;
-}
-
-void t30_acm_remove_client(struct nvhost_module *mod, void *priv)
-{
- int i;
- struct nvhost_module_client *m;
-
- mutex_lock(&client_list_lock);
- list_for_each_entry(m, &mod->client_list, node) {
- if (priv == m->priv) {
- list_del(&m->node);
- break;
- }
- }
- if (m) {
- kfree(m);
- for (i = 0; i < mod->num_clks; i++)
- t30_acm_update_rate(mod, i);
- }
- mutex_unlock(&client_list_lock);
-}
-
-int nvhost_init_t30_acm(struct nvhost_master *host)
-{
- host->op.acm.get_rate = t30_acm_get_rate;
- host->op.acm.set_rate = t30_acm_set_rate;
- host->op.acm.add_client = t30_acm_add_client;
- host->op.acm.remove_client = t30_acm_remove_client;
-
- return 0;
-}
diff --git a/drivers/video/tegra/host/t30/t30.c b/drivers/video/tegra/host/t30/t30.c
index 00e0f648afcc..1f89824c0e25 100644
--- a/drivers/video/tegra/host/t30/t30.c
+++ b/drivers/video/tegra/host/t30/t30.c
@@ -46,8 +46,5 @@ int nvhost_init_t30_support(struct nvhost_master *host)
err = nvhost_init_t20_cpuaccess_support(host);
if (err)
return err;
- err = nvhost_init_t30_acm(host);
- if (err)
- return err;
return 0;
}
diff --git a/drivers/video/tegra/host/t30/t30.h b/drivers/video/tegra/host/t30/t30.h
index bbc88bbb81f0..4c0c2d175d73 100644
--- a/drivers/video/tegra/host/t30/t30.h
+++ b/drivers/video/tegra/host/t30/t30.h
@@ -26,6 +26,5 @@
int nvhost_init_t30_channel_support(struct nvhost_master *);
int nvhost_init_t30_debug_support(struct nvhost_master *);
-int nvhost_init_t30_acm(struct nvhost_master *);
#endif /* _NVHOST_T30_H_ */