aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/hdac_hdmi.c83
1 files changed, 38 insertions, 45 deletions
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index da3432c9f64d..aaa038ffc8a5 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1420,32 +1420,39 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec)
1420} 1420}
1421 1421
1422#ifdef CONFIG_PM 1422#ifdef CONFIG_PM
1423static int hdmi_codec_prepare(struct device *dev)
1424{
1425 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1426 struct hdac_device *hdac = &edev->hdac;
1427
1428 pm_runtime_get_sync(&edev->hdac.dev);
1429
1430 /*
1431 * Power down afg.
1432 * codec_read is preferred over codec_write to set the power state.
1433 * This way verb is send to set the power state and response
1434 * is received. So setting power state is ensured without using loop
1435 * to read the state.
1436 */
1437 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1438 AC_PWRST_D3);
1439
1440 return 0;
1441}
1442
1423static void hdmi_codec_complete(struct device *dev) 1443static void hdmi_codec_complete(struct device *dev)
1424{ 1444{
1425 struct hdac_ext_device *edev = to_hda_ext_device(dev); 1445 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1426 struct hdac_hdmi_priv *hdmi = edev->private_data; 1446 struct hdac_hdmi_priv *hdmi = edev->private_data;
1427 struct hdac_hdmi_pin *pin; 1447 struct hdac_hdmi_pin *pin;
1428 struct hdac_device *hdac = &edev->hdac; 1448 struct hdac_device *hdac = &edev->hdac;
1429 struct hdac_bus *bus = hdac->bus;
1430 int err;
1431 unsigned long timeout;
1432
1433 hdac_hdmi_skl_enable_all_pins(&edev->hdac);
1434 hdac_hdmi_skl_enable_dp12(&edev->hdac);
1435 1449
1436 /* Power up afg */ 1450 /* Power up afg */
1437 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)) { 1451 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1438 1452 AC_PWRST_D0);
1439 snd_hdac_codec_write(hdac, hdac->afg, 0,
1440 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1441 1453
1442 /* Wait till power state is set to D0 */ 1454 hdac_hdmi_skl_enable_all_pins(&edev->hdac);
1443 timeout = jiffies + msecs_to_jiffies(1000); 1455 hdac_hdmi_skl_enable_dp12(&edev->hdac);
1444 while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)
1445 && time_before(jiffies, timeout)) {
1446 msleep(50);
1447 }
1448 }
1449 1456
1450 /* 1457 /*
1451 * As the ELD notify callback request is not entertained while the 1458 * As the ELD notify callback request is not entertained while the
@@ -1455,18 +1462,10 @@ static void hdmi_codec_complete(struct device *dev)
1455 list_for_each_entry(pin, &hdmi->pin_list, head) 1462 list_for_each_entry(pin, &hdmi->pin_list, head)
1456 hdac_hdmi_present_sense(pin, 1); 1463 hdac_hdmi_present_sense(pin, 1);
1457 1464
1458 /* 1465 pm_runtime_put_sync(&edev->hdac.dev);
1459 * Codec power is turned ON during controller resume.
1460 * Turn it OFF here
1461 */
1462 err = snd_hdac_display_power(bus, false);
1463 if (err < 0) {
1464 dev_err(bus->dev,
1465 "Cannot turn OFF display power on i915, err: %d\n",
1466 err);
1467 }
1468} 1466}
1469#else 1467#else
1468#define hdmi_codec_prepare NULL
1470#define hdmi_codec_complete NULL 1469#define hdmi_codec_complete NULL
1471#endif 1470#endif
1472 1471
@@ -1557,7 +1556,6 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
1557 struct hdac_ext_device *edev = to_hda_ext_device(dev); 1556 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1558 struct hdac_device *hdac = &edev->hdac; 1557 struct hdac_device *hdac = &edev->hdac;
1559 struct hdac_bus *bus = hdac->bus; 1558 struct hdac_bus *bus = hdac->bus;
1560 unsigned long timeout;
1561 int err; 1559 int err;
1562 1560
1563 dev_dbg(dev, "Enter: %s\n", __func__); 1561 dev_dbg(dev, "Enter: %s\n", __func__);
@@ -1566,20 +1564,15 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
1566 if (!bus) 1564 if (!bus)
1567 return 0; 1565 return 0;
1568 1566
1569 /* Power down afg */ 1567 /*
1570 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3)) { 1568 * Power down afg.
1571 snd_hdac_codec_write(hdac, hdac->afg, 0, 1569 * codec_read is preferred over codec_write to set the power state.
1572 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 1570 * This way verb is send to set the power state and response
1573 1571 * is received. So setting power state is ensured without using loop
1574 /* Wait till power state is set to D3 */ 1572 * to read the state.
1575 timeout = jiffies + msecs_to_jiffies(1000); 1573 */
1576 while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3) 1574 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1577 && time_before(jiffies, timeout)) { 1575 AC_PWRST_D3);
1578
1579 msleep(50);
1580 }
1581 }
1582
1583 err = snd_hdac_display_power(bus, false); 1576 err = snd_hdac_display_power(bus, false);
1584 if (err < 0) { 1577 if (err < 0) {
1585 dev_err(bus->dev, "Cannot turn on display power on i915\n"); 1578 dev_err(bus->dev, "Cannot turn on display power on i915\n");
@@ -1612,9 +1605,8 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
1612 hdac_hdmi_skl_enable_dp12(&edev->hdac); 1605 hdac_hdmi_skl_enable_dp12(&edev->hdac);
1613 1606
1614 /* Power up afg */ 1607 /* Power up afg */
1615 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)) 1608 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1616 snd_hdac_codec_write(hdac, hdac->afg, 0, 1609 AC_PWRST_D0);
1617 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1618 1610
1619 return 0; 1611 return 0;
1620} 1612}
@@ -1625,6 +1617,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
1625 1617
1626static const struct dev_pm_ops hdac_hdmi_pm = { 1618static const struct dev_pm_ops hdac_hdmi_pm = {
1627 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) 1619 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
1620 .prepare = hdmi_codec_prepare,
1628 .complete = hdmi_codec_complete, 1621 .complete = hdmi_codec_complete,
1629}; 1622};
1630 1623