xref: /aosp_15_r20/external/coreboot/src/soc/qualcomm/sc7180/display/dsi_phy_pll.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <stdint.h>
5 #include <soc/clock.h>
6 #include <soc/display/mdssreg.h>
7 #include <soc/display/dsi_phy_pll.h>
8 
9 #define VCO_DELAY_USEC 1
10 
11 /* Bit definition of SSC control registers */
12 #define SSC_CENTER		BIT(0)
13 #define SSC_EN			BIT(1)
14 
15 struct dsi_pll_regs {
16 	u32 pll_prop_gain_rate;
17 	u32 decimal_div_start;
18 	u32 frac_div_start_low;
19 	u32 frac_div_start_mid;
20 	u32 frac_div_start_high;
21 	u32 pll_clock_inverters;
22 };
23 
dsi_pll_init_val(void)24 static void dsi_pll_init_val(void)
25 {
26 	write32(&phy_pll_qlink->pll_core_input_override, 0x10);
27 	write32(&phy_pll_qlink->pll_int_loop_settings, 0x3f);
28 	write32(&phy_pll_qlink->pll_int_loop_settings_two, 0x0);
29 	write32(&phy_pll_qlink->pll_analog_ctrls_four, 0x0);
30 	write32(&phy_pll_qlink->pll_int_loop_ctrls, 0x80);
31 	write32(&phy_pll_qlink->pll_freq_update_ctrl_overrides, 0x0);
32 	write32(&phy_pll_qlink->pll_band_sel_cal_timer_low, 0x0);
33 	write32(&phy_pll_qlink->pll_band_sel_cal_timer_high, 0x02);
34 	write32(&phy_pll_qlink->pll_band_sel_cal_settings, 0x82);
35 	write32(&phy_pll_qlink->pll_band_sel_min, 0x00);
36 	write32(&phy_pll_qlink->pll_band_sel_max, 0xff);
37 	write32(&phy_pll_qlink->pll_band_sel_pfilt, 0x00);
38 	write32(&phy_pll_qlink->pll_band_sel_ifilt, 0x00);
39 	write32(&phy_pll_qlink->pll_band_sel_cal_settings_two, 0x25);
40 	write32(&phy_pll_qlink->pll_band_sel_cal_settings_four, 0x4f);
41 	write32(&phy_pll_qlink->pll_band_sel_icode_high, 0x0a);
42 	write32(&phy_pll_qlink->pll_band_sel_icode_low, 0x0);
43 	write32(&phy_pll_qlink->pll_pll_gain, 0x42);
44 	write32(&phy_pll_qlink->pll_icode_low, 0x00);
45 	write32(&phy_pll_qlink->pll_icode_high, 0x00);
46 	write32(&phy_pll_qlink->pll_lockdet, 0x30);
47 	write32(&phy_pll_qlink->pll_fastlock_ctrl, 0x04);
48 	write32(&phy_pll_qlink->pll_pass_out_override_one, 0x00);
49 	write32(&phy_pll_qlink->pll_pass_out_override_two, 0x00);
50 	write32(&phy_pll_qlink->pll_rate_change, 0x01);
51 	write32(&phy_pll_qlink->pll_digital_timers, 0x08);
52 	write32(&phy_pll_qlink->pll_dec_frac_muxes, 0x00);
53 	write32(&phy_pll_qlink->pll_mash_ctrl, 0x03);
54 	write32(&phy_pll_qlink->pll_ssc_mux_ctrl, 0x0);
55 	write32(&phy_pll_qlink->pll_ssc_ctrl, 0x0);
56 	write32(&phy_pll_qlink->pll_pll_fastlock_en_band, 0x03);
57 	write32(&phy_pll_qlink->pll_freq_tune_accum_init_mux, 0x0);
58 	write32(&phy_pll_qlink->pll_lock_min_delay, 0x19);
59 	write32(&phy_pll_qlink->pll_spare_and_jpc_overrides, 0x0);
60 	write32(&phy_pll_qlink->pll_bias_ctrl_1, 0x40);
61 	write32(&phy_pll_qlink->pll_bias_ctrl_2, 0x20);
62 	write32(&phy_pll_qlink->pll_alog_obsv_bus_ctrl_1, 0x0);
63 }
64 
dsi_pll_calc_dec_frac(struct dsi_pll_regs * regs,unsigned long rate)65 static void dsi_pll_calc_dec_frac(struct dsi_pll_regs *regs,
66 				  unsigned long rate)
67 {
68 	u32 frac_bits = 18;
69 	u64 pll_freq;
70 	u64 divider;
71 	u64 dec, dec_multiple;
72 	u32 frac;
73 	u64 multiplier;
74 
75 	pll_freq = rate;
76 	divider = SRC_XO_HZ * 2;
77 
78 	multiplier = 1 << frac_bits;
79 	dec_multiple = (pll_freq * multiplier) / divider;
80 	frac = dec_multiple % multiplier;
81 
82 	dec = dec_multiple / multiplier;
83 	if (pll_freq <= 1900UL * MHz)
84 		regs->pll_prop_gain_rate = 8;
85 	else if (pll_freq <= 3000UL * MHz)
86 		regs->pll_prop_gain_rate = 10;
87 	else
88 		regs->pll_prop_gain_rate = 12;
89 
90 	if (pll_freq < 1100UL * MHz)
91 		regs->pll_clock_inverters = 8;
92 	else
93 		regs->pll_clock_inverters = 0;
94 
95 	regs->decimal_div_start = dec;
96 	regs->frac_div_start_low = (frac & 0xff);
97 	regs->frac_div_start_mid = (frac & 0xff00) >> 8;
98 	regs->frac_div_start_high = (frac & 0x30000) >> 16;
99 }
100 
dsi_pll_commit(struct dsi_pll_regs * reg)101 static void dsi_pll_commit(struct dsi_pll_regs *reg)
102 {
103 	write32(&phy_pll_qlink->pll_core_input_override, 0x12);
104 	write32(&phy_pll_qlink->pll_decimal_div_start_1, reg->decimal_div_start);
105 	write32(&phy_pll_qlink->pll_frac_div_start_low1, reg->frac_div_start_low);
106 	write32(&phy_pll_qlink->pll_frac_div_start_mid1, reg->frac_div_start_mid);
107 	write32(&phy_pll_qlink->pll_frac_div_start_high1, reg->frac_div_start_high);
108 	write32(&phy_pll_qlink->pll_lockdet_rate[0], 0x40);
109 	write32(&phy_pll_qlink->pll_lock_delay, 0x06);
110 	write32(&phy_pll_qlink->pll_cmode, 0x10);
111 	write32(&phy_pll_qlink->pll_clock_inverters, reg->pll_clock_inverters);
112 }
113 
dsi_pll_config_hzindep_reg(struct dsi_pll_regs * reg)114 static void dsi_pll_config_hzindep_reg(struct dsi_pll_regs *reg)
115 {
116 	write32(&phy_pll_qlink->pll_analog_ctrls_one, 0x80);
117 	write32(&phy_pll_qlink->pll_analog_ctrls_two, 0x03);
118 	write32(&phy_pll_qlink->pll_analog_ctrls_three, 0x00);
119 	write32(&phy_pll_qlink->pll_dsm_divider, 0x00);
120 	write32(&phy_pll_qlink->pll_feedback_divider, 0x4e);
121 	write32(&phy_pll_qlink->pll_cal_settings, 0x40);
122 	write32(&phy_pll_qlink->pll_band_sel_cal_settings_three, 0xba);
123 	write32(&phy_pll_qlink->pll_freq_detect_settings_one, 0x0c);
124 	write32(&phy_pll_qlink->pll_outdiv, 0x00);
125 	write32(&phy_pll_qlink->pll_core_override, 0x00);
126 	write32(&phy_pll_qlink->pll_digital_timers_two, 0x08);
127 	write32(&phy_pll_qlink->pll_prop_gain_rate[0], reg->pll_prop_gain_rate);
128 	write32(&phy_pll_qlink->pll_band_set_rate[0], 0xc0);
129 	write32(&phy_pll_qlink->pll_gain_ifilt_band[0], 0xfa);
130 	write32(&phy_pll_qlink->pll_fl_int_gain_pfilt_band[0], 0x4c);
131 	write32(&phy_pll_qlink->pll_lock_override, 0x80);
132 	write32(&phy_pll_qlink->pll_pfilt, 0x29);
133 	write32(&phy_pll_qlink->pll_ifilt, 0x3f);
134 }
135 
dsi_phy_pll_vco_10nm_set_rate(unsigned long rate)136 void dsi_phy_pll_vco_10nm_set_rate(unsigned long rate)
137 {
138 	struct dsi_pll_regs regs;
139 
140 	dsi_pll_init_val();
141 	dsi_pll_calc_dec_frac(&regs, rate);
142 	dsi_pll_commit(&regs);
143 	dsi_pll_config_hzindep_reg(&regs);
144 }
145