int phy_id;
        struct phy *phy;
+       struct phy_configure_opts_hdmi hdmi_cfg;
        struct clk_bulk_data *clks;
        int nr_clks;
        struct reset_control_bulk_data rsts[RST_MAX];
 {
        struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
        enum phy_mode mode = phy_get_mode(phy);
-       unsigned long long rate;
        int ret, lane;
 
-       /*
-        * FIXME: Temporary workaround to pass pixel_clk_rate
-        * from the HDMI bridge driver until phy_configure_opts_hdmi
-        * becomes available in the PHY API.
-        */
-       rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
-       rate *= 100;
+       if (mode != PHY_MODE_DP) {
+               if (!hdptx->hdmi_cfg.tmds_char_rate) {
+                       /*
+                        * FIXME: Temporary workaround to setup TMDS char rate
+                        * from the RK DW HDMI QP bridge driver.
+                        * Will be removed as soon the switch to the HDMI PHY
+                        * configuration API has been completed on both ends.
+                        */
+                       hdptx->hdmi_cfg.tmds_char_rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
+                       hdptx->hdmi_cfg.tmds_char_rate *= 100;
+               }
 
-       dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, rate);
+               dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.tmds_char_rate);
+       }
 
-       ret = rk_hdptx_phy_consumer_get(hdptx, rate);
+       ret = rk_hdptx_phy_consumer_get(hdptx, hdptx->hdmi_cfg.tmds_char_rate);
        if (ret)
                return ret;
 
                regmap_write(hdptx->grf, GRF_HDPTX_CON0,
                             HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
 
-               ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
+               ret = rk_hdptx_ropll_tmds_mode_config(hdptx, hdptx->hdmi_cfg.tmds_char_rate);
                if (ret)
                        rk_hdptx_phy_consumer_put(hdptx, true);
        }
        return rk_hdptx_phy_consumer_put(hdptx, false);
 }
 
-static int rk_hdptx_phy_verify_config(struct rk_hdptx_phy *hdptx,
-                                     struct phy_configure_opts_dp *dp)
+static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
+                                          struct phy_configure_opts_hdmi *hdmi)
+{
+       int i;
+
+       if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE)
+               return -EINVAL;
+
+       for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
+               if (hdmi->tmds_char_rate == ropll_tmds_cfg[i].rate)
+                       break;
+
+       if (i == ARRAY_SIZE(ropll_tmds_cfg) &&
+           !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int rk_hdptx_phy_verify_dp_config(struct rk_hdptx_phy *hdptx,
+                                        struct phy_configure_opts_dp *dp)
 {
        int i;
 
        enum phy_mode mode = phy_get_mode(phy);
        int ret;
 
-       if (mode != PHY_MODE_DP)
-               return 0;
+       if (mode != PHY_MODE_DP) {
+               ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi);
+               if (ret)
+                       dev_err(hdptx->dev, "invalid hdmi params for phy configure\n");
+               else
+                       hdptx->hdmi_cfg = opts->hdmi;
+               return ret;
+       }
 
-       ret = rk_hdptx_phy_verify_config(hdptx, &opts->dp);
+       ret = rk_hdptx_phy_verify_dp_config(hdptx, &opts->dp);
        if (ret) {
-               dev_err(hdptx->dev, "invalid params for phy configure\n");
+               dev_err(hdptx->dev, "invalid dp params for phy configure\n");
                return ret;
        }