Skip to content

Commit

Permalink
[media] s5p-fimc: Ensure CAMCLK clock can be enabled by FIMC-LITE dev…
Browse files Browse the repository at this point in the history
…ices

In configurations where FIMC-LITE is used to capture image signal
from an external sensor only we need to ensure one of FIMC devices
is in active power state and the "fimc" gate clock is enabled.
Otherwise the CAMCLK clock output signal will be masked off
preventing an external sensor's operation.
This affect processing pipelines like:
 - sensor -> FIMC-LITE -> memory
 - sensor -> MIPI-CSIS -> FIMC-LITE -> memory

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Mar 31, 2013
1 parent 88fa831 commit 3e20c34
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
18 changes: 10 additions & 8 deletions drivers/media/platform/s5p-fimc/fimc-mdevice.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,21 +509,17 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
{
struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
struct device_node *of_node = fmd->pdev->dev.of_node;
struct fimc_dev *fd = NULL;
int num_clients = 0;
int ret, i;

/*
* Runtime resume one of the FIMC entities to make sure
* the sclk_cam clocks are not globally disabled.
*/
for (i = 0; !fd && i < ARRAY_SIZE(fmd->fimc); i++)
if (fmd->fimc[i])
fd = fmd->fimc[i];
if (!fd)
if (!fmd->pmf)
return -ENXIO;

ret = pm_runtime_get_sync(&fd->pdev->dev);
ret = pm_runtime_get_sync(fmd->pmf);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -557,7 +553,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
}
}

pm_runtime_put(&fd->pdev->dev);
pm_runtime_put(fmd->pmf);
return ret;
}

Expand Down Expand Up @@ -602,6 +598,8 @@ static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc)

ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
if (!ret) {
if (!fmd->pmf && fimc->pdev)
fmd->pmf = &fimc->pdev->dev;
fmd->fimc[fimc->id] = fimc;
fimc->vid_cap.user_subdev_api = fmd->user_subdev_api;
} else {
Expand Down Expand Up @@ -1085,7 +1083,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
struct fimc_camclk_info *camclk;
int ret = 0;

if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL)
if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf)
return -EINVAL;

camclk = &fmd->camclk[pdata->clk_id];
Expand All @@ -1101,6 +1099,9 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
if (camclk->use_count++ == 0) {
clk_set_rate(camclk->clock, pdata->clk_frequency);
camclk->frequency = pdata->clk_frequency;
ret = pm_runtime_get_sync(fmd->pmf);
if (ret < 0)
return ret;
ret = clk_enable(camclk->clock);
dbg("Enabled camclk %d: f: %lu", pdata->clk_id,
clk_get_rate(camclk->clock));
Expand All @@ -1113,6 +1114,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,

if (--camclk->use_count == 0) {
clk_disable(camclk->clock);
pm_runtime_put(fmd->pmf);
dbg("Disabled camclk %d", pdata->clk_id);
}
return ret;
Expand Down
2 changes: 2 additions & 0 deletions drivers/media/platform/s5p-fimc/fimc-mdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct fimc_sensor_info {
* @camclk: external sensor clock information
* @fimc: array of registered fimc devices
* @use_isp: set to true when FIMC-IS subsystem is used
* @pmf: handle to the CAMCLK clock control FIMC helper device
* @media_dev: top level media device
* @v4l2_dev: top level v4l2_device holding up the subdevs
* @pdev: platform device this media device is hooked up into
Expand All @@ -99,6 +100,7 @@ struct fimc_md {
struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
struct fimc_dev *fimc[FIMC_MAX_DEVS];
bool use_isp;
struct device *pmf;
struct media_device media_dev;
struct v4l2_device v4l2_dev;
struct platform_device *pdev;
Expand Down

0 comments on commit 3e20c34

Please sign in to comment.