Commit 2fd07a4a authored by Tomasz Stanislawski's avatar Tomasz Stanislawski Committed by Mauro Carvalho Chehab

[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: default avatarTomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 3f468acc
...@@ -87,6 +87,8 @@ struct hdmi_device { ...@@ -87,6 +87,8 @@ struct hdmi_device {
struct v4l2_subdev *mhl_sd; struct v4l2_subdev *mhl_sd;
/** configuration of current graphic mode */ /** configuration of current graphic mode */
const struct hdmi_timings *cur_conf; const struct hdmi_timings *cur_conf;
/** flag indicating that timings are dirty */
int cur_conf_dirty;
/** current preset */ /** current preset */
u32 cur_preset; u32 cur_preset;
/** other resources */ /** other resources */
...@@ -253,6 +255,10 @@ static int hdmi_conf_apply(struct hdmi_device *hdmi_dev) ...@@ -253,6 +255,10 @@ static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
dev_dbg(dev, "%s\n", __func__); dev_dbg(dev, "%s\n", __func__);
/* skip if conf is already synchronized with HW */
if (!hdmi_dev->cur_conf_dirty)
return 0;
/* reset hdmiphy */ /* reset hdmiphy */
hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
mdelay(10); mdelay(10);
...@@ -278,6 +284,8 @@ static int hdmi_conf_apply(struct hdmi_device *hdmi_dev) ...@@ -278,6 +284,8 @@ static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
/* setting core registers */ /* setting core registers */
hdmi_timing_apply(hdmi_dev, conf); hdmi_timing_apply(hdmi_dev, conf);
hdmi_dev->cur_conf_dirty = 0;
return 0; return 0;
} }
...@@ -500,6 +508,10 @@ static int hdmi_streamon(struct hdmi_device *hdev) ...@@ -500,6 +508,10 @@ static int hdmi_streamon(struct hdmi_device *hdev)
dev_dbg(dev, "%s\n", __func__); dev_dbg(dev, "%s\n", __func__);
ret = hdmi_conf_apply(hdev);
if (ret)
return ret;
ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1); ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1);
if (ret) if (ret)
return ret; return ret;
...@@ -620,6 +632,7 @@ static int hdmi_s_dv_preset(struct v4l2_subdev *sd, ...@@ -620,6 +632,7 @@ static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
return -EINVAL; return -EINVAL;
} }
hdev->cur_conf = conf; hdev->cur_conf = conf;
hdev->cur_conf_dirty = 1;
hdev->cur_preset = preset->preset; hdev->cur_preset = preset->preset;
return 0; return 0;
} }
...@@ -689,6 +702,8 @@ static int hdmi_runtime_suspend(struct device *dev) ...@@ -689,6 +702,8 @@ static int hdmi_runtime_suspend(struct device *dev)
dev_dbg(dev, "%s\n", __func__); dev_dbg(dev, "%s\n", __func__);
v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0); v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0);
hdmi_resource_poweroff(&hdev->res); hdmi_resource_poweroff(&hdev->res);
/* flag that device context is lost */
hdev->cur_conf_dirty = 1;
return 0; return 0;
} }
...@@ -702,10 +717,6 @@ static int hdmi_runtime_resume(struct device *dev) ...@@ -702,10 +717,6 @@ static int hdmi_runtime_resume(struct device *dev)
hdmi_resource_poweron(&hdev->res); hdmi_resource_poweron(&hdev->res);
ret = hdmi_conf_apply(hdev);
if (ret)
goto fail;
/* starting MHL */ /* starting MHL */
ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1); ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
if (hdev->mhl_sd && ret) if (hdev->mhl_sd && ret)
...@@ -946,6 +957,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) ...@@ -946,6 +957,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET; hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
/* FIXME: missing fail preset is not supported */ /* FIXME: missing fail preset is not supported */
hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset); hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset);
hdmi_dev->cur_conf_dirty = 1;
/* storing subdev for call that have only access to struct device */ /* storing subdev for call that have only access to struct device */
dev_set_drvdata(dev, sd); dev_set_drvdata(dev, sd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment