Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/exynos/hdmi: expose HDMI-PHY clock as pipeline clock

HDMI-PHY clock should be accessible from other components in the pipeline.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>

authored by

Andrzej Hajda and committed by
Inki Dae
59b62d3c 2e726dc4

+48 -19
+48 -19
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 146 146 struct clk **clk_muxes; 147 147 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)]; 148 148 struct regulator *reg_hdmi_en; 149 + struct exynos_drm_clk phy_clk; 149 150 }; 150 151 151 152 static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e) ··· 1446 1445 1447 1446 static void hdmi_conf_apply(struct hdmi_context *hdata) 1448 1447 { 1449 - hdmiphy_conf_apply(hdata); 1450 1448 hdmi_start(hdata, false); 1451 1449 hdmi_conf_init(hdata); 1452 1450 hdmi_audio_init(hdata); ··· 1478 1478 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0); 1479 1479 } 1480 1480 1481 - static void hdmi_enable(struct drm_encoder *encoder) 1481 + static void hdmiphy_enable(struct hdmi_context *hdata) 1482 1482 { 1483 - struct hdmi_context *hdata = encoder_to_hdmi(encoder); 1484 - 1485 1483 if (hdata->powered) 1486 1484 return; 1487 1485 ··· 1495 1497 1496 1498 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN); 1497 1499 1498 - hdmi_conf_apply(hdata); 1500 + hdmiphy_conf_apply(hdata); 1499 1501 1500 1502 hdata->powered = true; 1503 + } 1504 + 1505 + static void hdmiphy_disable(struct hdmi_context *hdata) 1506 + { 1507 + if (!hdata->powered) 1508 + return; 1509 + 1510 + hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN); 1511 + 1512 + hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN); 1513 + 1514 + hdmi_set_refclk(hdata, false); 1515 + 1516 + regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, 1517 + PMU_HDMI_PHY_ENABLE_BIT, 0); 1518 + 1519 + regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk); 1520 + 1521 + pm_runtime_put_sync(hdata->dev); 1522 + 1523 + hdata->powered = false; 1524 + } 1525 + 1526 + static void hdmi_enable(struct drm_encoder *encoder) 1527 + { 1528 + struct hdmi_context *hdata = encoder_to_hdmi(encoder); 1529 + 1530 + hdmiphy_enable(hdata); 1531 + hdmi_conf_apply(hdata); 1501 1532 } 1502 1533 1503 1534 static void hdmi_disable(struct drm_encoder *encoder) ··· 1552 1525 if (funcs && funcs->disable) 1553 1526 (*funcs->disable)(crtc); 1554 1527 1555 - hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN); 1556 - 1557 1528 cancel_delayed_work(&hdata->hotplug_work); 1558 1529 1559 - hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN); 1560 - 1561 - hdmi_set_refclk(hdata, false); 1562 - 1563 - regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, 1564 - PMU_HDMI_PHY_ENABLE_BIT, 0); 1565 - 1566 - regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk); 1567 - 1568 - pm_runtime_put_sync(hdata->dev); 1569 - 1570 - hdata->powered = false; 1530 + hdmiphy_disable(hdata); 1571 1531 } 1572 1532 1573 1533 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = { ··· 1638 1624 return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes); 1639 1625 } 1640 1626 1627 + 1628 + static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable) 1629 + { 1630 + struct hdmi_context *hdata = container_of(clk, struct hdmi_context, 1631 + phy_clk); 1632 + 1633 + if (enable) 1634 + hdmiphy_enable(hdata); 1635 + else 1636 + hdmiphy_disable(hdata); 1637 + } 1641 1638 1642 1639 static int hdmi_resources_init(struct hdmi_context *hdata) 1643 1640 { ··· 1734 1709 EXYNOS_DISPLAY_TYPE_HDMI); 1735 1710 if (pipe < 0) 1736 1711 return pipe; 1712 + 1713 + hdata->phy_clk.enable = hdmiphy_clk_enable; 1714 + 1715 + exynos_drm_crtc_from_pipe(drm_dev, pipe)->pipe_clk = &hdata->phy_clk; 1737 1716 1738 1717 encoder->possible_crtcs = 1 << pipe; 1739 1718