aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/hdac_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/hdac_hdmi.c')
-rw-r--r--sound/soc/codecs/hdac_hdmi.c116
1 files changed, 13 insertions, 103 deletions
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 3ab2949c1dfa..b19d7a3e7a2c 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1890,51 +1890,31 @@ static void hdmi_codec_remove(struct snd_soc_component *component)
1890 pm_runtime_disable(&hdev->dev); 1890 pm_runtime_disable(&hdev->dev);
1891} 1891}
1892 1892
1893#ifdef CONFIG_PM 1893#ifdef CONFIG_PM_SLEEP
1894static int hdmi_codec_prepare(struct device *dev) 1894static int hdmi_codec_resume(struct device *dev)
1895{
1896 struct hdac_device *hdev = dev_to_hdac_dev(dev);
1897
1898 pm_runtime_get_sync(&hdev->dev);
1899
1900 /*
1901 * Power down afg.
1902 * codec_read is preferred over codec_write to set the power state.
1903 * This way verb is send to set the power state and response
1904 * is received. So setting power state is ensured without using loop
1905 * to read the state.
1906 */
1907 snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,
1908 AC_PWRST_D3);
1909
1910 return 0;
1911}
1912
1913static void hdmi_codec_complete(struct device *dev)
1914{ 1895{
1915 struct hdac_device *hdev = dev_to_hdac_dev(dev); 1896 struct hdac_device *hdev = dev_to_hdac_dev(dev);
1916 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); 1897 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
1898 int ret;
1917 1899
1918 /* Power up afg */ 1900 ret = pm_runtime_force_resume(dev);
1919 snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, 1901 if (ret < 0)
1920 AC_PWRST_D0); 1902 return ret;
1921
1922 hdac_hdmi_skl_enable_all_pins(hdev);
1923 hdac_hdmi_skl_enable_dp12(hdev);
1924
1925 /* 1903 /*
1926 * As the ELD notify callback request is not entertained while the 1904 * As the ELD notify callback request is not entertained while the
1927 * device is in suspend state. Need to manually check detection of 1905 * device is in suspend state. Need to manually check detection of
1928 * all pins here. pin capablity change is not support, so use the 1906 * all pins here. pin capablity change is not support, so use the
1929 * already set pin caps. 1907 * already set pin caps.
1908 *
1909 * NOTE: this is safe to call even if the codec doesn't actually resume.
1910 * The pin check involves only with DRM audio component hooks, so it
1911 * works even if the HD-audio side is still dreaming peacefully.
1930 */ 1912 */
1931 hdac_hdmi_present_sense_all_pins(hdev, hdmi, false); 1913 hdac_hdmi_present_sense_all_pins(hdev, hdmi, false);
1932 1914 return 0;
1933 pm_runtime_put_sync(&hdev->dev);
1934} 1915}
1935#else 1916#else
1936#define hdmi_codec_prepare NULL 1917#define hdmi_codec_resume NULL
1937#define hdmi_codec_complete NULL
1938#endif 1918#endif
1939 1919
1940static const struct snd_soc_component_driver hdmi_hda_codec = { 1920static const struct snd_soc_component_driver hdmi_hda_codec = {
@@ -2135,75 +2115,6 @@ static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
2135} 2115}
2136 2116
2137#ifdef CONFIG_PM 2117#ifdef CONFIG_PM
2138/*
2139 * Power management sequences
2140 * ==========================
2141 *
2142 * The following explains the PM handling of HDAC HDMI with its parent
2143 * device SKL and display power usage
2144 *
2145 * Probe
2146 * -----
2147 * In SKL probe,
2148 * 1. skl_probe_work() powers up the display (refcount++ -> 1)
2149 * 2. enumerates the codecs on the link
2150 * 3. powers down the display (refcount-- -> 0)
2151 *
2152 * In HDAC HDMI probe,
2153 * 1. hdac_hdmi_dev_probe() powers up the display (refcount++ -> 1)
2154 * 2. probe the codec
2155 * 3. put the HDAC HDMI device to runtime suspend
2156 * 4. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
2157 *
2158 * Once children are runtime suspended, SKL device also goes to runtime
2159 * suspend
2160 *
2161 * HDMI Playback
2162 * -------------
2163 * Open HDMI device,
2164 * 1. skl_runtime_resume() invoked
2165 * 2. hdac_hdmi_runtime_resume() powers up the display (refcount++ -> 1)
2166 *
2167 * Close HDMI device,
2168 * 1. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
2169 * 2. skl_runtime_suspend() invoked
2170 *
2171 * S0/S3 Cycle with playback in progress
2172 * -------------------------------------
2173 * When the device is opened for playback, the device is runtime active
2174 * already and the display refcount is 1 as explained above.
2175 *
2176 * Entering to S3,
2177 * 1. hdmi_codec_prepare() invoke the runtime resume of codec which just
2178 * increments the PM runtime usage count of the codec since the device
2179 * is in use already
2180 * 2. skl_suspend() powers down the display (refcount-- -> 0)
2181 *
2182 * Wakeup from S3,
2183 * 1. skl_resume() powers up the display (refcount++ -> 1)
2184 * 2. hdmi_codec_complete() invokes the runtime suspend of codec which just
2185 * decrements the PM runtime usage count of the codec since the device
2186 * is in use already
2187 *
2188 * Once playback is stopped, the display refcount is set to 0 as explained
2189 * above in the HDMI playback sequence. The PM handlings are designed in
2190 * such way that to balance the refcount of display power when the codec
2191 * device put to S3 while playback is going on.
2192 *
2193 * S0/S3 Cycle without playback in progress
2194 * ----------------------------------------
2195 * Entering to S3,
2196 * 1. hdmi_codec_prepare() invoke the runtime resume of codec
2197 * 2. skl_runtime_resume() invoked
2198 * 3. hdac_hdmi_runtime_resume() powers up the display (refcount++ -> 1)
2199 * 4. skl_suspend() powers down the display (refcount-- -> 0)
2200 *
2201 * Wakeup from S3,
2202 * 1. skl_resume() powers up the display (refcount++ -> 1)
2203 * 2. hdmi_codec_complete() invokes the runtime suspend of codec
2204 * 3. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
2205 * 4. skl_runtime_suspend() invoked
2206 */
2207static int hdac_hdmi_runtime_suspend(struct device *dev) 2118static int hdac_hdmi_runtime_suspend(struct device *dev)
2208{ 2119{
2209 struct hdac_device *hdev = dev_to_hdac_dev(dev); 2120 struct hdac_device *hdev = dev_to_hdac_dev(dev);
@@ -2277,8 +2188,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
2277 2188
2278static const struct dev_pm_ops hdac_hdmi_pm = { 2189static const struct dev_pm_ops hdac_hdmi_pm = {
2279 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) 2190 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
2280 .prepare = hdmi_codec_prepare, 2191 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, hdmi_codec_resume)
2281 .complete = hdmi_codec_complete,
2282}; 2192};
2283 2193
2284static const struct hda_device_id hdmi_list[] = { 2194static const struct hda_device_id hdmi_list[] = {