1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <drm/drmP.h>
20#include <drm/drm_atomic_helper.h>
21#include <drm/drm_connector.h>
22#include <drm/drm_crtc.h>
23#include <drm/drm_crtc_helper.h>
24#include <drm/drm_dp_helper.h>
25#include <drm/drm_of.h>
26#include <drm/drm_probe_helper.h>
27
28#include <linux/delay.h>
29#include <linux/device.h>
30#include <linux/module.h>
31#include <linux/mutex.h>
32#include <linux/phy/phy.h>
33#include <linux/phy/phy-zynqmp.h>
34#include <linux/platform_device.h>
35#include <linux/pm_runtime.h>
36#include <linux/uaccess.h>
37
38#include "zynqmp_disp.h"
39#include "zynqmp_dpsub.h"
40
41static uint zynqmp_dp_aux_timeout_ms = 50;
42module_param_named(aux_timeout_ms, zynqmp_dp_aux_timeout_ms, uint, 0444);
43MODULE_PARM_DESC(aux_timeout_ms, "DP aux timeout value in msec (default: 50)");
44
45
46
47
48static uint zynqmp_dp_power_on_delay_ms = 4;
49module_param_named(power_on_delay_ms, zynqmp_dp_power_on_delay_ms, uint, 0444);
50MODULE_PARM_DESC(aux_timeout_ms, "DP power on delay in msec (default: 4)");
51
52
53#define ZYNQMP_DP_TX_LINK_BW_SET 0x0
54#define ZYNQMP_DP_TX_LANE_CNT_SET 0x4
55#define ZYNQMP_DP_TX_ENHANCED_FRAME_EN 0x8
56#define ZYNQMP_DP_TX_TRAINING_PATTERN_SET 0xc
57#define ZYNQMP_DP_TX_SCRAMBLING_DISABLE 0x14
58#define ZYNQMP_DP_TX_DOWNSPREAD_CTL 0x18
59#define ZYNQMP_DP_TX_SW_RESET 0x1c
60#define ZYNQMP_DP_TX_SW_RESET_STREAM1 BIT(0)
61#define ZYNQMP_DP_TX_SW_RESET_STREAM2 BIT(1)
62#define ZYNQMP_DP_TX_SW_RESET_STREAM3 BIT(2)
63#define ZYNQMP_DP_TX_SW_RESET_STREAM4 BIT(3)
64#define ZYNQMP_DP_TX_SW_RESET_AUX BIT(7)
65#define ZYNQMP_DP_TX_SW_RESET_ALL (ZYNQMP_DP_TX_SW_RESET_STREAM1 | \
66 ZYNQMP_DP_TX_SW_RESET_STREAM2 | \
67 ZYNQMP_DP_TX_SW_RESET_STREAM3 | \
68 ZYNQMP_DP_TX_SW_RESET_STREAM4 | \
69 ZYNQMP_DP_TX_SW_RESET_AUX)
70
71
72#define ZYNQMP_DP_TX_ENABLE 0x80
73#define ZYNQMP_DP_TX_ENABLE_MAIN_STREAM 0x84
74#define ZYNQMP_DP_TX_FORCE_SCRAMBLER_RESET 0xc0
75#define ZYNQMP_DP_TX_VERSION 0xf8
76#define ZYNQMP_DP_TX_VERSION_MAJOR_MASK GENMASK(31, 24)
77#define ZYNQMP_DP_TX_VERSION_MAJOR_SHIFT 24
78#define ZYNQMP_DP_TX_VERSION_MINOR_MASK GENMASK(23, 16)
79#define ZYNQMP_DP_TX_VERSION_MINOR_SHIFT 16
80#define ZYNQMP_DP_TX_VERSION_REVISION_MASK GENMASK(15, 12)
81#define ZYNQMP_DP_TX_VERSION_REVISION_SHIFT 12
82#define ZYNQMP_DP_TX_VERSION_PATCH_MASK GENMASK(11, 8)
83#define ZYNQMP_DP_TX_VERSION_PATCH_SHIFT 8
84#define ZYNQMP_DP_TX_VERSION_INTERNAL_MASK GENMASK(7, 0)
85#define ZYNQMP_DP_TX_VERSION_INTERNAL_SHIFT 0
86
87
88#define ZYNQMP_DP_TX_CORE_ID 0xfc
89#define ZYNQMP_DP_TX_CORE_ID_MAJOR_MASK GENMASK(31, 24)
90#define ZYNQMP_DP_TX_CORE_ID_MAJOR_SHIFT 24
91#define ZYNQMP_DP_TX_CORE_ID_MINOR_MASK GENMASK(23, 16)
92#define ZYNQMP_DP_TX_CORE_ID_MINOR_SHIFT 16
93#define ZYNQMP_DP_TX_CORE_ID_REVISION_MASK GENMASK(15, 8)
94#define ZYNQMP_DP_TX_CORE_ID_REVISION_SHIFT 8
95#define ZYNQMP_DP_TX_CORE_ID_DIRECTION GENMASK(1)
96
97
98#define ZYNQMP_DP_TX_AUX_COMMAND 0x100
99#define ZYNQMP_DP_TX_AUX_COMMAND_CMD_SHIFT 8
100#define ZYNQMP_DP_TX_AUX_COMMAND_ADDRESS_ONLY BIT(12)
101#define ZYNQMP_DP_TX_AUX_COMMAND_BYTES_SHIFT 0
102#define ZYNQMP_DP_TX_AUX_WRITE_FIFO 0x104
103#define ZYNQMP_DP_TX_AUX_ADDRESS 0x108
104#define ZYNQMP_DP_TX_CLK_DIVIDER 0x10c
105#define ZYNQMP_DP_TX_CLK_DIVIDER_MHZ 1000000
106#define ZYNQMP_DP_TX_CLK_DIVIDER_AUX_FILTER_SHIFT 8
107#define ZYNQMP_DP_TX_INTR_SIGNAL_STATE 0x130
108#define ZYNQMP_DP_TX_INTR_SIGNAL_STATE_HPD BIT(0)
109#define ZYNQMP_DP_TX_INTR_SIGNAL_STATE_REQUEST BIT(1)
110#define ZYNQMP_DP_TX_INTR_SIGNAL_STATE_REPLY BIT(2)
111#define ZYNQMP_DP_TX_INTR_SIGNAL_STATE_REPLY_TIMEOUT BIT(3)
112#define ZYNQMP_DP_TX_AUX_REPLY_DATA 0x134
113#define ZYNQMP_DP_TX_AUX_REPLY_CODE 0x138
114#define ZYNQMP_DP_TX_AUX_REPLY_CODE_AUX_ACK (0)
115#define ZYNQMP_DP_TX_AUX_REPLY_CODE_AUX_NACK BIT(0)
116#define ZYNQMP_DP_TX_AUX_REPLY_CODE_AUX_DEFER BIT(1)
117#define ZYNQMP_DP_TX_AUX_REPLY_CODE_I2C_ACK (0)
118#define ZYNQMP_DP_TX_AUX_REPLY_CODE_I2C_NACK BIT(2)
119#define ZYNQMP_DP_TX_AUX_REPLY_CODE_I2C_DEFER BIT(3)
120#define ZYNQMP_DP_TX_AUX_REPLY_CNT 0x13c
121#define ZYNQMP_DP_TX_AUX_REPLY_CNT_MASK 0xff
122#define ZYNQMP_DP_TX_INTR_STATUS 0x140
123#define ZYNQMP_DP_TX_INTR_MASK 0x144
124#define ZYNQMP_DP_TX_INTR_HPD_IRQ BIT(0)
125#define ZYNQMP_DP_TX_INTR_HPD_EVENT BIT(1)
126#define ZYNQMP_DP_TX_INTR_REPLY_RECV BIT(2)
127#define ZYNQMP_DP_TX_INTR_REPLY_TIMEOUT BIT(3)
128#define ZYNQMP_DP_TX_INTR_HPD_PULSE BIT(4)
129#define ZYNQMP_DP_TX_INTR_EXT_PKT_TXD BIT(5)
130#define ZYNQMP_DP_TX_INTR_LIV_ABUF_UNDRFLW BIT(12)
131#define ZYNQMP_DP_TX_INTR_VBLANK_START BIT(13)
132#define ZYNQMP_DP_TX_INTR_PIXEL0_MATCH BIT(14)
133#define ZYNQMP_DP_TX_INTR_PIXEL1_MATCH BIT(15)
134#define ZYNQMP_DP_TX_INTR_CHBUF_UNDERFLW_MASK 0x3f0000
135#define ZYNQMP_DP_TX_INTR_CHBUF_OVERFLW_MASK 0xfc00000
136#define ZYNQMP_DP_TX_INTR_CUST_TS_2 BIT(28)
137#define ZYNQMP_DP_TX_INTR_CUST_TS BIT(29)
138#define ZYNQMP_DP_TX_INTR_EXT_VSYNC_TS BIT(30)
139#define ZYNQMP_DP_TX_INTR_VSYNC_TS BIT(31)
140#define ZYNQMP_DP_TX_INTR_ALL (ZYNQMP_DP_TX_INTR_HPD_IRQ | \
141 ZYNQMP_DP_TX_INTR_HPD_EVENT | \
142 ZYNQMP_DP_TX_INTR_REPLY_RECV | \
143 ZYNQMP_DP_TX_INTR_REPLY_TIMEOUT | \
144 ZYNQMP_DP_TX_INTR_HPD_PULSE | \
145 ZYNQMP_DP_TX_INTR_EXT_PKT_TXD | \
146 ZYNQMP_DP_TX_INTR_LIV_ABUF_UNDRFLW | \
147 ZYNQMP_DP_TX_INTR_CHBUF_UNDERFLW_MASK | \
148 ZYNQMP_DP_TX_INTR_CHBUF_OVERFLW_MASK)
149#define ZYNQMP_DP_TX_NO_INTR_ALL (ZYNQMP_DP_TX_INTR_PIXEL0_MATCH | \
150 ZYNQMP_DP_TX_INTR_PIXEL1_MATCH | \
151 ZYNQMP_DP_TX_INTR_CUST_TS_2 | \
152 ZYNQMP_DP_TX_INTR_CUST_TS | \
153 ZYNQMP_DP_TX_INTR_EXT_VSYNC_TS | \
154 ZYNQMP_DP_TX_INTR_VSYNC_TS)
155#define ZYNQMP_DP_TX_REPLY_DATA_CNT 0x148
156#define ZYNQMP_DP_SUB_TX_INTR_STATUS 0x3a0
157#define ZYNQMP_DP_SUB_TX_INTR_MASK 0x3a4
158#define ZYNQMP_DP_SUB_TX_INTR_EN 0x3a8
159#define ZYNQMP_DP_SUB_TX_INTR_DS 0x3ac
160
161
162#define ZYNQMP_DP_TX_MAIN_STREAM_HTOTAL 0x180
163#define ZYNQMP_DP_TX_MAIN_STREAM_VTOTAL 0x184
164#define ZYNQMP_DP_TX_MAIN_STREAM_POLARITY 0x188
165#define ZYNQMP_DP_TX_MAIN_STREAM_POLARITY_HSYNC_SHIFT 0
166#define ZYNQMP_DP_TX_MAIN_STREAM_POLARITY_VSYNC_SHIFT 1
167#define ZYNQMP_DP_TX_MAIN_STREAM_HSWIDTH 0x18c
168#define ZYNQMP_DP_TX_MAIN_STREAM_VSWIDTH 0x190
169#define ZYNQMP_DP_TX_MAIN_STREAM_HRES 0x194
170#define ZYNQMP_DP_TX_MAIN_STREAM_VRES 0x198
171#define ZYNQMP_DP_TX_MAIN_STREAM_HSTART 0x19c
172#define ZYNQMP_DP_TX_MAIN_STREAM_VSTART 0x1a0
173#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0 0x1a4
174#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0_SYNC BIT(0)
175#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0_FORMAT_SHIFT 1
176#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0_DYNAMIC_RANGE BIT(3)
177#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0_YCBCR_COLRIMETRY BIT(4)
178#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0_BPC_SHIFT 5
179#define ZYNQMP_DP_TX_MAIN_STREAM_MISC1 0x1a8
180#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0_INTERLACED_VERT BIT(0)
181#define ZYNQMP_DP_TX_MAIN_STREAM_MISC0_STEREO_VID_SHIFT 1
182#define ZYNQMP_DP_TX_M_VID 0x1ac
183#define ZYNQMP_DP_TX_TRANSFER_UNIT_SIZE 0x1b0
184#define ZYNQMP_DP_TX_DEF_TRANSFER_UNIT_SIZE 64
185#define ZYNQMP_DP_TX_N_VID 0x1b4
186#define ZYNQMP_DP_TX_USER_PIXEL_WIDTH 0x1b8
187#define ZYNQMP_DP_TX_USER_DATA_CNT_PER_LANE 0x1bc
188#define ZYNQMP_DP_TX_MIN_BYTES_PER_TU 0x1c4
189#define ZYNQMP_DP_TX_FRAC_BYTES_PER_TU 0x1c8
190#define ZYNQMP_DP_TX_INIT_WAIT 0x1cc
191
192
193#define ZYNQMP_DP_TX_PHY_CONFIG 0x200
194#define ZYNQMP_DP_TX_PHY_CONFIG_PHY_RESET BIT(0)
195#define ZYNQMP_DP_TX_PHY_CONFIG_GTTX_RESET BIT(1)
196#define ZYNQMP_DP_TX_PHY_CONFIG_PHY_PMA_RESET BIT(8)
197#define ZYNQMP_DP_TX_PHY_CONFIG_PHY_PCS_RESET BIT(9)
198#define ZYNQMP_DP_TX_PHY_CONFIG_ALL_RESET (ZYNQMP_DP_TX_PHY_CONFIG_PHY_RESET | \
199 ZYNQMP_DP_TX_PHY_CONFIG_GTTX_RESET | \
200 ZYNQMP_DP_TX_PHY_CONFIG_PHY_PMA_RESET | \
201 ZYNQMP_DP_TX_PHY_CONFIG_PHY_PCS_RESET)
202#define ZYNQMP_DP_TX_PHY_PREEMPHASIS_LANE_0 0x210
203#define ZYNQMP_DP_TX_PHY_PREEMPHASIS_LANE_1 0x214
204#define ZYNQMP_DP_TX_PHY_PREEMPHASIS_LANE_2 0x218
205#define ZYNQMP_DP_TX_PHY_PREEMPHASIS_LANE_3 0x21c
206#define ZYNQMP_DP_TX_PHY_VOLTAGE_DIFF_LANE_0 0x220
207#define ZYNQMP_DP_TX_PHY_VOLTAGE_DIFF_LANE_1 0x224
208#define ZYNQMP_DP_TX_PHY_VOLTAGE_DIFF_LANE_2 0x228
209#define ZYNQMP_DP_TX_PHY_VOLTAGE_DIFF_LANE_3 0x22c
210#define ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING 0x234
211#define ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING_162 0x1
212#define ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING_270 0x3
213#define ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING_540 0x5
214#define ZYNQMP_DP_TX_PHY_POWER_DOWN 0x238
215#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_0 BIT(0)
216#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_1 BIT(1)
217#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_2 BIT(2)
218#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_3 BIT(3)
219#define ZYNQMP_DP_TX_PHY_POWER_DOWN_ALL 0xf
220#define ZYNQMP_DP_TX_PHY_PRECURSOR_LANE_0 0x23c
221#define ZYNQMP_DP_TX_PHY_PRECURSOR_LANE_1 0x240
222#define ZYNQMP_DP_TX_PHY_PRECURSOR_LANE_2 0x244
223#define ZYNQMP_DP_TX_PHY_PRECURSOR_LANE_3 0x248
224#define ZYNQMP_DP_TX_PHY_POSTCURSOR_LANE_0 0x24c
225#define ZYNQMP_DP_TX_PHY_POSTCURSOR_LANE_1 0x250
226#define ZYNQMP_DP_TX_PHY_POSTCURSOR_LANE_2 0x254
227#define ZYNQMP_DP_TX_PHY_POSTCURSOR_LANE_3 0x258
228#define ZYNQMP_DP_SUB_TX_PHY_PRECURSOR_LANE_0 0x24c
229#define ZYNQMP_DP_SUB_TX_PHY_PRECURSOR_LANE_1 0x250
230#define ZYNQMP_DP_TX_PHY_STATUS 0x280
231#define ZYNQMP_DP_TX_PHY_STATUS_PLL_LOCKED_SHIFT 4
232#define ZYNQMP_DP_TX_PHY_STATUS_FPGA_PLL_LOCKED BIT(6)
233
234
235#define ZYNQMP_DP_TX_AUDIO_CONTROL 0x300
236#define ZYNQMP_DP_TX_AUDIO_CHANNELS 0x304
237#define ZYNQMP_DP_TX_AUDIO_INFO_DATA 0x308
238#define ZYNQMP_DP_TX_AUDIO_M_AUD 0x328
239#define ZYNQMP_DP_TX_AUDIO_N_AUD 0x32c
240#define ZYNQMP_DP_TX_AUDIO_EXT_DATA 0x330
241
242#define ZYNQMP_DP_MISC0_RGB (0)
243#define ZYNQMP_DP_MISC0_YCRCB_422 (5 << 1)
244#define ZYNQMP_DP_MISC0_YCRCB_444 (6 << 1)
245#define ZYNQMP_DP_MISC0_FORMAT_MASK 0xe
246#define ZYNQMP_DP_MISC0_BPC_6 (0 << 5)
247#define ZYNQMP_DP_MISC0_BPC_8 (1 << 5)
248#define ZYNQMP_DP_MISC0_BPC_10 (2 << 5)
249#define ZYNQMP_DP_MISC0_BPC_12 (3 << 5)
250#define ZYNQMP_DP_MISC0_BPC_16 (4 << 5)
251#define ZYNQMP_DP_MISC0_BPC_MASK 0xe0
252#define ZYNQMP_DP_MISC1_Y_ONLY (1 << 7)
253
254#define ZYNQMP_DP_MAX_LANES 2
255#define ZYNQMP_MAX_FREQ 3000000
256
257#define DP_REDUCED_BIT_RATE 162000
258#define DP_HIGH_BIT_RATE 270000
259#define DP_HIGH_BIT_RATE2 540000
260#define DP_MAX_TRAINING_TRIES 5
261#define DP_V1_2 0x12
262
263
264
265
266
267
268struct zynqmp_dp_link_config {
269 int max_rate;
270 u8 max_lanes;
271};
272
273
274
275
276
277
278
279
280struct zynqmp_dp_mode {
281 u8 bw_code;
282 u8 lane_cnt;
283 int pclock;
284 const char *fmt;
285};
286
287
288
289
290
291
292
293
294
295struct zynqmp_dp_config {
296 u8 misc0;
297 u8 misc1;
298 u8 bpp;
299 u8 bpc;
300 u8 num_colors;
301};
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327struct zynqmp_dp {
328 struct drm_encoder encoder;
329 struct drm_connector connector;
330 struct drm_property *sync_prop;
331 struct drm_property *bpc_prop;
332 struct device *dev;
333 struct zynqmp_dpsub *dpsub;
334 struct drm_device *drm;
335 void __iomem *iomem;
336 int irq;
337
338 struct zynqmp_dp_config config;
339 struct drm_dp_aux aux;
340 struct phy *phy[ZYNQMP_DP_MAX_LANES];
341 u8 num_lanes;
342 struct delayed_work hpd_work;
343 enum drm_connector_status status;
344 bool enabled;
345
346 int dpms;
347 u8 dpcd[DP_RECEIVER_CAP_SIZE];
348 struct zynqmp_dp_link_config link_config;
349 struct zynqmp_dp_mode mode;
350 u8 train_set[ZYNQMP_DP_MAX_LANES];
351};
352
353static inline struct zynqmp_dp *encoder_to_dp(struct drm_encoder *encoder)
354{
355 return container_of(encoder, struct zynqmp_dp, encoder);
356}
357
358static inline struct zynqmp_dp *connector_to_dp(struct drm_connector *connector)
359{
360 return container_of(connector, struct zynqmp_dp, connector);
361}
362
363static void zynqmp_dp_write(void __iomem *base, int offset, u32 val)
364{
365 writel(val, base + offset);
366}
367
368static u32 zynqmp_dp_read(void __iomem *base, int offset)
369{
370 return readl(base + offset);
371}
372
373static void zynqmp_dp_clr(void __iomem *base, int offset, u32 clr)
374{
375 zynqmp_dp_write(base, offset, zynqmp_dp_read(base, offset) & ~clr);
376}
377
378static void zynqmp_dp_set(void __iomem *base, int offset, u32 set)
379{
380 zynqmp_dp_write(base, offset, zynqmp_dp_read(base, offset) | set);
381}
382
383
384
385
386
387
388
389
390
391
392
393
394
395static void zynqmp_dp_update_bpp(struct zynqmp_dp *dp)
396{
397 struct zynqmp_dp_config *config = &dp->config;
398
399 config->bpp = dp->config.bpc * dp->config.num_colors;
400}
401
402
403
404
405
406
407
408
409
410
411int zynqmp_dp_set_color(struct zynqmp_dp *dp, const char *color)
412{
413 struct zynqmp_dp_config *config = &dp->config;
414
415 config->misc0 &= ~ZYNQMP_DP_MISC0_FORMAT_MASK;
416 config->misc1 &= ~ZYNQMP_DP_MISC1_Y_ONLY;
417 if (strcmp(color, "rgb") == 0) {
418 config->misc0 |= ZYNQMP_DP_MISC0_RGB;
419 config->num_colors = 3;
420 } else if (strcmp(color, "ycrcb422") == 0) {
421 config->misc0 |= ZYNQMP_DP_MISC0_YCRCB_422;
422 config->num_colors = 2;
423 } else if (strcmp(color, "ycrcb444") == 0) {
424 config->misc0 |= ZYNQMP_DP_MISC0_YCRCB_444;
425 config->num_colors = 3;
426 } else if (strcmp(color, "yonly") == 0) {
427 config->misc1 |= ZYNQMP_DP_MISC1_Y_ONLY;
428 config->num_colors = 1;
429 } else {
430 dev_err(dp->dev, "Invalid colormetry in DT\n");
431 return -EINVAL;
432 }
433 zynqmp_dp_update_bpp(dp);
434
435 return 0;
436}
437
438
439
440
441
442
443
444void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp)
445{
446 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_EN,
447 ZYNQMP_DP_TX_INTR_VBLANK_START);
448}
449
450
451
452
453
454
455
456void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp)
457{
458 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_DS,
459 ZYNQMP_DP_TX_INTR_VBLANK_START);
460}
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476static int zynqmp_dp_init_phy(struct zynqmp_dp *dp)
477{
478 unsigned int i;
479 int ret;
480
481 for (i = 0; i < dp->num_lanes; i++) {
482 ret = phy_init(dp->phy[i]);
483 if (ret) {
484 dev_err(dp->dev, "failed to init phy lane %d\n", i);
485 return ret;
486 }
487 }
488
489 if (dp->phy[0]) {
490 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_DS,
491 ZYNQMP_DP_TX_INTR_ALL);
492 zynqmp_dp_clr(dp->iomem, ZYNQMP_DP_TX_PHY_CONFIG,
493 ZYNQMP_DP_TX_PHY_CONFIG_ALL_RESET);
494 ret = xpsgtr_wait_pll_lock(dp->phy[0]);
495 if (ret) {
496 dev_err(dp->dev, "failed to lock pll\n");
497 return ret;
498 }
499 }
500
501 return 0;
502}
503
504
505
506
507
508
509
510static void zynqmp_dp_exit_phy(struct zynqmp_dp *dp)
511{
512 unsigned int i;
513 int ret;
514
515 for (i = 0; i < dp->num_lanes; i++) {
516 ret = phy_exit(dp->phy[i]);
517 if (ret)
518 dev_err(dp->dev, "failed to exit phy(%d) %d\n", i, ret);
519 }
520}
521
522
523
524
525
526
527
528
529
530
531static int zynqmp_dp_phy_ready(struct zynqmp_dp *dp)
532{
533 u32 i, reg, ready;
534
535 ready = (1 << dp->num_lanes) - 1;
536
537
538 for (i = 0; ; i++) {
539 reg = zynqmp_dp_read(dp->iomem, ZYNQMP_DP_TX_PHY_STATUS);
540 if ((reg & ready) == ready)
541 return 0;
542
543 if (i == 100) {
544 dev_err(dp->dev, "PHY isn't ready\n");
545 return -ENODEV;
546 }
547
548 usleep_range(1000, 1100);
549 }
550
551 return 0;
552}
553
554
555
556
557
558
559
560
561
562
563void zynqmp_dp_pm_resume(struct zynqmp_dp *dp)
564{
565 zynqmp_dp_init_phy(dp);
566}
567
568
569
570
571
572
573void zynqmp_dp_pm_suspend(struct zynqmp_dp *dp)
574{
575 zynqmp_dp_exit_phy(dp);
576}
577
578
579
580
581
582
583
584
585
586
587
588
589static inline int zynqmp_dp_max_rate(int link_rate, u8 lane_num, u8 bpp)
590{
591 return link_rate * lane_num * 8 / bpp;
592}
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607static int zynqmp_dp_mode_configure(struct zynqmp_dp *dp, int pclock,
608 u8 current_bw)
609{
610 int max_rate = dp->link_config.max_rate;
611 u8 bws[3] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 };
612 u8 max_lanes = dp->link_config.max_lanes;
613 u8 max_link_rate_code = drm_dp_link_rate_to_bw_code(max_rate);
614 u8 bpp = dp->config.bpp;
615 u8 lane_cnt;
616 s8 i;
617
618 if (current_bw == DP_LINK_BW_1_62) {
619 dev_err(dp->dev, "can't downshift. already lowest link rate\n");
620 return -EINVAL;
621 }
622
623 for (i = ARRAY_SIZE(bws) - 1; i >= 0; i--) {
624 if (current_bw && bws[i] >= current_bw)
625 continue;
626
627 if (bws[i] <= max_link_rate_code)
628 break;
629 }
630
631 for (lane_cnt = 1; lane_cnt <= max_lanes; lane_cnt <<= 1) {
632 int bw;
633 u32 rate;
634
635 bw = drm_dp_bw_code_to_link_rate(bws[i]);
636 rate = zynqmp_dp_max_rate(bw, lane_cnt, bpp);
637 if (pclock <= rate) {
638 dp->mode.bw_code = bws[i];
639 dp->mode.lane_cnt = lane_cnt;
640 dp->mode.pclock = pclock;
641 return dp->mode.bw_code;
642 }
643 }
644
645 dev_err(dp->dev, "failed to configure link values\n");
646
647 return -EINVAL;
648}
649
650
651
652
653
654
655static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp,
656 u8 link_status[DP_LINK_STATUS_SIZE])
657{
658 u8 *train_set = dp->train_set;
659 u8 voltage = 0, preemphasis = 0;
660 u8 i;
661
662 for (i = 0; i < dp->mode.lane_cnt; i++) {
663 u8 v = drm_dp_get_adjust_request_voltage(link_status, i);
664 u8 p = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
665
666 if (v > voltage)
667 voltage = v;
668
669 if (p > preemphasis)
670 preemphasis = p;
671 }
672
673 if (voltage >= DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
674 voltage |= DP_TRAIN_MAX_SWING_REACHED;
675
676 if (preemphasis >= DP_TRAIN_PRE_EMPH_LEVEL_2)
677 preemphasis |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
678
679 for (i = 0; i < dp->mode.lane_cnt; i++)
680 train_set[i] = voltage | preemphasis;
681}
682
683
684
685
686
687
688
689
690
691
692
693static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp)
694{
695 u8 *train_set = dp->train_set;
696 u8 i, v_level, p_level;
697 int ret;
698
699 ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, train_set,
700 dp->mode.lane_cnt);
701 if (ret < 0)
702 return ret;
703
704 for (i = 0; i < dp->mode.lane_cnt; i++) {
705 u32 reg = ZYNQMP_DP_SUB_TX_PHY_PRECURSOR_LANE_0 + i * 4;
706
707 v_level = (train_set[i] & DP_TRAIN_VOLTAGE_SWING_MASK) >>
708 DP_TRAIN_VOLTAGE_SWING_SHIFT;
709 p_level = (train_set[i] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
710 DP_TRAIN_PRE_EMPHASIS_SHIFT;
711
712 xpsgtr_margining_factor(dp->phy[i], p_level, v_level);
713 xpsgtr_override_deemph(dp->phy[i], p_level, v_level);
714 zynqmp_dp_write(dp->iomem, reg, 0x2);
715 }
716
717 return 0;
718}
719
720
721
722
723
724
725
726
727static int zynqmp_dp_link_train_cr(struct zynqmp_dp *dp)
728{
729 u8 link_status[DP_LINK_STATUS_SIZE];
730 u8 lane_cnt = dp->mode.lane_cnt;
731 u8 vs = 0, tries = 0;
732 u16 max_tries, i;
733 bool cr_done;
734 int ret;
735
736 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_TRAINING_PATTERN_SET,
737 DP_TRAINING_PATTERN_1);
738 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
739 DP_TRAINING_PATTERN_1 |
740 DP_LINK_SCRAMBLING_DISABLE);
741 if (ret < 0)
742 return ret;
743
744
745
746
747
748 for (max_tries = 0; max_tries < 512; max_tries++) {
749 ret = zynqmp_dp_update_vs_emph(dp);
750 if (ret)
751 return ret;
752
753 drm_dp_link_train_clock_recovery_delay(dp->dpcd);
754 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status);
755 if (ret < 0)
756 return ret;
757
758 cr_done = drm_dp_clock_recovery_ok(link_status, lane_cnt);
759 if (cr_done)
760 break;
761
762 for (i = 0; i < lane_cnt; i++)
763 if (!(dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED))
764 break;
765 if (i == lane_cnt)
766 break;
767
768 if ((dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == vs)
769 tries++;
770 else
771 tries = 0;
772
773 if (tries == DP_MAX_TRAINING_TRIES)
774 break;
775
776 vs = dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
777 zynqmp_dp_adjust_train(dp, link_status);
778 }
779
780 if (!cr_done)
781 return -EIO;
782
783 return 0;
784}
785
786
787
788
789
790
791
792
793static int zynqmp_dp_link_train_ce(struct zynqmp_dp *dp)
794{
795 u8 link_status[DP_LINK_STATUS_SIZE];
796 u8 lane_cnt = dp->mode.lane_cnt;
797 u32 pat, tries;
798 int ret;
799 bool ce_done;
800
801 if (dp->dpcd[DP_DPCD_REV] >= DP_V1_2 &&
802 dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED)
803 pat = DP_TRAINING_PATTERN_3;
804 else
805 pat = DP_TRAINING_PATTERN_2;
806
807 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_TRAINING_PATTERN_SET, pat);
808 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
809 pat | DP_LINK_SCRAMBLING_DISABLE);
810 if (ret < 0)
811 return ret;
812
813 for (tries = 0; tries < DP_MAX_TRAINING_TRIES; tries++) {
814 ret = zynqmp_dp_update_vs_emph(dp);
815 if (ret)
816 return ret;
817
818 drm_dp_link_train_channel_eq_delay(dp->dpcd);
819 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status);
820 if (ret < 0)
821 return ret;
822
823 ce_done = drm_dp_channel_eq_ok(link_status, lane_cnt);
824 if (ce_done)
825 break;
826
827 zynqmp_dp_adjust_train(dp, link_status);
828 }
829
830 if (!ce_done)
831 return -EIO;
832
833 return 0;
834}
835
836
837
838
839
840
841
842static int zynqmp_dp_train(struct zynqmp_dp *dp)
843{
844 u32 reg;
845 u8 bw_code = dp->mode.bw_code;
846 u8 lane_cnt = dp->mode.lane_cnt;
847 u8 aux_lane_cnt = lane_cnt;
848 bool enhanced;
849 int ret;
850
851 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_LANE_CNT_SET, lane_cnt);
852 enhanced = drm_dp_enhanced_frame_cap(dp->dpcd);
853 if (enhanced) {
854 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_ENHANCED_FRAME_EN, 1);
855 aux_lane_cnt |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
856 }
857
858 if (dp->dpcd[3] & 0x1) {
859 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_DOWNSPREAD_CTL, 1);
860 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL,
861 DP_SPREAD_AMP_0_5);
862 } else {
863 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_DOWNSPREAD_CTL, 0);
864 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, 0);
865 }
866
867 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, aux_lane_cnt);
868 if (ret < 0) {
869 dev_err(dp->dev, "failed to set lane count\n");
870 return ret;
871 }
872
873 ret = drm_dp_dpcd_writeb(&dp->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
874 DP_SET_ANSI_8B10B);
875 if (ret < 0) {
876 dev_err(dp->dev, "failed to set ANSI 8B/10B encoding\n");
877 return ret;
878 }
879
880 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LINK_BW_SET, bw_code);
881 if (ret < 0) {
882 dev_err(dp->dev, "failed to set DP bandwidth\n");
883 return ret;
884 }
885
886 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_LINK_BW_SET, bw_code);
887 switch (bw_code) {
888 case DP_LINK_BW_1_62:
889 reg = ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING_162;
890 break;
891 case DP_LINK_BW_2_7:
892 reg = ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING_270;
893 break;
894 case DP_LINK_BW_5_4:
895 default:
896 reg = ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING_540;
897 break;
898 }
899
900 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_PHY_CLOCK_FEEDBACK_SETTING,
901 reg);
902 ret = zynqmp_dp_phy_ready(dp);
903 if (ret < 0)
904 return ret;
905
906 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_SCRAMBLING_DISABLE, 1);
907 memset(dp->train_set, 0, 4);
908 ret = zynqmp_dp_link_train_cr(dp);
909 if (ret)
910 return ret;
911
912 ret = zynqmp_dp_link_train_ce(dp);
913 if (ret)
914 return ret;
915
916 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
917 DP_TRAINING_PATTERN_DISABLE);
918 if (ret < 0) {
919 dev_err(dp->dev, "failed to disable training pattern\n");
920 return ret;
921 }
922 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_TRAINING_PATTERN_SET,
923 DP_TRAINING_PATTERN_DISABLE);
924
925 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_SCRAMBLING_DISABLE, 0);
926
927 return 0;
928}
929
930
931
932
933
934
935
936static void zynqmp_dp_train_loop(struct zynqmp_dp *dp)
937{
938 struct zynqmp_dp_mode *mode = &dp->mode;
939 u8 bw = mode->bw_code;
940 int ret;
941
942 do {
943 if (dp->status == connector_status_disconnected ||
944 !dp->enabled)
945 return;
946
947 ret = zynqmp_dp_train(dp);
948 if (!ret)
949 return;
950
951 ret = zynqmp_dp_mode_configure(dp, mode->pclock, bw);
952 if (ret < 0)
953 goto err_out;
954
955 bw = ret;
956 } while (bw >= DP_LINK_BW_1_62);
957
958err_out:
959 dev_err(dp->dev, "failed to train the DP link\n");
960}
961
962
963
964
965
966#define AUX_READ_BIT 0x1
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr,
991 u8 *buf, u8 bytes, u8 *reply)
992{
993 bool is_read = (cmd & AUX_READ_BIT) ? true : false;
994 void __iomem *iomem = dp->iomem;
995 u32 reg, i;
996
997 reg = zynqmp_dp_read(iomem, ZYNQMP_DP_TX_INTR_SIGNAL_STATE);
998 if (reg & ZYNQMP_DP_TX_INTR_SIGNAL_STATE_REQUEST)
999 return -EBUSY;
1000
1001 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUX_ADDRESS, addr);
1002 if (!is_read)
1003 for (i = 0; i < bytes; i++)
1004 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUX_WRITE_FIFO,
1005 buf[i]);
1006
1007 reg = cmd << ZYNQMP_DP_TX_AUX_COMMAND_CMD_SHIFT;
1008 if (!buf || !bytes)
1009 reg |= ZYNQMP_DP_TX_AUX_COMMAND_ADDRESS_ONLY;
1010 else
1011 reg |= (bytes - 1) << ZYNQMP_DP_TX_AUX_COMMAND_BYTES_SHIFT;
1012 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUX_COMMAND, reg);
1013
1014
1015 for (i = 0; ; i++) {
1016 reg = zynqmp_dp_read(iomem, ZYNQMP_DP_TX_INTR_SIGNAL_STATE);
1017 if (reg & ZYNQMP_DP_TX_INTR_SIGNAL_STATE_REPLY)
1018 break;
1019
1020 if (reg & ZYNQMP_DP_TX_INTR_SIGNAL_STATE_REPLY_TIMEOUT ||
1021 i == 2)
1022 return -ETIMEDOUT;
1023
1024 usleep_range(1000, 1100);
1025 }
1026
1027 reg = zynqmp_dp_read(iomem, ZYNQMP_DP_TX_AUX_REPLY_CODE);
1028 if (reply)
1029 *reply = reg;
1030
1031 if (is_read &&
1032 (reg == ZYNQMP_DP_TX_AUX_REPLY_CODE_AUX_ACK ||
1033 reg == ZYNQMP_DP_TX_AUX_REPLY_CODE_I2C_ACK)) {
1034 reg = zynqmp_dp_read(iomem, ZYNQMP_DP_TX_REPLY_DATA_CNT);
1035 if ((reg & ZYNQMP_DP_TX_AUX_REPLY_CNT_MASK) != bytes)
1036 return -EIO;
1037
1038 for (i = 0; i < bytes; i++) {
1039 buf[i] = zynqmp_dp_read(iomem,
1040 ZYNQMP_DP_TX_AUX_REPLY_DATA);
1041 }
1042 }
1043
1044 return 0;
1045}
1046
1047static ssize_t
1048zynqmp_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
1049{
1050 struct zynqmp_dp *dp = container_of(aux, struct zynqmp_dp, aux);
1051 int ret;
1052 unsigned int i, iter;
1053
1054
1055 iter = zynqmp_dp_aux_timeout_ms * 1000 / 400;
1056 iter = iter ? iter : 1;
1057
1058 for (i = 0; i < iter; i++) {
1059 ret = zynqmp_dp_aux_cmd_submit(dp, msg->request, msg->address,
1060 msg->buffer, msg->size,
1061 &msg->reply);
1062 if (!ret) {
1063 dev_dbg(dp->dev, "aux %d retries\n", i);
1064 return msg->size;
1065 }
1066
1067 if (dp->status == connector_status_disconnected) {
1068 dev_dbg(dp->dev, "no connected aux device\n");
1069 return -ENODEV;
1070 }
1071
1072 usleep_range(400, 500);
1073 }
1074
1075 dev_dbg(dp->dev, "failed to do aux transfer (%d)\n", ret);
1076
1077 return ret;
1078}
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090static int zynqmp_dp_init_aux(struct zynqmp_dp *dp)
1091{
1092 unsigned int rate;
1093 u32 reg, w;
1094
1095 rate = zynqmp_disp_get_apb_clk_rate(dp->dpsub->disp);
1096 if (rate < ZYNQMP_DP_TX_CLK_DIVIDER_MHZ) {
1097 dev_err(dp->dev, "aclk should be higher than 1MHz\n");
1098 return -EINVAL;
1099 }
1100
1101
1102 for (w = 8; w <= 48; w += 8) {
1103
1104 if (w >= (4 * rate / 10000000) &&
1105 w <= (6 * rate / 10000000))
1106 break;
1107 }
1108
1109 if (w > 48) {
1110 dev_err(dp->dev, "aclk frequency too high\n");
1111 return -EINVAL;
1112 }
1113 reg = w << ZYNQMP_DP_TX_CLK_DIVIDER_AUX_FILTER_SHIFT;
1114 reg |= rate / ZYNQMP_DP_TX_CLK_DIVIDER_MHZ;
1115 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_CLK_DIVIDER, reg);
1116 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_EN,
1117 ZYNQMP_DP_TX_INTR_ALL);
1118 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_DS,
1119 ZYNQMP_DP_TX_NO_INTR_ALL);
1120 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_ENABLE, 1);
1121
1122 return 0;
1123}
1124
1125
1126
1127
1128
1129
1130
1131
1132static void zynqmp_dp_exit_aux(struct zynqmp_dp *dp)
1133{
1134 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_ENABLE, 0);
1135 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_DS, 0xffffffff);
1136}
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149static void zynqmp_dp_update_misc(struct zynqmp_dp *dp)
1150{
1151 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_MAIN_STREAM_MISC0,
1152 dp->config.misc0);
1153 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_MAIN_STREAM_MISC1,
1154 dp->config.misc1);
1155}
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165static void zynqmp_dp_set_sync_mode(struct zynqmp_dp *dp, bool mode)
1166{
1167 struct zynqmp_dp_config *config = &dp->config;
1168
1169 if (mode)
1170 config->misc0 |= ZYNQMP_DP_TX_MAIN_STREAM_MISC0_SYNC;
1171 else
1172 config->misc0 &= ~ZYNQMP_DP_TX_MAIN_STREAM_MISC0_SYNC;
1173}
1174
1175
1176
1177
1178
1179
1180
1181static bool zynqmp_dp_get_sync_mode(struct zynqmp_dp *dp)
1182{
1183 struct zynqmp_dp_config *config = &dp->config;
1184
1185 return !!(config->misc0 & ZYNQMP_DP_TX_MAIN_STREAM_MISC0_SYNC);
1186}
1187
1188
1189
1190
1191
1192
1193
1194
1195static u8 zynqmp_dp_set_bpc(struct zynqmp_dp *dp, u8 bpc)
1196{
1197 struct zynqmp_dp_config *config = &dp->config;
1198 u8 ret = 0;
1199
1200 if (dp->connector.display_info.bpc &&
1201 dp->connector.display_info.bpc != bpc) {
1202 dev_err(dp->dev, "requested bpc (%u) != display info (%u)\n",
1203 bpc, dp->connector.display_info.bpc);
1204 bpc = dp->connector.display_info.bpc;
1205 }
1206
1207 config->misc0 &= ~ZYNQMP_DP_MISC0_BPC_MASK;
1208 switch (bpc) {
1209 case 6:
1210 config->misc0 |= ZYNQMP_DP_MISC0_BPC_6;
1211 break;
1212 case 8:
1213 config->misc0 |= ZYNQMP_DP_MISC0_BPC_8;
1214 break;
1215 case 10:
1216 config->misc0 |= ZYNQMP_DP_MISC0_BPC_10;
1217 break;
1218 case 12:
1219 config->misc0 |= ZYNQMP_DP_MISC0_BPC_12;
1220 break;
1221 case 16:
1222 config->misc0 |= ZYNQMP_DP_MISC0_BPC_16;
1223 break;
1224 default:
1225 dev_err(dp->dev, "Not supported bpc (%u). fall back to 8bpc\n",
1226 bpc);
1227 config->misc0 |= ZYNQMP_DP_MISC0_BPC_8;
1228 ret = 8;
1229 break;
1230 }
1231 config->bpc = bpc;
1232 zynqmp_dp_update_bpp(dp);
1233
1234 return ret;
1235}
1236
1237
1238
1239
1240
1241
1242
1243static u8 zynqmp_dp_get_bpc(struct zynqmp_dp *dp)
1244{
1245 return dp->config.bpc;
1246}
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256static void
1257zynqmp_dp_encoder_mode_set_transfer_unit(struct zynqmp_dp *dp,
1258 struct drm_display_mode *mode)
1259{
1260 u32 tu = ZYNQMP_DP_TX_DEF_TRANSFER_UNIT_SIZE;
1261 u32 bw, vid_kbytes, avg_bytes_per_tu, init_wait;
1262
1263
1264 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_TRANSFER_UNIT_SIZE, tu);
1265
1266 vid_kbytes = mode->clock * (dp->config.bpp / 8);
1267 bw = drm_dp_bw_code_to_link_rate(dp->mode.bw_code);
1268 avg_bytes_per_tu = vid_kbytes * tu / (dp->mode.lane_cnt * bw / 1000);
1269 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_MIN_BYTES_PER_TU,
1270 avg_bytes_per_tu / 1000);
1271 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_FRAC_BYTES_PER_TU,
1272 avg_bytes_per_tu % 1000);
1273
1274
1275 if (tu < (avg_bytes_per_tu / 1000))
1276 init_wait = 0;
1277 else if ((avg_bytes_per_tu / 1000) <= 4)
1278 init_wait = tu;
1279 else
1280 init_wait = tu - avg_bytes_per_tu / 1000;
1281
1282 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_INIT_WAIT, init_wait);
1283}
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
1294 struct drm_display_mode *mode)
1295{
1296 void __iomem *iomem = dp->iomem;
1297 u8 lane_cnt = dp->mode.lane_cnt;
1298 u32 reg, wpl;
1299 unsigned int rate;
1300
1301 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_HTOTAL, mode->htotal);
1302 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_VTOTAL, mode->vtotal);
1303 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_POLARITY,
1304 (!!(mode->flags & DRM_MODE_FLAG_PVSYNC) <<
1305 ZYNQMP_DP_TX_MAIN_STREAM_POLARITY_VSYNC_SHIFT) |
1306 (!!(mode->flags & DRM_MODE_FLAG_PHSYNC) <<
1307 ZYNQMP_DP_TX_MAIN_STREAM_POLARITY_HSYNC_SHIFT));
1308 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_HSWIDTH,
1309 mode->hsync_end - mode->hsync_start);
1310 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_VSWIDTH,
1311 mode->vsync_end - mode->vsync_start);
1312 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_HRES, mode->hdisplay);
1313 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_VRES, mode->vdisplay);
1314 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_HSTART,
1315 mode->htotal - mode->hsync_start);
1316 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_MAIN_STREAM_VSTART,
1317 mode->vtotal - mode->vsync_start);
1318
1319
1320 if (dp->config.misc0 & ZYNQMP_DP_TX_MAIN_STREAM_MISC0_SYNC) {
1321 reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code);
1322 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_N_VID, reg);
1323 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_M_VID, mode->clock);
1324 rate = zynqmp_disp_get_aud_clk_rate(dp->dpsub->disp);
1325 if (rate) {
1326 dev_dbg(dp->dev, "Audio rate: %d\n", rate / 512);
1327 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUDIO_N_AUD, reg);
1328 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUDIO_M_AUD,
1329 rate / 1000);
1330 }
1331 }
1332
1333
1334 if (zynqmp_disp_aud_enabled(dp->dpsub->disp))
1335 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUDIO_CHANNELS, 1);
1336
1337 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_USER_PIXEL_WIDTH, 1);
1338
1339
1340 wpl = (mode->hdisplay * dp->config.bpp + 15) / 16;
1341 reg = wpl + wpl % lane_cnt - lane_cnt;
1342 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_USER_DATA_CNT_PER_LANE, reg);
1343}
1344
1345
1346
1347
1348
1349static enum drm_connector_status
1350zynqmp_dp_connector_detect(struct drm_connector *connector, bool force)
1351{
1352 struct zynqmp_dp *dp = connector_to_dp(connector);
1353 struct zynqmp_dp_link_config *link_config = &dp->link_config;
1354 u32 state, i;
1355 int ret;
1356
1357
1358
1359
1360
1361 for (i = 0; i < 10; i++) {
1362 state = zynqmp_dp_read(dp->iomem,
1363 ZYNQMP_DP_TX_INTR_SIGNAL_STATE);
1364 if (state & ZYNQMP_DP_TX_INTR_SIGNAL_STATE_HPD)
1365 break;
1366 msleep(100);
1367 }
1368
1369 if (state & ZYNQMP_DP_TX_INTR_SIGNAL_STATE_HPD) {
1370 dp->status = connector_status_connected;
1371 ret = drm_dp_dpcd_read(&dp->aux, 0x0, dp->dpcd,
1372 sizeof(dp->dpcd));
1373 if (ret < 0) {
1374 dev_dbg(dp->dev, "DPCD read first try fails");
1375 ret = drm_dp_dpcd_read(&dp->aux, 0x0, dp->dpcd,
1376 sizeof(dp->dpcd));
1377 if (ret < 0) {
1378 dev_dbg(dp->dev, "DPCD read retry fails");
1379 goto disconnected;
1380 }
1381 }
1382
1383 link_config->max_rate = min_t(int,
1384 drm_dp_max_link_rate(dp->dpcd),
1385 DP_HIGH_BIT_RATE2);
1386 link_config->max_lanes = min_t(u8,
1387 drm_dp_max_lane_count(dp->dpcd),
1388 dp->num_lanes);
1389
1390 return connector_status_connected;
1391 }
1392
1393disconnected:
1394 dp->status = connector_status_disconnected;
1395 return connector_status_disconnected;
1396}
1397
1398static int zynqmp_dp_connector_get_modes(struct drm_connector *connector)
1399{
1400 struct zynqmp_dp *dp = connector_to_dp(connector);
1401 struct edid *edid;
1402 int ret;
1403
1404 edid = drm_get_edid(connector, &dp->aux.ddc);
1405 if (!edid)
1406 return 0;
1407
1408 drm_connector_update_edid_property(connector, edid);
1409 ret = drm_add_edid_modes(connector, edid);
1410 kfree(edid);
1411
1412 return ret;
1413}
1414
1415static struct drm_encoder *
1416zynqmp_dp_connector_best_encoder(struct drm_connector *connector)
1417{
1418 struct zynqmp_dp *dp = connector_to_dp(connector);
1419
1420 return &dp->encoder;
1421}
1422
1423static int zynqmp_dp_connector_mode_valid(struct drm_connector *connector,
1424 struct drm_display_mode *mode)
1425{
1426 struct zynqmp_dp *dp = connector_to_dp(connector);
1427 u8 max_lanes = dp->link_config.max_lanes;
1428 u8 bpp = dp->config.bpp;
1429 int max_rate = dp->link_config.max_rate;
1430 int rate;
1431
1432 if (mode->clock > ZYNQMP_MAX_FREQ) {
1433 dev_dbg(dp->dev, "filtered the mode, %s,for high pixel rate\n",
1434 mode->name);
1435 drm_mode_debug_printmodeline(mode);
1436 return MODE_CLOCK_HIGH;
1437 }
1438
1439
1440 rate = zynqmp_dp_max_rate(max_rate, max_lanes, bpp);
1441 if (mode->clock > rate) {
1442 dev_dbg(dp->dev, "filtered the mode, %s,for high pixel rate\n",
1443 mode->name);
1444 drm_mode_debug_printmodeline(mode);
1445 return MODE_CLOCK_HIGH;
1446 }
1447
1448 return MODE_OK;
1449}
1450
1451static void zynqmp_dp_connector_destroy(struct drm_connector *connector)
1452{
1453 drm_connector_unregister(connector);
1454 drm_connector_cleanup(connector);
1455}
1456
1457static int
1458zynqmp_dp_connector_atomic_set_property(struct drm_connector *connector,
1459 struct drm_connector_state *state,
1460 struct drm_property *property,
1461 uint64_t val)
1462{
1463 struct zynqmp_dp *dp = connector_to_dp(connector);
1464 int ret;
1465
1466 if (property == dp->sync_prop) {
1467 zynqmp_dp_set_sync_mode(dp, val);
1468 } else if (property == dp->bpc_prop) {
1469 u8 bpc;
1470
1471 bpc = zynqmp_dp_set_bpc(dp, val);
1472 if (bpc) {
1473 drm_object_property_set_value(&connector->base,
1474 property, bpc);
1475 ret = -EINVAL;
1476 }
1477 } else {
1478 return -EINVAL;
1479 }
1480
1481 return 0;
1482}
1483
1484static int
1485zynqmp_dp_connector_atomic_get_property(struct drm_connector *connector,
1486 const struct drm_connector_state *state,
1487 struct drm_property *property,
1488 uint64_t *val)
1489{
1490 struct zynqmp_dp *dp = connector_to_dp(connector);
1491
1492 if (property == dp->sync_prop)
1493 *val = zynqmp_dp_get_sync_mode(dp);
1494 else if (property == dp->bpc_prop)
1495 *val = zynqmp_dp_get_bpc(dp);
1496 else
1497 return -EINVAL;
1498
1499 return 0;
1500}
1501
1502static const struct drm_connector_funcs zynqmp_dp_connector_funcs = {
1503 .detect = zynqmp_dp_connector_detect,
1504 .fill_modes = drm_helper_probe_single_connector_modes,
1505 .destroy = zynqmp_dp_connector_destroy,
1506 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1507 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1508 .reset = drm_atomic_helper_connector_reset,
1509 .atomic_set_property = zynqmp_dp_connector_atomic_set_property,
1510 .atomic_get_property = zynqmp_dp_connector_atomic_get_property,
1511};
1512
1513static struct drm_connector_helper_funcs zynqmp_dp_connector_helper_funcs = {
1514 .get_modes = zynqmp_dp_connector_get_modes,
1515 .best_encoder = zynqmp_dp_connector_best_encoder,
1516 .mode_valid = zynqmp_dp_connector_mode_valid,
1517};
1518
1519
1520
1521
1522
1523static void zynqmp_dp_encoder_enable(struct drm_encoder *encoder)
1524{
1525 struct zynqmp_dp *dp = encoder_to_dp(encoder);
1526 void __iomem *iomem = dp->iomem;
1527 unsigned int i;
1528 int ret = 0;
1529
1530 pm_runtime_get_sync(dp->dev);
1531 dp->enabled = true;
1532 zynqmp_dp_init_aux(dp);
1533 zynqmp_dp_update_misc(dp);
1534 if (zynqmp_disp_aud_enabled(dp->dpsub->disp))
1535 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUDIO_CONTROL, 1);
1536 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_PHY_POWER_DOWN, 0);
1537 if (dp->status == connector_status_connected) {
1538 for (i = 0; i < 3; i++) {
1539 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER,
1540 DP_SET_POWER_D0);
1541 if (ret == 1)
1542 break;
1543 usleep_range(300, 500);
1544 }
1545
1546 msleep(zynqmp_dp_power_on_delay_ms);
1547 }
1548 if (ret != 1)
1549 dev_dbg(dp->dev, "DP aux failed\n");
1550 else
1551 zynqmp_dp_train_loop(dp);
1552 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_SW_RESET,
1553 ZYNQMP_DP_TX_SW_RESET_ALL);
1554 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_ENABLE_MAIN_STREAM, 1);
1555}
1556
1557static void zynqmp_dp_encoder_disable(struct drm_encoder *encoder)
1558{
1559 struct zynqmp_dp *dp = encoder_to_dp(encoder);
1560 void __iomem *iomem = dp->iomem;
1561
1562 dp->enabled = false;
1563 cancel_delayed_work(&dp->hpd_work);
1564 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_ENABLE_MAIN_STREAM, 0);
1565 drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
1566 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_PHY_POWER_DOWN,
1567 ZYNQMP_DP_TX_PHY_POWER_DOWN_ALL);
1568 if (zynqmp_disp_aud_enabled(dp->dpsub->disp))
1569 zynqmp_dp_write(iomem, ZYNQMP_DP_TX_AUDIO_CONTROL, 0);
1570 pm_runtime_put_sync(dp->dev);
1571}
1572
1573static void
1574zynqmp_dp_encoder_atomic_mode_set(struct drm_encoder *encoder,
1575 struct drm_crtc_state *crtc_state,
1576 struct drm_connector_state *connector_state)
1577{
1578 struct zynqmp_dp *dp = encoder_to_dp(encoder);
1579 struct drm_display_mode *mode = &crtc_state->mode;
1580 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1581 u8 max_lanes = dp->link_config.max_lanes;
1582 u8 bpp = dp->config.bpp;
1583 int rate, max_rate = dp->link_config.max_rate;
1584 int ret;
1585
1586
1587 rate = zynqmp_dp_max_rate(max_rate, max_lanes, bpp);
1588 if (mode->clock > rate) {
1589 dev_err(dp->dev, "the mode, %s,has too high pixel rate\n",
1590 mode->name);
1591 drm_mode_debug_printmodeline(mode);
1592 }
1593
1594 ret = zynqmp_dp_mode_configure(dp, adjusted_mode->clock, 0);
1595 if (ret < 0)
1596 return;
1597
1598 zynqmp_dp_encoder_mode_set_transfer_unit(dp, adjusted_mode);
1599}
1600
1601#define ZYNQMP_DP_MIN_H_BACKPORCH 20
1602
1603static int
1604zynqmp_dp_encoder_atomic_check(struct drm_encoder *encoder,
1605 struct drm_crtc_state *crtc_state,
1606 struct drm_connector_state *conn_state)
1607{
1608 struct drm_display_mode *mode = &crtc_state->mode;
1609 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1610 int diff = mode->htotal - mode->hsync_end;
1611
1612
1613
1614
1615
1616 if (diff < ZYNQMP_DP_MIN_H_BACKPORCH) {
1617 int vrefresh = (adjusted_mode->clock * 1000) /
1618 (adjusted_mode->vtotal * adjusted_mode->htotal);
1619
1620 dev_dbg(encoder->dev->dev, "hbackporch adjusted: %d to %d",
1621 diff, ZYNQMP_DP_MIN_H_BACKPORCH - diff);
1622 diff = ZYNQMP_DP_MIN_H_BACKPORCH - diff;
1623 adjusted_mode->htotal += diff;
1624 adjusted_mode->clock = adjusted_mode->vtotal *
1625 adjusted_mode->htotal * vrefresh / 1000;
1626 }
1627
1628 return 0;
1629}
1630
1631static const struct drm_encoder_funcs zynqmp_dp_encoder_funcs = {
1632 .destroy = drm_encoder_cleanup,
1633};
1634
1635static const struct drm_encoder_helper_funcs zynqmp_dp_encoder_helper_funcs = {
1636 .enable = zynqmp_dp_encoder_enable,
1637 .disable = zynqmp_dp_encoder_disable,
1638 .atomic_mode_set = zynqmp_dp_encoder_atomic_mode_set,
1639 .atomic_check = zynqmp_dp_encoder_atomic_check,
1640};
1641
1642
1643
1644
1645
1646static void zynqmp_dp_hpd_work_func(struct work_struct *work)
1647{
1648 struct zynqmp_dp *dp;
1649
1650 dp = container_of(work, struct zynqmp_dp, hpd_work.work);
1651
1652 if (dp->drm)
1653 drm_helper_hpd_irq_event(dp->drm);
1654}
1655
1656static struct drm_prop_enum_list zynqmp_dp_bpc_enum[] = {
1657 { 6, "6BPC" },
1658 { 8, "8BPC" },
1659 { 10, "10BPC" },
1660 { 12, "12BPC" },
1661};
1662
1663int zynqmp_dp_bind(struct device *dev, struct device *master, void *data)
1664{
1665 struct zynqmp_dpsub *dpsub = dev_get_drvdata(dev);
1666 struct zynqmp_dp *dp = dpsub->dp;
1667 struct drm_encoder *encoder = &dp->encoder;
1668 struct drm_connector *connector = &dp->connector;
1669 struct drm_device *drm = data;
1670 struct device_node *port;
1671 int ret;
1672
1673 if (!dp->num_lanes)
1674 return 0;
1675
1676 encoder->possible_crtcs |= zynqmp_disp_get_crtc_mask(dpsub->disp);
1677 for_each_child_of_node(dev->of_node, port) {
1678 if (!port->name || of_node_cmp(port->name, "port"))
1679 continue;
1680 encoder->possible_crtcs |= drm_of_find_possible_crtcs(drm,
1681 port);
1682 }
1683 drm_encoder_init(drm, encoder, &zynqmp_dp_encoder_funcs,
1684 DRM_MODE_ENCODER_TMDS, NULL);
1685 drm_encoder_helper_add(encoder, &zynqmp_dp_encoder_helper_funcs);
1686
1687 connector->polled = DRM_CONNECTOR_POLL_HPD;
1688 ret = drm_connector_init(encoder->dev, connector,
1689 &zynqmp_dp_connector_funcs,
1690 DRM_MODE_CONNECTOR_DisplayPort);
1691 if (ret) {
1692 dev_err(dp->dev, "failed to initialize the drm connector");
1693 goto error_encoder;
1694 }
1695
1696 drm_connector_helper_add(connector, &zynqmp_dp_connector_helper_funcs);
1697 drm_connector_register(connector);
1698 drm_connector_attach_encoder(connector, encoder);
1699 connector->dpms = DRM_MODE_DPMS_OFF;
1700
1701 dp->drm = drm;
1702 dp->sync_prop = drm_property_create_bool(drm, 0, "sync");
1703 dp->bpc_prop = drm_property_create_enum(drm, 0, "bpc",
1704 zynqmp_dp_bpc_enum,
1705 ARRAY_SIZE(zynqmp_dp_bpc_enum));
1706
1707 dp->config.misc0 &= ~ZYNQMP_DP_TX_MAIN_STREAM_MISC0_SYNC;
1708 drm_object_attach_property(&connector->base, dp->sync_prop, false);
1709 ret = zynqmp_dp_set_bpc(dp, 8);
1710 drm_object_attach_property(&connector->base, dp->bpc_prop,
1711 ret ? ret : 8);
1712 zynqmp_dp_update_bpp(dp);
1713
1714 INIT_DELAYED_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func);
1715
1716
1717 ret = zynqmp_dp_init_aux(dp);
1718 if (ret) {
1719 dev_err(dp->dev, "failed to initialize DP aux");
1720 goto error_prop;
1721 }
1722
1723 return 0;
1724
1725error_prop:
1726 drm_property_destroy(dp->drm, dp->bpc_prop);
1727 drm_property_destroy(dp->drm, dp->sync_prop);
1728 zynqmp_dp_connector_destroy(&dp->connector);
1729error_encoder:
1730 drm_encoder_cleanup(&dp->encoder);
1731 return ret;
1732}
1733
1734void zynqmp_dp_unbind(struct device *dev, struct device *master, void *data)
1735{
1736 struct zynqmp_dpsub *dpsub = dev_get_drvdata(dev);
1737 struct zynqmp_dp *dp = dpsub->dp;
1738
1739 disable_irq(dp->irq);
1740 if (!dp->num_lanes)
1741 return;
1742
1743 cancel_delayed_work_sync(&dp->hpd_work);
1744 zynqmp_dp_exit_aux(dp);
1745 drm_property_destroy(dp->drm, dp->bpc_prop);
1746 drm_property_destroy(dp->drm, dp->sync_prop);
1747 zynqmp_dp_connector_destroy(&dp->connector);
1748 drm_encoder_cleanup(&dp->encoder);
1749}
1750
1751
1752
1753
1754
1755static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
1756{
1757 struct zynqmp_dp *dp = (struct zynqmp_dp *)data;
1758 u32 status, mask;
1759
1760 status = zynqmp_dp_read(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_STATUS);
1761 mask = zynqmp_dp_read(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_MASK);
1762 if (!(status & ~mask))
1763 return IRQ_NONE;
1764
1765
1766 if (status & ZYNQMP_DP_TX_INTR_CHBUF_UNDERFLW_MASK)
1767 dev_dbg_ratelimited(dp->dev, "underflow interrupt\n");
1768 if (status & ZYNQMP_DP_TX_INTR_CHBUF_OVERFLW_MASK)
1769 dev_dbg_ratelimited(dp->dev, "overflow interrupt\n");
1770
1771 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_SUB_TX_INTR_STATUS, status);
1772
1773
1774 if (status & ZYNQMP_DP_TX_INTR_VBLANK_START)
1775 zynqmp_disp_handle_vblank(dp->dpsub->disp);
1776
1777 if (status & ZYNQMP_DP_TX_INTR_HPD_EVENT)
1778 schedule_delayed_work(&dp->hpd_work, 0);
1779
1780 if (status & ZYNQMP_DP_TX_INTR_HPD_IRQ) {
1781 int ret;
1782 u8 status[DP_LINK_STATUS_SIZE + 2];
1783
1784 ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status,
1785 DP_LINK_STATUS_SIZE + 2);
1786 if (ret < 0)
1787 goto handled;
1788
1789 if (status[4] & DP_LINK_STATUS_UPDATED ||
1790 !drm_dp_clock_recovery_ok(&status[2], dp->mode.lane_cnt) ||
1791 !drm_dp_channel_eq_ok(&status[2], dp->mode.lane_cnt)) {
1792 zynqmp_dp_train_loop(dp);
1793 }
1794 }
1795
1796handled:
1797 return IRQ_HANDLED;
1798}
1799
1800int zynqmp_dp_probe(struct platform_device *pdev)
1801{
1802 struct zynqmp_dpsub *dpsub;
1803 struct zynqmp_dp *dp;
1804 struct resource *res;
1805 unsigned int i;
1806 int irq, ret;
1807
1808 dp = devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);
1809 if (!dp)
1810 return -ENOMEM;
1811
1812 dp->dpms = DRM_MODE_DPMS_OFF;
1813 dp->status = connector_status_disconnected;
1814 dp->dev = &pdev->dev;
1815
1816 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp");
1817 dp->iomem = devm_ioremap_resource(dp->dev, res);
1818 if (IS_ERR(dp->iomem))
1819 return PTR_ERR(dp->iomem);
1820
1821 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_PHY_POWER_DOWN,
1822 ZYNQMP_DP_TX_PHY_POWER_DOWN_ALL);
1823 zynqmp_dp_set(dp->iomem, ZYNQMP_DP_TX_PHY_CONFIG,
1824 ZYNQMP_DP_TX_PHY_CONFIG_ALL_RESET);
1825 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_FORCE_SCRAMBLER_RESET, 1);
1826 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_ENABLE, 0);
1827
1828 dp->num_lanes = 2;
1829 for (i = 0; i < ZYNQMP_DP_MAX_LANES; i++) {
1830 char phy_name[16];
1831
1832 snprintf(phy_name, sizeof(phy_name), "dp-phy%d", i);
1833 dp->phy[i] = devm_phy_get(dp->dev, phy_name);
1834 if (IS_ERR(dp->phy[i])) {
1835 ret = PTR_ERR(dp->phy[i]);
1836 dp->phy[i] = NULL;
1837
1838
1839 if (i == 1 && ret == -ENODEV) {
1840 dp->num_lanes = 1;
1841 break;
1842 }
1843
1844
1845
1846
1847
1848
1849
1850 if (i == 0 && ret == -ENODEV) {
1851 dp->num_lanes = 0;
1852 goto out;
1853 }
1854
1855 if (ret != -EPROBE_DEFER)
1856 dev_err(dp->dev, "failed to get phy lane\n");
1857
1858 return ret;
1859 }
1860 }
1861
1862 ret = zynqmp_dp_init_phy(dp);
1863 if (ret)
1864 goto error_phy;
1865
1866 dp->aux.name = "ZynqMP DP AUX";
1867 dp->aux.dev = dp->dev;
1868 dp->aux.transfer = zynqmp_dp_aux_transfer;
1869 ret = drm_dp_aux_register(&dp->aux);
1870 if (ret < 0) {
1871 dev_err(dp->dev, "failed to initialize DP aux\n");
1872 goto error;
1873 }
1874
1875out:
1876 irq = platform_get_irq(pdev, 0);
1877 if (irq < 0) {
1878 ret = irq;
1879 goto error;
1880 }
1881
1882 ret = devm_request_threaded_irq(dp->dev, irq, NULL,
1883 zynqmp_dp_irq_handler, IRQF_ONESHOT,
1884 dev_name(dp->dev), dp);
1885 if (ret < 0)
1886 goto error;
1887 dp->irq = irq;
1888
1889 dpsub = platform_get_drvdata(pdev);
1890 dpsub->dp = dp;
1891 dp->dpsub = dpsub;
1892
1893 dev_dbg(dp->dev,
1894 "ZynqMP DisplayPort Tx driver probed with %u phy lanes\n",
1895 dp->num_lanes);
1896
1897 return 0;
1898
1899error:
1900 drm_dp_aux_unregister(&dp->aux);
1901error_phy:
1902 zynqmp_dp_exit_phy(dp);
1903 return ret;
1904}
1905
1906int zynqmp_dp_remove(struct platform_device *pdev)
1907{
1908 struct zynqmp_dpsub *dpsub = platform_get_drvdata(pdev);
1909 struct zynqmp_dp *dp = dpsub->dp;
1910
1911 zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_ENABLE, 0);
1912 drm_dp_aux_unregister(&dp->aux);
1913 zynqmp_dp_exit_phy(dp);
1914 dpsub->dp = NULL;
1915
1916 return 0;
1917}
1918