summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorArto Merilainen <amerilainen@nvidia.com>2014-09-03 19:01:19 +0300
committerMatthew Pedro <mapedro@nvidia.com>2015-02-10 08:49:43 -0800
commitdc96e4178b5a232456468ffaf21799146a5b9a1e (patch)
treed3cd1e729e67bda4d7c6c5291dbce7f568ef0b3f /drivers/video
parent231a96efcdf47e971ce70412332ad436b1ffb619 (diff)
video: tegra: host: Never release firmware
Firmwares are currently released at the time we close the channel device node. This causes unexpected side effects in cases where the finalize_poweron is called only once to get the device booted during the first time the device is accessed. This patch fixes the issue by not releasing the firmware after it has once loaded. Bug 200033244 Change-Id: I8fc6748846e56ac0cc347feb170b239533a47252 Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Reviewed-on: http://git-master/r/495220 (cherry-picked from commit 69bce0a17ad1e5457cfce0d66f6e1b4add7e9820) Reviewed-on: http://git-master/r/670671 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Matthew Pedro <mapedro@nvidia.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/tegra/host/flcn/flcn.c69
-rw-r--r--drivers/video/tegra/host/flcn/flcn.h7
-rw-r--r--drivers/video/tegra/host/nvhost_channel.c5
-rw-r--r--drivers/video/tegra/host/t124/t124.c13
-rw-r--r--drivers/video/tegra/host/tsec/tsec.c26
-rw-r--r--drivers/video/tegra/host/tsec/tsec.h3
6 files changed, 51 insertions, 72 deletions
diff --git a/drivers/video/tegra/host/flcn/flcn.c b/drivers/video/tegra/host/flcn/flcn.c
index 9943ecf25ff7..012ab96eb84c 100644
--- a/drivers/video/tegra/host/flcn/flcn.c
+++ b/drivers/video/tegra/host/flcn/flcn.c
@@ -1,7 +1,7 @@
/*
* Tegra flcn common driver
*
-* Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+* Copyright (c) 2011-2015, 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,
@@ -380,6 +380,9 @@ int nvhost_flcn_init(struct platform_device *dev)
nvhost_dbg_fn("in dev:%p v:%p", dev, v);
+ if (v)
+ return 0;
+
v = kzalloc(sizeof(*v), GFP_KERNEL);
if (!v) {
dev_err(&dev->dev, "couldn't alloc flcn support");
@@ -397,9 +400,6 @@ int nvhost_flcn_init(struct platform_device *dev)
err = nvhost_flcn_boot(dev);
nvhost_module_idle(dev);
- if (pdata->scaling_init)
- nvhost_scale_hw_init(dev);
-
return 0;
clean_up:
@@ -407,33 +407,6 @@ int nvhost_flcn_init(struct platform_device *dev)
return err;
}
-void nvhost_flcn_deinit(struct platform_device *dev)
-{
- struct flcn *v = get_flcn(dev);
- struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
-
- DEFINE_DMA_ATTRS(attrs);
- dma_set_attr(DMA_ATTR_READ_ONLY, &attrs);
-
- if (!v)
- return;
-
- if (pdata->scaling_init)
- nvhost_scale_hw_deinit(dev);
-
- if (v->mapped) {
- dma_free_attrs(&dev->dev,
- v->size, v->mapped,
- v->dma_addr, &attrs);
- v->mapped = NULL;
- v->dma_addr = 0;
- }
-
- /* zap, free */
- set_flcn(dev, NULL);
- kfree(v);
-}
-
static struct nvhost_hwctx *vic03_alloc_hwctx(struct nvhost_hwctx_handler *h,
struct nvhost_channel *ch)
{
@@ -575,6 +548,8 @@ struct nvhost_hwctx_handler *nvhost_vic03_alloc_hwctx_handler(u32 syncpt,
int nvhost_vic_finalize_poweron(struct platform_device *pdev)
{
+ struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
+
nvhost_dbg_fn("");
host1x_writel(pdev, flcn_slcg_override_high_a_r(), 0);
@@ -582,13 +557,40 @@ int nvhost_vic_finalize_poweron(struct platform_device *pdev)
flcn_cg_idle_cg_dly_cnt_f(4) |
flcn_cg_idle_cg_en_f(1) |
flcn_cg_wakeup_dly_cnt_f(4));
+
+ if (pdata->scaling_init)
+ nvhost_scale_hw_init(pdev);
+
+ return nvhost_flcn_boot(pdev);
+}
+
+int nvhost_flcn_finalize_poweron(struct platform_device *pdev)
+{
+ struct nvhost_device_data *pdata = nvhost_get_devdata(pdev);
+
+ nvhost_dbg_fn("");
+
+ if (pdata->scaling_init)
+ nvhost_scale_hw_init(pdev);
+
return nvhost_flcn_boot(pdev);
}
+int nvhost_flcn_prepare_poweroff(struct platform_device *dev)
+{
+ struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
+
+ nvhost_dbg_fn("");
+
+ if (pdata->scaling_deinit)
+ nvhost_scale_hw_deinit(dev);
+
+ return 0;
+}
+
int nvhost_vic_prepare_poweroff(struct platform_device *dev)
{
struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
- struct flcn *v;
struct nvhost_channel *ch = pdata->channels[0];
nvhost_dbg_fn("");
@@ -599,7 +601,8 @@ int nvhost_vic_prepare_poweroff(struct platform_device *dev)
mutex_unlock(&ch->submitlock);
}
- v = get_flcn(pdata->pdev);
+ if (pdata->scaling_deinit)
+ nvhost_scale_hw_deinit(dev);
return 0;
}
diff --git a/drivers/video/tegra/host/flcn/flcn.h b/drivers/video/tegra/host/flcn/flcn.h
index a09292e58e16..e12582d0b89f 100644
--- a/drivers/video/tegra/host/flcn/flcn.h
+++ b/drivers/video/tegra/host/flcn/flcn.h
@@ -1,7 +1,7 @@
/*
* Tegra flcn common Module Support
*
- * Copyright (c) 2011-2014, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2011-2015, 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,
@@ -93,9 +93,8 @@ void nvhost_flcn_busy(struct platform_device *);
void nvhost_flcn_idle(struct platform_device *);
void nvhost_flcn_suspend(struct platform_device *);
int nvhost_flcn_init(struct platform_device *);
-void nvhost_flcn_deinit(struct platform_device *);
-
-
+int nvhost_flcn_finalize_poweron(struct platform_device *);
+int nvhost_flcn_prepare_poweroff(struct platform_device *);
/* hack, get these from elsewhere */
#define NVA0B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID (0x00000200)
diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c
index 05a31d8c3934..369748ab3574 100644
--- a/drivers/video/tegra/host/nvhost_channel.c
+++ b/drivers/video/tegra/host/nvhost_channel.c
@@ -3,7 +3,7 @@
*
* Tegra Graphics Host Channel
*
- * Copyright (c) 2010-2014, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2015, 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,
@@ -169,9 +169,6 @@ static int nvhost_channel_unmap_locked(struct nvhost_channel *ch)
if (pdata->keepalive)
nvhost_module_enable_poweroff(pdata->pdev);
- if (pdata->deinit)
- pdata->deinit(ch->dev);
-
/*
* when ALL of the channels are unmapped from device,
* we can free all the host managed syncpts assigned
diff --git a/drivers/video/tegra/host/t124/t124.c b/drivers/video/tegra/host/t124/t124.c
index 264eae151375..0bbb567c89d2 100644
--- a/drivers/video/tegra/host/t124/t124.c
+++ b/drivers/video/tegra/host/t124/t124.c
@@ -3,7 +3,7 @@
*
* Tegra Graphics Init for T124 Architecture Chips
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2015, 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,
@@ -281,8 +281,8 @@ struct nvhost_device_data t124_msenc_info = {
.powergate_delay = 100,
.can_powergate = true,
.init = nvhost_flcn_init,
- .deinit = nvhost_flcn_deinit,
- .finalize_poweron = nvhost_flcn_boot,
+ .finalize_poweron = nvhost_flcn_finalize_poweron,
+ .prepare_poweroff = nvhost_flcn_prepare_poweroff,
.scaling_init = nvhost_scale_init,
.scaling_deinit = nvhost_scale_deinit,
.actmon_regs = HOST1X_CHANNEL_ACTMON1_REG_BASE,
@@ -323,7 +323,6 @@ struct nvhost_device_data t124_tsec_info = {
.keepalive = true,
.moduleid = NVHOST_MODULE_TSEC,
.init = nvhost_tsec_init,
- .deinit = nvhost_tsec_deinit,
.finalize_poweron = nvhost_tsec_finalize_poweron,
.prepare_poweroff = nvhost_tsec_prepare_poweroff,
};
@@ -362,7 +361,6 @@ struct nvhost_device_data t124_vic_info = {
.powergate_delay = 500,
.powergate_ids = { TEGRA_POWERGATE_VIC, -1 },
.init = nvhost_flcn_init,
- .deinit = nvhost_flcn_deinit,
.alloc_hwctx_handler = nvhost_vic03_alloc_hwctx_handler,
.finalize_poweron = nvhost_vic_finalize_poweron,
.prepare_poweroff = nvhost_vic_prepare_poweroff,
@@ -490,8 +488,8 @@ struct nvhost_device_data t132_msenc_info = {
.powergate_delay = 100,
.can_powergate = true,
.init = nvhost_flcn_init,
- .deinit = nvhost_flcn_deinit,
- .finalize_poweron = nvhost_flcn_boot,
+ .finalize_poweron = nvhost_flcn_finalize_poweron,
+ .prepare_poweroff = nvhost_flcn_prepare_poweroff,
.firmware_name = "nvhost_msenc031.fw",
};
@@ -506,7 +504,6 @@ struct nvhost_device_data t132_tsec_info = {
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_TSEC,
.init = nvhost_tsec_init,
- .deinit = nvhost_tsec_deinit,
.finalize_poweron = nvhost_tsec_finalize_poweron,
};
diff --git a/drivers/video/tegra/host/tsec/tsec.c b/drivers/video/tegra/host/tsec/tsec.c
index 006f86ced925..2afc0c75cb9a 100644
--- a/drivers/video/tegra/host/tsec/tsec.c
+++ b/drivers/video/tegra/host/tsec/tsec.c
@@ -1,7 +1,7 @@
/*
* Tegra TSEC Module Support
*
- * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2015, 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,
@@ -423,9 +423,12 @@ clean_up:
int nvhost_tsec_init(struct platform_device *dev)
{
int err = 0;
- struct tsec *m;
+ struct tsec *m = get_tsec(dev);
char *fw_name;
+ if (m)
+ return 0;
+
fw_name = tsec_get_fw_name(dev);
if (!fw_name) {
dev_err(&dev->dev, "couldn't determine firmware name");
@@ -464,25 +467,6 @@ clean_up:
return err;
}
-void nvhost_tsec_deinit(struct platform_device *dev)
-{
- struct tsec *m = get_tsec(dev);
-
- DEFINE_DMA_ATTRS(attrs);
- dma_set_attr(DMA_ATTR_READ_ONLY, &attrs);
-
- if (m->mapped) {
- dma_free_attrs(&dev->dev,
- m->size, m->mapped,
- m->dma_addr, &attrs);
- m->mapped = NULL;
- m->dma_addr = 0;
- }
-
- kfree(m);
- set_tsec(dev, NULL);
-}
-
int nvhost_tsec_finalize_poweron(struct platform_device *dev)
{
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
diff --git a/drivers/video/tegra/host/tsec/tsec.h b/drivers/video/tegra/host/tsec/tsec.h
index c72fd11f0084..a3f363e8d2c5 100644
--- a/drivers/video/tegra/host/tsec/tsec.h
+++ b/drivers/video/tegra/host/tsec/tsec.h
@@ -3,7 +3,7 @@
*
* Tegra TSEC Module Support
*
- * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2015, 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,
@@ -30,7 +30,6 @@ int nvhost_tsec_prepare_poweroff(struct platform_device *dev);
int nvhost_tsec_init(struct platform_device *dev);
void nvhost_tsec_isr(void);
void nvhost_tsec_isr_thread(void);
-void nvhost_tsec_deinit(struct platform_device *dev);
/* Would have preferred a static inline here... but we're using this
* in a place where a constant initializer is required */