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>
This commit is contained in:
Andrzej Hajda 2016-05-10 13:56:32 +09:00 committed by Inki Dae
parent 2e726dc4b4
commit 59b62d3c8b
1 changed files with 48 additions and 19 deletions

View File

@ -146,6 +146,7 @@ struct hdmi_context {
struct clk **clk_muxes; struct clk **clk_muxes;
struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)]; struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)];
struct regulator *reg_hdmi_en; struct regulator *reg_hdmi_en;
struct exynos_drm_clk phy_clk;
}; };
static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e) static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
@ -1445,7 +1446,6 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
static void hdmi_conf_apply(struct hdmi_context *hdata) static void hdmi_conf_apply(struct hdmi_context *hdata)
{ {
hdmiphy_conf_apply(hdata);
hdmi_start(hdata, false); hdmi_start(hdata, false);
hdmi_conf_init(hdata); hdmi_conf_init(hdata);
hdmi_audio_init(hdata); hdmi_audio_init(hdata);
@ -1478,10 +1478,8 @@ static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0); SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
} }
static void hdmi_enable(struct drm_encoder *encoder) static void hdmiphy_enable(struct hdmi_context *hdata)
{ {
struct hdmi_context *hdata = encoder_to_hdmi(encoder);
if (hdata->powered) if (hdata->powered)
return; return;
@ -1497,11 +1495,40 @@ static void hdmi_enable(struct drm_encoder *encoder)
hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN); hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
hdmi_conf_apply(hdata); hdmiphy_conf_apply(hdata);
hdata->powered = true; hdata->powered = true;
} }
static void hdmiphy_disable(struct hdmi_context *hdata)
{
if (!hdata->powered)
return;
hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
hdmi_set_refclk(hdata, false);
regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
PMU_HDMI_PHY_ENABLE_BIT, 0);
regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
pm_runtime_put_sync(hdata->dev);
hdata->powered = false;
}
static void hdmi_enable(struct drm_encoder *encoder)
{
struct hdmi_context *hdata = encoder_to_hdmi(encoder);
hdmiphy_enable(hdata);
hdmi_conf_apply(hdata);
}
static void hdmi_disable(struct drm_encoder *encoder) static void hdmi_disable(struct drm_encoder *encoder)
{ {
struct hdmi_context *hdata = encoder_to_hdmi(encoder); struct hdmi_context *hdata = encoder_to_hdmi(encoder);
@ -1525,22 +1552,9 @@ static void hdmi_disable(struct drm_encoder *encoder)
if (funcs && funcs->disable) if (funcs && funcs->disable)
(*funcs->disable)(crtc); (*funcs->disable)(crtc);
hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
cancel_delayed_work(&hdata->hotplug_work); cancel_delayed_work(&hdata->hotplug_work);
hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN); hdmiphy_disable(hdata);
hdmi_set_refclk(hdata, false);
regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
PMU_HDMI_PHY_ENABLE_BIT, 0);
regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
pm_runtime_put_sync(hdata->dev);
hdata->powered = false;
} }
static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = { static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
@ -1625,6 +1639,17 @@ static int hdmi_clk_init(struct hdmi_context *hdata)
} }
static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
{
struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
phy_clk);
if (enable)
hdmiphy_enable(hdata);
else
hdmiphy_disable(hdata);
}
static int hdmi_resources_init(struct hdmi_context *hdata) static int hdmi_resources_init(struct hdmi_context *hdata)
{ {
struct device *dev = hdata->dev; struct device *dev = hdata->dev;
@ -1710,6 +1735,10 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
if (pipe < 0) if (pipe < 0)
return pipe; return pipe;
hdata->phy_clk.enable = hdmiphy_clk_enable;
exynos_drm_crtc_from_pipe(drm_dev, pipe)->pipe_clk = &hdata->phy_clk;
encoder->possible_crtcs = 1 << pipe; encoder->possible_crtcs = 1 << pipe;
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);