Loading arch/arm/mach-msm/clock-8084.c +2 −9 Original line number Diff line number Diff line Loading @@ -5188,25 +5188,18 @@ static struct branch_clk mdss_pclk1_clk = { }; static struct clk_freq_tbl ftbl_mdss_extpclk_clk[] = { F_MM( 25200000, hdmipll, 1, 0, 0), F_MM( 27000000, hdmipll, 1, 0, 0), F_MM( 27030000, hdmipll, 1, 0, 0), F_MM( 65000000, hdmipll, 1, 0, 0), F_MM( 74250000, hdmipll, 1, 0, 0), F_MM(108000000, hdmipll, 1, 0, 0), F_MM(148500000, hdmipll, 1, 0, 0), F_MM(268500000, hdmipll, 1, 0, 0), F_MM(297000000, hdmipll, 1, 0, 0), F_END }; static struct rcg_clk extpclk_clk_src = { .cmd_rcgr_reg = EXTPCLK_CMD_RCGR, .freq_tbl = ftbl_mdss_extpclk_clk, .current_freq = &rcg_dummy_freq, .current_freq = ftbl_mdss_extpclk_clk, .base = &virt_bases[MMSS_BASE], .c = { .dbg_name = "extpclk_clk_src", .parent = &hdmipll_clk_src.c, .ops = &clk_ops_rcg_hdmi, VDD_DIG_FMAX_MAP2(LOW, 150000000, NOMINAL, 297000000), CLK_INIT(extpclk_clk_src.c), Loading arch/arm/mach-msm/clock-8974.c +3 −21 Original line number Diff line number Diff line Loading @@ -580,17 +580,6 @@ static void __iomem *virt_bases[N_BASES]; | BVAL(10, 8, s##_mm_source_val), \ } #define F_HDMI(f, s, div, m, n) \ { \ .freq_hz = (f), \ .src_clk = &s##_clk_src.c, \ .m_val = (m), \ .n_val = ~((n)-(m)) * !!(n), \ .d_val = ~(n),\ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \ | BVAL(10, 8, s##_mm_source_val), \ } #define F_EDP(f, s, div, m, n) \ { \ .freq_hz = (f), \ Loading Loading @@ -3271,25 +3260,18 @@ static struct rcg_clk esc1_clk_src = { }; static struct clk_freq_tbl ftbl_mdss_extpclk_clk[] = { F_HDMI( 25200000, hdmipll, 1, 0, 0), F_HDMI( 27000000, hdmipll, 1, 0, 0), F_HDMI( 27030000, hdmipll, 1, 0, 0), F_HDMI( 65000000, hdmipll, 1, 0, 0), F_HDMI( 74250000, hdmipll, 1, 0, 0), F_HDMI(108000000, hdmipll, 1, 0, 0), F_HDMI(148500000, hdmipll, 1, 0, 0), F_HDMI(268500000, hdmipll, 1, 0, 0), F_HDMI(297000000, hdmipll, 1, 0, 0), F_MM(148500000, hdmipll, 1, 0, 0), F_END }; static struct rcg_clk extpclk_clk_src = { .cmd_rcgr_reg = EXTPCLK_CMD_RCGR, .freq_tbl = ftbl_mdss_extpclk_clk, .current_freq = &rcg_dummy_freq, .current_freq = ftbl_mdss_extpclk_clk, .base = &virt_bases[MMSS_BASE], .c = { .dbg_name = "extpclk_clk_src", .parent = &hdmipll_clk_src.c, .ops = &clk_ops_rcg_hdmi, VDD_DIG_FMAX_MAP2(LOW, 148500000, NOMINAL, 297000000), CLK_INIT(extpclk_clk_src.c), Loading arch/arm/mach-msm/clock-local2.c +34 −2 Original line number Diff line number Diff line Loading @@ -1034,6 +1034,38 @@ static int set_rate_pixel(struct clk *clk, unsigned long rate) * re-programming. It is also routed through an HID divider. */ static int rcg_clk_set_rate_hdmi(struct clk *c, unsigned long rate) { struct rcg_clk *rcg = to_rcg_clk(c); struct clk_freq_tbl *nf = rcg->freq_tbl; int rc; rc = clk_set_rate(nf->src_clk, rate); if (rc < 0) goto out; set_rate_hid(rcg, nf); rcg->current_freq = nf; out: return rc; } static struct clk *rcg_hdmi_clk_get_parent(struct clk *c) { struct rcg_clk *rcg = to_rcg_clk(c); struct clk_freq_tbl *freq = rcg->freq_tbl; u32 cmd_rcgr_regval; /* Is there a pending configuration? */ cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg)); if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK) return NULL; rcg->current_freq->freq_hz = clk_get_rate(c->parent); return freq->src_clk; } static int rcg_clk_set_rate_edp(struct clk *c, unsigned long rate) { struct clk_freq_tbl *nf; struct rcg_clk *rcg = to_rcg_clk(c); Loading Loading @@ -1272,13 +1304,13 @@ struct clk_ops clk_ops_rcg_hdmi = { .list_rate = rcg_clk_list_rate, .round_rate = rcg_clk_round_rate, .handoff = rcg_clk_handoff, .get_parent = rcg_clk_get_parent, .get_parent = rcg_hdmi_clk_get_parent, .list_registers = rcg_hid_clk_list_registers, }; struct clk_ops clk_ops_rcg_edp = { .enable = rcg_clk_prepare, .set_rate = rcg_clk_set_rate_hdmi, .set_rate = rcg_clk_set_rate_edp, .list_rate = rcg_clk_list_rate, .round_rate = rcg_clk_round_rate, .handoff = rcg_clk_handoff, Loading arch/arm/mach-msm/clock-mdss-8974.c +190 −25 Original line number Diff line number Diff line Loading @@ -291,6 +291,140 @@ static inline struct hdmi_pll_vco_clk *to_hdmi_vco_clk(struct clk *clk) return container_of(clk, struct hdmi_pll_vco_clk, c); } static void hdmi_phy_pll_calculator(u32 vco_freq) { u32 ref_clk = 19200000; u32 sdm_mode = 1; u32 ref_clk_multiplier = sdm_mode == 1 ? 2 : 1; u32 int_ref_clk_freq = ref_clk * ref_clk_multiplier; u32 fbclk_pre_div = 1; u32 ssc_mode = 0; u32 kvco = 270; u32 vdd = 95; u32 ten_power_six = 1000000; u32 ssc_ds_ppm = ssc_mode ? 5000 : 0; u32 sdm_res = 16; u32 ssc_tri_step = 32; u32 ssc_freq = 2; u64 ssc_ds = vco_freq * ssc_ds_ppm; u32 div_in_freq = vco_freq / fbclk_pre_div; u64 dc_offset = (div_in_freq / int_ref_clk_freq - 1) * ten_power_six * 10; u32 ssc_kdiv = (int_ref_clk_freq / ssc_freq) - ten_power_six; u64 sdm_freq_seed; u32 ssc_tri_inc; u64 fb_div_n; u32 val; pr_debug("%s: vco_freq = %u\n", __func__, vco_freq); do_div(ssc_ds, (u64)ten_power_six); fb_div_n = (u64)div_in_freq * (u64)ten_power_six * 10; do_div(fb_div_n, int_ref_clk_freq); sdm_freq_seed = ((fb_div_n - dc_offset - ten_power_six * 10) * (1 << sdm_res) * 10) + 5; do_div(sdm_freq_seed, ((u64)ten_power_six * 100)); ssc_tri_inc = (u32)ssc_ds; ssc_tri_inc = (ssc_tri_inc / int_ref_clk_freq) * (1 << 16) / ssc_tri_step; val = (ref_clk_multiplier == 2 ? 1 : 0) + ((fbclk_pre_div == 2 ? 1 : 0) * 16); pr_debug("%s: HDMI_UNI_PLL_REFCLK_CFG = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG); REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CHFPUMP_CFG); REG_W(0x19, hdmi_phy_pll_base + HDMI_UNI_PLL_VCOLPF_CFG); REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_PWRGEN_CFG); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG); REG_W(0x0E, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFR_CFG); REG_W(0x20, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC1_CFG); REG_W(0x0D, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC2_CFG); do_div(dc_offset, (u64)ten_power_six * 10); val = sdm_mode == 0 ? 64 + dc_offset : 0; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG0 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG0); val = 64 + dc_offset; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG1 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG1); val = sdm_freq_seed & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG2 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG2); val = (sdm_freq_seed >> 8) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG3 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG3); val = (sdm_freq_seed >> 16) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG4 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG4); val = (ssc_mode == 0 ? 128 : 0) + (ssc_kdiv / ten_power_six); pr_debug("%s: HDMI_UNI_PLL_SSC_CFG0 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG0); val = ssc_tri_inc & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SSC_CFG1 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG1); val = (ssc_tri_inc >> 8) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SSC_CFG2 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG2); pr_debug("%s: HDMI_UNI_PLL_SSC_CFG3 = 0x%x\n", __func__, ssc_tri_step); REG_W(ssc_tri_step, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG3); REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0); REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1); REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2); REG_W(0x0A, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG0); REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG1); REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG3); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG4); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG5); val = (kvco * vdd * 10000) / 6; val += 500000; val /= ten_power_six; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG6 = 0x%x\n", __func__, val); REG_W(val & 0xFF, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG6); val = (kvco * vdd * 10000) / 6; val -= ten_power_six; val /= ten_power_six; val = (val >> 8) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG7 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG7); val = (ref_clk * 5) / ten_power_six; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG8 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG8); val = ((ref_clk * 5) / ten_power_six) >> 8; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG9 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG9); vco_freq /= ten_power_six; val = vco_freq & 0xFF; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG10 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10); val = vco_freq >> 8; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG11 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11); } /* hdmi_phy_pll_calculator */ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate) { unsigned int set_power_dwn = 0; Loading @@ -313,6 +447,9 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate) pr_debug("%s: rate=%ld\n", __func__, rate); switch (rate) { case 0: break; case 756000000: /* 640x480p60 */ REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG); Loading Loading @@ -663,7 +800,52 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate) break; default: pr_err("%s: not supported rate=%ld\n", __func__, rate); pr_debug("%s: Use pll settings calculator for rate=%ld\n", __func__, rate); REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG); hdmi_phy_pll_calculator(rate); REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0); udelay(50); REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG); REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1); REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0); REG_W(0x43, hdmi_phy_base + HDMI_PHY_ANA_CFG1); if (rate < 825000000) { REG_W(0x01, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0x00, hdmi_phy_base + HDMI_PHY_ANA_CFG3); } else if (rate >= 825000000 && rate < 1342500000) { REG_W(0x05, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3); } else { REG_W(0x06, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3); } REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG); REG_W(0xD0, hdmi_phy_base + HDMI_PHY_DCC_CFG0); REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1); REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0); REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1); if (rate < 825000000) REG_W(0x01, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2); else REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2); REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3); REG_W(0x62, hdmi_phy_base + HDMI_PHY_BIST_PATN0); REG_W(0x03, hdmi_phy_base + HDMI_PHY_BIST_PATN1); REG_W(0x69, hdmi_phy_base + HDMI_PHY_BIST_PATN2); REG_W(0x02, hdmi_phy_base + HDMI_PHY_BIST_PATN3); udelay(200); REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG1); REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG0); } /* Make sure writes complete before disabling iface clock */ Loading Loading @@ -2404,17 +2586,13 @@ static unsigned long hdmi_vco_get_rate(struct clk *c) static long hdmi_vco_round_rate(struct clk *c, unsigned long rate) { unsigned long rrate = rate; struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); unsigned long rrate = 0; unsigned long *lp = vco->rate_list; while (*lp) { rrate = *lp; if (rate <= rrate) break; lp++; } if (rate < vco->min_rate) rrate = vco->min_rate; if (rate > vco->max_rate) rrate = vco->max_rate; pr_debug("%s: rrate=%ld\n", __func__, rrate); Loading Loading @@ -2486,20 +2664,6 @@ static enum handoff hdmi_vco_handoff(struct clk *c) return ret; } /* Should be in increasing order */ static unsigned long hdmi_vco_rate_list[] = { 650000000, 742500000, 756000000, 810000000, 810900000, 1080000000, 1342500000, 1485000000, 0 }; static struct clk_ops hdmi_vco_clk_ops = { .enable = hdmi_vco_enable, .set_rate = hdmi_vco_set_rate, Loading @@ -2512,7 +2676,8 @@ static struct clk_ops hdmi_vco_clk_ops = { }; static struct hdmi_pll_vco_clk hdmi_vco_clk = { .rate_list = hdmi_vco_rate_list, .min_rate = 600000000, .max_rate = 1800000000, .c = { .dbg_name = "hdmi_vco_clk", .ops = &hdmi_vco_clk_ops, Loading arch/arm/mach-msm/clock-mdss-8974.h +3 −2 Original line number Diff line number Diff line Loading @@ -32,8 +32,9 @@ struct edp_pll_vco_clk { }; struct hdmi_pll_vco_clk { unsigned long rate; /* vco rate */ unsigned long *rate_list; unsigned long rate; /* current vco rate */ unsigned long min_rate; /* min vco rate */ unsigned long max_rate; /* max vco rate */ bool rate_set; struct clk c; Loading Loading
arch/arm/mach-msm/clock-8084.c +2 −9 Original line number Diff line number Diff line Loading @@ -5188,25 +5188,18 @@ static struct branch_clk mdss_pclk1_clk = { }; static struct clk_freq_tbl ftbl_mdss_extpclk_clk[] = { F_MM( 25200000, hdmipll, 1, 0, 0), F_MM( 27000000, hdmipll, 1, 0, 0), F_MM( 27030000, hdmipll, 1, 0, 0), F_MM( 65000000, hdmipll, 1, 0, 0), F_MM( 74250000, hdmipll, 1, 0, 0), F_MM(108000000, hdmipll, 1, 0, 0), F_MM(148500000, hdmipll, 1, 0, 0), F_MM(268500000, hdmipll, 1, 0, 0), F_MM(297000000, hdmipll, 1, 0, 0), F_END }; static struct rcg_clk extpclk_clk_src = { .cmd_rcgr_reg = EXTPCLK_CMD_RCGR, .freq_tbl = ftbl_mdss_extpclk_clk, .current_freq = &rcg_dummy_freq, .current_freq = ftbl_mdss_extpclk_clk, .base = &virt_bases[MMSS_BASE], .c = { .dbg_name = "extpclk_clk_src", .parent = &hdmipll_clk_src.c, .ops = &clk_ops_rcg_hdmi, VDD_DIG_FMAX_MAP2(LOW, 150000000, NOMINAL, 297000000), CLK_INIT(extpclk_clk_src.c), Loading
arch/arm/mach-msm/clock-8974.c +3 −21 Original line number Diff line number Diff line Loading @@ -580,17 +580,6 @@ static void __iomem *virt_bases[N_BASES]; | BVAL(10, 8, s##_mm_source_val), \ } #define F_HDMI(f, s, div, m, n) \ { \ .freq_hz = (f), \ .src_clk = &s##_clk_src.c, \ .m_val = (m), \ .n_val = ~((n)-(m)) * !!(n), \ .d_val = ~(n),\ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \ | BVAL(10, 8, s##_mm_source_val), \ } #define F_EDP(f, s, div, m, n) \ { \ .freq_hz = (f), \ Loading Loading @@ -3271,25 +3260,18 @@ static struct rcg_clk esc1_clk_src = { }; static struct clk_freq_tbl ftbl_mdss_extpclk_clk[] = { F_HDMI( 25200000, hdmipll, 1, 0, 0), F_HDMI( 27000000, hdmipll, 1, 0, 0), F_HDMI( 27030000, hdmipll, 1, 0, 0), F_HDMI( 65000000, hdmipll, 1, 0, 0), F_HDMI( 74250000, hdmipll, 1, 0, 0), F_HDMI(108000000, hdmipll, 1, 0, 0), F_HDMI(148500000, hdmipll, 1, 0, 0), F_HDMI(268500000, hdmipll, 1, 0, 0), F_HDMI(297000000, hdmipll, 1, 0, 0), F_MM(148500000, hdmipll, 1, 0, 0), F_END }; static struct rcg_clk extpclk_clk_src = { .cmd_rcgr_reg = EXTPCLK_CMD_RCGR, .freq_tbl = ftbl_mdss_extpclk_clk, .current_freq = &rcg_dummy_freq, .current_freq = ftbl_mdss_extpclk_clk, .base = &virt_bases[MMSS_BASE], .c = { .dbg_name = "extpclk_clk_src", .parent = &hdmipll_clk_src.c, .ops = &clk_ops_rcg_hdmi, VDD_DIG_FMAX_MAP2(LOW, 148500000, NOMINAL, 297000000), CLK_INIT(extpclk_clk_src.c), Loading
arch/arm/mach-msm/clock-local2.c +34 −2 Original line number Diff line number Diff line Loading @@ -1034,6 +1034,38 @@ static int set_rate_pixel(struct clk *clk, unsigned long rate) * re-programming. It is also routed through an HID divider. */ static int rcg_clk_set_rate_hdmi(struct clk *c, unsigned long rate) { struct rcg_clk *rcg = to_rcg_clk(c); struct clk_freq_tbl *nf = rcg->freq_tbl; int rc; rc = clk_set_rate(nf->src_clk, rate); if (rc < 0) goto out; set_rate_hid(rcg, nf); rcg->current_freq = nf; out: return rc; } static struct clk *rcg_hdmi_clk_get_parent(struct clk *c) { struct rcg_clk *rcg = to_rcg_clk(c); struct clk_freq_tbl *freq = rcg->freq_tbl; u32 cmd_rcgr_regval; /* Is there a pending configuration? */ cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg)); if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK) return NULL; rcg->current_freq->freq_hz = clk_get_rate(c->parent); return freq->src_clk; } static int rcg_clk_set_rate_edp(struct clk *c, unsigned long rate) { struct clk_freq_tbl *nf; struct rcg_clk *rcg = to_rcg_clk(c); Loading Loading @@ -1272,13 +1304,13 @@ struct clk_ops clk_ops_rcg_hdmi = { .list_rate = rcg_clk_list_rate, .round_rate = rcg_clk_round_rate, .handoff = rcg_clk_handoff, .get_parent = rcg_clk_get_parent, .get_parent = rcg_hdmi_clk_get_parent, .list_registers = rcg_hid_clk_list_registers, }; struct clk_ops clk_ops_rcg_edp = { .enable = rcg_clk_prepare, .set_rate = rcg_clk_set_rate_hdmi, .set_rate = rcg_clk_set_rate_edp, .list_rate = rcg_clk_list_rate, .round_rate = rcg_clk_round_rate, .handoff = rcg_clk_handoff, Loading
arch/arm/mach-msm/clock-mdss-8974.c +190 −25 Original line number Diff line number Diff line Loading @@ -291,6 +291,140 @@ static inline struct hdmi_pll_vco_clk *to_hdmi_vco_clk(struct clk *clk) return container_of(clk, struct hdmi_pll_vco_clk, c); } static void hdmi_phy_pll_calculator(u32 vco_freq) { u32 ref_clk = 19200000; u32 sdm_mode = 1; u32 ref_clk_multiplier = sdm_mode == 1 ? 2 : 1; u32 int_ref_clk_freq = ref_clk * ref_clk_multiplier; u32 fbclk_pre_div = 1; u32 ssc_mode = 0; u32 kvco = 270; u32 vdd = 95; u32 ten_power_six = 1000000; u32 ssc_ds_ppm = ssc_mode ? 5000 : 0; u32 sdm_res = 16; u32 ssc_tri_step = 32; u32 ssc_freq = 2; u64 ssc_ds = vco_freq * ssc_ds_ppm; u32 div_in_freq = vco_freq / fbclk_pre_div; u64 dc_offset = (div_in_freq / int_ref_clk_freq - 1) * ten_power_six * 10; u32 ssc_kdiv = (int_ref_clk_freq / ssc_freq) - ten_power_six; u64 sdm_freq_seed; u32 ssc_tri_inc; u64 fb_div_n; u32 val; pr_debug("%s: vco_freq = %u\n", __func__, vco_freq); do_div(ssc_ds, (u64)ten_power_six); fb_div_n = (u64)div_in_freq * (u64)ten_power_six * 10; do_div(fb_div_n, int_ref_clk_freq); sdm_freq_seed = ((fb_div_n - dc_offset - ten_power_six * 10) * (1 << sdm_res) * 10) + 5; do_div(sdm_freq_seed, ((u64)ten_power_six * 100)); ssc_tri_inc = (u32)ssc_ds; ssc_tri_inc = (ssc_tri_inc / int_ref_clk_freq) * (1 << 16) / ssc_tri_step; val = (ref_clk_multiplier == 2 ? 1 : 0) + ((fbclk_pre_div == 2 ? 1 : 0) * 16); pr_debug("%s: HDMI_UNI_PLL_REFCLK_CFG = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG); REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CHFPUMP_CFG); REG_W(0x19, hdmi_phy_pll_base + HDMI_UNI_PLL_VCOLPF_CFG); REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_PWRGEN_CFG); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG); REG_W(0x0E, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFR_CFG); REG_W(0x20, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC1_CFG); REG_W(0x0D, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC2_CFG); do_div(dc_offset, (u64)ten_power_six * 10); val = sdm_mode == 0 ? 64 + dc_offset : 0; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG0 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG0); val = 64 + dc_offset; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG1 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG1); val = sdm_freq_seed & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG2 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG2); val = (sdm_freq_seed >> 8) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG3 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG3); val = (sdm_freq_seed >> 16) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SDM_CFG4 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG4); val = (ssc_mode == 0 ? 128 : 0) + (ssc_kdiv / ten_power_six); pr_debug("%s: HDMI_UNI_PLL_SSC_CFG0 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG0); val = ssc_tri_inc & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SSC_CFG1 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG1); val = (ssc_tri_inc >> 8) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_SSC_CFG2 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG2); pr_debug("%s: HDMI_UNI_PLL_SSC_CFG3 = 0x%x\n", __func__, ssc_tri_step); REG_W(ssc_tri_step, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG3); REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0); REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1); REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2); REG_W(0x0A, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG0); REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG1); REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG3); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG4); REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG5); val = (kvco * vdd * 10000) / 6; val += 500000; val /= ten_power_six; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG6 = 0x%x\n", __func__, val); REG_W(val & 0xFF, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG6); val = (kvco * vdd * 10000) / 6; val -= ten_power_six; val /= ten_power_six; val = (val >> 8) & 0xFF; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG7 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG7); val = (ref_clk * 5) / ten_power_six; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG8 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG8); val = ((ref_clk * 5) / ten_power_six) >> 8; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG9 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG9); vco_freq /= ten_power_six; val = vco_freq & 0xFF; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG10 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10); val = vco_freq >> 8; pr_debug("%s: HDMI_UNI_PLL_CAL_CFG11 = 0x%x\n", __func__, val); REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11); } /* hdmi_phy_pll_calculator */ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate) { unsigned int set_power_dwn = 0; Loading @@ -313,6 +447,9 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate) pr_debug("%s: rate=%ld\n", __func__, rate); switch (rate) { case 0: break; case 756000000: /* 640x480p60 */ REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG); Loading Loading @@ -663,7 +800,52 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate) break; default: pr_err("%s: not supported rate=%ld\n", __func__, rate); pr_debug("%s: Use pll settings calculator for rate=%ld\n", __func__, rate); REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG); hdmi_phy_pll_calculator(rate); REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0); udelay(50); REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG); REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1); REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0); REG_W(0x43, hdmi_phy_base + HDMI_PHY_ANA_CFG1); if (rate < 825000000) { REG_W(0x01, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0x00, hdmi_phy_base + HDMI_PHY_ANA_CFG3); } else if (rate >= 825000000 && rate < 1342500000) { REG_W(0x05, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3); } else { REG_W(0x06, hdmi_phy_base + HDMI_PHY_ANA_CFG2); REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3); } REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG); REG_W(0xD0, hdmi_phy_base + HDMI_PHY_DCC_CFG0); REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1); REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0); REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1); if (rate < 825000000) REG_W(0x01, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2); else REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2); REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3); REG_W(0x62, hdmi_phy_base + HDMI_PHY_BIST_PATN0); REG_W(0x03, hdmi_phy_base + HDMI_PHY_BIST_PATN1); REG_W(0x69, hdmi_phy_base + HDMI_PHY_BIST_PATN2); REG_W(0x02, hdmi_phy_base + HDMI_PHY_BIST_PATN3); udelay(200); REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG1); REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG0); } /* Make sure writes complete before disabling iface clock */ Loading Loading @@ -2404,17 +2586,13 @@ static unsigned long hdmi_vco_get_rate(struct clk *c) static long hdmi_vco_round_rate(struct clk *c, unsigned long rate) { unsigned long rrate = rate; struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); unsigned long rrate = 0; unsigned long *lp = vco->rate_list; while (*lp) { rrate = *lp; if (rate <= rrate) break; lp++; } if (rate < vco->min_rate) rrate = vco->min_rate; if (rate > vco->max_rate) rrate = vco->max_rate; pr_debug("%s: rrate=%ld\n", __func__, rrate); Loading Loading @@ -2486,20 +2664,6 @@ static enum handoff hdmi_vco_handoff(struct clk *c) return ret; } /* Should be in increasing order */ static unsigned long hdmi_vco_rate_list[] = { 650000000, 742500000, 756000000, 810000000, 810900000, 1080000000, 1342500000, 1485000000, 0 }; static struct clk_ops hdmi_vco_clk_ops = { .enable = hdmi_vco_enable, .set_rate = hdmi_vco_set_rate, Loading @@ -2512,7 +2676,8 @@ static struct clk_ops hdmi_vco_clk_ops = { }; static struct hdmi_pll_vco_clk hdmi_vco_clk = { .rate_list = hdmi_vco_rate_list, .min_rate = 600000000, .max_rate = 1800000000, .c = { .dbg_name = "hdmi_vco_clk", .ops = &hdmi_vco_clk_ops, Loading
arch/arm/mach-msm/clock-mdss-8974.h +3 −2 Original line number Diff line number Diff line Loading @@ -32,8 +32,9 @@ struct edp_pll_vco_clk { }; struct hdmi_pll_vco_clk { unsigned long rate; /* vco rate */ unsigned long *rate_list; unsigned long rate; /* current vco rate */ unsigned long min_rate; /* min vco rate */ unsigned long max_rate; /* max vco rate */ bool rate_set; struct clk c; Loading