aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorTomasz Stanislawski <t.stanislaws@samsung.com>2012-03-09 06:05:24 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-20 08:02:15 -0400
commit2fd07a4a9e0d34fc53443601781ae58b2e8f1649 (patch)
tree8d7fb45c20f65f043ac2cbcda190a7c5901ed6ee /drivers/media
parent3f468accf2ae2951dacebc04f186a08f495ce92a (diff)
[media] v4l: s5p-tv: hdmi: fix mode synchronization
The mode setup was applied on HDMI hardware only on resume event. This caused problem if HDMI was not suspended between mode switches. This patch fixes this problem by setting a dirty flag on a mode change event. If flag is set, then new mode is applied on the next stream-on event. Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/s5p-tv/hdmi_drv.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
index eefb903313c3..20cb6eef2979 100644
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ b/drivers/media/video/s5p-tv/hdmi_drv.c
@@ -87,6 +87,8 @@ struct hdmi_device {
87 struct v4l2_subdev *mhl_sd; 87 struct v4l2_subdev *mhl_sd;
88 /** configuration of current graphic mode */ 88 /** configuration of current graphic mode */
89 const struct hdmi_timings *cur_conf; 89 const struct hdmi_timings *cur_conf;
90 /** flag indicating that timings are dirty */
91 int cur_conf_dirty;
90 /** current preset */ 92 /** current preset */
91 u32 cur_preset; 93 u32 cur_preset;
92 /** other resources */ 94 /** other resources */
@@ -253,6 +255,10 @@ static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
253 255
254 dev_dbg(dev, "%s\n", __func__); 256 dev_dbg(dev, "%s\n", __func__);
255 257
258 /* skip if conf is already synchronized with HW */
259 if (!hdmi_dev->cur_conf_dirty)
260 return 0;
261
256 /* reset hdmiphy */ 262 /* reset hdmiphy */
257 hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); 263 hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
258 mdelay(10); 264 mdelay(10);
@@ -278,6 +284,8 @@ static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
278 /* setting core registers */ 284 /* setting core registers */
279 hdmi_timing_apply(hdmi_dev, conf); 285 hdmi_timing_apply(hdmi_dev, conf);
280 286
287 hdmi_dev->cur_conf_dirty = 0;
288
281 return 0; 289 return 0;
282} 290}
283 291
@@ -500,6 +508,10 @@ static int hdmi_streamon(struct hdmi_device *hdev)
500 508
501 dev_dbg(dev, "%s\n", __func__); 509 dev_dbg(dev, "%s\n", __func__);
502 510
511 ret = hdmi_conf_apply(hdev);
512 if (ret)
513 return ret;
514
503 ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1); 515 ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1);
504 if (ret) 516 if (ret)
505 return ret; 517 return ret;
@@ -620,6 +632,7 @@ static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
620 return -EINVAL; 632 return -EINVAL;
621 } 633 }
622 hdev->cur_conf = conf; 634 hdev->cur_conf = conf;
635 hdev->cur_conf_dirty = 1;
623 hdev->cur_preset = preset->preset; 636 hdev->cur_preset = preset->preset;
624 return 0; 637 return 0;
625} 638}
@@ -689,6 +702,8 @@ static int hdmi_runtime_suspend(struct device *dev)
689 dev_dbg(dev, "%s\n", __func__); 702 dev_dbg(dev, "%s\n", __func__);
690 v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0); 703 v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0);
691 hdmi_resource_poweroff(&hdev->res); 704 hdmi_resource_poweroff(&hdev->res);
705 /* flag that device context is lost */
706 hdev->cur_conf_dirty = 1;
692 return 0; 707 return 0;
693} 708}
694 709
@@ -702,10 +717,6 @@ static int hdmi_runtime_resume(struct device *dev)
702 717
703 hdmi_resource_poweron(&hdev->res); 718 hdmi_resource_poweron(&hdev->res);
704 719
705 ret = hdmi_conf_apply(hdev);
706 if (ret)
707 goto fail;
708
709 /* starting MHL */ 720 /* starting MHL */
710 ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1); 721 ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
711 if (hdev->mhl_sd && ret) 722 if (hdev->mhl_sd && ret)
@@ -946,6 +957,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
946 hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET; 957 hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
947 /* FIXME: missing fail preset is not supported */ 958 /* FIXME: missing fail preset is not supported */
948 hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset); 959 hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset);
960 hdmi_dev->cur_conf_dirty = 1;
949 961
950 /* storing subdev for call that have only access to struct device */ 962 /* storing subdev for call that have only access to struct device */
951 dev_set_drvdata(dev, sd); 963 dev_set_drvdata(dev, sd);