1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/mmio.h>
6 #include <soc/display/edp_reg.h>
7 #include <soc/display/edp_phy.h>
10 static void edp_phy_ssc_en(bool 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);
20 write32(&edp_phy_pll
->qserdes_com_ssc_en_center
, 0x00);
24 int edp_phy_enable(void)
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);
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
));
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);
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 */
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 */
66 void edp_phy_vm_pe_init(void)
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]);
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);
82 void edp_phy_config(u8 v_level
, u8 p_level
)
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
]);
94 static void edp_phy_pll_vco_init(uint32_t link_rate
)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
211 printk(BIOS_ERR
, "%s: Invalid link rate. rate = %u\n", __func__
,
217 static void edp_phy_lanes_init(void)
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);
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);
232 static void edp_lanes_configure(void)
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);
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);
242 write32(&edp_phy_lane_tx1
->tx_highz_drvr_en
, 0x04);
243 write32(&edp_phy_lane_tx1
->tx_tx_pol_inv
, 0x00);
245 write32(&edp_phy_lane_tx0
->tx_drv_lvl_offset
, 0x10);
246 write32(&edp_phy_lane_tx1
->tx_drv_lvl_offset
, 0x10);
248 write32(&edp_phy_lane_tx0
->tx_rescode_lane_offset_tx0
, 0x11);
249 write32(&edp_phy_lane_tx0
->tx_rescode_lane_offset_tx1
, 0x11);
251 write32(&edp_phy_lane_tx1
->tx_rescode_lane_offset_tx0
, 0x11);
252 write32(&edp_phy_lane_tx1
->tx_rescode_lane_offset_tx1
, 0x11);
255 static int edp_phy_pll_vco_configure(uint32_t link_rate
)
278 printk(BIOS_ERR
, "%s: Invalid link rate. rate = %u\n", __func__
,
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__
);
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__
);
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__
);
312 int edp_phy_power_on(uint32_t link_rate
)
315 edp_phy_pll_vco_init(link_rate
);
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
);