xref: /aosp_15_r20/external/coreboot/src/soc/qualcomm/sc7280/display/edp_phy_7nm.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <soc/clock.h>
6 #include <soc/display/edp_reg.h>
7 #include <soc/display/edp_phy.h>
8 #include <timer.h>
9 
edp_phy_ssc_en(bool en)10 static void edp_phy_ssc_en(bool en)
11 {
12 	if (en) {
13 		write32(&edp_phy_pll->qserdes_com_ssc_en_center, 0x01);
14 		write32(&edp_phy_pll->qserdes_com_ssc_adj_per1, 0x00);
15 		write32(&edp_phy_pll->qserdes_com_ssc_per1, 0x36);
16 		write32(&edp_phy_pll->qserdes_com_ssc_per2, 0x01);
17 		write32(&edp_phy_pll->qserdes_com_ssc_step_size1_mode0, 0x5c);
18 		write32(&edp_phy_pll->qserdes_com_ssc_step_size2_mode0, 0x08);
19 	} else {
20 		write32(&edp_phy_pll->qserdes_com_ssc_en_center, 0x00);
21 	}
22 }
23 
edp_phy_enable(void)24 int edp_phy_enable(void)
25 {
26 	write32(&edp_phy->pd_ctl, 0x7D);
27 	write32(&edp_phy_pll->qserdes_com_bias_en_clkbuflr_en, 0x17);
28 	write32(&edp_phy->aux_cfg[1], 0x13);
29 	write32(&edp_phy->aux_cfg[2], 0x24);
30 	write32(&edp_phy->aux_cfg[3], 0x00);
31 	write32(&edp_phy->aux_cfg[4], 0x0a);
32 	write32(&edp_phy->aux_cfg[5], 0x26);
33 	write32(&edp_phy->aux_cfg[6], 0x0a);
34 	write32(&edp_phy->aux_cfg[7], 0x03);
35 	write32(&edp_phy->aux_cfg[8], 0x37);
36 	write32(&edp_phy->aux_cfg[9], 0x03);
37 	write32(&edp_phy->aux_interrupt_mask, 0x1f);
38 	write32(&edp_phy->mode, 0xFC);
39 
40 	if (!wait_us(1000, read32(&edp_phy_pll->qserdes_com_cmn_status) & BIT(7)))
41 		printk(BIOS_ERR, "%s: refgen not ready : 0x%x\n", __func__,
42 		       read32(&edp_phy_pll->qserdes_com_cmn_status));
43 
44 	write32(&edp_phy_lane_tx0->tx_ldo_config, 0x01);
45 	write32(&edp_phy_lane_tx1->tx_ldo_config, 0x01);
46 	write32(&edp_phy_lane_tx0->tx_lane_mode1, 0x00);
47 	write32(&edp_phy_lane_tx1->tx_lane_mode1, 0x00);
48 
49 	return 0;
50 }
51 
52 static const u8 edp_hbr2_pre_emphasis[4][4] = {
53 	{0x0c, 0x15, 0x19, 0x1e},	/* pe0, 0 db */
54 	{0x08, 0x15, 0x19, 0xFF},	/* pe1, 3.5 db */
55 	{0x0e, 0x14, 0xFF, 0xFF},	/* pe2, 6.0 db */
56 	{0x0d, 0xFF, 0xFF, 0xFF}	/* pe3, 9.5 db */
57 };
58 
59 static const u8 edp_hbr2_voltage_swing[4][4] = {
60 	{0xb, 0x11, 0x17, 0x1c}, /* sw0, 0.4v  */
61 	{0x10, 0x19, 0x1f, 0xFF}, /* sw1, 0.6 v */
62 	{0x19, 0x1F, 0xFF, 0xFF}, /* sw1, 0.8 v */
63 	{0x1f, 0xFF, 0xFF, 0xFF}  /* sw1, 1.2 v, optional */
64 };
65 
edp_phy_vm_pe_init(void)66 void edp_phy_vm_pe_init(void)
67 {
68 	write32(&edp_phy_lane_tx0->tx_drv_lvl, edp_hbr2_voltage_swing[0][0]);
69 	write32(&edp_phy_lane_tx0->tx_emp_post1_lvl,
70 		edp_hbr2_pre_emphasis[0][0]);
71 	write32(&edp_phy_lane_tx1->tx_drv_lvl, edp_hbr2_voltage_swing[0][0]);
72 	write32(&edp_phy_lane_tx1->tx_emp_post1_lvl,
73 		edp_hbr2_pre_emphasis[0][0]);
74 
75 	write32(&edp_phy_lane_tx0->tx_highz_drvr_en, 4);
76 	write32(&edp_phy_lane_tx0->tx_transceiver_bias_en, 3);
77 	write32(&edp_phy_lane_tx1->tx_highz_drvr_en, 7);
78 	write32(&edp_phy_lane_tx1->tx_transceiver_bias_en, 0);
79 	write32(&edp_phy->cfg1, 3);
80 }
81 
edp_phy_config(u8 v_level,u8 p_level)82 void edp_phy_config(u8 v_level, u8 p_level)
83 {
84 	write32(&edp_phy_lane_tx0->tx_drv_lvl,
85 		edp_hbr2_voltage_swing[v_level][p_level]);
86 	write32(&edp_phy_lane_tx0->tx_emp_post1_lvl,
87 		edp_hbr2_pre_emphasis[v_level][p_level]);
88 	write32(&edp_phy_lane_tx1->tx_drv_lvl,
89 		edp_hbr2_voltage_swing[v_level][p_level]);
90 	write32(&edp_phy_lane_tx1->tx_emp_post1_lvl,
91 		edp_hbr2_pre_emphasis[v_level][p_level]);
92 }
93 
edp_phy_pll_vco_init(uint32_t link_rate)94 static void edp_phy_pll_vco_init(uint32_t link_rate)
95 {
96 	edp_phy_ssc_en(true);
97 	write32(&edp_phy_pll->qserdes_com_svs_mode_clk_sel, 0x01);
98 	write32(&edp_phy_pll->qserdes_com_sysclk_en_sel, 0x0b);
99 	write32(&edp_phy_pll->qserdes_com_sys_clk_ctrl, 0x02);
100 	write32(&edp_phy_pll->qserdes_com_clk_enable1, 0x0c);
101 	write32(&edp_phy_pll->qserdes_com_sysclk_buf_enable, 0x06);
102 	write32(&edp_phy_pll->qserdes_com_clk_sel, 0x30);
103 	write32(&edp_phy_pll->qserdes_com_pll_ivco, 0x07);
104 	write32(&edp_phy_pll->qserdes_com_lock_cmp_en, 0x04);
105 	write32(&edp_phy_pll->qserdes_com_pll_cctrl_mode0, 0x36);
106 	write32(&edp_phy_pll->qserdes_com_pll_rctrl_mode0, 0x16);
107 	write32(&edp_phy_pll->qserdes_com_cp_ctrl_mode0, 0x06);
108 	write32(&edp_phy_pll->qserdes_com_div_frac_start1_mode0, 0x00);
109 	write32(&edp_phy_pll->qserdes_com_cmn_config, 0x02);
110 	write32(&edp_phy_pll->qserdes_com_integloop_gain0_mode0, 0x3f);
111 	write32(&edp_phy_pll->qserdes_com_integloop_gain1_mode0, 0x00);
112 	write32(&edp_phy_pll->qserdes_com_vco_tune_map, 0x00);
113 	write32(&edp_phy_pll->qserdes_com_bg_timer, 0x0a);
114 	write32(&edp_phy_pll->qserdes_com_coreclk_div_mode0, 0x14);
115 	write32(&edp_phy_pll->qserdes_com_vco_tune_ctrl, 0x00);
116 	write32(&edp_phy_pll->qserdes_com_bias_en_clkbuflr_en, 0x17);
117 	write32(&edp_phy_pll->qserdes_com_core_clk_en, 0x0f);
118 
119 	switch (link_rate) {
120 	case 162000:
121 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x05);
122 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x69);
123 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x80);
124 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x07);
125 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0x6f);
126 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x08);
127 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0xa0);
128 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x03);
129 		break;
130 	case 216000:
131 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x04);
132 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x70);
133 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x00);
134 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x08);
135 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0x3f);
136 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x0b);
137 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0x34);
138 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x03);
139 		break;
140 	case 243000:
141 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x04);
142 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x7e);
143 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x00);
144 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x09);
145 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0xa7);
146 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x0c);
147 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0x5c);
148 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x02);
149 		break;
150 	case 270000:
151 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x03);
152 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x69);
153 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x80);
154 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x07);
155 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0x0f);
156 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x0e);
157 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0xa0);
158 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x03);
159 		break;
160 	case 324000:
161 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x03);
162 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x7e);
163 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x00);
164 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x09);
165 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0xdf);
166 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x10);
167 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0x5c);
168 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x02);
169 		break;
170 	case 432000:
171 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x01);
172 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x70);
173 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x00);
174 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x08);
175 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0x7f);
176 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x16);
177 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0x34);
178 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x03);
179 		break;
180 	case 540000:
181 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x01);
182 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x8c);
183 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x00);
184 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x0a);
185 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0x1f);
186 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x1c);
187 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0x84);
188 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x01);
189 		break;
190 	case 594000:
191 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x01);
192 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x9a);
193 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x00);
194 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x0b);
195 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0xef);
196 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x1e);
197 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0xac);
198 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x00);
199 		break;
200 	case 810000:
201 		write32(&edp_phy_pll->qserdes_com_hsclk_sel, 0x00);
202 		write32(&edp_phy_pll->qserdes_com_dec_start_mode0, 0x69);
203 		write32(&edp_phy_pll->qserdes_com_div_frac_start2_mode0, 0x80);
204 		write32(&edp_phy_pll->qserdes_com_div_frac_start3_mode0, 0x07);
205 		write32(&edp_phy_pll->qserdes_com_lock_cmp1_mode0, 0x2f);
206 		write32(&edp_phy_pll->qserdes_com_lock_cmp2_mode0, 0x2a);
207 		write32(&edp_phy_pll->qserdes_com_vco_tune1_mode0, 0xa0);
208 		write32(&edp_phy_pll->qserdes_com_vco_tune2_mode0, 0x03);
209 		break;
210 	default:
211 		printk(BIOS_ERR, "%s: Invalid link rate. rate = %u\n", __func__,
212 		       link_rate);
213 		break;
214 	}
215 }
216 
edp_phy_lanes_init(void)217 static void edp_phy_lanes_init(void)
218 {
219 	write32(&edp_phy_lane_tx0->tx_transceiver_bias_en, 0x03);
220 	write32(&edp_phy_lane_tx0->tx_clk_buf_enable, 0x0f);
221 	write32(&edp_phy_lane_tx0->tx_reset_tsync_en, 0x03);
222 	write32(&edp_phy_lane_tx0->tx_tran_drvr_emp_en, 0x01);
223 	write32(&edp_phy_lane_tx0->tx_tx_band, 0x4);
224 
225 	write32(&edp_phy_lane_tx1->tx_transceiver_bias_en, 0x03);
226 	write32(&edp_phy_lane_tx1->tx_clk_buf_enable, 0x0f);
227 	write32(&edp_phy_lane_tx1->tx_reset_tsync_en, 0x03);
228 	write32(&edp_phy_lane_tx1->tx_tran_drvr_emp_en, 0x01);
229 	write32(&edp_phy_lane_tx1->tx_tx_band, 0x4);
230 }
231 
edp_lanes_configure(void)232 static void edp_lanes_configure(void)
233 {
234 	write32(&edp_phy_lane_tx0->tx_highz_drvr_en, 0x1f);
235 	write32(&edp_phy_lane_tx0->tx_highz_drvr_en, 0x04);
236 	write32(&edp_phy_lane_tx0->tx_tx_pol_inv, 0x00);
237 
238 	write32(&edp_phy_lane_tx1->tx_highz_drvr_en, 0x1f);
239 	write32(&edp_phy_lane_tx1->tx_highz_drvr_en, 0x04);
240 	write32(&edp_phy_lane_tx1->tx_tx_pol_inv, 0x00);
241 
242 	write32(&edp_phy_lane_tx1->tx_highz_drvr_en, 0x04);
243 	write32(&edp_phy_lane_tx1->tx_tx_pol_inv, 0x00);
244 
245 	write32(&edp_phy_lane_tx0->tx_drv_lvl_offset, 0x10);
246 	write32(&edp_phy_lane_tx1->tx_drv_lvl_offset, 0x10);
247 
248 	write32(&edp_phy_lane_tx0->tx_rescode_lane_offset_tx0, 0x11);
249 	write32(&edp_phy_lane_tx0->tx_rescode_lane_offset_tx1, 0x11);
250 
251 	write32(&edp_phy_lane_tx1->tx_rescode_lane_offset_tx0, 0x11);
252 	write32(&edp_phy_lane_tx1->tx_rescode_lane_offset_tx1, 0x11);
253 }
254 
edp_phy_pll_vco_configure(uint32_t link_rate)255 static int edp_phy_pll_vco_configure(uint32_t link_rate)
256 {
257 	u32 phy_vco_div = 0;
258 
259 	switch (link_rate) {
260 	case 162000:
261 		phy_vco_div = 2;
262 	break;
263 	case 216000:
264 	case 243000:
265 	case 270000:
266 		phy_vco_div = 1;
267 	break;
268 	case 324000:
269 	case 432000:
270 	case 540000:
271 		phy_vco_div = 2;
272 	break;
273 	case 594000:
274 	case 810000:
275 		phy_vco_div = 0;
276 	break;
277 	default:
278 		printk(BIOS_ERR, "%s: Invalid link rate. rate = %u\n", __func__,
279 		       link_rate);
280 	break;
281 	}
282 
283 	write32(&edp_phy->vco_div, phy_vco_div);
284 	write32(&edp_phy->cfg, 0x01);
285 	write32(&edp_phy->cfg, 0x05);
286 	write32(&edp_phy->cfg, 0x01);
287 	write32(&edp_phy->cfg, 0x09);
288 	write32(&edp_phy_pll->qserdes_com_resetsm_cntrl, 0x20);
289 	if (!wait_us(10000, read32(&edp_phy_pll->qserdes_com_c_ready_status) & BIT(0))) {
290 		printk(BIOS_ERR, "%s: PLL not locked. Status\n", __func__);
291 		return -1;
292 	}
293 
294 	write32(&edp_phy->cfg, 0x19);
295 	edp_lanes_configure();
296 	edp_phy_vm_pe_init();
297 	if (!wait_us(10000, read32(&edp_phy->status) & BIT(1))) {
298 		printk(BIOS_ERR, "%s: PHY not ready. Status\n", __func__);
299 		return -1;
300 	}
301 
302 	write32(&edp_phy->cfg, 0x18);
303 	write32(&edp_phy->cfg, 0x19);
304 	if (!wait_us(10000, read32(&edp_phy_pll->qserdes_com_c_ready_status) & BIT(0))) {
305 		printk(BIOS_ERR, "%s: PLL not locked. Status\n", __func__);
306 		return -1;
307 	}
308 
309 	return 0;
310 }
311 
edp_phy_power_on(uint32_t link_rate)312 int edp_phy_power_on(uint32_t link_rate)
313 {
314 	int ret = 0;
315 	edp_phy_pll_vco_init(link_rate);
316 
317 	write32(&edp_phy->tx0_tx1_lane_ctl, 0x5);
318 	write32(&edp_phy->tx2_tx3_lane_ctl, 0x5);
319 	edp_phy_lanes_init();
320 	ret = edp_phy_pll_vco_configure(link_rate);
321 
322 	return ret;
323 }
324