drm/rockchip: dw_hdmi: Introduce hdmiphy-pll clock
If drm bind takes too long when entering the kernel, for example, retry reading edid. When the clock is not enabled, it will closed by rockchip_clocks_loader_unprotect(). Therefore, if the uboot logo is displayed, hdmi needs to enable hdmiphy pll when hdmi bind. Signed-off-by: Algea Cao <algea.cao@rock-chips.com> Change-Id: I908f3f23bd60535d01399c972ae0942e6abe3dd4
This commit is contained in:
@ -3482,6 +3482,8 @@ static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
|
|||||||
handle_plugged_change(hdmi, false);
|
handle_plugged_change(hdmi, false);
|
||||||
dw_hdmi_update_power(hdmi);
|
dw_hdmi_update_power(hdmi);
|
||||||
dw_hdmi_update_phy_mask(hdmi);
|
dw_hdmi_update_phy_mask(hdmi);
|
||||||
|
if (hdmi->plat_data->dclk_set)
|
||||||
|
hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, false, 0);
|
||||||
mutex_unlock(&hdmi->mutex);
|
mutex_unlock(&hdmi->mutex);
|
||||||
|
|
||||||
mutex_lock(&hdmi->i2c->lock);
|
mutex_lock(&hdmi->i2c->lock);
|
||||||
@ -3496,6 +3498,8 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
|
|||||||
|
|
||||||
mutex_lock(&hdmi->mutex);
|
mutex_lock(&hdmi->mutex);
|
||||||
hdmi->disabled = false;
|
hdmi->disabled = false;
|
||||||
|
if (hdmi->plat_data->dclk_set)
|
||||||
|
hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, true, 0);
|
||||||
dw_hdmi_update_power(hdmi);
|
dw_hdmi_update_power(hdmi);
|
||||||
dw_hdmi_update_phy_mask(hdmi);
|
dw_hdmi_update_phy_mask(hdmi);
|
||||||
handle_plugged_change(hdmi, true);
|
handle_plugged_change(hdmi, true);
|
||||||
@ -4285,6 +4289,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
|||||||
hdmi->initialized = true;
|
hdmi->initialized = true;
|
||||||
if (hdmi->plat_data->set_ddc_io)
|
if (hdmi->plat_data->set_ddc_io)
|
||||||
hdmi->plat_data->set_ddc_io(hdmi->plat_data->phy_data, true);
|
hdmi->plat_data->set_ddc_io(hdmi->plat_data->phy_data, true);
|
||||||
|
if (hdmi->plat_data->dclk_set)
|
||||||
|
hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, true, 0);
|
||||||
} else if (ret & HDMI_PHY_TX_PHY_LOCK) {
|
} else if (ret & HDMI_PHY_TX_PHY_LOCK) {
|
||||||
hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
|
hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
|
||||||
if (hdmi->plat_data->set_ddc_io)
|
if (hdmi->plat_data->set_ddc_io)
|
||||||
|
|||||||
@ -128,6 +128,7 @@ struct rockchip_hdmi {
|
|||||||
struct clk *grf_clk;
|
struct clk *grf_clk;
|
||||||
struct clk *hclk_vio;
|
struct clk *hclk_vio;
|
||||||
struct clk *hclk_vop;
|
struct clk *hclk_vop;
|
||||||
|
struct clk *dclk_vop;
|
||||||
struct dw_hdmi *hdmi;
|
struct dw_hdmi *hdmi;
|
||||||
|
|
||||||
struct phy *phy;
|
struct phy *phy;
|
||||||
@ -646,6 +647,12 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
|
|||||||
return PTR_ERR(hdmi->hclk_vop);
|
return PTR_ERR(hdmi->hclk_vop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdmi->dclk_vop = devm_clk_get_optional(hdmi->dev, "dclk_vop");
|
||||||
|
if (IS_ERR(hdmi->dclk_vop)) {
|
||||||
|
dev_err(hdmi->dev, "failed to get dclk_vop\n");
|
||||||
|
return PTR_ERR(hdmi->dclk_vop);
|
||||||
|
}
|
||||||
|
|
||||||
ret = of_property_read_u32(np, "max-tmdsclk",
|
ret = of_property_read_u32(np, "max-tmdsclk",
|
||||||
&hdmi->max_tmdsclk);
|
&hdmi->max_tmdsclk);
|
||||||
if (ret != -EINVAL && ret < 0) {
|
if (ret != -EINVAL && ret < 0) {
|
||||||
@ -1302,6 +1309,25 @@ static void dw_hdmi_rockchip_set_ddc_io(void *data, bool enable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dw_hdmi_rockchip_dclk_set(void *data, bool enable, int vp_id)
|
||||||
|
{
|
||||||
|
struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!hdmi->dclk_vop)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
ret = clk_prepare_enable(hdmi->dclk_vop);
|
||||||
|
if (ret < 0)
|
||||||
|
dev_err(hdmi->dev, "failed to enable dclk_vop\n");
|
||||||
|
} else {
|
||||||
|
clk_disable_unprepare(hdmi->dclk_vop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct drm_prop_enum_list color_depth_enum_list[] = {
|
static const struct drm_prop_enum_list color_depth_enum_list[] = {
|
||||||
{ 0, "Automatic" }, /* Prefer highest color depth */
|
{ 0, "Automatic" }, /* Prefer highest color depth */
|
||||||
{ 8, "24bit" },
|
{ 8, "24bit" },
|
||||||
@ -1981,6 +2007,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
|||||||
dw_hdmi_rockchip_set_prev_bus_format;
|
dw_hdmi_rockchip_set_prev_bus_format;
|
||||||
plat_data->set_ddc_io =
|
plat_data->set_ddc_io =
|
||||||
dw_hdmi_rockchip_set_ddc_io;
|
dw_hdmi_rockchip_set_ddc_io;
|
||||||
|
plat_data->dclk_set =
|
||||||
|
dw_hdmi_rockchip_dclk_set;
|
||||||
plat_data->property_ops = &dw_hdmi_rockchip_property_ops;
|
plat_data->property_ops = &dw_hdmi_rockchip_property_ops;
|
||||||
|
|
||||||
encoder = &hdmi->encoder;
|
encoder = &hdmi->encoder;
|
||||||
|
|||||||
@ -184,6 +184,7 @@ struct dw_hdmi_plat_data {
|
|||||||
bool (*check_hdr_color_change)(struct drm_connector_state *conn_state, void *data);
|
bool (*check_hdr_color_change)(struct drm_connector_state *conn_state, void *data);
|
||||||
void (*set_prev_bus_format)(void *data, unsigned long bus_format);
|
void (*set_prev_bus_format)(void *data, unsigned long bus_format);
|
||||||
void (*set_ddc_io)(void *data, bool enable);
|
void (*set_ddc_io)(void *data, bool enable);
|
||||||
|
int (*dclk_set)(void *data, bool enable, int vp_id);
|
||||||
|
|
||||||
/* Vendor Property support */
|
/* Vendor Property support */
|
||||||
const struct dw_hdmi_property_ops *property_ops;
|
const struct dw_hdmi_property_ops *property_ops;
|
||||||
|
|||||||
Reference in New Issue
Block a user