diff options
author | Adam Jiang <chaoj@nvidia.com> | 2012-10-22 20:59:47 +0900 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:38:25 -0700 |
commit | 7a2287e9f72d9bf9e8db6744b97542a4593b3baa (patch) | |
tree | 834da3190a9bc8c03b33f4443ce4ea5c4f42fb88 /drivers/media/video | |
parent | 472193e35299bf6cecb2ce8dc1cf4e2d4472153e (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.c | 46 |
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)) { |