drm/rockchip: dw_hdmi-rockchip: get phy config from dts

Change-Id: I6903f3b9498be32f9d4936beb2d6d2aa5db43d09
Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
Algea Cao 2017-03-17 15:56:47 +08:00 committed by Tao Huang
commit 4088ea06bc
2 changed files with 55 additions and 2 deletions

View file

@ -26,6 +26,7 @@ Required properties:
corresponding to the video input of the controller. The port shall have two
endpoints, numbered 0 and 1, connected respectively to the vopb and vopl.
- rockchip,grf: Shall reference the GRF to mux vopl/vopb.
- rockchip,phy-table: the parameter table of hdmi phy configuration.
Optional properties
@ -68,4 +69,9 @@ hdmi: hdmi@ff980000 {
};
};
};
rockchip,phy-table = <74250000 0x8009 0x0004 0x0272>,
<165000000 0x802b 0x0004 0x0209>,
<297000000 0x8039 0x0005 0x028d>,
<594000000 0x8039 0x0000 0x019d>,
<000000000 0x0000 0x0000 0x0000>;
};

View file

@ -288,7 +288,7 @@ static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
}
};
static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
static struct dw_hdmi_phy_config rockchip_phy_config[] = {
/*pixelclk symbol term vlev*/
{ 74250000, 0x8009, 0x0004, 0x0272},
{ 165000000, 0x802b, 0x0004, 0x0209},
@ -297,9 +297,34 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
{ ~0UL, 0x0000, 0x0000, 0x0000}
};
static int rockchip_hdmi_update_phy_table(struct rockchip_hdmi *hdmi,
u32 *config,
int phy_table_size)
{
int i;
if (phy_table_size > ARRAY_SIZE(rockchip_phy_config)) {
dev_err(hdmi->dev, "phy table array number is out of range\n");
return -E2BIG;
}
for (i = 0; i < phy_table_size; i++) {
if (config[i * 4] != 0)
rockchip_phy_config[i].mpixelclock = (u64)config[i * 4];
else
rockchip_phy_config[i].mpixelclock = ~0UL;
rockchip_phy_config[i].sym_ctr = (u16)config[i * 4 + 1];
rockchip_phy_config[i].term = (u16)config[i * 4 + 2];
rockchip_phy_config[i].vlev_ctr = (u16)config[i * 4 + 3];
}
return 0;
}
static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
{
int ret;
int ret, val, phy_table_size;
u32 *phy_config;
struct device_node *np = hdmi->dev->of_node;
hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
@ -343,6 +368,28 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
hdmi->unsupported_deep_color =
of_property_read_bool(np, "unsupported-deep-color");
if (of_get_property(np, "rockchip,phy-table", &val)) {
phy_config = kmalloc(val, GFP_KERNEL);
if (!phy_config) {
/* use default table when kmalloc failed. */
dev_err(hdmi->dev, "kmalloc phy table failed\n");
return -ENOMEM;
}
phy_table_size = val / 16;
of_property_read_u32_array(np, "rockchip,phy_table",
phy_config, val / sizeof(u32));
ret = rockchip_hdmi_update_phy_table(hdmi, phy_config,
phy_table_size);
if (ret) {
kfree(phy_config);
return ret;
}
kfree(phy_config);
} else {
dev_dbg(hdmi->dev, "use default hdmi phy table\n");
}
return 0;
}