video: tegra: host: Make rate requests per clock
Terje Bergstrom [Fri, 14 Sep 2012 06:47:31 +0000 (09:47 +0300)]
Change the IOCTLs for getting and setting the clock rate for a
module to allow setting each clock separately. Clock is specified
with module id.

Bug 1046244

Change-Id: I184e823d51deb1535f0b5267d98881ae264e7407
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/132568
Reviewed-by: Automatic_Commit_Validation_User

drivers/video/tegra/host/bus_client.c
drivers/video/tegra/host/nvhost_acm.c
drivers/video/tegra/host/t114/t114.c
drivers/video/tegra/host/t30/t30.c
include/linux/nvhost.h
include/linux/nvhost_ioctl.h

index 97f06cc..742e2aa 100644 (file)
@@ -404,6 +404,37 @@ static int nvhost_ioctl_channel_read_3d_reg(struct nvhost_channel_userctx *ctx,
                        args->offset, &args->value);
 }
 
+static int moduleid_to_index(struct nvhost_device *dev, u32 moduleid)
+{
+       int i;
+
+       for (i = 0; i < NVHOST_MODULE_MAX_CLOCKS; i++) {
+               if (dev->clocks[i].moduleid == moduleid)
+                       return i;
+       }
+
+       /* Old user space is sending a random number in args. Return clock
+        * zero in these cases. */
+       return 0;
+}
+
+static int nvhost_ioctl_channel_set_rate(struct nvhost_channel_userctx *ctx,
+       u32 moduleid, u32 rate)
+{
+       int index = moduleid ? moduleid_to_index(ctx->ch->dev, moduleid) : 0;
+
+       return nvhost_module_set_rate(ctx->ch->dev, ctx, rate, index);
+}
+
+static int nvhost_ioctl_channel_get_rate(struct nvhost_channel_userctx *ctx,
+       u32 moduleid, u32 *rate)
+{
+       int index = moduleid ? moduleid_to_index(ctx->ch->dev, moduleid) : 0;
+
+       return nvhost_module_get_rate(ctx->ch->dev,
+                       (unsigned long *)rate, index);
+}
+
 static long nvhost_channelctl(struct file *filp,
        unsigned int cmd, unsigned long arg)
 {
@@ -497,22 +528,20 @@ static long nvhost_channelctl(struct file *filp,
                break;
        case NVHOST_IOCTL_CHANNEL_GET_CLK_RATE:
        {
-               unsigned long rate;
                struct nvhost_clk_rate_args *arg =
                                (struct nvhost_clk_rate_args *)buf;
 
-               err = nvhost_module_get_rate(priv->ch->dev, &rate, 0);
-               if (err == 0)
-                       arg->rate = rate;
+               err = nvhost_ioctl_channel_get_rate(priv,
+                               arg->moduleid, &arg->rate);
                break;
        }
        case NVHOST_IOCTL_CHANNEL_SET_CLK_RATE:
        {
                struct nvhost_clk_rate_args *arg =
                                (struct nvhost_clk_rate_args *)buf;
-               unsigned long rate = (unsigned long)arg->rate;
 
-               err = nvhost_module_set_rate(priv->ch->dev, priv, rate, 0);
+               err = nvhost_ioctl_channel_set_rate(priv,
+                       arg->moduleid, arg->rate);
                break;
        }
        case NVHOST_IOCTL_CHANNEL_SET_TIMEOUT:
index 74983e5..c7f7263 100644 (file)
@@ -314,27 +314,15 @@ int nvhost_module_set_rate(struct nvhost_device *dev, void *priv,
                unsigned long rate, int index)
 {
        struct nvhost_module_client *m;
-       int i, ret = 0;
+       int ret = 0;
 
        mutex_lock(&client_list_lock);
        list_for_each_entry(m, &dev->client_list, node) {
-               if (m->priv == priv) {
-                       if (!strcmp(dev->name, "mpe")) {
-                               m->rate[0] = clk_round_rate(dev->clk[0], rate);
-                       } else {
-                               for (i = 0; i < dev->num_clks; i++)
-                                       m->rate[i] = clk_round_rate(dev->clk[i],
-                                                                       rate);
-                       }
-                       break;
-               }
+               if (m->priv == priv)
+                       m->rate[index] = clk_round_rate(dev->clk[index], rate);
        }
 
-       for (i = 0; i < dev->num_clks; i++) {
-               ret = nvhost_module_update_rate(dev, i);
-               if (ret < 0)
-                       break;
-       }
+       ret = nvhost_module_update_rate(dev, index);
        mutex_unlock(&client_list_lock);
        return ret;
 
index 550b308..a89e383 100644 (file)
@@ -128,8 +128,8 @@ static struct nvhost_device tegra_gr3d03_device = {
        .waitbases     = BIT(NVWAITBASE_3D),
        .modulemutexes = BIT(NVMODMUTEX_3D),
        .class         = NV_GRAPHICS_3D_CLASS_ID,
-       .clocks = {{"gr3d", UINT_MAX},
-                       {"emc", UINT_MAX} },
+       .clocks = {{"gr3d", UINT_MAX, 8},
+                       {"emc", UINT_MAX, 75} },
        .powergate_ids = { TEGRA_POWERGATE_3D, -1 },
        NVHOST_DEFAULT_CLOCKGATE_DELAY,
        .can_powergate = true,
@@ -145,9 +145,9 @@ static struct nvhost_device tegra_gr2d03_device = {
        .waitbases     = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
        .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
                         BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
-       .clocks = {{"gr2d", 0},
-                       {"epp", 0},
-                       {"emc", 300000000} },
+       .clocks        = { {"gr2d", 0, 7},
+                       {"epp", 0, 10},
+                       {"emc", 300000000, 75 } },
        NVHOST_MODULE_NO_POWERGATE_IDS,
        .clockgate_delay = 0,
        .moduleid       = NVHOST_MODULE_NONE,
@@ -171,7 +171,7 @@ static struct nvhost_device tegra_isp01_device = {
        .index          = 3,
        .syncpts        = BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
                          BIT(NVSYNCPT_VI_ISP_4),
-       .clocks         = { {"epp", 0} },
+       .clocks         = { {"epp", 0, 10} },
        .keepalive      = true,
        NVHOST_MODULE_NO_POWERGATE_IDS,
        NVHOST_DEFAULT_CLOCKGATE_DELAY,
@@ -225,7 +225,8 @@ static struct nvhost_device tegra_msenc02_device = {
        .class         = NV_VIDEO_ENCODE_MSENC_CLASS_ID,
        .exclusive     = false,
        .keepalive     = true,
-       .clocks = {{"msenc", UINT_MAX}, {"emc", 300000000} },
+       .clocks        = { {"msenc", UINT_MAX, 107},
+                       {"emc", 300000000, 75} },
        NVHOST_MODULE_NO_POWERGATE_IDS,
        NVHOST_DEFAULT_CLOCKGATE_DELAY,
        .moduleid      = NVHOST_MODULE_MSENC,
@@ -263,7 +264,8 @@ static struct nvhost_device tegra_tsec01_device = {
        .waitbases     = BIT(NVWAITBASE_TSEC),
        .class         = NV_TSEC_CLASS_ID,
        .exclusive     = false,
-       .clocks = {{"tsec", UINT_MAX}, {"emc", 300000000} },
+       .clocks        = { {"tsec", UINT_MAX, 108},
+                       {"emc", 300000000, 75} },
        NVHOST_MODULE_NO_POWERGATE_IDS,
        NVHOST_DEFAULT_CLOCKGATE_DELAY,
        .moduleid      = NVHOST_MODULE_TSEC,
index f7b8cef..28cc876 100644 (file)
@@ -125,9 +125,9 @@ static struct nvhost_device tegra_gr3d02_device = {
        .waitbases      = BIT(NVWAITBASE_3D),
        .modulemutexes  = BIT(NVMODMUTEX_3D),
        .class          = NV_GRAPHICS_3D_CLASS_ID,
-       .clocks         = { {"gr3d", UINT_MAX},
+       .clocks         = { {"gr3d", UINT_MAX, 8},
                            {"gr3d2", UINT_MAX},
-                           {"emc", UINT_MAX} },
+                           {"emc", UINT_MAX, 75} },
        .powergate_ids = { TEGRA_POWERGATE_3D,
                           TEGRA_POWERGATE_3D1 },
        NVHOST_DEFAULT_CLOCKGATE_DELAY,
@@ -145,9 +145,9 @@ static struct nvhost_device tegra_gr2d02_device = {
        .waitbases      = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
        .modulemutexes  = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
                          BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
-       .clocks         = { {"gr2d", 0},
-                         {"epp", 0},
-                         {"emc", 300000000} },
+       .clocks         = { {"gr2d", 0, 7},
+                         {"epp", 0, 10},
+                         {"emc", 300000000, 75} },
        NVHOST_MODULE_NO_POWERGATE_IDS,
        .clockgate_delay = 0,
        .moduleid       = NVHOST_MODULE_NONE,
@@ -171,7 +171,7 @@ static struct nvhost_device tegra_isp01_device = {
        .index          = 3,
        .syncpts        = BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
                          BIT(NVSYNCPT_VI_ISP_4),
-       .clocks         = { {"epp", 0}
+       .clocks         = { {"epp", 0, 10}
                          },
        .keepalive      = true,
        NVHOST_MODULE_NO_POWERGATE_IDS,
@@ -227,8 +227,8 @@ static struct nvhost_device tegra_mpe02_device = {
        .class          = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
        .waitbasesync   = true,
        .keepalive      = true,
-       .clocks         = { {"mpe", UINT_MAX},
-                           {"emc", 400000000} },
+       .clocks         = { {"mpe", UINT_MAX, 29},
+                           {"emc", 400000000, 75} },
        .powergate_ids  = {TEGRA_POWERGATE_MPE, -1},
        NVHOST_DEFAULT_CLOCKGATE_DELAY,
        .can_powergate  = true,
index cf4a67c..ff22e55 100644 (file)
@@ -73,7 +73,8 @@ struct nvhost_device_id {
 
 struct nvhost_clock {
        char *name;
-       long default_rate;
+       unsigned long default_rate;
+       u32 moduleid;
 };
 
 enum nvhost_device_powerstate_t {
index 85b7a12..5a7bcdd 100644 (file)
@@ -101,7 +101,8 @@ struct nvhost_read_3d_reg_args {
 };
 
 struct nvhost_clk_rate_args {
-       __u64 rate;
+       __u32 rate;
+       __u32 moduleid;
 };
 
 struct nvhost_set_timeout_args {