summaryrefslogtreecommitdiff
path: root/drivers/media/video
diff options
context:
space:
mode:
authorAdam Jiang <chaoj@nvidia.com>2012-10-22 20:59:47 +0900
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:38:25 -0700
commit7a2287e9f72d9bf9e8db6744b97542a4593b3baa (patch)
tree834da3190a9bc8c03b33f4443ce4ea5c4f42fb88 /drivers/media/video
parent472193e35299bf6cecb2ce8dc1cf4e2d4472153e (diff)
video: tegra: dtv: Add shared clock support
DTV interface could run with 0-20MHz synchronizing clock. When DTV runs with high speed, it is necessary to ensure system bus and EMC running on higher frequency to support data transferring between the interface and memory. Bug 1061456 Bug 1258577 Change-Id: Id5af7cd8f8aa0373a5c45c9f9f884cd2b755e146 (cherry picked from commit 3370a67507a5ea08b0fe03943345dc34bde8fd7c) (cherry picked from commit e4bb9378786655898c2f62a57319bdc05bd8e410) Signed-off-by: Adam Jiang <chaoj@nvidia.com> Reviewed-on: http://git-master/r/224679 Reviewed-on: http://git-master/r/244467 Reviewed-on: http://git-master/r/256183 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/tegra/tegra_dtv.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/media/video/tegra/tegra_dtv.c b/drivers/media/video/tegra/tegra_dtv.c
index 161968cadd35..d2255a16ec7a 100644
--- a/drivers/media/video/tegra/tegra_dtv.c
+++ b/drivers/media/video/tegra/tegra_dtv.c
@@ -146,6 +146,9 @@ struct tegra_dtv_context {
struct clk *clk;
int clk_enabled;
+ struct clk *sclk;
+ struct clk *emc_clk;
+
phys_addr_t phys;
void * __iomem base;
unsigned long dma_req_sel;
@@ -620,8 +623,28 @@ static int tegra_dtv_open(struct inode *inode, struct file *file)
struct miscdevice *miscdev = file->private_data;
struct tegra_dtv_context *dtv_ctx =
container_of(miscdev, struct tegra_dtv_context, miscdev);
+ struct platform_device *pdev;
file->private_data = dtv_ctx;
+ /* hold system bus clock and EMC clock to ensure DTV driver has
+ * enought bandwidth.
+ *
+ * The frequencies for these clocks should be set up on platform
+ * bias in board files.
+ */
+ pdev = dtv_ctx->pdev;
+
+ if (clk_enable(dtv_ctx->sclk) < 0) {
+ dev_err(&pdev->dev, "cannot enable SBus clock.\n");
+ return -ENOSYS;
+ }
+
+ if (clk_enable(dtv_ctx->emc_clk) < 0) {
+ dev_err(&pdev->dev, "cannot enable EMC clock.\n");
+ clk_disable(dtv_ctx->sclk);
+ return -ENOSYS;
+ }
+
dtv_ctx = (struct tegra_dtv_context *) file->private_data;
pr_debug("%s called\n", __func__);
@@ -665,6 +688,10 @@ static int tegra_dtv_release(struct inode *inode, struct file *file)
complete(&dtv_ctx->stream.stop_completion);
__force_xfer_stop(&dtv_ctx->stream);
}
+
+ clk_disable(dtv_ctx->sclk);
+ clk_disable(dtv_ctx->emc_clk);
+
/* wakeup any pending process */
wakeup_suspend(&dtv_ctx->stream);
mutex_unlock(&dtv_ctx->stream.mtx);
@@ -894,6 +921,7 @@ static int tegra_dtv_probe(struct platform_device *pdev)
{
int ret;
struct tegra_dtv_context *dtv_ctx;
+ struct tegra_dtv_platform_data *pdata;
struct clk *clk;
struct resource *res;
@@ -909,6 +937,8 @@ static int tegra_dtv_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, dtv_ctx);
+ pdata = pdev->dev.platform_data;
+
/* for refer back */
dtv_ctx->pdev = pdev;
@@ -927,6 +957,22 @@ static int tegra_dtv_probe(struct platform_device *pdev)
}
dtv_ctx->clk_enabled = 1;
+ /* get shared system bus clock and emc clock */
+ dtv_ctx->sclk = clk_get(&pdev->dev, "sclk");
+ if (IS_ERR_OR_NULL(dtv_ctx->sclk)) {
+ dev_err(&pdev->dev,
+ "cannot get SBus clock for tegra_dtv.\n");
+ ret = -EIO;
+ goto fail_no_clk;
+ }
+ dtv_ctx->emc_clk = clk_get(&pdev->dev, "emc");
+ if (IS_ERR_OR_NULL(dtv_ctx->emc_clk)) {
+ dev_err(&pdev->dev,
+ "cannot get EMC clock for tegra_dtv.\n");
+ ret = -EIO;
+ goto fail_no_clk;
+ }
+
/* get resource */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!res)) {