video: tegra: host: Reset 3D after power on
Terje Bergstrom [Mon, 5 Mar 2012 07:02:30 +0000 (09:02 +0200)]
Sometimes 3D unit comes up with incorrect scissor configuration.
Earlier patch added the scissor registers to the context save list,
but that did not solve the problem. Remove the extra registers, and
reset 3D after powering it up.

Bug 939307

Change-Id: Id795f2d99ec3c6b907da2785b1816ce753af7a3f
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/87654
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Graziano Misuraca <gmisuraca@nvidia.com>
Tested-by: Graziano Misuraca <gmisuraca@nvidia.com>
Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Reviewed-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>

drivers/video/tegra/host/gr3d/gr3d_t30.c
drivers/video/tegra/host/nvhost_acm.c
drivers/video/tegra/host/t30/t30.c
include/linux/nvhost.h

index 8ca6b7b..ab4d04f 100644 (file)
@@ -71,7 +71,6 @@ static const struct hwctx_reginfo ctxsave_regs_3d_global[] = {
        HWCTX_REGINFO(0xa02,   10, DIRECT),
        HWCTX_REGINFO(0xb04,    1, DIRECT),
        HWCTX_REGINFO(0xb06,   13, DIRECT),
-       HWCTX_REGINFO(0xe42,    2, DIRECT), /* HW bug workaround */
 };
 
 static const struct hwctx_reginfo ctxsave_regs_3d_perset[] = {
index f2a61a9..015b7c4 100644 (file)
@@ -55,15 +55,8 @@ static void do_unpowergate_locked(int id)
                tegra_unpowergate_partition(id);
 }
 
-void nvhost_module_reset(struct nvhost_device *dev)
+static void do_module_reset_locked(struct nvhost_device *dev)
 {
-       dev_dbg(&dev->dev,
-               "%s: asserting %s module reset (id %d, id2 %d)\n",
-               __func__, dev->name,
-               dev->powergate_ids[0], dev->powergate_ids[1]);
-
-       mutex_lock(&dev->lock);
-
        /* assert module and mc client reset */
        if (dev->powergate_ids[0] != -1) {
                tegra_powergate_mc_disable(dev->powergate_ids[0]);
@@ -89,7 +82,17 @@ void nvhost_module_reset(struct nvhost_device *dev)
                tegra_periph_reset_deassert(dev->clk[1]);
                tegra_powergate_mc_enable(dev->powergate_ids[1]);
        }
+}
 
+void nvhost_module_reset(struct nvhost_device *dev)
+{
+       dev_dbg(&dev->dev,
+               "%s: asserting %s module reset (id %d, id2 %d)\n",
+               __func__, dev->name,
+               dev->powergate_ids[0], dev->powergate_ids[1]);
+
+       mutex_lock(&dev->lock);
+       do_module_reset_locked(dev);
        mutex_unlock(&dev->lock);
 
        dev_dbg(&dev->dev, "%s: module %s out of reset\n",
@@ -108,6 +111,9 @@ static void to_state_clockgated_locked(struct nvhost_device *dev)
                        && dev->can_powergate) {
                do_unpowergate_locked(dev->powergate_ids[0]);
                do_unpowergate_locked(dev->powergate_ids[1]);
+
+               if (dev->powerup_reset)
+                       do_module_reset_locked(dev);
        }
        dev->powerstate = NVHOST_POWER_STATE_CLOCKGATED;
 }
index 8a8b1f4..da56a9b 100644 (file)
@@ -82,7 +82,8 @@ struct nvhost_device t30_devices[] = {
        .powergate_ids = { TEGRA_POWERGATE_3D,
                           TEGRA_POWERGATE_3D1 },
        NVHOST_DEFAULT_CLOCKGATE_DELAY,
-       .can_powergate = false,
+       .can_powergate = true,
+       .powerup_reset = true,
        .powergate_delay = 250,
        .moduleid       = NVHOST_MODULE_NONE,
 },
index da5e1e6..faa183d 100644 (file)
@@ -64,6 +64,7 @@ struct nvhost_device {
        bool            exclusive;      /* True if only one user at a time */
        bool            keepalive;      /* Do not power gate when opened */
        bool            waitbasesync;   /* Force sync of wait bases */
+       bool            powerup_reset;  /* Do a reset after power un-gating */
 
        int             powergate_ids[NVHOST_MODULE_MAX_POWERGATE_IDS];
        bool            can_powergate;  /* True if module can be power gated */