1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
5 #include <device/i2c_simple.h>
10 #include <soc/addressmap.h>
11 #include "sn65dsi86bridge.h"
13 #define BRIDGE_GETHIGHERBYTE(x) ((uint8_t)((x & 0xff00) >> 8))
14 #define BRIDGE_GETLOWERBYTE(x) ((uint8_t)(x & 0x00ff))
16 /* fudge factor required to account for 8b/10b encoding */
17 #define DP_CLK_FUDGE_NUM 10
18 #define DP_CLK_FUDGE_DEN 8
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
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
40 #define AUX_CMD_SEND 0x1
41 #define MIN_DSI_CLK_FREQ_MHZ 40
42 #define MAX_DSI_CLK_FREQ_MHZ 750
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,
115 SOT_ERR_TOL_DSI
= 0x0,
118 DSI_CHANNEL_MODE
= 0x3,
119 LEFT_RIGHT_PIXELS
= 0x4,
122 enum vstream_config
{
127 enum aux_cmd_status
{
128 NAT_I2C_FAIL
= 1 << 6,
131 AUX_RPLY_TOUT
= 1 << 3,
142 HBR2_COMPLIANCE_EYE_PATTERN
= 0x6,
143 SYMBOL_ERR_RATE_MEASUREMENT_PATTERN
= 0x7,
144 CUTSOM_PATTERN
= 0x8,
145 FAST_LINK_TRAINING
= 0x9,
146 SEMI_AUTO_LINK_TRAINING
= 0xa,
147 REDRIVER_SEMI_AUTO_LINK_TRAINING
= 0xb,
151 * LUT index corresponds to register value and LUT values corresponds
152 * to dp data rate supported by the bridge in Mbps unit.
154 static const unsigned int sn65dsi86_bridge_dp_rate_lut
[] = {
155 0, 1620, 2160, 2430, 2700, 3240, 4320, 5400
158 static enum cb_err
sn65dsi86_bridge_aux_request(uint8_t bus
,
160 unsigned int target_reg
,
161 unsigned int total_size
,
162 enum aux_request request
,
170 /* Clear old status flags just in case they're left over from a previous transfer. */
171 i2c_writeb(bus
, chip
, SN_AUX_CMD_STATUS_REG
,
172 NAT_I2C_FAIL
| AUX_SHORT
| AUX_DFER
| AUX_RPLY_TOUT
| SEND_INT
);
175 length
= MIN(total_size
, DP_AUX_MAX_PAYLOAD_BYTES
);
176 total_size
-= length
;
178 enum i2c_over_aux cmd
= dp_get_aux_cmd(request
, total_size
);
179 if (i2c_writeb(bus
, chip
, SN_AUX_CMD_REG
, (cmd
<< 4)) ||
180 i2c_writeb(bus
, chip
, SN_AUX_ADDR_19_16_REG
, (target_reg
>> 16) & 0xF) ||
181 i2c_writeb(bus
, chip
, SN_AUX_ADDR_15_8_REG
, (target_reg
>> 8) & 0xFF) ||
182 i2c_writeb(bus
, chip
, SN_AUX_ADDR_7_0_REG
, (target_reg
) & 0xFF) ||
183 i2c_writeb(bus
, chip
, SN_AUX_LENGTH_REG
, length
))
186 if (dp_aux_request_is_write(request
)) {
187 reg
= SN_AUX_WDATA_REG_0
;
188 for (i
= 0; i
< length
; i
++)
189 if (i2c_writeb(bus
, chip
, reg
++, *data
++))
193 if (i2c_writeb(bus
, chip
, SN_AUX_CMD_REG
, AUX_CMD_SEND
| (cmd
<< 4)))
195 if (!wait_ms(100, !i2c_readb(bus
, chip
, SN_AUX_CMD_REG
, &buf
) &&
196 !(buf
& AUX_CMD_SEND
))) {
197 printk(BIOS_ERR
, "AUX_CMD_SEND not acknowledged\n");
200 if (i2c_readb(bus
, chip
, SN_AUX_CMD_STATUS_REG
, &buf
))
202 if (buf
& (NAT_I2C_FAIL
| AUX_SHORT
| AUX_DFER
| AUX_RPLY_TOUT
)) {
203 printk(BIOS_ERR
, "AUX command failed, status = %#x\n", buf
);
207 if (!dp_aux_request_is_write(request
)) {
208 reg
= SN_AUX_RDATA_REG_0
;
209 for (i
= 0; i
< length
; i
++) {
210 if (i2c_readb(bus
, chip
, reg
++, &buf
))
220 enum cb_err
sn65dsi86_bridge_read_edid(uint8_t bus
, uint8_t chip
, struct edid
*out
)
223 u8 edid
[EDID_LENGTH
* 2];
224 int edid_size
= EDID_LENGTH
;
226 uint8_t reg_addr
= 0;
227 err
= sn65dsi86_bridge_aux_request(bus
, chip
, EDID_I2C_ADDR
, 1,
228 I2C_RAW_WRITE
, ®_addr
);
230 err
= sn65dsi86_bridge_aux_request(bus
, chip
, EDID_I2C_ADDR
, EDID_LENGTH
,
231 I2C_RAW_READ_AND_STOP
, edid
);
233 printk(BIOS_ERR
, "Failed to read EDID.\n");
237 if (edid
[EDID_EXTENSION_FLAG
]) {
238 edid_size
+= EDID_LENGTH
;
239 reg_addr
= EDID_LENGTH
;
240 err
= sn65dsi86_bridge_aux_request(bus
, chip
, EDID_I2C_ADDR
, 1,
241 I2C_RAW_WRITE
, ®_addr
);
243 err
= sn65dsi86_bridge_aux_request(bus
, chip
, EDID_I2C_ADDR
,
244 EDID_LENGTH
, I2C_RAW_READ_AND_STOP
, &edid
[EDID_LENGTH
]);
246 printk(BIOS_ERR
, "Failed to read EDID ext block.\n");
251 if (decode_edid(edid
, edid_size
, out
) != EDID_CONFORMANT
) {
252 printk(BIOS_ERR
, "Failed to decode EDID.\n");
259 static void sn65dsi86_bridge_valid_dp_rates(uint8_t bus
, uint8_t chip
, bool rate_valid
[])
261 unsigned int rate_per_200khz
;
265 sn65dsi86_bridge_aux_request(bus
, chip
,
266 DP_BRIDGE_DPCD_REV
, 1, DPCD_READ
, &dpcd_val
);
267 if (dpcd_val
>= DP_BRIDGE_14
) {
268 /* eDP 1.4 devices must provide a custom table */
269 uint16_t sink_rates
[DP_MAX_SUPPORTED_RATES
] = {0};
271 sn65dsi86_bridge_aux_request(bus
, chip
, DP_SUPPORTED_LINK_RATES
,
273 DPCD_READ
, (void *)sink_rates
);
274 for (i
= 0; i
< ARRAY_SIZE(sink_rates
); i
++) {
275 rate_per_200khz
= le16_to_cpu(sink_rates
[i
]);
277 if (!rate_per_200khz
)
281 j
< ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut
);
283 if (sn65dsi86_bridge_dp_rate_lut
[j
] * (MHz
/ KHz
) ==
284 rate_per_200khz
* 200)
285 rate_valid
[j
] = true;
289 for (i
= 0; i
< ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut
); i
++) {
294 printk(BIOS_ERR
, "No matching eDP rates in table; falling back\n");
297 /* On older versions best we can do is use DP_MAX_LINK_RATE */
298 sn65dsi86_bridge_aux_request(bus
, chip
, DP_MAX_LINK_RATE
, 1, DPCD_READ
, &dpcd_val
);
302 printk(BIOS_ERR
, "Unexpected max rate (%#x); assuming 5.4 GHz\n",
311 case DP_LINK_BW_1_62
:
317 static void sn65dsi86_bridge_set_dsi_clock_range(uint8_t bus
, uint8_t chip
,
319 uint32_t num_of_lanes
, uint32_t bpp
)
321 uint64_t pixel_clk_hz
;
322 uint64_t stream_bit_rate_mhz
;
323 uint64_t min_req_dsi_clk
;
325 pixel_clk_hz
= edid
->mode
.pixel_clock
* KHz
;
326 stream_bit_rate_mhz
= (pixel_clk_hz
* bpp
) / MHz
;
328 /* For TI the clock frequencies are half the bit rates */
329 min_req_dsi_clk
= stream_bit_rate_mhz
/ (num_of_lanes
* 2);
331 /* for each increment in val, frequency increases by 5MHz */
332 min_req_dsi_clk
= MAX(MIN_DSI_CLK_FREQ_MHZ
,
333 MIN(MAX_DSI_CLK_FREQ_MHZ
, min_req_dsi_clk
)) / 5;
334 i2c_writeb(bus
, chip
, SN_DSIA_CLK_FREQ_REG
, min_req_dsi_clk
);
337 static void sn65dsi86_bridge_set_dp_clock_range(uint8_t bus
, uint8_t chip
,
338 struct edid
*edid
, uint32_t num_of_lanes
)
340 uint64_t stream_bit_rate_khz
;
341 bool rate_valid
[ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut
)] = { };
342 uint64_t dp_rate_mhz
;
345 stream_bit_rate_khz
= edid
->mode
.pixel_clock
* 18;
347 /* Calculate minimum DP data rate, taking 80% as per DP spec */
348 dp_rate_mhz
= DIV_ROUND_UP(stream_bit_rate_khz
* DP_CLK_FUDGE_NUM
,
349 KHz
* num_of_lanes
* DP_CLK_FUDGE_DEN
);
351 for (i
= 0; i
< ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut
) - 1; i
++)
352 if (sn65dsi86_bridge_dp_rate_lut
[i
] > dp_rate_mhz
)
355 sn65dsi86_bridge_valid_dp_rates(bus
, chip
, rate_valid
);
357 /* Train until we run out of rates */
358 for (dp_rate_idx
= i
;
359 dp_rate_idx
< ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut
);
361 if (rate_valid
[dp_rate_idx
])
364 if (dp_rate_idx
< ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut
))
365 i2c_write_field(bus
, chip
, SN_DATARATE_CONFIG_REG
, dp_rate_idx
, 8, 5);
367 printk(BIOS_ERR
, "valid dp rate not found");
370 static void sn65dsi86_bridge_set_bridge_active_timing(uint8_t bus
,
374 i2c_writeb(bus
, chip
, SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG
,
375 BRIDGE_GETLOWERBYTE(edid
->mode
.ha
));
376 i2c_writeb(bus
, chip
, SN_CHA_ACTIVE_LINE_LENGTH_HIGH_REG
,
377 BRIDGE_GETHIGHERBYTE(edid
->mode
.ha
));
378 i2c_writeb(bus
, chip
, SN_CHA_VERTICAL_DISPLAY_SIZE_LOW_REG
,
379 BRIDGE_GETLOWERBYTE(edid
->mode
.va
));
380 i2c_writeb(bus
, chip
, SN_CHA_VERTICAL_DISPLAY_SIZE_HIGH_REG
,
381 BRIDGE_GETHIGHERBYTE(edid
->mode
.va
));
382 i2c_writeb(bus
, chip
, SN_CHA_HSYNC_PULSE_WIDTH_LOW_REG
,
383 BRIDGE_GETLOWERBYTE(edid
->mode
.hspw
));
384 i2c_writeb(bus
, chip
, SN_CHA_HSYNC_PULSE_WIDTH_HIGH_REG
,
385 BRIDGE_GETHIGHERBYTE(edid
->mode
.hspw
));
386 i2c_writeb(bus
, chip
, SN_CHA_VSYNC_PULSE_WIDTH_LOW_REG
,
387 BRIDGE_GETLOWERBYTE(edid
->mode
.vspw
));
388 i2c_writeb(bus
, chip
, SN_CHA_VSYNC_PULSE_WIDTH_HIGH_REG
,
389 BRIDGE_GETHIGHERBYTE(edid
->mode
.vspw
));
390 i2c_writeb(bus
, chip
, SN_CHA_HORIZONTAL_BACK_PORCH_REG
,
391 edid
->mode
.hbl
- edid
->mode
.hso
- edid
->mode
.hspw
);
392 i2c_writeb(bus
, chip
, SN_CHA_VERTICAL_BACK_PORCH_REG
,
393 edid
->mode
.vbl
- edid
->mode
.vso
- edid
->mode
.vspw
);
394 i2c_writeb(bus
, chip
, SN_CHA_HORIZONTAL_FRONT_PORCH_REG
,
396 i2c_writeb(bus
, chip
, SN_CHA_VERTICAL_FRONT_PORCH_REG
,
400 static void sn65dsi86_bridge_link_training(uint8_t bus
, uint8_t chip
)
404 /* enable pll lock */
405 i2c_writeb(bus
, chip
, SN_PLL_ENABLE_REG
, 0x1);
408 !(i2c_readb(bus
, chip
, SN_DPPLL_SRC_REG
, &buf
)) &&
410 printk(BIOS_ERR
, "PLL lock failure\n");
414 * The SN65DSI86 only supports ASSR Display Authentication method and
415 * this method is enabled by default. An eDP panel must support this
416 * authentication method. We need to enable this method in the eDP panel
417 * at DisplayPort address 0x0010A prior to link training.
420 sn65dsi86_bridge_aux_request(bus
, chip
,
421 DP_BRIDGE_CONFIGURATION_SET
, 1, DPCD_WRITE
, &buf
);
423 int i
; /* Kernel driver suggests to retry this up to 10 times if it fails. */
424 for (i
= 0; i
< 10; i
++) {
425 i2c_writeb(bus
, chip
, SN_ML_TX_MODE_REG
, SEMI_AUTO_LINK_TRAINING
);
427 if (!wait_ms(500, !(i2c_readb(bus
, chip
, SN_ML_TX_MODE_REG
, &buf
)) &&
428 (buf
== NORMAL_MODE
|| buf
== MAIN_LINK_OFF
))) {
429 printk(BIOS_ERR
, "unexpected link training state: %#x\n", buf
);
432 if (buf
== NORMAL_MODE
)
436 printk(BIOS_ERR
, "Link training failed 10 times\n");
439 void sn65dsi86_backlight_enable(uint8_t bus
, uint8_t chip
)
441 uint8_t val
= DP_BACKLIGHT_CONTROL_MODE_DPCD
;
442 sn65dsi86_bridge_aux_request(bus
, chip
, DP_BACKLIGHT_MODE_SET
, 1, DPCD_WRITE
, &val
);
445 sn65dsi86_bridge_aux_request(bus
, chip
, DP_BACKLIGHT_BRIGHTNESS_MSB
, 1,
448 val
= DP_BACKLIGHT_ENABLE
;
449 sn65dsi86_bridge_aux_request(bus
, chip
, DP_DISPLAY_CONTROL_REGISTER
, 1,
453 static void sn65dsi86_bridge_assr_config(uint8_t bus
, uint8_t chip
, int enable
)
456 i2c_write_field(bus
, chip
, SN_ENH_FRAME_REG
, VSTREAM_ENABLE
, 1, 3);
458 i2c_write_field(bus
, chip
, SN_ENH_FRAME_REG
, VSTREAM_DISABLE
, 1, 3);
461 static int sn65dsi86_bridge_dp_lane_config(uint8_t bus
, uint8_t chip
)
465 sn65dsi86_bridge_aux_request(bus
, chip
, DP_MAX_LANE_COUNT
, 1, DPCD_READ
, &lane_count
);
466 lane_count
&= DP_LANE_COUNT_MASK
;
467 i2c_write_field(bus
, chip
, SN_SSC_CONFIG_REG
, MIN(lane_count
, 3), 3, 4);
472 void sn65dsi86_bridge_init(uint8_t bus
, uint8_t chip
, enum dp_pll_clk_src ref_clk
)
475 i2c_write_field(bus
, chip
, SN_HPD_DISABLE_REG
, HPD_DISABLE
, 1, 0);
477 /* set refclk to 19.2 MHZ */
478 i2c_write_field(bus
, chip
, SN_DPPLL_SRC_REG
, ref_clk
, 7, 1);
481 void sn65dsi86_bridge_configure(uint8_t bus
, uint8_t chip
,
482 struct edid
*edid
, uint32_t num_of_lanes
,
487 /* DSI Lanes config */
488 i2c_write_field(bus
, chip
, SN_DSI_LANES_REG
, (4 - num_of_lanes
), 3, 3);
491 dp_lanes
= sn65dsi86_bridge_dp_lane_config(bus
, chip
);
493 sn65dsi86_bridge_set_dsi_clock_range(bus
, chip
, edid
, num_of_lanes
, dsi_bpp
);
495 sn65dsi86_bridge_set_dp_clock_range(bus
, chip
, edid
, dp_lanes
);
497 /* Disable vstream */
498 sn65dsi86_bridge_assr_config(bus
, chip
, 0);
499 sn65dsi86_bridge_link_training(bus
, chip
);
500 sn65dsi86_bridge_set_bridge_active_timing(bus
, chip
, edid
);
503 i2c_writeb(bus
, chip
, SN_DATA_FORMAT_REG
, 0x1);
505 /* color bar disabled */
506 i2c_writeb(bus
, chip
, SN_COLOR_BAR_REG
, 0x5);
509 sn65dsi86_bridge_assr_config(bus
, chip
, 1);