aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-02-06 20:03:30 -0500
committerDave Airlie <airlied@redhat.com>2017-02-06 20:03:30 -0500
commit538f1dcdc5e20adb2488fa0932d56906de166405 (patch)
treeda6f5198b14870f542e6cee044332e4f799665dd
parent31f408c8a8e7c1976e868206156ae14bf35e4ac9 (diff)
parentef1844b7ed847430955a95d20242f0d1b9f5fa64 (diff)
Merge branch 'drm-rockchip-next-2017-02-05' of https://github.com/markyzq/kernel-drm-rockchip into drm-next
rockchip CDN-DP support. * 'drm-rockchip-next-2017-02-05' of https://github.com/markyzq/kernel-drm-rockchip: drm/rockchip: cdn-dp: don't configure hardware in mode_set drm/rockchip: cdn-dp: retry to check sink count drm/rockchip: cdn-dp: Move mutex_init to probe drm/rockchip: cdn-dp: do not use drm_helper_hpd_irq_event drm/rockchip: cdn-dp: Do not run worker while suspended drm/rockchip: cdn-dp: Load firmware if no monitor connected drm/rockchip: cdn-dp: add cdn DP support for rk3399 drm/rockchip: return ERR_PTR instead of NULL drm/rockchip: vop: make vop register setting take effect
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig10
-rw-r--r--drivers/gpu/drm/rockchip/Makefile2
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c1260
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.h112
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-reg.c979
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-reg.h483
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fb.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c17
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.h9
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c2
10 files changed, 2872 insertions, 4 deletions
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 6f7f9c59f05b..ad31b3eb408f 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -21,6 +21,16 @@ config ROCKCHIP_ANALOGIX_DP
21 for the Analogix Core DP driver. If you want to enable DP 21 for the Analogix Core DP driver. If you want to enable DP
22 on RK3288 based SoC, you should selet this option. 22 on RK3288 based SoC, you should selet this option.
23 23
24config ROCKCHIP_CDN_DP
25 tristate "Rockchip cdn DP"
26 depends on DRM_ROCKCHIP
27 select SND_SOC_HDMI_CODEC if SND_SOC
28 help
29 This selects support for Rockchip SoC specific extensions
30 for the cdn DP driver. If you want to enable Dp on
31 RK3399 based SoC, you should select this
32 option.
33
24config ROCKCHIP_DW_HDMI 34config ROCKCHIP_DW_HDMI
25 tristate "Rockchip specific extensions for Synopsys DW HDMI" 35 tristate "Rockchip specific extensions for Synopsys DW HDMI"
26 depends on DRM_ROCKCHIP 36 depends on DRM_ROCKCHIP
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index 9746365694ba..c931e2a7d8de 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -7,6 +7,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
7rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o 7rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
8 8
9obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o 9obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
10obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp.o
11cdn-dp-objs := cdn-dp-core.o cdn-dp-reg.o
10obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o 12obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
11obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o 13obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
12obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o 14obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
new file mode 100644
index 000000000000..9ab67a670885
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -0,0 +1,1260 @@
1/*
2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Author: Chris Zhong <zyw@rock-chips.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <drm/drmP.h>
16#include <drm/drm_atomic_helper.h>
17#include <drm/drm_crtc_helper.h>
18#include <drm/drm_dp_helper.h>
19#include <drm/drm_edid.h>
20#include <drm/drm_of.h>
21
22#include <linux/clk.h>
23#include <linux/component.h>
24#include <linux/extcon.h>
25#include <linux/firmware.h>
26#include <linux/regmap.h>
27#include <linux/reset.h>
28#include <linux/mfd/syscon.h>
29#include <linux/phy/phy.h>
30
31#include <sound/hdmi-codec.h>
32
33#include "cdn-dp-core.h"
34#include "cdn-dp-reg.h"
35#include "rockchip_drm_vop.h"
36
37#define connector_to_dp(c) \
38 container_of(c, struct cdn_dp_device, connector)
39
40#define encoder_to_dp(c) \
41 container_of(c, struct cdn_dp_device, encoder)
42
43#define GRF_SOC_CON9 0x6224
44#define DP_SEL_VOP_LIT BIT(12)
45#define GRF_SOC_CON26 0x6268
46#define UPHY_SEL_BIT 3
47#define UPHY_SEL_MASK BIT(19)
48#define DPTX_HPD_SEL (3 << 12)
49#define DPTX_HPD_DEL (2 << 12)
50#define DPTX_HPD_SEL_MASK (3 << 28)
51
52#define CDN_FW_TIMEOUT_MS (64 * 1000)
53#define CDN_DPCD_TIMEOUT_MS 5000
54#define CDN_DP_FIRMWARE "rockchip/dptx.bin"
55
56struct cdn_dp_data {
57 u8 max_phy;
58};
59
60struct cdn_dp_data rk3399_cdn_dp = {
61 .max_phy = 2,
62};
63
64static const struct of_device_id cdn_dp_dt_ids[] = {
65 { .compatible = "rockchip,rk3399-cdn-dp",
66 .data = (void *)&rk3399_cdn_dp },
67 {}
68};
69
70MODULE_DEVICE_TABLE(of, cdn_dp_dt_ids);
71
72static int cdn_dp_grf_write(struct cdn_dp_device *dp,
73 unsigned int reg, unsigned int val)
74{
75 int ret;
76
77 ret = clk_prepare_enable(dp->grf_clk);
78 if (ret) {
79 DRM_DEV_ERROR(dp->dev, "Failed to prepare_enable grf clock\n");
80 return ret;
81 }
82
83 ret = regmap_write(dp->grf, reg, val);
84 if (ret) {
85 DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
86 return ret;
87 }
88
89 clk_disable_unprepare(dp->grf_clk);
90
91 return 0;
92}
93
94static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
95{
96 int ret;
97 u32 rate;
98
99 ret = clk_prepare_enable(dp->pclk);
100 if (ret < 0) {
101 DRM_DEV_ERROR(dp->dev, "cannot enable dp pclk %d\n", ret);
102 goto err_pclk;
103 }
104
105 ret = clk_prepare_enable(dp->core_clk);
106 if (ret < 0) {
107 DRM_DEV_ERROR(dp->dev, "cannot enable core_clk %d\n", ret);
108 goto err_core_clk;
109 }
110
111 ret = pm_runtime_get_sync(dp->dev);
112 if (ret < 0) {
113 DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret);
114 goto err_pclk;
115 }
116
117 reset_control_assert(dp->core_rst);
118 reset_control_assert(dp->dptx_rst);
119 reset_control_assert(dp->apb_rst);
120 reset_control_deassert(dp->core_rst);
121 reset_control_deassert(dp->dptx_rst);
122 reset_control_deassert(dp->apb_rst);
123
124 rate = clk_get_rate(dp->core_clk);
125 if (!rate) {
126 DRM_DEV_ERROR(dp->dev, "get clk rate failed: %d\n", rate);
127 goto err_set_rate;
128 }
129
130 cdn_dp_set_fw_clk(dp, rate);
131 cdn_dp_clock_reset(dp);
132
133 return 0;
134
135err_set_rate:
136 clk_disable_unprepare(dp->core_clk);
137err_core_clk:
138 clk_disable_unprepare(dp->pclk);
139err_pclk:
140 return ret;
141}
142
143static void cdn_dp_clk_disable(struct cdn_dp_device *dp)
144{
145 pm_runtime_put_sync(dp->dev);
146 clk_disable_unprepare(dp->pclk);
147 clk_disable_unprepare(dp->core_clk);
148}
149
150static int cdn_dp_get_port_lanes(struct cdn_dp_port *port)
151{
152 struct extcon_dev *edev = port->extcon;
153 union extcon_property_value property;
154 int dptx;
155 u8 lanes;
156
157 dptx = extcon_get_state(edev, EXTCON_DISP_DP);
158 if (dptx > 0) {
159 extcon_get_property(edev, EXTCON_DISP_DP,
160 EXTCON_PROP_USB_SS, &property);
161 if (property.intval)
162 lanes = 2;
163 else
164 lanes = 4;
165 } else {
166 lanes = 0;
167 }
168
169 return lanes;
170}
171
172static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
173{
174 int ret;
175 u8 value;
176
177 *sink_count = 0;
178 ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, &value, 1);
179 if (ret)
180 return ret;
181
182 *sink_count = DP_GET_SINK_COUNT(value);
183 return 0;
184}
185
186static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
187{
188 struct cdn_dp_port *port;
189 int i, lanes;
190
191 for (i = 0; i < dp->ports; i++) {
192 port = dp->port[i];
193 lanes = cdn_dp_get_port_lanes(port);
194 if (lanes)
195 return port;
196 }
197 return NULL;
198}
199
200static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
201{
202 unsigned long timeout = jiffies + msecs_to_jiffies(CDN_DPCD_TIMEOUT_MS);
203 struct cdn_dp_port *port;
204 u8 sink_count = 0;
205
206 if (dp->active_port < 0 || dp->active_port >= dp->ports) {
207 DRM_DEV_ERROR(dp->dev, "active_port is wrong!\n");
208 return false;
209 }
210
211 port = dp->port[dp->active_port];
212
213 /*
214 * Attempt to read sink count, retry in case the sink may not be ready.
215 *
216 * Sinks are *supposed* to come up within 1ms from an off state, but
217 * some docks need more time to power up.
218 */
219 while (time_before(jiffies, timeout)) {
220 if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
221 return false;
222
223 if (!cdn_dp_get_sink_count(dp, &sink_count))
224 return sink_count ? true : false;
225
226 usleep_range(5000, 10000);
227 }
228
229 DRM_DEV_ERROR(dp->dev, "Get sink capability timed out\n");
230 return false;
231}
232
233static enum drm_connector_status
234cdn_dp_connector_detect(struct drm_connector *connector, bool force)
235{
236 struct cdn_dp_device *dp = connector_to_dp(connector);
237 enum drm_connector_status status = connector_status_disconnected;
238
239 mutex_lock(&dp->lock);
240 if (dp->connected)
241 status = connector_status_connected;
242 mutex_unlock(&dp->lock);
243
244 return status;
245}
246
247static void cdn_dp_connector_destroy(struct drm_connector *connector)
248{
249 drm_connector_unregister(connector);
250 drm_connector_cleanup(connector);
251}
252
253static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
254 .dpms = drm_atomic_helper_connector_dpms,
255 .detect = cdn_dp_connector_detect,
256 .destroy = cdn_dp_connector_destroy,
257 .fill_modes = drm_helper_probe_single_connector_modes,
258 .reset = drm_atomic_helper_connector_reset,
259 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
260 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
261};
262
263static int cdn_dp_connector_get_modes(struct drm_connector *connector)
264{
265 struct cdn_dp_device *dp = connector_to_dp(connector);
266 struct edid *edid;
267 int ret = 0;
268
269 mutex_lock(&dp->lock);
270 edid = dp->edid;
271 if (edid) {
272 DRM_DEV_DEBUG_KMS(dp->dev, "got edid: width[%d] x height[%d]\n",
273 edid->width_cm, edid->height_cm);
274
275 dp->sink_has_audio = drm_detect_monitor_audio(edid);
276 ret = drm_add_edid_modes(connector, edid);
277 if (ret) {
278 drm_mode_connector_update_edid_property(connector,
279 edid);
280 drm_edid_to_eld(connector, edid);
281 }
282 }
283 mutex_unlock(&dp->lock);
284
285 return ret;
286}
287
288static struct drm_encoder *
289cdn_dp_connector_best_encoder(struct drm_connector *connector)
290{
291 struct cdn_dp_device *dp = connector_to_dp(connector);
292
293 return &dp->encoder;
294}
295
296static int cdn_dp_connector_mode_valid(struct drm_connector *connector,
297 struct drm_display_mode *mode)
298{
299 struct cdn_dp_device *dp = connector_to_dp(connector);
300 struct drm_display_info *display_info = &dp->connector.display_info;
301 u32 requested, actual, rate, sink_max, source_max = 0;
302 u8 lanes, bpc;
303
304 /* If DP is disconnected, every mode is invalid */
305 if (!dp->connected)
306 return MODE_BAD;
307
308 switch (display_info->bpc) {
309 case 10:
310 bpc = 10;
311 break;
312 case 6:
313 bpc = 6;
314 break;
315 default:
316 bpc = 8;
317 break;
318 }
319
320 requested = mode->clock * bpc * 3 / 1000;
321
322 source_max = dp->lanes;
323 sink_max = drm_dp_max_lane_count(dp->dpcd);
324 lanes = min(source_max, sink_max);
325
326 source_max = drm_dp_bw_code_to_link_rate(CDN_DP_MAX_LINK_RATE);
327 sink_max = drm_dp_max_link_rate(dp->dpcd);
328 rate = min(source_max, sink_max);
329
330 actual = rate * lanes / 100;
331
332 /* efficiency is about 0.8 */
333 actual = actual * 8 / 10;
334
335 if (requested > actual) {
336 DRM_DEV_DEBUG_KMS(dp->dev,
337 "requested=%d, actual=%d, clock=%d\n",
338 requested, actual, mode->clock);
339 return MODE_CLOCK_HIGH;
340 }
341
342 return MODE_OK;
343}
344
345static struct drm_connector_helper_funcs cdn_dp_connector_helper_funcs = {
346 .get_modes = cdn_dp_connector_get_modes,
347 .best_encoder = cdn_dp_connector_best_encoder,
348 .mode_valid = cdn_dp_connector_mode_valid,
349};
350
351static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
352{
353 int ret;
354 const u32 *iram_data, *dram_data;
355 const struct firmware *fw = dp->fw;
356 const struct cdn_firmware_header *hdr;
357
358 hdr = (struct cdn_firmware_header *)fw->data;
359 if (fw->size != le32_to_cpu(hdr->size_bytes)) {
360 DRM_DEV_ERROR(dp->dev, "firmware is invalid\n");
361 return -EINVAL;
362 }
363
364 iram_data = (const u32 *)(fw->data + hdr->header_size);
365 dram_data = (const u32 *)(fw->data + hdr->header_size + hdr->iram_size);
366
367 ret = cdn_dp_load_firmware(dp, iram_data, hdr->iram_size,
368 dram_data, hdr->dram_size);
369 if (ret)
370 return ret;
371
372 ret = cdn_dp_set_firmware_active(dp, true);
373 if (ret) {
374 DRM_DEV_ERROR(dp->dev, "active ucpu failed: %d\n", ret);
375 return ret;
376 }
377
378 return cdn_dp_event_config(dp);
379}
380
381static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
382{
383 int ret;
384
385 if (!cdn_dp_check_sink_connection(dp))
386 return -ENODEV;
387
388 ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
389 DP_RECEIVER_CAP_SIZE);
390 if (ret) {
391 DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
392 return ret;
393 }
394
395 kfree(dp->edid);
396 dp->edid = drm_do_get_edid(&dp->connector,
397 cdn_dp_get_edid_block, dp);
398 return 0;
399}
400
401static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
402{
403 union extcon_property_value property;
404 int ret;
405
406 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26,
407 (port->id << UPHY_SEL_BIT) | UPHY_SEL_MASK);
408 if (ret)
409 return ret;
410
411 if (!port->phy_enabled) {
412 ret = phy_power_on(port->phy);
413 if (ret) {
414 DRM_DEV_ERROR(dp->dev, "phy power on failed: %d\n",
415 ret);
416 goto err_phy;
417 }
418 port->phy_enabled = true;
419 }
420
421 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26,
422 DPTX_HPD_SEL_MASK | DPTX_HPD_SEL);
423 if (ret) {
424 DRM_DEV_ERROR(dp->dev, "Failed to write HPD_SEL %d\n", ret);
425 goto err_power_on;
426 }
427
428 ret = cdn_dp_get_hpd_status(dp);
429 if (ret <= 0) {
430 if (!ret)
431 DRM_DEV_ERROR(dp->dev, "hpd does not exist\n");
432 goto err_power_on;
433 }
434
435 ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
436 EXTCON_PROP_USB_TYPEC_POLARITY, &property);
437 if (ret) {
438 DRM_DEV_ERROR(dp->dev, "get property failed\n");
439 goto err_power_on;
440 }
441
442 port->lanes = cdn_dp_get_port_lanes(port);
443 ret = cdn_dp_set_host_cap(dp, port->lanes, property.intval);
444 if (ret) {
445 DRM_DEV_ERROR(dp->dev, "set host capabilities failed: %d\n",
446 ret);
447 goto err_power_on;
448 }
449
450 dp->active_port = port->id;
451 return 0;
452
453err_power_on:
454 if (phy_power_off(port->phy))
455 DRM_DEV_ERROR(dp->dev, "phy power off failed: %d", ret);
456 else
457 port->phy_enabled = false;
458
459err_phy:
460 cdn_dp_grf_write(dp, GRF_SOC_CON26,
461 DPTX_HPD_SEL_MASK | DPTX_HPD_DEL);
462 return ret;
463}
464
465static int cdn_dp_disable_phy(struct cdn_dp_device *dp,
466 struct cdn_dp_port *port)
467{
468 int ret;
469
470 if (port->phy_enabled) {
471 ret = phy_power_off(port->phy);
472 if (ret) {
473 DRM_DEV_ERROR(dp->dev, "phy power off failed: %d", ret);
474 return ret;
475 }
476 }
477
478 port->phy_enabled = false;
479 port->lanes = 0;
480 dp->active_port = -1;
481 return 0;
482}
483
484static int cdn_dp_disable(struct cdn_dp_device *dp)
485{
486 int ret, i;
487
488 if (!dp->active)
489 return 0;
490
491 for (i = 0; i < dp->ports; i++)
492 cdn_dp_disable_phy(dp, dp->port[i]);
493
494 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26,
495 DPTX_HPD_SEL_MASK | DPTX_HPD_DEL);
496 if (ret) {
497 DRM_DEV_ERROR(dp->dev, "Failed to clear hpd sel %d\n",
498 ret);
499 return ret;
500 }
501
502 cdn_dp_set_firmware_active(dp, false);
503 cdn_dp_clk_disable(dp);
504 dp->active = false;
505 dp->link.rate = 0;
506 dp->link.num_lanes = 0;
507 if (!dp->connected) {
508 kfree(dp->edid);
509 dp->edid = NULL;
510 }
511
512 return 0;
513}
514
515static int cdn_dp_enable(struct cdn_dp_device *dp)
516{
517 int ret, i, lanes;
518 struct cdn_dp_port *port;
519
520 port = cdn_dp_connected_port(dp);
521 if (!port) {
522 DRM_DEV_ERROR(dp->dev,
523 "Can't enable without connection\n");
524 return -ENODEV;
525 }
526
527 if (dp->active)
528 return 0;
529
530 ret = cdn_dp_clk_enable(dp);
531 if (ret)
532 return ret;
533
534 ret = cdn_dp_firmware_init(dp);
535 if (ret) {
536 DRM_DEV_ERROR(dp->dev, "firmware init failed: %d", ret);
537 goto err_clk_disable;
538 }
539
540 /* only enable the port that connected with downstream device */
541 for (i = port->id; i < dp->ports; i++) {
542 port = dp->port[i];
543 lanes = cdn_dp_get_port_lanes(port);
544 if (lanes) {
545 ret = cdn_dp_enable_phy(dp, port);
546 if (ret)
547 continue;
548
549 ret = cdn_dp_get_sink_capability(dp);
550 if (ret) {
551 cdn_dp_disable_phy(dp, port);
552 } else {
553 dp->active = true;
554 dp->lanes = port->lanes;
555 return 0;
556 }
557 }
558 }
559
560err_clk_disable:
561 cdn_dp_clk_disable(dp);
562 return ret;
563}
564
565static void cdn_dp_encoder_mode_set(struct drm_encoder *encoder,
566 struct drm_display_mode *mode,
567 struct drm_display_mode *adjusted)
568{
569 struct cdn_dp_device *dp = encoder_to_dp(encoder);
570 struct drm_display_info *display_info = &dp->connector.display_info;
571 struct video_info *video = &dp->video_info;
572
573 switch (display_info->bpc) {
574 case 10:
575 video->color_depth = 10;
576 break;
577 case 6:
578 video->color_depth = 6;
579 break;
580 default:
581 video->color_depth = 8;
582 break;
583 }
584
585 video->color_fmt = PXL_RGB;
586 video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
587 video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
588
589 memcpy(&dp->mode, adjusted, sizeof(*mode));
590}
591
592static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
593{
594 u8 link_status[DP_LINK_STATUS_SIZE];
595 struct cdn_dp_port *port = cdn_dp_connected_port(dp);
596 u8 sink_lanes = drm_dp_max_lane_count(dp->dpcd);
597
598 if (!port || !dp->link.rate || !dp->link.num_lanes)
599 return false;
600
601 if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
602 DP_LINK_STATUS_SIZE)) {
603 DRM_ERROR("Failed to get link status\n");
604 return false;
605 }
606
607 /* if link training is requested we should perform it always */
608 return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
609}
610
611static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
612{
613 struct cdn_dp_device *dp = encoder_to_dp(encoder);
614 int ret, val;
615 struct rockchip_crtc_state *state;
616
617 ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
618 if (ret < 0) {
619 DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
620 return;
621 }
622
623 DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n",
624 (ret) ? "LIT" : "BIG");
625 state = to_rockchip_crtc_state(encoder->crtc->state);
626 if (ret) {
627 val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
628 state->output_mode = ROCKCHIP_OUT_MODE_P888;
629 } else {
630 val = DP_SEL_VOP_LIT << 16;
631 state->output_mode = ROCKCHIP_OUT_MODE_AAAA;
632 }
633
634 ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);
635 if (ret)
636 return;
637
638 mutex_lock(&dp->lock);
639
640 ret = cdn_dp_enable(dp);
641 if (ret) {
642 DRM_DEV_ERROR(dp->dev, "Failed to enable encoder %d\n",
643 ret);
644 goto out;
645 }
646 if (!cdn_dp_check_link_status(dp)) {
647 ret = cdn_dp_train_link(dp);
648 if (ret) {
649 DRM_DEV_ERROR(dp->dev, "Failed link train %d\n", ret);
650 goto out;
651 }
652 }
653
654 ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
655 if (ret) {
656 DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
657 goto out;
658 }
659
660 ret = cdn_dp_config_video(dp);
661 if (ret) {
662 DRM_DEV_ERROR(dp->dev, "Failed to config video %d\n", ret);
663 goto out;
664 }
665
666 ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
667 if (ret) {
668 DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
669 goto out;
670 }
671out:
672 mutex_unlock(&dp->lock);
673}
674
675static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
676{
677 struct cdn_dp_device *dp = encoder_to_dp(encoder);
678 int ret;
679
680 mutex_lock(&dp->lock);
681 if (dp->active) {
682 ret = cdn_dp_disable(dp);
683 if (ret) {
684 DRM_DEV_ERROR(dp->dev, "Failed to disable encoder %d\n",
685 ret);
686 }
687 }
688 mutex_unlock(&dp->lock);
689
690 /*
691 * In the following 2 cases, we need to run the event_work to re-enable
692 * the DP:
693 * 1. If there is not just one port device is connected, and remove one
694 * device from a port, the DP will be disabled here, at this case,
695 * run the event_work to re-open DP for the other port.
696 * 2. If re-training or re-config failed, the DP will be disabled here.
697 * run the event_work to re-connect it.
698 */
699 if (!dp->connected && cdn_dp_connected_port(dp))
700 schedule_work(&dp->event_work);
701}
702
703static int cdn_dp_encoder_atomic_check(struct drm_encoder *encoder,
704 struct drm_crtc_state *crtc_state,
705 struct drm_connector_state *conn_state)
706{
707 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
708
709 s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
710 s->output_type = DRM_MODE_CONNECTOR_DisplayPort;
711
712 return 0;
713}
714
715static const struct drm_encoder_helper_funcs cdn_dp_encoder_helper_funcs = {
716 .mode_set = cdn_dp_encoder_mode_set,
717 .enable = cdn_dp_encoder_enable,
718 .disable = cdn_dp_encoder_disable,
719 .atomic_check = cdn_dp_encoder_atomic_check,
720};
721
722static const struct drm_encoder_funcs cdn_dp_encoder_funcs = {
723 .destroy = drm_encoder_cleanup,
724};
725
726static int cdn_dp_parse_dt(struct cdn_dp_device *dp)
727{
728 struct device *dev = dp->dev;
729 struct device_node *np = dev->of_node;
730 struct platform_device *pdev = to_platform_device(dev);
731 struct resource *res;
732
733 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
734 if (IS_ERR(dp->grf)) {
735 DRM_DEV_ERROR(dev, "cdn-dp needs rockchip,grf property\n");
736 return PTR_ERR(dp->grf);
737 }
738
739 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
740 dp->regs = devm_ioremap_resource(dev, res);
741 if (IS_ERR(dp->regs)) {
742 DRM_DEV_ERROR(dev, "ioremap reg failed\n");
743 return PTR_ERR(dp->regs);
744 }
745
746 dp->core_clk = devm_clk_get(dev, "core-clk");
747 if (IS_ERR(dp->core_clk)) {
748 DRM_DEV_ERROR(dev, "cannot get core_clk_dp\n");
749 return PTR_ERR(dp->core_clk);
750 }
751
752 dp->pclk = devm_clk_get(dev, "pclk");
753 if (IS_ERR(dp->pclk)) {
754 DRM_DEV_ERROR(dev, "cannot get pclk\n");
755 return PTR_ERR(dp->pclk);
756 }
757
758 dp->spdif_clk = devm_clk_get(dev, "spdif");
759 if (IS_ERR(dp->spdif_clk)) {
760 DRM_DEV_ERROR(dev, "cannot get spdif_clk\n");
761 return PTR_ERR(dp->spdif_clk);
762 }
763
764 dp->grf_clk = devm_clk_get(dev, "grf");
765 if (IS_ERR(dp->grf_clk)) {
766 DRM_DEV_ERROR(dev, "cannot get grf clk\n");
767 return PTR_ERR(dp->grf_clk);
768 }
769
770 dp->spdif_rst = devm_reset_control_get(dev, "spdif");
771 if (IS_ERR(dp->spdif_rst)) {
772 DRM_DEV_ERROR(dev, "no spdif reset control found\n");
773 return PTR_ERR(dp->spdif_rst);
774 }
775
776 dp->dptx_rst = devm_reset_control_get(dev, "dptx");
777 if (IS_ERR(dp->dptx_rst)) {
778 DRM_DEV_ERROR(dev, "no uphy reset control found\n");
779 return PTR_ERR(dp->dptx_rst);
780 }
781
782 dp->core_rst = devm_reset_control_get(dev, "core");
783 if (IS_ERR(dp->core_rst)) {
784 DRM_DEV_ERROR(dev, "no core reset control found\n");
785 return PTR_ERR(dp->core_rst);
786 }
787
788 dp->apb_rst = devm_reset_control_get(dev, "apb");
789 if (IS_ERR(dp->apb_rst)) {
790 DRM_DEV_ERROR(dev, "no apb reset control found\n");
791 return PTR_ERR(dp->apb_rst);
792 }
793
794 return 0;
795}
796
797static int cdn_dp_audio_hw_params(struct device *dev, void *data,
798 struct hdmi_codec_daifmt *daifmt,
799 struct hdmi_codec_params *params)
800{
801 struct cdn_dp_device *dp = dev_get_drvdata(dev);
802 struct audio_info audio = {
803 .sample_width = params->sample_width,
804 .sample_rate = params->sample_rate,
805 .channels = params->channels,
806 };
807 int ret;
808
809 mutex_lock(&dp->lock);
810 if (!dp->active) {
811 ret = -ENODEV;
812 goto out;
813 }
814
815 switch (daifmt->fmt) {
816 case HDMI_I2S:
817 audio.format = AFMT_I2S;
818 break;
819 case HDMI_SPDIF:
820 audio.format = AFMT_SPDIF;
821 break;
822 default:
823 DRM_DEV_ERROR(dev, "Invalid format %d\n", daifmt->fmt);
824 ret = -EINVAL;
825 goto out;
826 }
827
828 ret = cdn_dp_audio_config(dp, &audio);
829 if (!ret)
830 dp->audio_info = audio;
831
832out:
833 mutex_unlock(&dp->lock);
834 return ret;
835}
836
837static void cdn_dp_audio_shutdown(struct device *dev, void *data)
838{
839 struct cdn_dp_device *dp = dev_get_drvdata(dev);
840 int ret;
841
842 mutex_lock(&dp->lock);
843 if (!dp->active)
844 goto out;
845
846 ret = cdn_dp_audio_stop(dp, &dp->audio_info);
847 if (!ret)
848 dp->audio_info.format = AFMT_UNUSED;
849out:
850 mutex_unlock(&dp->lock);
851}
852
853static int cdn_dp_audio_digital_mute(struct device *dev, void *data,
854 bool enable)
855{
856 struct cdn_dp_device *dp = dev_get_drvdata(dev);
857 int ret;
858
859 mutex_lock(&dp->lock);
860 if (!dp->active) {
861 ret = -ENODEV;
862 goto out;
863 }
864
865 ret = cdn_dp_audio_mute(dp, enable);
866
867out:
868 mutex_unlock(&dp->lock);
869 return ret;
870}
871
872static int cdn_dp_audio_get_eld(struct device *dev, void *data,
873 u8 *buf, size_t len)
874{
875 struct cdn_dp_device *dp = dev_get_drvdata(dev);
876
877 memcpy(buf, dp->connector.eld, min(sizeof(dp->connector.eld), len));
878
879 return 0;
880}
881
882static const struct hdmi_codec_ops audio_codec_ops = {
883 .hw_params = cdn_dp_audio_hw_params,
884 .audio_shutdown = cdn_dp_audio_shutdown,
885 .digital_mute = cdn_dp_audio_digital_mute,
886 .get_eld = cdn_dp_audio_get_eld,
887};
888
889static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
890 struct device *dev)
891{
892 struct hdmi_codec_pdata codec_data = {
893 .i2s = 1,
894 .spdif = 1,
895 .ops = &audio_codec_ops,
896 .max_i2s_channels = 8,
897 };
898
899 dp->audio_pdev = platform_device_register_data(
900 dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
901 &codec_data, sizeof(codec_data));
902
903 return PTR_ERR_OR_ZERO(dp->audio_pdev);
904}
905
906static int cdn_dp_request_firmware(struct cdn_dp_device *dp)
907{
908 int ret;
909 unsigned long timeout = jiffies + msecs_to_jiffies(CDN_FW_TIMEOUT_MS);
910 unsigned long sleep = 1000;
911
912 WARN_ON(!mutex_is_locked(&dp->lock));
913
914 if (dp->fw_loaded)
915 return 0;
916
917 /* Drop the lock before getting the firmware to avoid blocking boot */
918 mutex_unlock(&dp->lock);
919
920 while (time_before(jiffies, timeout)) {
921 ret = request_firmware(&dp->fw, CDN_DP_FIRMWARE, dp->dev);
922 if (ret == -ENOENT) {
923 msleep(sleep);
924 sleep *= 2;
925 continue;
926 } else if (ret) {
927 DRM_DEV_ERROR(dp->dev,
928 "failed to request firmware: %d\n", ret);
929 goto out;
930 }
931
932 dp->fw_loaded = true;
933 ret = 0;
934 goto out;
935 }
936
937 DRM_DEV_ERROR(dp->dev, "Timed out trying to load firmware\n");
938 ret = -ETIMEDOUT;
939out:
940 mutex_lock(&dp->lock);
941 return ret;
942}
943
944static void cdn_dp_pd_event_work(struct work_struct *work)
945{
946 struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
947 event_work);
948 struct drm_connector *connector = &dp->connector;
949 enum drm_connector_status old_status;
950
951 int ret;
952
953 mutex_lock(&dp->lock);
954
955 if (dp->suspended)
956 goto out;
957
958 ret = cdn_dp_request_firmware(dp);
959 if (ret)
960 goto out;
961
962 dp->connected = true;
963
964 /* Not connected, notify userspace to disable the block */
965 if (!cdn_dp_connected_port(dp)) {
966 DRM_DEV_INFO(dp->dev, "Not connected. Disabling cdn\n");
967 dp->connected = false;
968
969 /* Connected but not enabled, enable the block */
970 } else if (!dp->active) {
971 DRM_DEV_INFO(dp->dev, "Connected, not enabled. Enabling cdn\n");
972 ret = cdn_dp_enable(dp);
973 if (ret) {
974 DRM_DEV_ERROR(dp->dev, "Enable dp failed %d\n", ret);
975 dp->connected = false;
976 }
977
978 /* Enabled and connected to a dongle without a sink, notify userspace */
979 } else if (!cdn_dp_check_sink_connection(dp)) {
980 DRM_DEV_INFO(dp->dev, "Connected without sink. Assert hpd\n");
981 dp->connected = false;
982
983 /* Enabled and connected with a sink, re-train if requested */
984 } else if (!cdn_dp_check_link_status(dp)) {
985 unsigned int rate = dp->link.rate;
986 unsigned int lanes = dp->link.num_lanes;
987 struct drm_display_mode *mode = &dp->mode;
988
989 DRM_DEV_INFO(dp->dev, "Connected with sink. Re-train link\n");
990 ret = cdn_dp_train_link(dp);
991 if (ret) {
992 dp->connected = false;
993 DRM_DEV_ERROR(dp->dev, "Train link failed %d\n", ret);
994 goto out;
995 }
996
997 /* If training result is changed, update the video config */
998 if (mode->clock &&
999 (rate != dp->link.rate || lanes != dp->link.num_lanes)) {
1000 ret = cdn_dp_config_video(dp);
1001 if (ret) {
1002 dp->connected = false;
1003 DRM_DEV_ERROR(dp->dev,
1004 "Failed to config video %d\n",
1005 ret);
1006 }
1007 }
1008 }
1009
1010out:
1011 mutex_unlock(&dp->lock);
1012
1013 old_status = connector->status;
1014 connector->status = connector->funcs->detect(connector, false);
1015 if (old_status != connector->status)
1016 drm_kms_helper_hotplug_event(dp->drm_dev);
1017}
1018
1019static int cdn_dp_pd_event(struct notifier_block *nb,
1020 unsigned long event, void *priv)
1021{
1022 struct cdn_dp_port *port = container_of(nb, struct cdn_dp_port,
1023 event_nb);
1024 struct cdn_dp_device *dp = port->dp;
1025
1026 /*
1027 * It would be nice to be able to just do the work inline right here.
1028 * However, we need to make a bunch of calls that might sleep in order
1029 * to turn on the block/phy, so use a worker instead.
1030 */
1031 schedule_work(&dp->event_work);
1032
1033 return NOTIFY_DONE;
1034}
1035
1036static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
1037{
1038 struct cdn_dp_device *dp = dev_get_drvdata(dev);
1039 struct drm_encoder *encoder;
1040 struct drm_connector *connector;
1041 struct cdn_dp_port *port;
1042 struct drm_device *drm_dev = data;
1043 int ret, i;
1044
1045 ret = cdn_dp_parse_dt(dp);
1046 if (ret < 0)
1047 return ret;
1048
1049 dp->drm_dev = drm_dev;
1050 dp->connected = false;
1051 dp->active = false;
1052 dp->active_port = -1;
1053
1054 INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
1055
1056 encoder = &dp->encoder;
1057
1058 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
1059 dev->of_node);
1060 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
1061
1062 ret = drm_encoder_init(drm_dev, encoder, &cdn_dp_encoder_funcs,
1063 DRM_MODE_ENCODER_TMDS, NULL);
1064 if (ret) {
1065 DRM_ERROR("failed to initialize encoder with drm\n");
1066 return ret;
1067 }
1068
1069 drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
1070
1071 connector = &dp->connector;
1072 connector->polled = DRM_CONNECTOR_POLL_HPD;
1073 connector->dpms = DRM_MODE_DPMS_OFF;
1074
1075 ret = drm_connector_init(drm_dev, connector,
1076 &cdn_dp_atomic_connector_funcs,
1077 DRM_MODE_CONNECTOR_DisplayPort);
1078 if (ret) {
1079 DRM_ERROR("failed to initialize connector with drm\n");
1080 goto err_free_encoder;
1081 }
1082
1083 drm_connector_helper_add(connector, &cdn_dp_connector_helper_funcs);
1084
1085 ret = drm_mode_connector_attach_encoder(connector, encoder);
1086 if (ret) {
1087 DRM_ERROR("failed to attach connector and encoder\n");
1088 goto err_free_connector;
1089 }
1090
1091 cdn_dp_audio_codec_init(dp, dev);
1092
1093 for (i = 0; i < dp->ports; i++) {
1094 port = dp->port[i];
1095
1096 port->event_nb.notifier_call = cdn_dp_pd_event;
1097 ret = devm_extcon_register_notifier(dp->dev, port->extcon,
1098 EXTCON_DISP_DP,
1099 &port->event_nb);
1100 if (ret) {
1101 DRM_DEV_ERROR(dev,
1102 "register EXTCON_DISP_DP notifier err\n");
1103 goto err_free_connector;
1104 }
1105 }
1106
1107 pm_runtime_enable(dev);
1108
1109 schedule_work(&dp->event_work);
1110
1111 return 0;
1112
1113err_free_connector:
1114 drm_connector_cleanup(connector);
1115err_free_encoder:
1116 drm_encoder_cleanup(encoder);
1117 return ret;
1118}
1119
1120static void cdn_dp_unbind(struct device *dev, struct device *master, void *data)
1121{
1122 struct cdn_dp_device *dp = dev_get_drvdata(dev);
1123 struct drm_encoder *encoder = &dp->encoder;
1124 struct drm_connector *connector = &dp->connector;
1125
1126 cancel_work_sync(&dp->event_work);
1127 platform_device_unregister(dp->audio_pdev);
1128 cdn_dp_encoder_disable(encoder);
1129 encoder->funcs->destroy(encoder);
1130 connector->funcs->destroy(connector);
1131
1132 pm_runtime_disable(dev);
1133 release_firmware(dp->fw);
1134 kfree(dp->edid);
1135 dp->edid = NULL;
1136}
1137
1138static const struct component_ops cdn_dp_component_ops = {
1139 .bind = cdn_dp_bind,
1140 .unbind = cdn_dp_unbind,
1141};
1142
1143int cdn_dp_suspend(struct device *dev)
1144{
1145 struct cdn_dp_device *dp = dev_get_drvdata(dev);
1146 int ret = 0;
1147
1148 mutex_lock(&dp->lock);
1149 if (dp->active)
1150 ret = cdn_dp_disable(dp);
1151 dp->suspended = true;
1152 mutex_unlock(&dp->lock);
1153
1154 return ret;
1155}
1156
1157int cdn_dp_resume(struct device *dev)
1158{
1159 struct cdn_dp_device *dp = dev_get_drvdata(dev);
1160
1161 mutex_lock(&dp->lock);
1162 dp->suspended = false;
1163 if (dp->fw_loaded)
1164 schedule_work(&dp->event_work);
1165 mutex_unlock(&dp->lock);
1166
1167 return 0;
1168}
1169
1170static int cdn_dp_probe(struct platform_device *pdev)
1171{
1172 struct device *dev = &pdev->dev;
1173 const struct of_device_id *match;
1174 struct cdn_dp_data *dp_data;
1175 struct cdn_dp_port *port;
1176 struct cdn_dp_device *dp;
1177 struct extcon_dev *extcon;
1178 struct phy *phy;
1179 int i;
1180
1181 dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
1182 if (!dp)
1183 return -ENOMEM;
1184 dp->dev = dev;
1185
1186 match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node);
1187 dp_data = (struct cdn_dp_data *)match->data;
1188
1189 for (i = 0; i < dp_data->max_phy; i++) {
1190 extcon = extcon_get_edev_by_phandle(dev, i);
1191 phy = devm_of_phy_get_by_index(dev, dev->of_node, i);
1192
1193 if (PTR_ERR(extcon) == -EPROBE_DEFER ||
1194 PTR_ERR(phy) == -EPROBE_DEFER)
1195 return -EPROBE_DEFER;
1196
1197 if (IS_ERR(extcon) || IS_ERR(phy))
1198 continue;
1199
1200 port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
1201 if (!dp)
1202 return -ENOMEM;
1203
1204 port->extcon = extcon;
1205 port->phy = phy;
1206 port->dp = dp;
1207 port->id = i;
1208 dp->port[dp->ports++] = port;
1209 }
1210
1211 if (!dp->ports) {
1212 DRM_DEV_ERROR(dev, "missing extcon or phy\n");
1213 return -EINVAL;
1214 }
1215
1216 mutex_init(&dp->lock);
1217 dev_set_drvdata(dev, dp);
1218
1219 return component_add(dev, &cdn_dp_component_ops);
1220}
1221
1222static int cdn_dp_remove(struct platform_device *pdev)
1223{
1224 struct cdn_dp_device *dp = platform_get_drvdata(pdev);
1225
1226 cdn_dp_suspend(dp->dev);
1227 component_del(&pdev->dev, &cdn_dp_component_ops);
1228
1229 return 0;
1230}
1231
1232static void cdn_dp_shutdown(struct platform_device *pdev)
1233{
1234 struct cdn_dp_device *dp = platform_get_drvdata(pdev);
1235
1236 cdn_dp_suspend(dp->dev);
1237}
1238
1239static const struct dev_pm_ops cdn_dp_pm_ops = {
1240 SET_SYSTEM_SLEEP_PM_OPS(cdn_dp_suspend,
1241 cdn_dp_resume)
1242};
1243
1244static struct platform_driver cdn_dp_driver = {
1245 .probe = cdn_dp_probe,
1246 .remove = cdn_dp_remove,
1247 .shutdown = cdn_dp_shutdown,
1248 .driver = {
1249 .name = "cdn-dp",
1250 .owner = THIS_MODULE,
1251 .of_match_table = of_match_ptr(cdn_dp_dt_ids),
1252 .pm = &cdn_dp_pm_ops,
1253 },
1254};
1255
1256module_platform_driver(cdn_dp_driver);
1257
1258MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
1259MODULE_DESCRIPTION("cdn DP Driver");
1260MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
new file mode 100644
index 000000000000..f57e296401b8
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (C) 2016 Chris Zhong <zyw@rock-chips.com>
3 * Copyright (C) 2016 ROCKCHIP, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef _CDN_DP_CORE_H
16#define _CDN_DP_CORE_H
17
18#include <drm/drmP.h>
19#include <drm/drm_crtc_helper.h>
20#include <drm/drm_dp_helper.h>
21#include <drm/drm_panel.h>
22#include "rockchip_drm_drv.h"
23
24#define MAX_PHY 2
25
26enum audio_format {
27 AFMT_I2S = 0,
28 AFMT_SPDIF = 1,
29 AFMT_UNUSED,
30};
31
32struct audio_info {
33 enum audio_format format;
34 int sample_rate;
35 int channels;
36 int sample_width;
37};
38
39enum vic_pxl_encoding_format {
40 PXL_RGB = 0x1,
41 YCBCR_4_4_4 = 0x2,
42 YCBCR_4_2_2 = 0x4,
43 YCBCR_4_2_0 = 0x8,
44 Y_ONLY = 0x10,
45};
46
47struct video_info {
48 bool h_sync_polarity;
49 bool v_sync_polarity;
50 bool interlaced;
51 int color_depth;
52 enum vic_pxl_encoding_format color_fmt;
53};
54
55struct cdn_firmware_header {
56 u32 size_bytes; /* size of the entire header+image(s) in bytes */
57 u32 header_size; /* size of just the header in bytes */
58 u32 iram_size; /* size of iram */
59 u32 dram_size; /* size of dram */
60};
61
62struct cdn_dp_port {
63 struct cdn_dp_device *dp;
64 struct notifier_block event_nb;
65 struct extcon_dev *extcon;
66 struct phy *phy;
67 u8 lanes;
68 bool phy_enabled;
69 u8 id;
70};
71
72struct cdn_dp_device {
73 struct device *dev;
74 struct drm_device *drm_dev;
75 struct drm_connector connector;
76 struct drm_encoder encoder;
77 struct drm_display_mode mode;
78 struct platform_device *audio_pdev;
79 struct work_struct event_work;
80 struct edid *edid;
81
82 struct mutex lock;
83 bool connected;
84 bool active;
85 bool suspended;
86
87 const struct firmware *fw; /* cdn dp firmware */
88 unsigned int fw_version; /* cdn fw version */
89 bool fw_loaded;
90
91 void __iomem *regs;
92 struct regmap *grf;
93 struct clk *core_clk;
94 struct clk *pclk;
95 struct clk *spdif_clk;
96 struct clk *grf_clk;
97 struct reset_control *spdif_rst;
98 struct reset_control *dptx_rst;
99 struct reset_control *apb_rst;
100 struct reset_control *core_rst;
101 struct audio_info audio_info;
102 struct video_info video_info;
103 struct drm_dp_link link;
104 struct cdn_dp_port *port[MAX_PHY];
105 u8 ports;
106 u8 lanes;
107 int active_port;
108
109 u8 dpcd[DP_RECEIVER_CAP_SIZE];
110 bool sink_has_audio;
111};
112#endif /* _CDN_DP_CORE_H */
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
new file mode 100644
index 000000000000..3a5b8a4aa1e7
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -0,0 +1,979 @@
1/*
2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Author: Chris Zhong <zyw@rock-chips.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/clk.h>
16#include <linux/device.h>
17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/iopoll.h>
20#include <linux/reset.h>
21
22#include "cdn-dp-core.h"
23#include "cdn-dp-reg.h"
24
25#define CDN_DP_SPDIF_CLK 200000000
26#define FW_ALIVE_TIMEOUT_US 1000000
27#define MAILBOX_RETRY_US 1000
28#define MAILBOX_TIMEOUT_US 5000000
29#define LINK_TRAINING_RETRY_MS 20
30#define LINK_TRAINING_TIMEOUT_MS 500
31
32void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, u32 clk)
33{
34 writel(clk / 1000000, dp->regs + SW_CLK_H);
35}
36
37void cdn_dp_clock_reset(struct cdn_dp_device *dp)
38{
39 u32 val;
40
41 val = DPTX_FRMR_DATA_CLK_RSTN_EN |
42 DPTX_FRMR_DATA_CLK_EN |
43 DPTX_PHY_DATA_RSTN_EN |
44 DPTX_PHY_DATA_CLK_EN |
45 DPTX_PHY_CHAR_RSTN_EN |
46 DPTX_PHY_CHAR_CLK_EN |
47 SOURCE_AUX_SYS_CLK_RSTN_EN |
48 SOURCE_AUX_SYS_CLK_EN |
49 DPTX_SYS_CLK_RSTN_EN |
50 DPTX_SYS_CLK_EN |
51 CFG_DPTX_VIF_CLK_RSTN_EN |
52 CFG_DPTX_VIF_CLK_EN;
53 writel(val, dp->regs + SOURCE_DPTX_CAR);
54
55 val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN;
56 writel(val, dp->regs + SOURCE_PHY_CAR);
57
58 val = SOURCE_PKT_SYS_RSTN_EN |
59 SOURCE_PKT_SYS_CLK_EN |
60 SOURCE_PKT_DATA_RSTN_EN |
61 SOURCE_PKT_DATA_CLK_EN;
62 writel(val, dp->regs + SOURCE_PKT_CAR);
63
64 val = SPDIF_CDR_CLK_RSTN_EN |
65 SPDIF_CDR_CLK_EN |
66 SOURCE_AIF_SYS_RSTN_EN |
67 SOURCE_AIF_SYS_CLK_EN |
68 SOURCE_AIF_CLK_RSTN_EN |
69 SOURCE_AIF_CLK_EN;
70 writel(val, dp->regs + SOURCE_AIF_CAR);
71
72 val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN |
73 SOURCE_CIPHER_SYS_CLK_EN |
74 SOURCE_CIPHER_CHAR_CLK_RSTN_EN |
75 SOURCE_CIPHER_CHAR_CLK_EN;
76 writel(val, dp->regs + SOURCE_CIPHER_CAR);
77
78 val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN |
79 SOURCE_CRYPTO_SYS_CLK_EN;
80 writel(val, dp->regs + SOURCE_CRYPTO_CAR);
81
82 /* enable Mailbox and PIF interrupt */
83 writel(0, dp->regs + APB_INT_MASK);
84}
85
86static int cdn_dp_mailbox_read(struct cdn_dp_device *dp)
87{
88 int val, ret;
89
90 ret = readx_poll_timeout(readl, dp->regs + MAILBOX_EMPTY_ADDR,
91 val, !val, MAILBOX_RETRY_US,
92 MAILBOX_TIMEOUT_US);
93 if (ret < 0)
94 return ret;
95
96 return readl(dp->regs + MAILBOX0_RD_DATA) & 0xff;
97}
98
99static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val)
100{
101 int ret, full;
102
103 ret = readx_poll_timeout(readl, dp->regs + MAILBOX_FULL_ADDR,
104 full, !full, MAILBOX_RETRY_US,
105 MAILBOX_TIMEOUT_US);
106 if (ret < 0)
107 return ret;
108
109 writel(val, dp->regs + MAILBOX0_WR_DATA);
110
111 return 0;
112}
113
114static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp,
115 u8 module_id, u8 opcode,
116 u8 req_size)
117{
118 u32 mbox_size, i;
119 u8 header[4];
120 int ret;
121
122 /* read the header of the message */
123 for (i = 0; i < 4; i++) {
124 ret = cdn_dp_mailbox_read(dp);
125 if (ret < 0)
126 return ret;
127
128 header[i] = ret;
129 }
130
131 mbox_size = (header[2] << 8) | header[3];
132
133 if (opcode != header[0] || module_id != header[1] ||
134 req_size != mbox_size) {
135 /*
136 * If the message in mailbox is not what we want, we need to
137 * clear the mailbox by reading its contents.
138 */
139 for (i = 0; i < mbox_size; i++)
140 if (cdn_dp_mailbox_read(dp) < 0)
141 break;
142
143 return -EINVAL;
144 }
145
146 return 0;
147}
148
149static int cdn_dp_mailbox_read_receive(struct cdn_dp_device *dp,
150 u8 *buff, u8 buff_size)
151{
152 u32 i;
153 int ret;
154
155 for (i = 0; i < buff_size; i++) {
156 ret = cdn_dp_mailbox_read(dp);
157 if (ret < 0)
158 return ret;
159
160 buff[i] = ret;
161 }
162
163 return 0;
164}
165
166static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
167 u8 opcode, u16 size, u8 *message)
168{
169 u8 header[4];
170 int ret, i;
171
172 header[0] = opcode;
173 header[1] = module_id;
174 header[2] = (size >> 8) & 0xff;
175 header[3] = size & 0xff;
176
177 for (i = 0; i < 4; i++) {
178 ret = cdp_dp_mailbox_write(dp, header[i]);
179 if (ret)
180 return ret;
181 }
182
183 for (i = 0; i < size; i++) {
184 ret = cdp_dp_mailbox_write(dp, message[i]);
185 if (ret)
186 return ret;
187 }
188
189 return 0;
190}
191
192static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
193{
194 u8 msg[6];
195
196 msg[0] = (addr >> 8) & 0xff;
197 msg[1] = addr & 0xff;
198 msg[2] = (val >> 24) & 0xff;
199 msg[3] = (val >> 16) & 0xff;
200 msg[4] = (val >> 8) & 0xff;
201 msg[5] = val & 0xff;
202 return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_REGISTER,
203 sizeof(msg), msg);
204}
205
206static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr,
207 u8 start_bit, u8 bits_no, u32 val)
208{
209 u8 field[8];
210
211 field[0] = (addr >> 8) & 0xff;
212 field[1] = addr & 0xff;
213 field[2] = start_bit;
214 field[3] = bits_no;
215 field[4] = (val >> 24) & 0xff;
216 field[5] = (val >> 16) & 0xff;
217 field[6] = (val >> 8) & 0xff;
218 field[7] = val & 0xff;
219
220 return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_FIELD,
221 sizeof(field), field);
222}
223
224int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
225{
226 u8 msg[5], reg[5];
227 int ret;
228
229 msg[0] = (len >> 8) & 0xff;
230 msg[1] = len & 0xff;
231 msg[2] = (addr >> 16) & 0xff;
232 msg[3] = (addr >> 8) & 0xff;
233 msg[4] = addr & 0xff;
234 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD,
235 sizeof(msg), msg);
236 if (ret)
237 goto err_dpcd_read;
238
239 ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
240 DPTX_READ_DPCD,
241 sizeof(reg) + len);
242 if (ret)
243 goto err_dpcd_read;
244
245 ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
246 if (ret)
247 goto err_dpcd_read;
248
249 ret = cdn_dp_mailbox_read_receive(dp, data, len);
250
251err_dpcd_read:
252 return ret;
253}
254
255int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
256{
257 u8 msg[6], reg[5];
258 int ret;
259
260 msg[0] = 0;
261 msg[1] = 1;
262 msg[2] = (addr >> 16) & 0xff;
263 msg[3] = (addr >> 8) & 0xff;
264 msg[4] = addr & 0xff;
265 msg[5] = value;
266 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
267 sizeof(msg), msg);
268 if (ret)
269 goto err_dpcd_write;
270
271 ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
272 DPTX_WRITE_DPCD, sizeof(reg));
273 if (ret)
274 goto err_dpcd_write;
275
276 ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
277 if (ret)
278 goto err_dpcd_write;
279
280 if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
281 ret = -EINVAL;
282
283err_dpcd_write:
284 if (ret)
285 DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret);
286 return ret;
287}
288
289int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
290 u32 i_size, const u32 *d_mem, u32 d_size)
291{
292 u32 reg;
293 int i, ret;
294
295 /* reset ucpu before load firmware*/
296 writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET,
297 dp->regs + APB_CTRL);
298
299 for (i = 0; i < i_size; i += 4)
300 writel(*i_mem++, dp->regs + ADDR_IMEM + i);
301
302 for (i = 0; i < d_size; i += 4)
303 writel(*d_mem++, dp->regs + ADDR_DMEM + i);
304
305 /* un-reset ucpu */
306 writel(0, dp->regs + APB_CTRL);
307
308 /* check the keep alive register to make sure fw working */
309 ret = readx_poll_timeout(readl, dp->regs + KEEP_ALIVE,
310 reg, reg, 2000, FW_ALIVE_TIMEOUT_US);
311 if (ret < 0) {
312 DRM_DEV_ERROR(dp->dev, "failed to loaded the FW reg = %x\n",
313 reg);
314 return -EINVAL;
315 }
316
317 reg = readl(dp->regs + VER_L) & 0xff;
318 dp->fw_version = reg;
319 reg = readl(dp->regs + VER_H) & 0xff;
320 dp->fw_version |= reg << 8;
321 reg = readl(dp->regs + VER_LIB_L_ADDR) & 0xff;
322 dp->fw_version |= reg << 16;
323 reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff;
324 dp->fw_version |= reg << 24;
325
326 dev_dbg(dp->dev, "firmware version: %x\n", dp->fw_version);
327
328 return 0;
329}
330
331int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable)
332{
333 u8 msg[5];
334 int ret, i;
335
336 msg[0] = GENERAL_MAIN_CONTROL;
337 msg[1] = MB_MODULE_ID_GENERAL;
338 msg[2] = 0;
339 msg[3] = 1;
340 msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
341
342 for (i = 0; i < sizeof(msg); i++) {
343 ret = cdp_dp_mailbox_write(dp, msg[i]);
344 if (ret)
345 goto err_set_firmware_active;
346 }
347
348 /* read the firmware state */
349 for (i = 0; i < sizeof(msg); i++) {
350 ret = cdn_dp_mailbox_read(dp);
351 if (ret < 0)
352 goto err_set_firmware_active;
353
354 msg[i] = ret;
355 }
356
357 ret = 0;
358
359err_set_firmware_active:
360 if (ret < 0)
361 DRM_DEV_ERROR(dp->dev, "set firmware active failed\n");
362 return ret;
363}
364
365int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip)
366{
367 u8 msg[8];
368 int ret;
369
370 msg[0] = CDN_DP_MAX_LINK_RATE;
371 msg[1] = lanes | SCRAMBLER_EN;
372 msg[2] = VOLTAGE_LEVEL_2;
373 msg[3] = PRE_EMPHASIS_LEVEL_3;
374 msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
375 msg[5] = FAST_LT_NOT_SUPPORT;
376 msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL;
377 msg[7] = ENHANCED;
378
379 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
380 DPTX_SET_HOST_CAPABILITIES,
381 sizeof(msg), msg);
382 if (ret)
383 goto err_set_host_cap;
384
385 ret = cdn_dp_reg_write(dp, DP_AUX_SWAP_INVERSION_CONTROL,
386 AUX_HOST_INVERT);
387
388err_set_host_cap:
389 if (ret)
390 DRM_DEV_ERROR(dp->dev, "set host cap failed: %d\n", ret);
391 return ret;
392}
393
394int cdn_dp_event_config(struct cdn_dp_device *dp)
395{
396 u8 msg[5];
397 int ret;
398
399 memset(msg, 0, sizeof(msg));
400
401 msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING;
402
403 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT,
404 sizeof(msg), msg);
405 if (ret)
406 DRM_DEV_ERROR(dp->dev, "set event config failed: %d\n", ret);
407
408 return ret;
409}
410
411u32 cdn_dp_get_event(struct cdn_dp_device *dp)
412{
413 return readl(dp->regs + SW_EVENTS0);
414}
415
416int cdn_dp_get_hpd_status(struct cdn_dp_device *dp)
417{
418 u8 status;
419 int ret;
420
421 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE,
422 0, NULL);
423 if (ret)
424 goto err_get_hpd;
425
426 ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
427 DPTX_HPD_STATE, sizeof(status));
428 if (ret)
429 goto err_get_hpd;
430
431 ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
432 if (ret)
433 goto err_get_hpd;
434
435 return status;
436
437err_get_hpd:
438 DRM_DEV_ERROR(dp->dev, "get hpd status failed: %d\n", ret);
439 return ret;
440}
441
442int cdn_dp_get_edid_block(void *data, u8 *edid,
443 unsigned int block, size_t length)
444{
445 struct cdn_dp_device *dp = data;
446 u8 msg[2], reg[2], i;
447 int ret;
448
449 for (i = 0; i < 4; i++) {
450 msg[0] = block / 2;
451 msg[1] = block % 2;
452
453 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_GET_EDID,
454 sizeof(msg), msg);
455 if (ret)
456 continue;
457
458 ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
459 DPTX_GET_EDID,
460 sizeof(reg) + length);
461 if (ret)
462 continue;
463
464 ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
465 if (ret)
466 continue;
467
468 ret = cdn_dp_mailbox_read_receive(dp, edid, length);
469 if (ret)
470 continue;
471
472 if (reg[0] == length && reg[1] == block / 2)
473 break;
474 }
475
476 if (ret)
477 DRM_DEV_ERROR(dp->dev, "get block[%d] edid failed: %d\n", block,
478 ret);
479
480 return ret;
481}
482
483static int cdn_dp_training_start(struct cdn_dp_device *dp)
484{
485 unsigned long timeout;
486 u8 msg, event[2];
487 int ret;
488
489 msg = LINK_TRAINING_RUN;
490
491 /* start training */
492 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_TRAINING_CONTROL,
493 sizeof(msg), &msg);
494 if (ret)
495 goto err_training_start;
496
497 timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
498 while (time_before(jiffies, timeout)) {
499 msleep(LINK_TRAINING_RETRY_MS);
500 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
501 DPTX_READ_EVENT, 0, NULL);
502 if (ret)
503 goto err_training_start;
504
505 ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
506 DPTX_READ_EVENT,
507 sizeof(event));
508 if (ret)
509 goto err_training_start;
510
511 ret = cdn_dp_mailbox_read_receive(dp, event, sizeof(event));
512 if (ret)
513 goto err_training_start;
514
515 if (event[1] & EQ_PHASE_FINISHED)
516 return 0;
517 }
518
519 ret = -ETIMEDOUT;
520
521err_training_start:
522 DRM_DEV_ERROR(dp->dev, "training failed: %d\n", ret);
523 return ret;
524}
525
526static int cdn_dp_get_training_status(struct cdn_dp_device *dp)
527{
528 u8 status[10];
529 int ret;
530
531 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT,
532 0, NULL);
533 if (ret)
534 goto err_get_training_status;
535
536 ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
537 DPTX_READ_LINK_STAT,
538 sizeof(status));
539 if (ret)
540 goto err_get_training_status;
541
542 ret = cdn_dp_mailbox_read_receive(dp, status, sizeof(status));
543 if (ret)
544 goto err_get_training_status;
545
546 dp->link.rate = status[0];
547 dp->link.num_lanes = status[1];
548
549err_get_training_status:
550 if (ret)
551 DRM_DEV_ERROR(dp->dev, "get training status failed: %d\n", ret);
552 return ret;
553}
554
555int cdn_dp_train_link(struct cdn_dp_device *dp)
556{
557 int ret;
558
559 ret = cdn_dp_training_start(dp);
560 if (ret) {
561 DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
562 return ret;
563 }
564
565 ret = cdn_dp_get_training_status(dp);
566 if (ret) {
567 DRM_DEV_ERROR(dp->dev, "Failed to get training stat %d\n", ret);
568 return ret;
569 }
570
571 DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
572 dp->link.num_lanes);
573 return ret;
574}
575
576int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
577{
578 u8 msg;
579 int ret;
580
581 msg = !!active;
582
583 ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
584 sizeof(msg), &msg);
585 if (ret)
586 DRM_DEV_ERROR(dp->dev, "set video status failed: %d\n", ret);
587
588 return ret;
589}
590
591static int cdn_dp_get_msa_misc(struct video_info *video,
592 struct drm_display_mode *mode)
593{
594 u32 msa_misc;
595 u8 val[2];
596
597 switch (video->color_fmt) {
598 case PXL_RGB:
599 case Y_ONLY:
600 val[0] = 0;
601 break;
602 /* set YUV default color space conversion to BT601 */
603 case YCBCR_4_4_4:
604 val[0] = 6 + BT_601 * 8;
605 break;
606 case YCBCR_4_2_2:
607 val[0] = 5 + BT_601 * 8;
608 break;
609 case YCBCR_4_2_0:
610 val[0] = 5;
611 break;
612 };
613
614 switch (video->color_depth) {
615 case 6:
616 val[1] = 0;
617 break;
618 case 8:
619 val[1] = 1;
620 break;
621 case 10:
622 val[1] = 2;
623 break;
624 case 12:
625 val[1] = 3;
626 break;
627 case 16:
628 val[1] = 4;
629 break;
630 };
631
632 msa_misc = 2 * val[0] + 32 * val[1] +
633 ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0);
634
635 return msa_misc;
636}
637
638int cdn_dp_config_video(struct cdn_dp_device *dp)
639{
640 struct video_info *video = &dp->video_info;
641 struct drm_display_mode *mode = &dp->mode;
642 u64 symbol;
643 u32 val, link_rate, rem;
644 u8 bit_per_pix, tu_size_reg = TU_SIZE;
645 int ret;
646
647 bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ?
648 (video->color_depth * 2) : (video->color_depth * 3);
649
650 link_rate = drm_dp_bw_code_to_link_rate(dp->link.rate) / 1000;
651
652 ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
653 if (ret)
654 goto err_config_video;
655
656 ret = cdn_dp_reg_write(dp, HSYNC2VSYNC_POL_CTRL, 0);
657 if (ret)
658 goto err_config_video;
659
660 /*
661 * get a best tu_size and valid symbol:
662 * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
663 * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
664 * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
665 * TU += 2 and repeat 2nd step.
666 */
667 do {
668 tu_size_reg += 2;
669 symbol = tu_size_reg * mode->clock * bit_per_pix;
670 do_div(symbol, dp->link.num_lanes * link_rate * 8);
671 rem = do_div(symbol, 1000);
672 if (tu_size_reg > 64) {
673 ret = -EINVAL;
674 goto err_config_video;
675 }
676 } while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
677 (rem > 850) || (rem < 100));
678
679 val = symbol + (tu_size_reg << 8);
680 val |= TU_CNT_RST_EN;
681 ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val);
682 if (ret)
683 goto err_config_video;
684
685 /* set the FIFO Buffer size */
686 val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
687 val /= (dp->link.num_lanes * link_rate);
688 val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
689 val += 2;
690 ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
691
692 switch (video->color_depth) {
693 case 6:
694 val = BCS_6;
695 break;
696 case 8:
697 val = BCS_8;
698 break;
699 case 10:
700 val = BCS_10;
701 break;
702 case 12:
703 val = BCS_12;
704 break;
705 case 16:
706 val = BCS_16;
707 break;
708 };
709
710 val += video->color_fmt << 8;
711 ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val);
712 if (ret)
713 goto err_config_video;
714
715 val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
716 val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
717 ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val);
718 if (ret)
719 goto err_config_video;
720
721 val = (mode->hsync_start - mode->hdisplay) << 16;
722 val |= mode->htotal - mode->hsync_end;
723 ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val);
724 if (ret)
725 goto err_config_video;
726
727 val = mode->hdisplay * bit_per_pix / 8;
728 ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val);
729 if (ret)
730 goto err_config_video;
731
732 val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
733 ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val);
734 if (ret)
735 goto err_config_video;
736
737 val = mode->hsync_end - mode->hsync_start;
738 val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15);
739 ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val);
740 if (ret)
741 goto err_config_video;
742
743 val = mode->vtotal;
744 val |= (mode->vtotal - mode->vsync_start) << 16;
745 ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val);
746 if (ret)
747 goto err_config_video;
748
749 val = mode->vsync_end - mode->vsync_start;
750 val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15);
751 ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val);
752 if (ret)
753 goto err_config_video;
754
755 val = cdn_dp_get_msa_misc(video, mode);
756 ret = cdn_dp_reg_write(dp, MSA_MISC, val);
757 if (ret)
758 goto err_config_video;
759
760 ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1);
761 if (ret)
762 goto err_config_video;
763
764 val = mode->hsync_end - mode->hsync_start;
765 val |= mode->hdisplay << 16;
766 ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val);
767 if (ret)
768 goto err_config_video;
769
770 val = mode->vdisplay;
771 val |= (mode->vtotal - mode->vsync_start) << 16;
772 ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val);
773 if (ret)
774 goto err_config_video;
775
776 val = mode->vtotal;
777 ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val);
778 if (ret)
779 goto err_config_video;
780
781 ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0);
782
783err_config_video:
784 if (ret)
785 DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret);
786 return ret;
787}
788
789int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio)
790{
791 u32 val;
792 int ret;
793
794 ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0);
795 if (ret) {
796 DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret);
797 return ret;
798 }
799
800 val = SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
801 val |= SPDIF_FIFO_MID_RANGE(0xe0);
802 val |= SPDIF_JITTER_THRSH(0xe0);
803 val |= SPDIF_JITTER_AVG_WIN(7);
804 writel(val, dp->regs + SPDIF_CTRL_ADDR);
805
806 /* clearn the audio config and reset */
807 writel(0, dp->regs + AUDIO_SRC_CNTL);
808 writel(0, dp->regs + AUDIO_SRC_CNFG);
809 writel(AUDIO_SW_RST, dp->regs + AUDIO_SRC_CNTL);
810 writel(0, dp->regs + AUDIO_SRC_CNTL);
811
812 /* reset smpl2pckt component */
813 writel(0, dp->regs + SMPL2PKT_CNTL);
814 writel(AUDIO_SW_RST, dp->regs + SMPL2PKT_CNTL);
815 writel(0, dp->regs + SMPL2PKT_CNTL);
816
817 /* reset FIFO */
818 writel(AUDIO_SW_RST, dp->regs + FIFO_CNTL);
819 writel(0, dp->regs + FIFO_CNTL);
820
821 if (audio->format == AFMT_SPDIF)
822 clk_disable_unprepare(dp->spdif_clk);
823
824 return 0;
825}
826
827int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable)
828{
829 int ret;
830
831 ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 4, 1, enable);
832 if (ret)
833 DRM_DEV_ERROR(dp->dev, "audio mute failed: %d\n", ret);
834
835 return ret;
836}
837
838static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp,
839 struct audio_info *audio)
840{
841 int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
842 u32 val;
843
844 if (audio->channels == 2) {
845 if (dp->link.num_lanes == 1)
846 sub_pckt_num = 2;
847 else
848 sub_pckt_num = 4;
849
850 i2s_port_en_val = 1;
851 } else if (audio->channels == 4) {
852 i2s_port_en_val = 3;
853 }
854
855 writel(0x0, dp->regs + SPDIF_CTRL_ADDR);
856
857 writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
858
859 val = MAX_NUM_CH(audio->channels);
860 val |= NUM_OF_I2S_PORTS(audio->channels);
861 val |= AUDIO_TYPE_LPCM;
862 val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
863 writel(val, dp->regs + SMPL2PKT_CNFG);
864
865 if (audio->sample_width == 16)
866 val = 0;
867 else if (audio->sample_width == 24)
868 val = 1 << 9;
869 else
870 val = 2 << 9;
871
872 val |= AUDIO_CH_NUM(audio->channels);
873 val |= I2S_DEC_PORT_EN(i2s_port_en_val);
874 val |= TRANS_SMPL_WIDTH_32;
875 writel(val, dp->regs + AUDIO_SRC_CNFG);
876
877 for (i = 0; i < (audio->channels + 1) / 2; i++) {
878 if (audio->sample_width == 16)
879 val = (0x02 << 8) | (0x02 << 20);
880 else if (audio->sample_width == 24)
881 val = (0x0b << 8) | (0x0b << 20);
882
883 val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
884 writel(val, dp->regs + STTS_BIT_CH(i));
885 }
886
887 switch (audio->sample_rate) {
888 case 32000:
889 val = SAMPLING_FREQ(3) |
890 ORIGINAL_SAMP_FREQ(0xc);
891 break;
892 case 44100:
893 val = SAMPLING_FREQ(0) |
894 ORIGINAL_SAMP_FREQ(0xf);
895 break;
896 case 48000:
897 val = SAMPLING_FREQ(2) |
898 ORIGINAL_SAMP_FREQ(0xd);
899 break;
900 case 88200:
901 val = SAMPLING_FREQ(8) |
902 ORIGINAL_SAMP_FREQ(0x7);
903 break;
904 case 96000:
905 val = SAMPLING_FREQ(0xa) |
906 ORIGINAL_SAMP_FREQ(5);
907 break;
908 case 176400:
909 val = SAMPLING_FREQ(0xc) |
910 ORIGINAL_SAMP_FREQ(3);
911 break;
912 case 192000:
913 val = SAMPLING_FREQ(0xe) |
914 ORIGINAL_SAMP_FREQ(1);
915 break;
916 }
917 val |= 4;
918 writel(val, dp->regs + COM_CH_STTS_BITS);
919
920 writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
921 writel(I2S_DEC_START, dp->regs + AUDIO_SRC_CNTL);
922}
923
924static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp)
925{
926 u32 val;
927
928 val = SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
929 val |= SPDIF_FIFO_MID_RANGE(0xe0);
930 val |= SPDIF_JITTER_THRSH(0xe0);
931 val |= SPDIF_JITTER_AVG_WIN(7);
932 writel(val, dp->regs + SPDIF_CTRL_ADDR);
933
934 writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
935
936 val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
937 writel(val, dp->regs + SMPL2PKT_CNFG);
938 writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
939
940 val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
941 val |= SPDIF_FIFO_MID_RANGE(0xe0);
942 val |= SPDIF_JITTER_THRSH(0xe0);
943 val |= SPDIF_JITTER_AVG_WIN(7);
944 writel(val, dp->regs + SPDIF_CTRL_ADDR);
945
946 clk_prepare_enable(dp->spdif_clk);
947 clk_set_rate(dp->spdif_clk, CDN_DP_SPDIF_CLK);
948}
949
950int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio)
951{
952 int ret;
953
954 /* reset the spdif clk before config */
955 if (audio->format == AFMT_SPDIF) {
956 reset_control_assert(dp->spdif_rst);
957 reset_control_deassert(dp->spdif_rst);
958 }
959
960 ret = cdn_dp_reg_write(dp, CM_LANE_CTRL, LANE_REF_CYC);
961 if (ret)
962 goto err_audio_config;
963
964 ret = cdn_dp_reg_write(dp, CM_CTRL, 0);
965 if (ret)
966 goto err_audio_config;
967
968 if (audio->format == AFMT_I2S)
969 cdn_dp_audio_config_i2s(dp, audio);
970 else if (audio->format == AFMT_SPDIF)
971 cdn_dp_audio_config_spdif(dp);
972
973 ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
974
975err_audio_config:
976 if (ret)
977 DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
978 return ret;
979}
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
new file mode 100644
index 000000000000..b5f215324694
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
@@ -0,0 +1,483 @@
1/*
2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Author: Chris Zhong <zyw@rock-chips.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef _CDN_DP_REG_H
16#define _CDN_DP_REG_H
17
18#include <linux/bitops.h>
19
20#define ADDR_IMEM 0x10000
21#define ADDR_DMEM 0x20000
22
23/* APB CFG addr */
24#define APB_CTRL 0
25#define XT_INT_CTRL 0x04
26#define MAILBOX_FULL_ADDR 0x08
27#define MAILBOX_EMPTY_ADDR 0x0c
28#define MAILBOX0_WR_DATA 0x10
29#define MAILBOX0_RD_DATA 0x14
30#define KEEP_ALIVE 0x18
31#define VER_L 0x1c
32#define VER_H 0x20
33#define VER_LIB_L_ADDR 0x24
34#define VER_LIB_H_ADDR 0x28
35#define SW_DEBUG_L 0x2c
36#define SW_DEBUG_H 0x30
37#define MAILBOX_INT_MASK 0x34
38#define MAILBOX_INT_STATUS 0x38
39#define SW_CLK_L 0x3c
40#define SW_CLK_H 0x40
41#define SW_EVENTS0 0x44
42#define SW_EVENTS1 0x48
43#define SW_EVENTS2 0x4c
44#define SW_EVENTS3 0x50
45#define XT_OCD_CTRL 0x60
46#define APB_INT_MASK 0x6c
47#define APB_STATUS_MASK 0x70
48
49/* audio decoder addr */
50#define AUDIO_SRC_CNTL 0x30000
51#define AUDIO_SRC_CNFG 0x30004
52#define COM_CH_STTS_BITS 0x30008
53#define STTS_BIT_CH(x) (0x3000c + ((x) << 2))
54#define SPDIF_CTRL_ADDR 0x3004c
55#define SPDIF_CH1_CS_3100_ADDR 0x30050
56#define SPDIF_CH1_CS_6332_ADDR 0x30054
57#define SPDIF_CH1_CS_9564_ADDR 0x30058
58#define SPDIF_CH1_CS_12796_ADDR 0x3005c
59#define SPDIF_CH1_CS_159128_ADDR 0x30060
60#define SPDIF_CH1_CS_191160_ADDR 0x30064
61#define SPDIF_CH2_CS_3100_ADDR 0x30068
62#define SPDIF_CH2_CS_6332_ADDR 0x3006c
63#define SPDIF_CH2_CS_9564_ADDR 0x30070
64#define SPDIF_CH2_CS_12796_ADDR 0x30074
65#define SPDIF_CH2_CS_159128_ADDR 0x30078
66#define SPDIF_CH2_CS_191160_ADDR 0x3007c
67#define SMPL2PKT_CNTL 0x30080
68#define SMPL2PKT_CNFG 0x30084
69#define FIFO_CNTL 0x30088
70#define FIFO_STTS 0x3008c
71
72/* source pif addr */
73#define SOURCE_PIF_WR_ADDR 0x30800
74#define SOURCE_PIF_WR_REQ 0x30804
75#define SOURCE_PIF_RD_ADDR 0x30808
76#define SOURCE_PIF_RD_REQ 0x3080c
77#define SOURCE_PIF_DATA_WR 0x30810
78#define SOURCE_PIF_DATA_RD 0x30814
79#define SOURCE_PIF_FIFO1_FLUSH 0x30818
80#define SOURCE_PIF_FIFO2_FLUSH 0x3081c
81#define SOURCE_PIF_STATUS 0x30820
82#define SOURCE_PIF_INTERRUPT_SOURCE 0x30824
83#define SOURCE_PIF_INTERRUPT_MASK 0x30828
84#define SOURCE_PIF_PKT_ALLOC_REG 0x3082c
85#define SOURCE_PIF_PKT_ALLOC_WR_EN 0x30830
86#define SOURCE_PIF_SW_RESET 0x30834
87
88/* bellow registers need access by mailbox */
89/* source car addr */
90#define SOURCE_HDTX_CAR 0x0900
91#define SOURCE_DPTX_CAR 0x0904
92#define SOURCE_PHY_CAR 0x0908
93#define SOURCE_CEC_CAR 0x090c
94#define SOURCE_CBUS_CAR 0x0910
95#define SOURCE_PKT_CAR 0x0918
96#define SOURCE_AIF_CAR 0x091c
97#define SOURCE_CIPHER_CAR 0x0920
98#define SOURCE_CRYPTO_CAR 0x0924
99
100/* clock meters addr */
101#define CM_CTRL 0x0a00
102#define CM_I2S_CTRL 0x0a04
103#define CM_SPDIF_CTRL 0x0a08
104#define CM_VID_CTRL 0x0a0c
105#define CM_LANE_CTRL 0x0a10
106#define I2S_NM_STABLE 0x0a14
107#define I2S_NCTS_STABLE 0x0a18
108#define SPDIF_NM_STABLE 0x0a1c
109#define SPDIF_NCTS_STABLE 0x0a20
110#define NMVID_MEAS_STABLE 0x0a24
111#define I2S_MEAS 0x0a40
112#define SPDIF_MEAS 0x0a80
113#define NMVID_MEAS 0x0ac0
114
115/* source vif addr */
116#define BND_HSYNC2VSYNC 0x0b00
117#define HSYNC2VSYNC_F1_L1 0x0b04
118#define HSYNC2VSYNC_F2_L1 0x0b08
119#define HSYNC2VSYNC_STATUS 0x0b0c
120#define HSYNC2VSYNC_POL_CTRL 0x0b10
121
122/* dptx phy addr */
123#define DP_TX_PHY_CONFIG_REG 0x2000
124#define DP_TX_PHY_STATUS_REG 0x2004
125#define DP_TX_PHY_SW_RESET 0x2008
126#define DP_TX_PHY_SCRAMBLER_SEED 0x200c
127#define DP_TX_PHY_TRAINING_01_04 0x2010
128#define DP_TX_PHY_TRAINING_05_08 0x2014
129#define DP_TX_PHY_TRAINING_09_10 0x2018
130#define TEST_COR 0x23fc
131
132/* dptx hpd addr */
133#define HPD_IRQ_DET_MIN_TIMER 0x2100
134#define HPD_IRQ_DET_MAX_TIMER 0x2104
135#define HPD_UNPLGED_DET_MIN_TIMER 0x2108
136#define HPD_STABLE_TIMER 0x210c
137#define HPD_FILTER_TIMER 0x2110
138#define HPD_EVENT_MASK 0x211c
139#define HPD_EVENT_DET 0x2120
140
141/* dpyx framer addr */
142#define DP_FRAMER_GLOBAL_CONFIG 0x2200
143#define DP_SW_RESET 0x2204
144#define DP_FRAMER_TU 0x2208
145#define DP_FRAMER_PXL_REPR 0x220c
146#define DP_FRAMER_SP 0x2210
147#define AUDIO_PACK_CONTROL 0x2214
148#define DP_VC_TABLE(x) (0x2218 + ((x) << 2))
149#define DP_VB_ID 0x2258
150#define DP_MTPH_LVP_CONTROL 0x225c
151#define DP_MTPH_SYMBOL_VALUES 0x2260
152#define DP_MTPH_ECF_CONTROL 0x2264
153#define DP_MTPH_ACT_CONTROL 0x2268
154#define DP_MTPH_STATUS 0x226c
155#define DP_INTERRUPT_SOURCE 0x2270
156#define DP_INTERRUPT_MASK 0x2274
157#define DP_FRONT_BACK_PORCH 0x2278
158#define DP_BYTE_COUNT 0x227c
159
160/* dptx stream addr */
161#define MSA_HORIZONTAL_0 0x2280
162#define MSA_HORIZONTAL_1 0x2284
163#define MSA_VERTICAL_0 0x2288
164#define MSA_VERTICAL_1 0x228c
165#define MSA_MISC 0x2290
166#define STREAM_CONFIG 0x2294
167#define AUDIO_PACK_STATUS 0x2298
168#define VIF_STATUS 0x229c
169#define PCK_STUFF_STATUS_0 0x22a0
170#define PCK_STUFF_STATUS_1 0x22a4
171#define INFO_PACK_STATUS 0x22a8
172#define RATE_GOVERNOR_STATUS 0x22ac
173#define DP_HORIZONTAL 0x22b0
174#define DP_VERTICAL_0 0x22b4
175#define DP_VERTICAL_1 0x22b8
176#define DP_BLOCK_SDP 0x22bc
177
178/* dptx glbl addr */
179#define DPTX_LANE_EN 0x2300
180#define DPTX_ENHNCD 0x2304
181#define DPTX_INT_MASK 0x2308
182#define DPTX_INT_STATUS 0x230c
183
184/* dp aux addr */
185#define DP_AUX_HOST_CONTROL 0x2800
186#define DP_AUX_INTERRUPT_SOURCE 0x2804
187#define DP_AUX_INTERRUPT_MASK 0x2808
188#define DP_AUX_SWAP_INVERSION_CONTROL 0x280c
189#define DP_AUX_SEND_NACK_TRANSACTION 0x2810
190#define DP_AUX_CLEAR_RX 0x2814
191#define DP_AUX_CLEAR_TX 0x2818
192#define DP_AUX_TIMER_STOP 0x281c
193#define DP_AUX_TIMER_CLEAR 0x2820
194#define DP_AUX_RESET_SW 0x2824
195#define DP_AUX_DIVIDE_2M 0x2828
196#define DP_AUX_TX_PREACHARGE_LENGTH 0x282c
197#define DP_AUX_FREQUENCY_1M_MAX 0x2830
198#define DP_AUX_FREQUENCY_1M_MIN 0x2834
199#define DP_AUX_RX_PRE_MIN 0x2838
200#define DP_AUX_RX_PRE_MAX 0x283c
201#define DP_AUX_TIMER_PRESET 0x2840
202#define DP_AUX_NACK_FORMAT 0x2844
203#define DP_AUX_TX_DATA 0x2848
204#define DP_AUX_RX_DATA 0x284c
205#define DP_AUX_TX_STATUS 0x2850
206#define DP_AUX_RX_STATUS 0x2854
207#define DP_AUX_RX_CYCLE_COUNTER 0x2858
208#define DP_AUX_MAIN_STATES 0x285c
209#define DP_AUX_MAIN_TIMER 0x2860
210#define DP_AUX_AFE_OUT 0x2864
211
212/* crypto addr */
213#define CRYPTO_HDCP_REVISION 0x5800
214#define HDCP_CRYPTO_CONFIG 0x5804
215#define CRYPTO_INTERRUPT_SOURCE 0x5808
216#define CRYPTO_INTERRUPT_MASK 0x580c
217#define CRYPTO22_CONFIG 0x5818
218#define CRYPTO22_STATUS 0x581c
219#define SHA_256_DATA_IN 0x583c
220#define SHA_256_DATA_OUT_(x) (0x5850 + ((x) << 2))
221#define AES_32_KEY_(x) (0x5870 + ((x) << 2))
222#define AES_32_DATA_IN 0x5880
223#define AES_32_DATA_OUT_(x) (0x5884 + ((x) << 2))
224#define CRYPTO14_CONFIG 0x58a0
225#define CRYPTO14_STATUS 0x58a4
226#define CRYPTO14_PRNM_OUT 0x58a8
227#define CRYPTO14_KM_0 0x58ac
228#define CRYPTO14_KM_1 0x58b0
229#define CRYPTO14_AN_0 0x58b4
230#define CRYPTO14_AN_1 0x58b8
231#define CRYPTO14_YOUR_KSV_0 0x58bc
232#define CRYPTO14_YOUR_KSV_1 0x58c0
233#define CRYPTO14_MI_0 0x58c4
234#define CRYPTO14_MI_1 0x58c8
235#define CRYPTO14_TI_0 0x58cc
236#define CRYPTO14_KI_0 0x58d0
237#define CRYPTO14_KI_1 0x58d4
238#define CRYPTO14_BLOCKS_NUM 0x58d8
239#define CRYPTO14_KEY_MEM_DATA_0 0x58dc
240#define CRYPTO14_KEY_MEM_DATA_1 0x58e0
241#define CRYPTO14_SHA1_MSG_DATA 0x58e4
242#define CRYPTO14_SHA1_V_VALUE_(x) (0x58e8 + ((x) << 2))
243#define TRNG_CTRL 0x58fc
244#define TRNG_DATA_RDY 0x5900
245#define TRNG_DATA 0x5904
246
247/* cipher addr */
248#define HDCP_REVISION 0x60000
249#define INTERRUPT_SOURCE 0x60004
250#define INTERRUPT_MASK 0x60008
251#define HDCP_CIPHER_CONFIG 0x6000c
252#define AES_128_KEY_0 0x60010
253#define AES_128_KEY_1 0x60014
254#define AES_128_KEY_2 0x60018
255#define AES_128_KEY_3 0x6001c
256#define AES_128_RANDOM_0 0x60020
257#define AES_128_RANDOM_1 0x60024
258#define CIPHER14_KM_0 0x60028
259#define CIPHER14_KM_1 0x6002c
260#define CIPHER14_STATUS 0x60030
261#define CIPHER14_RI_PJ_STATUS 0x60034
262#define CIPHER_MODE 0x60038
263#define CIPHER14_AN_0 0x6003c
264#define CIPHER14_AN_1 0x60040
265#define CIPHER22_AUTH 0x60044
266#define CIPHER14_R0_DP_STATUS 0x60048
267#define CIPHER14_BOOTSTRAP 0x6004c
268
269#define DPTX_FRMR_DATA_CLK_RSTN_EN BIT(11)
270#define DPTX_FRMR_DATA_CLK_EN BIT(10)
271#define DPTX_PHY_DATA_RSTN_EN BIT(9)
272#define DPTX_PHY_DATA_CLK_EN BIT(8)
273#define DPTX_PHY_CHAR_RSTN_EN BIT(7)
274#define DPTX_PHY_CHAR_CLK_EN BIT(6)
275#define SOURCE_AUX_SYS_CLK_RSTN_EN BIT(5)
276#define SOURCE_AUX_SYS_CLK_EN BIT(4)
277#define DPTX_SYS_CLK_RSTN_EN BIT(3)
278#define DPTX_SYS_CLK_EN BIT(2)
279#define CFG_DPTX_VIF_CLK_RSTN_EN BIT(1)
280#define CFG_DPTX_VIF_CLK_EN BIT(0)
281
282#define SOURCE_PHY_RSTN_EN BIT(1)
283#define SOURCE_PHY_CLK_EN BIT(0)
284
285#define SOURCE_PKT_SYS_RSTN_EN BIT(3)
286#define SOURCE_PKT_SYS_CLK_EN BIT(2)
287#define SOURCE_PKT_DATA_RSTN_EN BIT(1)
288#define SOURCE_PKT_DATA_CLK_EN BIT(0)
289
290#define SPDIF_CDR_CLK_RSTN_EN BIT(5)
291#define SPDIF_CDR_CLK_EN BIT(4)
292#define SOURCE_AIF_SYS_RSTN_EN BIT(3)
293#define SOURCE_AIF_SYS_CLK_EN BIT(2)
294#define SOURCE_AIF_CLK_RSTN_EN BIT(1)
295#define SOURCE_AIF_CLK_EN BIT(0)
296
297#define SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN BIT(3)
298#define SOURCE_CIPHER_SYS_CLK_EN BIT(2)
299#define SOURCE_CIPHER_CHAR_CLK_RSTN_EN BIT(1)
300#define SOURCE_CIPHER_CHAR_CLK_EN BIT(0)
301
302#define SOURCE_CRYPTO_SYS_CLK_RSTN_EN BIT(1)
303#define SOURCE_CRYPTO_SYS_CLK_EN BIT(0)
304
305#define APB_IRAM_PATH BIT(2)
306#define APB_DRAM_PATH BIT(1)
307#define APB_XT_RESET BIT(0)
308
309#define MAILBOX_INT_MASK_BIT BIT(1)
310#define PIF_INT_MASK_BIT BIT(0)
311#define ALL_INT_MASK 3
312
313/* mailbox */
314#define MB_OPCODE_ID 0
315#define MB_MODULE_ID 1
316#define MB_SIZE_MSB_ID 2
317#define MB_SIZE_LSB_ID 3
318#define MB_DATA_ID 4
319
320#define MB_MODULE_ID_DP_TX 0x01
321#define MB_MODULE_ID_HDCP_TX 0x07
322#define MB_MODULE_ID_HDCP_RX 0x08
323#define MB_MODULE_ID_HDCP_GENERAL 0x09
324#define MB_MODULE_ID_GENERAL 0x0a
325
326/* general opcode */
327#define GENERAL_MAIN_CONTROL 0x01
328#define GENERAL_TEST_ECHO 0x02
329#define GENERAL_BUS_SETTINGS 0x03
330#define GENERAL_TEST_ACCESS 0x04
331
332#define DPTX_SET_POWER_MNG 0x00
333#define DPTX_SET_HOST_CAPABILITIES 0x01
334#define DPTX_GET_EDID 0x02
335#define DPTX_READ_DPCD 0x03
336#define DPTX_WRITE_DPCD 0x04
337#define DPTX_ENABLE_EVENT 0x05
338#define DPTX_WRITE_REGISTER 0x06
339#define DPTX_READ_REGISTER 0x07
340#define DPTX_WRITE_FIELD 0x08
341#define DPTX_TRAINING_CONTROL 0x09
342#define DPTX_READ_EVENT 0x0a
343#define DPTX_READ_LINK_STAT 0x0b
344#define DPTX_SET_VIDEO 0x0c
345#define DPTX_SET_AUDIO 0x0d
346#define DPTX_GET_LAST_AUX_STAUS 0x0e
347#define DPTX_SET_LINK_BREAK_POINT 0x0f
348#define DPTX_FORCE_LANES 0x10
349#define DPTX_HPD_STATE 0x11
350
351#define FW_STANDBY 0
352#define FW_ACTIVE 1
353
354#define DPTX_EVENT_ENABLE_HPD BIT(0)
355#define DPTX_EVENT_ENABLE_TRAINING BIT(1)
356
357#define LINK_TRAINING_NOT_ACTIVE 0
358#define LINK_TRAINING_RUN 1
359#define LINK_TRAINING_RESTART 2
360
361#define CONTROL_VIDEO_IDLE 0
362#define CONTROL_VIDEO_VALID 1
363
364#define TU_CNT_RST_EN BIT(15)
365#define VIF_BYPASS_INTERLACE BIT(13)
366#define INTERLACE_FMT_DET BIT(12)
367#define INTERLACE_DTCT_WIN 0x20
368
369#define DP_FRAMER_SP_INTERLACE_EN BIT(2)
370#define DP_FRAMER_SP_HSP BIT(1)
371#define DP_FRAMER_SP_VSP BIT(0)
372
373/* capability */
374#define AUX_HOST_INVERT 3
375#define FAST_LT_SUPPORT 1
376#define FAST_LT_NOT_SUPPORT 0
377#define LANE_MAPPING_NORMAL 0x1b
378#define LANE_MAPPING_FLIPPED 0xe4
379#define ENHANCED 1
380#define SCRAMBLER_EN BIT(4)
381
382#define FULL_LT_STARTED BIT(0)
383#define FASE_LT_STARTED BIT(1)
384#define CLK_RECOVERY_FINISHED BIT(2)
385#define EQ_PHASE_FINISHED BIT(3)
386#define FASE_LT_START_FINISHED BIT(4)
387#define CLK_RECOVERY_FAILED BIT(5)
388#define EQ_PHASE_FAILED BIT(6)
389#define FASE_LT_FAILED BIT(7)
390
391#define DPTX_HPD_EVENT BIT(0)
392#define DPTX_TRAINING_EVENT BIT(1)
393#define HDCP_TX_STATUS_EVENT BIT(4)
394#define HDCP2_TX_IS_KM_STORED_EVENT BIT(5)
395#define HDCP2_TX_STORE_KM_EVENT BIT(6)
396#define HDCP_TX_IS_RECEIVER_ID_VALID_EVENT BIT(7)
397
398#define TU_SIZE 30
399#define CDN_DP_MAX_LINK_RATE DP_LINK_BW_5_4
400
401/* audio */
402#define AUDIO_PACK_EN BIT(8)
403#define SAMPLING_FREQ(x) (((x) & 0xf) << 16)
404#define ORIGINAL_SAMP_FREQ(x) (((x) & 0xf) << 24)
405#define SYNC_WR_TO_CH_ZERO BIT(1)
406#define I2S_DEC_START BIT(1)
407#define AUDIO_SW_RST BIT(0)
408#define SMPL2PKT_EN BIT(1)
409#define MAX_NUM_CH(x) (((x) & 0x1f) - 1)
410#define NUM_OF_I2S_PORTS(x) ((((x) / 2 - 1) & 0x3) << 5)
411#define AUDIO_TYPE_LPCM (2 << 7)
412#define CFG_SUB_PCKT_NUM(x) ((((x) - 1) & 0x7) << 11)
413#define AUDIO_CH_NUM(x) ((((x) - 1) & 0x1f) << 2)
414#define TRANS_SMPL_WIDTH_16 0
415#define TRANS_SMPL_WIDTH_24 BIT(11)
416#define TRANS_SMPL_WIDTH_32 (2 << 11)
417#define I2S_DEC_PORT_EN(x) (((x) & 0xf) << 17)
418#define SPDIF_ENABLE BIT(21)
419#define SPDIF_AVG_SEL BIT(20)
420#define SPDIF_JITTER_BYPASS BIT(19)
421#define SPDIF_FIFO_MID_RANGE(x) (((x) & 0xff) << 11)
422#define SPDIF_JITTER_THRSH(x) (((x) & 0xff) << 3)
423#define SPDIF_JITTER_AVG_WIN(x) ((x) & 0x7)
424
425/* Reference cycles when using lane clock as reference */
426#define LANE_REF_CYC 0x8000
427
428enum voltage_swing_level {
429 VOLTAGE_LEVEL_0,
430 VOLTAGE_LEVEL_1,
431 VOLTAGE_LEVEL_2,
432 VOLTAGE_LEVEL_3,
433};
434
435enum pre_emphasis_level {
436 PRE_EMPHASIS_LEVEL_0,
437 PRE_EMPHASIS_LEVEL_1,
438 PRE_EMPHASIS_LEVEL_2,
439 PRE_EMPHASIS_LEVEL_3,
440};
441
442enum pattern_set {
443 PTS1 = BIT(0),
444 PTS2 = BIT(1),
445 PTS3 = BIT(2),
446 PTS4 = BIT(3),
447 DP_NONE = BIT(4)
448};
449
450enum vic_color_depth {
451 BCS_6 = 0x1,
452 BCS_8 = 0x2,
453 BCS_10 = 0x4,
454 BCS_12 = 0x8,
455 BCS_16 = 0x10,
456};
457
458enum vic_bt_type {
459 BT_601 = 0x0,
460 BT_709 = 0x1,
461};
462
463void cdn_dp_clock_reset(struct cdn_dp_device *dp);
464
465void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, u32 clk);
466int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
467 u32 i_size, const u32 *d_mem, u32 d_size);
468int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable);
469int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip);
470int cdn_dp_event_config(struct cdn_dp_device *dp);
471u32 cdn_dp_get_event(struct cdn_dp_device *dp);
472int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
473int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value);
474int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len);
475int cdn_dp_get_edid_block(void *dp, u8 *edid,
476 unsigned int block, size_t length);
477int cdn_dp_train_link(struct cdn_dp_device *dp);
478int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active);
479int cdn_dp_config_video(struct cdn_dp_device *dp);
480int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
481int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
482int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
483#endif /* _CDN_DP_REG_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index d5e1f8627d38..c9ccdf8f44bb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -213,7 +213,7 @@ rockchip_drm_framebuffer_init(struct drm_device *dev,
213 213
214 rockchip_fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1); 214 rockchip_fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1);
215 if (IS_ERR(rockchip_fb)) 215 if (IS_ERR(rockchip_fb))
216 return NULL; 216 return ERR_CAST(rockchip_fb);
217 217
218 return &rockchip_fb->fb; 218 return &rockchip_fb->fb;
219} 219}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fb5f001f51c3..76c79ac57df0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -531,6 +531,8 @@ static int vop_enable(struct drm_crtc *crtc)
531 } 531 }
532 532
533 memcpy(vop->regs, vop->regsbak, vop->len); 533 memcpy(vop->regs, vop->regsbak, vop->len);
534 vop_cfg_done(vop);
535
534 /* 536 /*
535 * At here, vop clock & iommu is enable, R/W vop regs would be safe. 537 * At here, vop clock & iommu is enable, R/W vop regs would be safe.
536 */ 538 */
@@ -582,6 +584,8 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
582 spin_unlock(&vop->reg_lock); 584 spin_unlock(&vop->reg_lock);
583 } 585 }
584 586
587 vop_cfg_done(vop);
588
585 drm_crtc_vblank_off(crtc); 589 drm_crtc_vblank_off(crtc);
586 590
587 /* 591 /*
@@ -932,9 +936,11 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
932 vop_dsp_hold_valid_irq_disable(vop); 936 vop_dsp_hold_valid_irq_disable(vop);
933 } 937 }
934 938
935 pin_pol = 0x8; 939 pin_pol = BIT(DCLK_INVERT);
936 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1; 940 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ?
937 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1); 941 0 : BIT(HSYNC_POSITIVE);
942 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ?
943 0 : BIT(VSYNC_POSITIVE);
938 VOP_CTRL_SET(vop, pin_pol, pin_pol); 944 VOP_CTRL_SET(vop, pin_pol, pin_pol);
939 945
940 switch (s->output_type) { 946 switch (s->output_type) {
@@ -954,6 +960,11 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
954 VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol); 960 VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol);
955 VOP_CTRL_SET(vop, mipi_en, 1); 961 VOP_CTRL_SET(vop, mipi_en, 1);
956 break; 962 break;
963 case DRM_MODE_CONNECTOR_DisplayPort:
964 pin_pol &= ~BIT(DCLK_INVERT);
965 VOP_CTRL_SET(vop, dp_pin_pol, pin_pol);
966 VOP_CTRL_SET(vop, dp_en, 1);
967 break;
957 default: 968 default:
958 DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n", 969 DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
959 s->output_type); 970 s->output_type);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 1dbc52615257..5a4faa85dbd2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -45,6 +45,7 @@ struct vop_ctrl {
45 struct vop_reg edp_en; 45 struct vop_reg edp_en;
46 struct vop_reg hdmi_en; 46 struct vop_reg hdmi_en;
47 struct vop_reg mipi_en; 47 struct vop_reg mipi_en;
48 struct vop_reg dp_en;
48 struct vop_reg out_mode; 49 struct vop_reg out_mode;
49 struct vop_reg dither_down; 50 struct vop_reg dither_down;
50 struct vop_reg dither_up; 51 struct vop_reg dither_up;
@@ -53,6 +54,7 @@ struct vop_ctrl {
53 struct vop_reg hdmi_pin_pol; 54 struct vop_reg hdmi_pin_pol;
54 struct vop_reg edp_pin_pol; 55 struct vop_reg edp_pin_pol;
55 struct vop_reg mipi_pin_pol; 56 struct vop_reg mipi_pin_pol;
57 struct vop_reg dp_pin_pol;
56 58
57 struct vop_reg htotal_pw; 59 struct vop_reg htotal_pw;
58 struct vop_reg hact_st_end; 60 struct vop_reg hact_st_end;
@@ -244,6 +246,13 @@ enum scale_down_mode {
244 SCALE_DOWN_AVG = 0x1 246 SCALE_DOWN_AVG = 0x1
245}; 247};
246 248
249enum vop_pol {
250 HSYNC_POSITIVE = 0,
251 VSYNC_POSITIVE = 1,
252 DEN_NEGATIVE = 2,
253 DCLK_INVERT = 3
254};
255
247#define FRAC_16_16(mult, div) (((mult) << 16) / (div)) 256#define FRAC_16_16(mult, div) (((mult) << 16) / (div))
248#define SCL_FT_DEFAULT_FIXPOINT_SHIFT 12 257#define SCL_FT_DEFAULT_FIXPOINT_SHIFT 12
249#define SCL_MAX_VSKIPLINES 4 258#define SCL_MAX_VSKIPLINES 4
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 35c51f3402f2..91fbc7b52147 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -284,6 +284,7 @@ static const struct vop_data rk3288_vop = {
284static const struct vop_ctrl rk3399_ctrl_data = { 284static const struct vop_ctrl rk3399_ctrl_data = {
285 .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22), 285 .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22),
286 .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23), 286 .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
287 .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
287 .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12), 288 .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12),
288 .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13), 289 .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13),
289 .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14), 290 .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14),
@@ -293,6 +294,7 @@ static const struct vop_ctrl rk3399_ctrl_data = {
293 .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19), 294 .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
294 .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0), 295 .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
295 .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16), 296 .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
297 .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
296 .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20), 298 .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20),
297 .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24), 299 .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24),
298 .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28), 300 .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28),