static int hdmi_20nm_vco_enable(struct clk *c)
{
    u32 ready_poll;
    u32 time_out_loop;
    /* Hardware recommended timeout iterator */
    u32 time_out_max = 50000;

    struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c);
    struct mdss_pll_resources *io = vco->priv;

    MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x00000000);
    udelay(1);
    mb();
    MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x00000003);
    udelay(1);
    mb();
    MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x00000009);
    udelay(1);
    mb();

    /* Poll for C_READY and PHY READY */
    pr_debug("%s: Waiting for PHY Ready\n", __func__);
    time_out_loop = 0;
    do {
        ready_poll = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_RESET_SM);
        time_out_loop++;
        udelay(1);
    } while (((ready_poll  & (1 << 6)) == 0) &&
             (time_out_loop < time_out_max));
    if (time_out_loop >= time_out_max)
        pr_err("%s: ERROR: TIMED OUT BEFORE C READY\n", __func__);
    else
        pr_debug("%s: C READY\n", __func__);

    /* Poll for PHY READY */
    pr_debug("%s: Waiting for PHY Ready\n", __func__);
    time_out_loop = 0;
    do {
        ready_poll = MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS);
        time_out_loop++;
        udelay(1);
    } while (((ready_poll & 0x1) == 0) && (time_out_loop < time_out_max));

    if (time_out_loop >= time_out_max)
        pr_err("%s: TIMED OUT BEFORE PHY READY\n", __func__);
    else
        pr_debug("%s: HDMI PHY READY\n", __func__);

    io->pll_on = true;

    return 0;
}
static int digital_get_div(struct div_clk *clk)
{
	int div = 0, rc;
	struct mdss_pll_resources *dsi_pll_res = clk->priv;

	rc = mdss_pll_resource_enable(dsi_pll_res, true);
	if (rc) {
		pr_err("Failed to enable mdss dsi pll resources\n");
		return rc;
	}

	div = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
					DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG);

	mdss_pll_resource_enable(dsi_pll_res, false);
	return div + 1;
}
static unsigned long vco_get_rate(struct clk *c)
{
	u32 sdm0, doubler, sdm_byp_div;
	u64 vco_rate;
	u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
	struct dsi_pll_vco_clk *vco = to_vco_clk(c);
	u64 ref_clk = vco->ref_clk_rate;
	int rc;
	struct mdss_pll_resources *dsi_pll_res = vco->priv;

	rc = mdss_pll_resource_enable(dsi_pll_res, true);
	if (rc) {
		pr_err("Failed to enable mdss dsi pll resources\n");
		return rc;
	}

	/* Check to see if the ref clk doubler is enabled */
	doubler = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
				 DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG) & BIT(0);
	ref_clk += (doubler * vco->ref_clk_rate);

	/* see if it is integer mode or sdm mode */
	sdm0 = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
					DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0);
	if (sdm0 & BIT(6)) {
		/* integer mode */
		sdm_byp_div = (MDSS_PLL_REG_R(dsi_pll_res->pll_base,
			DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0) & 0x3f) + 1;
		vco_rate = ref_clk * sdm_byp_div;
	} else {
		/* sdm mode */
		sdm_dc_off = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
			DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1) & 0xFF;
		pr_debug("sdm_dc_off = %d\n", sdm_dc_off);
		sdm2 = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
			DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2) & 0xFF;
		sdm3 = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
			DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3) & 0xFF;
		sdm_freq_seed = (sdm3 << 8) | sdm2;
		pr_debug("sdm_freq_seed = %d\n", sdm_freq_seed);

		vco_rate = (ref_clk * (sdm_dc_off + 1)) +
			mult_frac(ref_clk, sdm_freq_seed, BIT(16));
		pr_debug("vco rate = %lld", vco_rate);
	}

	pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);

	mdss_pll_resource_enable(dsi_pll_res, false);

	return (unsigned long)vco_rate;
}
int get_byte_mux_sel(struct mux_clk *clk)
{
	int mux_mode, rc;
	struct mdss_pll_resources *dsi_pll_res = clk->priv;

	rc = mdss_pll_resource_enable(dsi_pll_res, true);
	if (rc) {
		pr_err("Failed to enable mdss dsi pll resources\n");
		return rc;
	}

	mux_mode = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
				DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG) & BIT(1);

	pr_debug("byte mux mode = %s", mux_mode ? "indirect" : "direct");
	mdss_pll_resource_enable(dsi_pll_res, false);

	return !!mux_mode;
}