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; }