blob: e0058c4fe762a4561773a07ae9bd1e2fdcfab837 [file] [log] [blame]
Vinod Polimerac4e0b0a2020-06-23 16:23:06 +05301/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <console/console.h>
4#include <delay.h>
5#include <endian.h>
6#include <device/i2c_simple.h>
7#include <edid.h>
8#include <timer.h>
9#include <types.h>
10#include <soc/addressmap.h>
11#include "sn65dsi86bridge.h"
12
13#define BRIDGE_GETHIGHERBYTE(x) (uint8_t)((x & 0xff00) >> 8)
14#define BRIDGE_GETLOWERBYTE(x) (uint8_t)((x & 0x00ff))
15
16/* fudge factor required to account for 8b/10b encoding */
17#define DP_CLK_FUDGE_NUM 10
18#define DP_CLK_FUDGE_DEN 8
19
20/* DPCD */
21#define DP_BRIDGE_DPCD_REV 0x700
22#define DP_BRIDGE_11 0x00
23#define DP_BRIDGE_12 0x01
24#define DP_BRIDGE_13 0x02
25#define DP_BRIDGE_14 0x03
26#define DP_BRIDGE_CONFIGURATION_SET 0x10a
27#define DP_MAX_LINK_RATE 0x001
28#define DP_MAX_LANE_COUNT 0x002
29#define DP_SUPPORTED_LINK_RATES 0x010 /* eDP 1.4 */
30#define DP_MAX_LINK_RATE 0x001
31#define DP_MAX_SUPPORTED_RATES 8 /* 16-bit little-endian */
32#define DP_LANE_COUNT_MASK 0xf
33
34/* link configuration */
35#define DP_LINK_BW_SET 0x100
36#define DP_LINK_BW_1_62 0x06
37#define DP_LINK_BW_2_7 0x0a
38#define DP_LINK_BW_5_4 0x14
39
40#define AUX_CMD_SEND 0x1
41#define MIN_DSI_CLK_FREQ_MHZ 40
42#define MAX_DSI_CLK_FREQ_MHZ 750
43
44enum bridge_regs {
45 SN_DPPLL_SRC_REG = 0x0A,
46 SN_PLL_ENABLE_REG = 0x0D,
47 SN_DSI_LANES_REG = 0x10,
48 SN_DSIA_CLK_FREQ_REG = 0x12,
49 SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG = 0x20,
50 SN_CHA_ACTIVE_LINE_LENGTH_HIGH_REG = 0x21,
51 SN_CHA_VERTICAL_DISPLAY_SIZE_LOW_REG = 0x24,
52 SN_CHA_VERTICAL_DISPLAY_SIZE_HIGH_REG = 0x25,
53 SN_CHA_HSYNC_PULSE_WIDTH_LOW_REG = 0x2C,
54 SN_CHA_HSYNC_PULSE_WIDTH_HIGH_REG = 0x2D,
55 SN_CHA_VSYNC_PULSE_WIDTH_LOW_REG = 0x30,
56 SN_CHA_VSYNC_PULSE_WIDTH_HIGH_REG = 0x31,
57 SN_CHA_HORIZONTAL_BACK_PORCH_REG = 0x34,
58 SN_CHA_VERTICAL_BACK_PORCH_REG = 0x36,
59 SN_CHA_HORIZONTAL_FRONT_PORCH_REG = 0x38,
60 SN_CHA_VERTICAL_FRONT_PORCH_REG = 0x3A,
61 SN_COLOR_BAR_REG = 0x3C,
62 SN_ENH_FRAME_REG = 0x5A,
63 SN_DATA_FORMAT_REG = 0x5B,
64 SN_HPD_DISABLE_REG = 0x5C,
65 SN_I2C_CLAIM_ADDR_EN1 = 0x60,
66 SN_AUX_WDATA_REG_0 = 0x64,
67 SN_AUX_WDATA_REG_1 = 0x65,
68 SN_AUX_WDATA_REG_2 = 0x66,
69 SN_AUX_WDATA_REG_3 = 0x67,
70 SN_AUX_WDATA_REG_4 = 0x68,
71 SN_AUX_WDATA_REG_5 = 0x69,
72 SN_AUX_WDATA_REG_6 = 0x6A,
73 SN_AUX_WDATA_REG_7 = 0x6B,
74 SN_AUX_WDATA_REG_8 = 0x6C,
75 SN_AUX_WDATA_REG_9 = 0x6D,
76 SN_AUX_WDATA_REG_10 = 0x6E,
77 SN_AUX_WDATA_REG_11 = 0x6F,
78 SN_AUX_WDATA_REG_12 = 0x70,
79 SN_AUX_WDATA_REG_13 = 0x71,
80 SN_AUX_WDATA_REG_14 = 0x72,
81 SN_AUX_WDATA_REG_15 = 0x73,
82 SN_AUX_ADDR_19_16_REG = 0x74,
83 SN_AUX_ADDR_15_8_REG = 0x75,
84 SN_AUX_ADDR_7_0_REG = 0x76,
85 SN_AUX_LENGTH_REG = 0x77,
86 SN_AUX_CMD_REG = 0x78,
87 SN_AUX_RDATA_REG_0 = 0x79,
88 SN_AUX_RDATA_REG_1 = 0x7A,
89 SN_AUX_RDATA_REG_2 = 0x7B,
90 SN_AUX_RDATA_REG_3 = 0x7C,
91 SN_AUX_RDATA_REG_4 = 0x7D,
92 SN_AUX_RDATA_REG_5 = 0x7E,
93 SN_AUX_RDATA_REG_6 = 0x7F,
94 SN_AUX_RDATA_REG_7 = 0x80,
95 SN_AUX_RDATA_REG_8 = 0x81,
96 SN_AUX_RDATA_REG_9 = 0x82,
97 SN_AUX_RDATA_REG_10 = 0x83,
98 SN_AUX_RDATA_REG_11 = 0x84,
99 SN_AUX_RDATA_REG_12 = 0x85,
100 SN_AUX_RDATA_REG_13 = 0x86,
101 SN_AUX_RDATA_REG_14 = 0x87,
102 SN_AUX_RDATA_REG_15 = 0x88,
103 SN_SSC_CONFIG_REG = 0x93,
104 SN_DATARATE_CONFIG_REG = 0x94,
105 SN_ML_TX_MODE_REG = 0x96,
106 SN_AUX_CMD_STATUS_REG = 0xF4,
107};
108
109enum {
110 HPD_ENABLE = 0x0,
111 HPD_DISABLE = 0x1,
112};
113
114enum {
115 SOT_ERR_TOL_DSI = 0x0,
116 CHB_DSI_LANES = 0x1,
117 CHA_DSI_LANES = 0x2,
118 DSI_CHANNEL_MODE = 0x3,
119 LEFT_RIGHT_PIXELS = 0x4,
120};
121
122enum vstream_config {
123 VSTREAM_DISABLE = 0,
124 VSTREAM_ENABLE = 1,
125};
126
127enum i2c_over_aux {
128 I2C_OVER_AUX_WRITE_MOT_0 = 0x0,
129 I2C_OVER_AUX_READ_MOT_0 = 0x1,
130 I2C_OVER_AUX_WRITE_STATUS_UPDATE_0 = 0x4,
131 I2C_OVER_AUX_WRITE_MOT_1 = 0x5,
132 I2C_OVER_AUX_READ_MOT_1 = 0x6,
133 I2C_OVER_AUX_WRITE_STATUS_UPDATE_1 = 0x7,
134 NATIVE_AUX_WRITE = 0x8,
135 NATIVE_AUX_READ = 0x9,
136};
137
138enum ml_tx_mode {
139 MAIN_LINK_OFF = 0x0,
140 NORMAL_MODE = 0x1,
141 TPS1 = 0x2,
142 TPS2 = 0x3,
143 TPS3 = 0x4,
144 PRBS7 = 0x5,
145 HBR2_COMPLIANCE_EYE_PATTERN = 0x6,
146 SYMBOL_ERR_RATE_MEASUREMENT_PATTERN = 0x7,
147 CUTSOM_PATTERN = 0x8,
148 FAST_LINK_TRAINING = 0x9,
149 SEMI_AUTO_LINK_TRAINING = 0xa,
150 REDRIVER_SEMI_AUTO_LINK_TRAINING = 0xb,
151};
152
153enum dpcd_request {
154 DPCD_READ = 0x0,
155 DPCD_WRITE = 0x1,
156};
157
158enum {
159 EDID_LENGTH = 128,
160 EDID_I2C_ADDR = 0x50,
161 EDID_EXTENSION_FLAG = 0x7e,
162};
163
164/*
165 * LUT index corresponds to register value and LUT values corresponds
166 * to dp data rate supported by the bridge in Mbps unit.
167 */
168static const unsigned int sn65dsi86_bridge_dp_rate_lut[] = {
169 0, 1620, 2160, 2430, 2700, 3240, 4320, 5400
170};
171
172enum cb_err sn65dsi86_bridge_read_edid(uint8_t bus, uint8_t chip, struct edid *out)
173{
174 int ret;
175 u8 edid[EDID_LENGTH * 2];
176 int edid_size = EDID_LENGTH;
177
178 /* Send I2C command to claim EDID I2c slave */
179 i2c_writeb(bus, chip, SN_I2C_CLAIM_ADDR_EN1, (EDID_I2C_ADDR << 1) | 0x1);
180
181 /* read EDID */
182 ret = i2c_read_bytes(bus, EDID_I2C_ADDR, 0x0, edid, EDID_LENGTH);
183 if (ret != 0) {
184 printk(BIOS_ERR, "ERROR: Failed to read EDID.\n");
185 return CB_ERR;
186 }
187
188 if (edid[EDID_EXTENSION_FLAG]) {
189 edid_size += EDID_LENGTH;
190 ret = i2c_read_bytes(bus, EDID_I2C_ADDR, EDID_LENGTH,
191 &edid[EDID_LENGTH], EDID_LENGTH);
192 if (ret != 0) {
193 printk(BIOS_ERR, "Failed to read EDID ext block.\n");
194 return CB_ERR;
195 }
196 }
197
198 if (decode_edid(edid, edid_size, out) != EDID_CONFORMANT) {
199 printk(BIOS_ERR, "ERROR: Failed to decode EDID.\n");
200 return CB_ERR;
201 }
202
203 return CB_SUCCESS;
204}
205
206static void sn65dsi86_bridge_dpcd_request(uint8_t bus,
207 uint8_t chip,
208 unsigned int dpcd_reg,
209 unsigned int len,
210 enum dpcd_request request,
211 uint8_t *data)
212{
213 int i;
214 uint32_t length;
215 uint8_t buf;
216 uint8_t reg;
217
218 while (len) {
219 length = MIN(len, 16);
220
221 i2c_writeb(bus, chip, SN_AUX_ADDR_19_16_REG, (dpcd_reg >> 16) & 0xF);
222 i2c_writeb(bus, chip, SN_AUX_ADDR_15_8_REG, (dpcd_reg >> 8) & 0xFF);
223 i2c_writeb(bus, chip, SN_AUX_ADDR_7_0_REG, (dpcd_reg) & 0xFF);
224 i2c_writeb(bus, chip, SN_AUX_LENGTH_REG, length); /* size of 1 Byte data */
225 if (request == DPCD_WRITE) {
226 reg = SN_AUX_WDATA_REG_0;
227 for (i = 0; i < length; i++)
228 i2c_writeb(bus, chip, reg++, *data++);
229
230 i2c_writeb(bus, chip,
231 SN_AUX_CMD_REG, AUX_CMD_SEND | (NATIVE_AUX_WRITE << 4));
232 } else {
233 i2c_writeb(bus, chip,
234 SN_AUX_CMD_REG, AUX_CMD_SEND | (NATIVE_AUX_READ << 4));
235 if (!wait_ms(100,
236 !i2c_readb(bus, chip, SN_AUX_CMD_REG,
237 &buf) && !(buf & AUX_CMD_SEND))) {
238 printk(BIOS_ERR, "ERROR: aux command send failed\n");
239 }
240
241 reg = SN_AUX_RDATA_REG_0;
242 for (i = 0; i < length; i++) {
243 i2c_readb(bus, chip, reg++, &buf);
244 *data++ = buf;
245 }
246 }
247
248 len -= length;
249 }
250}
251
252static void sn65dsi86_bridge_valid_dp_rates(uint8_t bus, uint8_t chip, bool rate_valid[])
253{
254 unsigned int rate_per_200khz;
255 uint8_t dpcd_val;
256 int i, j;
257
258 sn65dsi86_bridge_dpcd_request(bus, chip,
259 DP_BRIDGE_DPCD_REV, 1, DPCD_READ, &dpcd_val);
260 if (dpcd_val >= DP_BRIDGE_14) {
261 /* eDP 1.4 devices must provide a custom table */
262 uint8_t sink_rates[DP_MAX_SUPPORTED_RATES * 2];
263
264 sn65dsi86_bridge_dpcd_request(bus, chip, DP_SUPPORTED_LINK_RATES,
265 sizeof(sink_rates),
266 DPCD_READ, sink_rates);
267 for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
268 rate_per_200khz = le16_to_cpu(sink_rates[i]);
269
270 if (!rate_per_200khz)
271 break;
272
273 for (j = 0;
274 j < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut);
275 j++) {
276 if (sn65dsi86_bridge_dp_rate_lut[j] * (MHz / KHz) ==
277 rate_per_200khz * 200)
278 rate_valid[j] = true;
279 }
280 }
281
282 for (i = 0; i < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut); i++) {
283 if (rate_valid[i])
284 return;
285 }
286
287 printk(BIOS_ERR, "No matching eDP rates in table; falling back\n");
288 }
289
290 /* On older versions best we can do is use DP_MAX_LINK_RATE */
291 sn65dsi86_bridge_dpcd_request(bus, chip,
292 DP_MAX_LINK_RATE, 1, DPCD_READ, &dpcd_val);
293
294 switch (dpcd_val) {
295 default:
296 printk(BIOS_ERR,
297 "Unexpected max rate (%#x); assuming 5.4 GHz\n",
298 (int)dpcd_val);
299 /* fall through */
300 case DP_LINK_BW_5_4:
301 rate_valid[7] = 1;
302 /* fall through */
303 case DP_LINK_BW_2_7:
304 rate_valid[4] = 1;
305 /* fall through */
306 case DP_LINK_BW_1_62:
307 rate_valid[1] = 1;
308 break;
309 }
310}
311
312static void sn65dsi86_bridge_set_dsi_clock_range(uint8_t bus, uint8_t chip,
313 struct edid *edid,
314 uint32_t num_of_lanes, uint32_t bpp)
315{
316 uint64_t pixel_clk_hz;
317 uint64_t stream_bit_rate_mhz;
318 uint64_t min_req_dsi_clk;
319
320 pixel_clk_hz = edid->mode.pixel_clock * KHz;
321 stream_bit_rate_mhz = (pixel_clk_hz * bpp) / MHz;
322
323 /* For TI the clock frequencies are half the bit rates */
324 min_req_dsi_clk = stream_bit_rate_mhz / (num_of_lanes * 2);
325
326 /* for each increment in val, frequency increases by 5MHz */
327 min_req_dsi_clk = MAX(MIN_DSI_CLK_FREQ_MHZ,
328 MIN(MAX_DSI_CLK_FREQ_MHZ, min_req_dsi_clk)) / 5;
329 i2c_writeb(bus, chip, SN_DSIA_CLK_FREQ_REG, min_req_dsi_clk);
330}
331
332static void sn65dsi86_bridge_set_dp_clock_range(uint8_t bus, uint8_t chip,
333 struct edid *edid, uint32_t num_of_lanes)
334{
335 uint64_t stream_bit_rate_khz;
336 bool rate_valid[ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut)] = { };
337 uint64_t dp_rate_mhz;
338 int dp_rate_idx, i;
339
340 stream_bit_rate_khz = edid->mode.pixel_clock * 18;
341
342 /* Calculate minimum DP data rate, taking 80% as per DP spec */
343 dp_rate_mhz = DIV_ROUND_UP(stream_bit_rate_khz * DP_CLK_FUDGE_NUM,
344 KHz * num_of_lanes * DP_CLK_FUDGE_DEN);
345
346 for (i = 0; i < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut) - 1; i++)
347 if (sn65dsi86_bridge_dp_rate_lut[i] > dp_rate_mhz)
348 break;
349
350 sn65dsi86_bridge_valid_dp_rates(bus, chip, rate_valid);
351
352 /* Train until we run out of rates */
353 for (dp_rate_idx = i;
354 dp_rate_idx < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut);
355 dp_rate_idx++)
356 if (rate_valid[dp_rate_idx])
357 break;
358
359 if (dp_rate_idx < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut))
360 i2c_write_field(bus, chip, SN_DATARATE_CONFIG_REG, dp_rate_idx, 8, 5);
361 else
362 printk(BIOS_ERR, "ERROR: valid dp rate not found");
363}
364
365static void sn65dsi86_bridge_set_bridge_active_timing(uint8_t bus,
366 uint8_t chip,
367 struct edid *edid)
368{
369 i2c_writeb(bus, chip, SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG,
370 BRIDGE_GETLOWERBYTE(edid->mode.ha));
371 i2c_writeb(bus, chip, SN_CHA_ACTIVE_LINE_LENGTH_HIGH_REG,
372 BRIDGE_GETHIGHERBYTE(edid->mode.ha));
373 i2c_writeb(bus, chip, SN_CHA_VERTICAL_DISPLAY_SIZE_LOW_REG,
374 BRIDGE_GETLOWERBYTE(edid->mode.va));
375 i2c_writeb(bus, chip, SN_CHA_VERTICAL_DISPLAY_SIZE_HIGH_REG,
376 BRIDGE_GETHIGHERBYTE(edid->mode.va));
377 i2c_writeb(bus, chip, SN_CHA_HSYNC_PULSE_WIDTH_LOW_REG,
378 BRIDGE_GETLOWERBYTE(edid->mode.hspw));
379 i2c_writeb(bus, chip, SN_CHA_HSYNC_PULSE_WIDTH_HIGH_REG,
380 BRIDGE_GETHIGHERBYTE(edid->mode.hspw));
381 i2c_writeb(bus, chip, SN_CHA_VSYNC_PULSE_WIDTH_LOW_REG,
382 BRIDGE_GETLOWERBYTE(edid->mode.vspw));
383 i2c_writeb(bus, chip, SN_CHA_VSYNC_PULSE_WIDTH_HIGH_REG,
384 BRIDGE_GETHIGHERBYTE(edid->mode.vspw));
385 i2c_writeb(bus, chip, SN_CHA_HORIZONTAL_BACK_PORCH_REG,
386 edid->mode.hbl - edid->mode.hso - edid->mode.hspw);
387 i2c_writeb(bus, chip, SN_CHA_VERTICAL_BACK_PORCH_REG,
388 edid->mode.vbl - edid->mode.vso - edid->mode.vspw);
389 i2c_writeb(bus, chip, SN_CHA_HORIZONTAL_FRONT_PORCH_REG,
390 edid->mode.hso);
391 i2c_writeb(bus, chip, SN_CHA_VERTICAL_FRONT_PORCH_REG,
392 edid->mode.vso);
393}
394
395static void sn65dsi86_bridge_link_training(uint8_t bus, uint8_t chip)
396{
397 uint8_t buf;
398
399 /* enable pll lock */
400 i2c_writeb(bus, chip, SN_PLL_ENABLE_REG, 0x1);
401
402 if (!wait_ms(500,
403 !(i2c_readb(bus, chip, SN_DPPLL_SRC_REG, &buf)) &&
404 (buf & BIT(7)))) {
405 printk(BIOS_ERR, "ERROR: PLL lock failure\n");
406 }
407
408 /*
409 * The SN65DSI86 only supports ASSR Display Authentication method and
410 * this method is enabled by default. An eDP panel must support this
411 * authentication method. We need to enable this method in the eDP panel
412 * at DisplayPort address 0x0010A prior to link training.
413 */
414 buf = 0x1;
415 sn65dsi86_bridge_dpcd_request(bus, chip,
416 DP_BRIDGE_CONFIGURATION_SET, 1, DPCD_WRITE, &buf);
417
418 /* semi auto link training mode */
419 i2c_writeb(bus, chip, SN_ML_TX_MODE_REG, 0xa);
420
421 if (!wait_ms(500,
422 !(i2c_readb(bus, chip, SN_ML_TX_MODE_REG, &buf)) &&
423 (buf & NORMAL_MODE))) {
424 printk(BIOS_ERR, "ERROR: Link training failed");
425 }
426
427}
428
429static enum cb_err sn65dsi86_bridge_get_plug_in_status(uint8_t bus, uint8_t chip)
430{
431 int val;
432 uint8_t buf;
433
434 val = i2c_readb(bus, chip, SN_HPD_DISABLE_REG, &buf);
435 if (val == 0 && (buf & HPD_DISABLE))
436 return CB_SUCCESS;
437
438 return CB_ERR;
439}
440
441/*
442 * support bridge HPD function some hardware versions do not support bridge hdp,
443 * we use 360ms to try to get the hpd single now, if we can not get bridge hpd single,
444 * it will delay 360ms, also meet the bridge power timing request, to be compatible
445 * all of the hardware versions
446 */
447static void sn65dsi86_bridge_wait_hpd(uint8_t bus, uint8_t chip)
448{
449 if (wait_ms(400, sn65dsi86_bridge_get_plug_in_status(bus, chip)))
450 return;
451
452 printk(BIOS_WARNING, "HPD detection failed, force hpd\n");
453
454 /* Force HPD */
455 i2c_write_field(bus, chip, SN_HPD_DISABLE_REG, HPD_DISABLE, 1, 0);
456}
457
458static void sn65dsi86_bridge_assr_config(uint8_t bus, uint8_t chip, int enable)
459{
460 if (enable)
461 i2c_write_field(bus, chip, SN_ENH_FRAME_REG, VSTREAM_ENABLE, 1, 3);
462 else
463 i2c_write_field(bus, chip, SN_ENH_FRAME_REG, VSTREAM_DISABLE, 1, 3);
464}
465
466static int sn65dsi86_bridge_dp_lane_config(uint8_t bus, uint8_t chip)
467{
468 uint8_t lane_count;
469
470 sn65dsi86_bridge_dpcd_request(bus, chip, DP_MAX_LANE_COUNT, 1, DPCD_READ, &lane_count);
471 lane_count &= DP_LANE_COUNT_MASK;
472 i2c_write_field(bus, chip, SN_SSC_CONFIG_REG, MIN(lane_count, 3), 3, 4);
473
474 return lane_count;
475}
476
477void sn65dsi86_bridge_init(uint8_t bus, uint8_t chip, enum dp_pll_clk_src ref_clk)
478{
479 sn65dsi86_bridge_wait_hpd(bus, chip);
480
481 /* set refclk to 19.2 MHZ */
482 i2c_write_field(bus, chip, SN_DPPLL_SRC_REG, ref_clk, 7, 1);
483}
484
485void sn65dsi86_bridge_configure(uint8_t bus, uint8_t chip,
486 struct edid *edid, uint32_t num_of_lanes,
487 uint32_t dsi_bpp)
488{
489 int dp_lanes;
490
491 /* DSI Lanes config */
492 i2c_write_field(bus, chip, SN_DSI_LANES_REG, (4 - num_of_lanes), 3, 3);
493
494 /* DP Lane config */
495 dp_lanes = sn65dsi86_bridge_dp_lane_config(bus, chip);
496
497 sn65dsi86_bridge_set_dsi_clock_range(bus, chip, edid, num_of_lanes, dsi_bpp);
498
499 sn65dsi86_bridge_set_dp_clock_range(bus, chip, edid, dp_lanes);
500
501 /* Disable vstream */
502 sn65dsi86_bridge_assr_config(bus, chip, 0);
503 sn65dsi86_bridge_link_training(bus, chip);
504 sn65dsi86_bridge_set_bridge_active_timing(bus, chip, edid);
505
506 /* DP BPP config */
507 i2c_writeb(bus, chip, SN_DATA_FORMAT_REG, 0x1);
508
509 /* color bar disabled */
510 i2c_writeb(bus, chip, SN_COLOR_BAR_REG, 0x5);
511
512 /* Enable vstream */
513 sn65dsi86_bridge_assr_config(bus, chip, 1);
514}