1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3 * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4 * Author: Andy Yan <andy.yan@rock-chips.com>
5 */
6 #include <drm/drm.h>
7 #include <drm/drm_atomic.h>
8 #include <drm/drm_atomic_uapi.h>
9 #include <drm/drm_crtc.h>
10 #include <drm/drm_crtc_helper.h>
11 #include <drm/drm_debugfs.h>
12 #include <drm/drm_flip_work.h>
13 #include <drm/drm_fourcc.h>
14 #include <drm/drm_gem_framebuffer_helper.h>
15 #include <drm/drm_plane_helper.h>
16 #include <drm/drm_probe_helper.h>
17 #include <drm/drm_self_refresh_helper.h>
18
19 #include <drm/drm_writeback.h>
20 #ifdef CONFIG_DRM_ANALOGIX_DP
21 #include <drm/bridge/analogix_dp.h>
22 #endif
23 #include <dt-bindings/soc/rockchip-system-status.h>
24
25 #include <linux/debugfs.h>
26 #include <linux/fixp-arith.h>
27 #include <linux/iopoll.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/platform_device.h>
31 #include <linux/clk.h>
32 #include <linux/clk-provider.h>
33 #include <linux/clk/clk-conf.h>
34 #include <linux/iopoll.h>
35 #include <linux/of.h>
36 #include <linux/of_device.h>
37 #include <linux/of_graph.h>
38 #include <linux/pm_runtime.h>
39 #include <linux/component.h>
40 #include <linux/regmap.h>
41 #include <linux/reset.h>
42 #include <linux/mfd/syscon.h>
43 #include <linux/delay.h>
44 #include <linux/swab.h>
45 #include <linux/sort.h>
46 #include <linux/rockchip/cpu.h>
47 #include <linux/workqueue.h>
48 #include <linux/types.h>
49 #include <soc/rockchip/rockchip_dmc.h>
50 #include <soc/rockchip/rockchip-system-status.h>
51 #include <uapi/linux/videodev2.h>
52
53 #include "../drm_crtc_internal.h"
54 #include "../drm_internal.h"
55
56 #include "rockchip_drm_drv.h"
57 #include "rockchip_drm_gem.h"
58 #include "rockchip_drm_fb.h"
59 #include "rockchip_drm_vop.h"
60 #include "rockchip_vop_reg.h"
61 #include "rockchip_post_csc.h"
62
63 #define _REG_SET(vop2, name, off, reg, mask, v, relaxed) \
64 vop2_mask_write(vop2, off + reg.offset, mask, reg.shift, v, reg.write_mask, relaxed)
65
66 #define REG_SET(x, name, off, reg, v, relaxed) \
67 _REG_SET(x, name, off, reg, reg.mask, v, relaxed)
68 #define REG_SET_MASK(x, name, off, reg, mask, v, relaxed) \
69 _REG_SET(x, name, off, reg, reg.mask & mask, v, relaxed)
70
71 #define REG_GET(vop2, reg) ((vop2_readl(vop2, reg.offset) >> reg.shift) & reg.mask)
72
73 #define VOP_CLUSTER_SET(x, win, name, v) \
74 do { \
75 if (win->regs->cluster) \
76 REG_SET(x, name, 0, win->regs->cluster->name, v, true); \
77 } while (0)
78
79 #define VOP_AFBC_SET(x, win, name, v) \
80 do { \
81 if (win->regs->afbc) \
82 REG_SET(x, name, win->offset, win->regs->afbc->name, v, true); \
83 } while (0)
84
85 #define VOP_WIN_SET(x, win, name, v) \
86 REG_SET(x, name, win->offset, VOP_WIN_NAME(win, name), v, true)
87
88 #define VOP_SCL_SET(x, win, name, v) \
89 REG_SET(x, name, win->offset, win->regs->scl->name, v, true)
90
91 #define VOP_CTRL_SET(x, name, v) \
92 REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
93
94 #define VOP_CTRL_GET(x, name) vop2_read_reg(x, 0, &(x)->data->ctrl->name)
95
96 #define VOP_INTR_GET(vop2, name) \
97 vop2_read_reg(vop2, 0, &vop2->data->ctrl->name)
98
99 #define VOP_INTR_SET(vop2, intr, name, v) \
100 REG_SET(vop2, name, 0, intr->name, v, false)
101
102 #define VOP_MODULE_SET(vop2, module, name, v) \
103 REG_SET(vop2, name, 0, module->regs->name, v, false)
104
105 #define VOP_INTR_SET_MASK(vop2, intr, name, mask, v) \
106 REG_SET_MASK(vop2, name, 0, intr->name, mask, v, false)
107
108 #define VOP_INTR_SET_TYPE(vop2, intr, name, type, v) \
109 do { \
110 int i, reg = 0, mask = 0; \
111 for (i = 0; i < intr->nintrs; i++) { \
112 if (intr->intrs[i] & type) { \
113 reg |= (v) << i; \
114 mask |= 1 << i; \
115 } \
116 } \
117 VOP_INTR_SET_MASK(vop2, intr, name, mask, reg); \
118 } while (0)
119
120 #define VOP_INTR_GET_TYPE(vop2, intr, name, type) \
121 vop2_get_intr_type(vop2, intr, &intr->name, type)
122
123 #define VOP_MODULE_GET(x, module, name) \
124 vop2_read_reg(x, 0, &module->regs->name)
125
126 #define VOP_WIN_GET(vop2, win, name) \
127 vop2_read_reg(vop2, win->offset, &VOP_WIN_NAME(win, name))
128
129 #define VOP_WIN_GET_REG_BAK(vop2, win, name) \
130 vop2_read_reg_bak(vop2, win->offset, &VOP_WIN_NAME(win, name))
131
132 #define VOP_WIN_NAME(win, name) \
133 (vop2_get_win_regs(win, &win->regs->name)->name)
134
135 #define VOP_WIN_TO_INDEX(vop2_win) \
136 ((vop2_win) - (vop2_win)->vop2->win)
137
138 #define VOP_GRF_SET(vop2, grf, reg, v) \
139 do { \
140 if (vop2->data->grf) { \
141 vop2_grf_writel(vop2->grf, vop2->data->grf->reg, v); \
142 } \
143 } while (0)
144
145 #define to_vop2_win(x) container_of(x, struct vop2_win, base)
146 #define to_vop2_plane_state(x) container_of(x, struct vop2_plane_state, base)
147 #define to_wb_state(x) container_of(x, struct vop2_wb_connector_state, base)
148 #define output_if_is_hdmi(x) (x & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1))
149 #define output_if_is_dp(x) (x & (VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1))
150 #define output_if_is_edp(x) (x & (VOP_OUTPUT_IF_eDP0 | VOP_OUTPUT_IF_eDP1))
151 #define output_if_is_mipi(x) (x & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_MIPI1))
152 #define output_if_is_lvds(x) (x & (VOP_OUTPUT_IF_LVDS0 | VOP_OUTPUT_IF_LVDS1))
153 #define output_if_is_dpi(x) (x & (VOP_OUTPUT_IF_BT656 | VOP_OUTPUT_IF_BT1120 | \
154 VOP_OUTPUT_IF_RGB))
155
156 /*
157 * max two jobs a time, one is running(writing back),
158 * another one will run in next frame.
159 */
160 #define VOP2_WB_JOB_MAX 2
161 #define VOP2_SYS_AXI_BUS_NUM 2
162
163 #define VOP2_MAX_VP_OUTPUT_WIDTH 4096
164 /* KHZ */
165 #define VOP2_MAX_DCLK_RATE 600000
166 /* KHZ */
167 #define VOP2_COMMON_ACLK_RATE 500000
168
169 enum vop2_data_format {
170 VOP2_FMT_ARGB8888 = 0,
171 VOP2_FMT_RGB888,
172 VOP2_FMT_RGB565,
173 VOP2_FMT_XRGB101010,
174 VOP2_FMT_YUV420SP,
175 VOP2_FMT_YUV422SP,
176 VOP2_FMT_YUV444SP,
177 VOP2_FMT_YUYV422 = 8,
178 VOP2_FMT_YUYV420,
179 VOP2_FMT_VYUY422,
180 VOP2_FMT_VYUY420,
181 VOP2_FMT_YUV420SP_TILE_8x4 = 0x10,
182 VOP2_FMT_YUV420SP_TILE_16x2,
183 VOP2_FMT_YUV422SP_TILE_8x4,
184 VOP2_FMT_YUV422SP_TILE_16x2,
185 VOP2_FMT_YUV420SP_10,
186 VOP2_FMT_YUV422SP_10,
187 VOP2_FMT_YUV444SP_10,
188 };
189
190 enum vop2_afbc_format {
191 VOP2_AFBC_FMT_RGB565,
192 VOP2_AFBC_FMT_ARGB2101010 = 2,
193 VOP2_AFBC_FMT_YUV420_10BIT,
194 VOP2_AFBC_FMT_RGB888,
195 VOP2_AFBC_FMT_ARGB8888,
196 VOP2_AFBC_FMT_YUV420 = 9,
197 VOP2_AFBC_FMT_YUV422 = 0xb,
198 VOP2_AFBC_FMT_YUV422_10BIT = 0xe,
199 VOP2_AFBC_FMT_INVALID = -1,
200 };
201
202 enum vop2_tiled_format {
203 VOP2_TILED_8X8_FMT_YUV420SP = 0xc,
204 VOP2_TILED_8X8_FMT_YUV422SP,
205 VOP2_TILED_8X8_FMT_YUV444SP,
206 VOP2_TILED_8X8_FMT_YUV400SP,
207 VOP2_TILED_8X8_FMT_YUV420SP_10 = 0x1c,
208 VOP2_TILED_8X8_FMT_YUV422SP_10,
209 VOP2_TILED_8X8_FMT_YUV444SP_10,
210 VOP2_TILED_8X8_FMT_YUV400SP_10,
211 VOP2_TILED_FMT_INVALID = -1,
212 };
213
214 enum vop3_tiled_format {
215 VOP3_TILED_4X4_FMT_YUV420SP = 0xc,
216 VOP3_TILED_4X4_FMT_YUV422SP,
217 VOP3_TILED_4X4_FMT_YUV444SP,
218 VOP3_TILED_4X4_FMT_YUV400SP,
219 VOP3_TILED_4X4_FMT_YUV420SP_10 = 0x1c,
220 VOP3_TILED_4X4_FMT_YUV422SP_10,
221 VOP3_TILED_4X4_FMT_YUV444SP_10,
222 VOP3_TILED_4X4_FMT_YUV400SP_10,
223
224 VOP3_TILED_8X8_FMT_YUV420SP = 0x2c,
225 VOP3_TILED_8X8_FMT_YUV422SP,
226 VOP3_TILED_8X8_FMT_YUV444SP,
227 VOP3_TILED_8X8_FMT_YUV400SP,
228 VOP3_TILED_8X8_FMT_YUV420SP_10 = 0x3c,
229 VOP3_TILED_8X8_FMT_YUV422SP_10,
230 VOP3_TILED_8X8_FMT_YUV444SP_10,
231 VOP3_TILED_8X8_FMT_YUV400SP_10,
232
233 VOP3_TILED_FMT_INVALID = -1,
234 };
235
236 enum vop2_hdr_lut_mode {
237 VOP2_HDR_LUT_MODE_AXI,
238 VOP2_HDR_LUT_MODE_AHB,
239 };
240
241 enum vop2_pending {
242 VOP_PENDING_FB_UNREF,
243 };
244
245 enum vop2_layer_phy_id {
246 ROCKCHIP_VOP2_CLUSTER0 = 0,
247 ROCKCHIP_VOP2_CLUSTER1,
248 ROCKCHIP_VOP2_ESMART0,
249 ROCKCHIP_VOP2_ESMART1,
250 ROCKCHIP_VOP2_SMART0,
251 ROCKCHIP_VOP2_SMART1,
252 ROCKCHIP_VOP2_CLUSTER2,
253 ROCKCHIP_VOP2_CLUSTER3,
254 ROCKCHIP_VOP2_ESMART2,
255 ROCKCHIP_VOP2_ESMART3,
256 ROCKCHIP_VOP2_PHY_ID_INVALID = -1,
257 };
258
259 struct vop2_power_domain {
260 struct vop2_power_domain *parent;
261 struct vop2 *vop2;
262 /*
263 * @lock: protect power up/down procedure.
264 * power on take effect immediately,
265 * power down take effect by vsync.
266 * we must check power_domain_status register
267 * to make sure the power domain is down before
268 * send a power on request.
269 *
270 */
271 spinlock_t lock;
272 unsigned int ref_count;
273 bool on;
274 /* @vp_mask: Bit mask of video port of the power domain's
275 * module attached to.
276 * For example: PD_CLUSTER0 belongs to module Cluster0, it's
277 * bitmask is the VP which Cluster0 attached to. PD_ESMART is
278 * shared between Esmart1/2/3, it's bitmask will be all the VP
279 * which Esmart1/2/3 attached to.
280 * This is used to check if we can power off a PD by vsync.
281 */
282 uint8_t vp_mask;
283
284 const struct vop2_power_domain_data *data;
285 struct list_head list;
286 struct delayed_work power_off_work;
287 };
288
289 struct vop2_zpos {
290 struct drm_plane *plane;
291 int win_phys_id;
292 int zpos;
293 };
294
295 union vop2_alpha_ctrl {
296 uint32_t val;
297 struct {
298 /* [0:1] */
299 uint32_t color_mode:1;
300 uint32_t alpha_mode:1;
301 /* [2:3] */
302 uint32_t blend_mode:2;
303 uint32_t alpha_cal_mode:1;
304 /* [5:7] */
305 uint32_t factor_mode:3;
306 /* [8:9] */
307 uint32_t alpha_en:1;
308 uint32_t src_dst_swap:1;
309 uint32_t reserved:6;
310 /* [16:23] */
311 uint32_t glb_alpha:8;
312 } bits;
313 };
314
315 union vop2_bg_alpha_ctrl {
316 uint32_t val;
317 struct {
318 /* [0:1] */
319 uint32_t alpha_en:1;
320 uint32_t alpha_mode:1;
321 /* [2:3] */
322 uint32_t alpha_pre_mul:1;
323 uint32_t alpha_sat_mode:1;
324 /* [4:7] */
325 uint32_t reserved:4;
326 /* [8:15] */
327 uint32_t glb_alpha:8;
328 } bits;
329 };
330
331 struct vop2_alpha {
332 union vop2_alpha_ctrl src_color_ctrl;
333 union vop2_alpha_ctrl dst_color_ctrl;
334 union vop2_alpha_ctrl src_alpha_ctrl;
335 union vop2_alpha_ctrl dst_alpha_ctrl;
336 };
337
338 struct vop2_alpha_config {
339 bool src_premulti_en;
340 bool dst_premulti_en;
341 bool src_pixel_alpha_en;
342 bool dst_pixel_alpha_en;
343 u16 src_glb_alpha_value;
344 u16 dst_glb_alpha_value;
345 };
346
347 struct vop2_plane_state {
348 struct drm_plane_state base;
349 int format;
350 int zpos;
351 struct drm_rect src;
352 struct drm_rect dest;
353 dma_addr_t yrgb_mst;
354 dma_addr_t uv_mst;
355 bool afbc_en;
356 bool hdr_in;
357 bool hdr2sdr_en;
358 bool r2y_en;
359 bool y2r_en;
360 uint32_t csc_mode;
361 uint8_t xmirror_en;
362 uint8_t ymirror_en;
363 uint8_t rotate_90_en;
364 uint8_t rotate_270_en;
365 uint8_t afbc_half_block_en;
366 uint8_t tiled_en;
367 int eotf;
368 int color_space;
369 int global_alpha;
370 int blend_mode;
371 uint64_t color_key;
372 unsigned long offset;
373 int pdaf_data_type;
374 bool async_commit;
375 struct vop_dump_list *planlist;
376 };
377
378 struct vop2_win {
379 const char *name;
380 struct vop2 *vop2;
381 struct vop2_win *parent;
382 struct drm_plane base;
383
384 /*
385 * This is for cluster window
386 *
387 * A cluster window can split as two windows:
388 * a main window and a sub window.
389 */
390 bool two_win_mode;
391
392 /**
393 * ---------------------------
394 * | | |
395 * | Left | Right |
396 * | | |
397 * | Cluster0 | Cluster1 |
398 * ---------------------------
399 */
400
401 /*
402 * @splice_mode_right: As right part of the screen in splice mode.
403 */
404 bool splice_mode_right;
405
406 /**
407 * @splice_win: splice win which used to splice for a plane
408 * hdisplay > 4096
409 */
410 struct vop2_win *splice_win;
411 struct vop2_win *left_win;
412
413 uint8_t splice_win_id;
414
415 struct vop2_power_domain *pd;
416
417 /**
418 * @phys_id: physical id for cluster0/1, esmart0/1, smart0/1
419 * Will be used as a identification for some register
420 * configuration such as OVL_LAYER_SEL/OVL_PORT_SEL.
421 */
422 uint8_t phys_id;
423
424 /**
425 * @win_id: graphic window id, a cluster maybe split into two
426 * graphics windows.
427 */
428 uint8_t win_id;
429 /**
430 * @area_id: multi display region id in a graphic window, they
431 * share the same win_id.
432 */
433 uint8_t area_id;
434 /**
435 * @plane_id: unique plane id.
436 */
437 uint8_t plane_id;
438 /**
439 * @layer_id: id of the layer which the window attached to
440 */
441 uint8_t layer_id;
442 const uint8_t *layer_sel_id;
443 /**
444 * @vp_mask: Bitmask of video_port0/1/2 this win attached to,
445 * one win can only attach to one vp at the one time.
446 */
447 uint8_t vp_mask;
448 /**
449 * @old_vp_mask: Bitmask of video_port0/1/2 this win attached of last commit,
450 * this is used for trackng the change of VOP2_PORT_SEL register.
451 */
452 uint8_t old_vp_mask;
453 uint8_t zpos;
454 uint32_t offset;
455 uint8_t axi_id;
456 uint8_t axi_yrgb_id;
457 uint8_t axi_uv_id;
458 uint8_t scale_engine_num;
459 uint8_t possible_crtcs;
460 enum drm_plane_type type;
461 unsigned int max_upscale_factor;
462 unsigned int max_downscale_factor;
463 unsigned int supported_rotations;
464 const uint8_t *dly;
465 /*
466 * vertical/horizontal scale up/down filter mode
467 */
468 uint8_t hsu_filter_mode;
469 uint8_t hsd_filter_mode;
470 uint8_t vsu_filter_mode;
471 uint8_t vsd_filter_mode;
472 uint8_t hsd_pre_filter_mode;
473 uint8_t vsd_pre_filter_mode;
474
475 const struct vop2_win_regs *regs;
476 const uint64_t *format_modifiers;
477 const uint32_t *formats;
478 uint32_t nformats;
479 uint64_t feature;
480 struct drm_property *feature_prop;
481 struct drm_property *input_width_prop;
482 struct drm_property *input_height_prop;
483 struct drm_property *output_width_prop;
484 struct drm_property *output_height_prop;
485 struct drm_property *color_key_prop;
486 struct drm_property *scale_prop;
487 struct drm_property *name_prop;
488 };
489
490 struct vop2_cluster {
491 bool splice_mode;
492 struct vop2_win *main;
493 struct vop2_win *sub;
494 };
495
496 struct vop2_layer {
497 uint8_t id;
498 /*
499 * @win_phys_id: window id of the layer selected.
500 * Every layer must make sure to select different
501 * windows of others.
502 */
503 uint8_t win_phys_id;
504 const struct vop2_layer_regs *regs;
505 };
506
507 struct vop2_wb_job {
508
509 bool pending;
510 /**
511 * @fs_vsync_cnt: frame start vysnc counter,
512 * used to get the write back complete event;
513 */
514 uint32_t fs_vsync_cnt;
515 };
516
517 struct vop2_wb {
518 uint8_t vp_id;
519 struct drm_writeback_connector conn;
520 const struct vop2_wb_regs *regs;
521 struct vop2_wb_job jobs[VOP2_WB_JOB_MAX];
522 uint8_t job_index;
523
524 /**
525 * @job_lock:
526 *
527 * spinlock to protect the job between vop2_wb_commit and vop2_wb_handler in isr.
528 */
529 spinlock_t job_lock;
530
531 };
532
533 struct vop2_dsc {
534 uint8_t id;
535 uint8_t max_slice_num;
536 uint8_t max_linebuf_depth; /* used to generate the bitstream */
537 uint8_t min_bits_per_pixel; /* bit num after encoder compress */
538 bool enabled;
539 char attach_vp_id;
540 const struct vop2_dsc_regs *regs;
541 struct vop2_power_domain *pd;
542 };
543
544 enum vop2_wb_format {
545 VOP2_WB_ARGB8888,
546 VOP2_WB_BGR888,
547 VOP2_WB_RGB565,
548 VOP2_WB_YUV420SP = 4,
549 VOP2_WB_INVALID = -1,
550 };
551
552 struct vop2_wb_connector_state {
553 struct drm_connector_state base;
554 dma_addr_t yrgb_addr;
555 dma_addr_t uv_addr;
556 enum vop2_wb_format format;
557 uint16_t scale_x_factor;
558 uint8_t scale_x_en;
559 uint8_t scale_y_en;
560 uint8_t vp_id;
561 };
562
563 struct vop2_video_port {
564 struct rockchip_crtc rockchip_crtc;
565 struct rockchip_mcu_timing mcu_timing;
566 struct vop2 *vop2;
567 struct reset_control *dclk_rst;
568 struct clk *dclk;
569 struct clk *dclk_parent;
570 uint8_t id;
571 bool layer_sel_update;
572 bool xmirror_en;
573 bool need_reset_p2i_flag;
574 atomic_t post_buf_empty_flag;
575 const struct vop2_video_port_regs *regs;
576
577 struct completion dsp_hold_completion;
578 struct completion line_flag_completion;
579
580 /* protected by dev->event_lock */
581 struct drm_pending_vblank_event *event;
582
583 struct drm_flip_work fb_unref_work;
584 unsigned long pending;
585
586 /**
587 * @hdr_in: Indicate we have a hdr plane input.
588 *
589 */
590 bool hdr_in;
591 /**
592 * @hdr_out: Indicate the screen want a hdr output
593 * from video port.
594 *
595 */
596 bool hdr_out;
597 /*
598 * @sdr2hdr_en: All the ui plane need to do sdr2hdr for a hdr_out enabled vp.
599 *
600 */
601 bool sdr2hdr_en;
602 /**
603 * @skip_vsync: skip on vsync when port_mux changed on this vp.
604 * a win move from one VP to another need wait one vsync until
605 * port_mut take effect before this win can be enabled.
606 *
607 */
608 bool skip_vsync;
609
610 /**
611 * @bg_ovl_dly: The timing delay from background layer
612 * to overlay module.
613 */
614 u8 bg_ovl_dly;
615
616 /**
617 * @hdr_en: Set when has a hdr video input.
618 */
619 int hdr_en;
620
621 /**
622 * -----------------
623 * | | |
624 * | Left | Right |
625 * | | |
626 * | VP0 | VP1 |
627 * -----------------
628 * @splice_mode_right: As right part of the screen in splice mode.
629 */
630 bool splice_mode_right;
631
632 /**
633 * @hdr10_at_splice_mode: enable hdr10 at splice mode on rk3588.
634 */
635 bool hdr10_at_splice_mode;
636 /**
637 * @left_vp: VP as left part of the screen in splice mode.
638 */
639 struct vop2_video_port *left_vp;
640
641 /**
642 * @win_mask: Bitmask of wins attached to the video port;
643 */
644 uint32_t win_mask;
645 /**
646 * @enabled_win_mask: Bitmask of enabled wins attached to the video port;
647 */
648 uint32_t enabled_win_mask;
649
650 /**
651 * @nr_layers: active layers attached to the video port;
652 */
653 uint8_t nr_layers;
654
655 int cursor_win_id;
656 /**
657 * @output_if: output connector attached to the video port,
658 * this flag is maintained in vop driver, updated in crtc_atomic_enable,
659 * cleared in crtc_atomic_disable;
660 */
661 u32 output_if;
662
663 /**
664 * @active_tv_state: TV connector related states
665 */
666 struct drm_tv_connector_state active_tv_state;
667
668 /**
669 * @lut: store legacy gamma look up table
670 */
671 u32 *lut;
672
673 /**
674 * @gamma_lut_len: gamma look up table size
675 */
676 u32 gamma_lut_len;
677
678 /**
679 * @gamma_lut_active: gamma states
680 */
681 bool gamma_lut_active;
682
683 /**
684 * @lut_dma_rid: lut dma id
685 */
686 u16 lut_dma_rid;
687
688 /**
689 * @gamma_lut: atomic gamma look up table
690 */
691 struct drm_color_lut *gamma_lut;
692
693 /**
694 * @cubic_lut_len: cubic look up table size
695 */
696 u32 cubic_lut_len;
697
698 /**
699 * @cubic_lut_gem_obj: gem obj to store cubic lut
700 */
701 struct rockchip_gem_object *cubic_lut_gem_obj;
702
703 /**
704 * @hdr_lut_gem_obj: gem obj to store hdr lut
705 */
706 struct rockchip_gem_object *hdr_lut_gem_obj;
707
708 /**
709 * @cubic_lut: cubic look up table
710 */
711 struct drm_color_lut *cubic_lut;
712
713 /**
714 * @loader_protect: loader logo protect state
715 */
716 bool loader_protect;
717
718 /**
719 * @plane_mask: show the plane attach to this vp,
720 * it maybe init at dts file or uboot driver
721 */
722 uint32_t plane_mask;
723
724 /**
725 * @plane_mask_prop: plane mask interaction with userspace
726 */
727 struct drm_property *plane_mask_prop;
728 /**
729 * @feature_prop: crtc feature interaction with userspace
730 */
731 struct drm_property *feature_prop;
732
733 /**
734 * @variable_refresh_rate_prop: crtc variable refresh rate interaction with userspace
735 */
736 struct drm_property *variable_refresh_rate_prop;
737
738 /**
739 * @max_refresh_rate_prop: crtc max refresh rate interaction with userspace
740 */
741 struct drm_property *max_refresh_rate_prop;
742
743 /**
744 * @min_refresh_rate_prop: crtc min refresh rate interaction with userspace
745 */
746 struct drm_property *min_refresh_rate_prop;
747
748 /**
749 * @hdr_ext_data_prop: hdr extend data interaction with userspace
750 */
751 struct drm_property *hdr_ext_data_prop;
752
753 int hdrvivid_mode;
754
755 /**
756 * @acm_lut_data_prop: acm lut data interaction with userspace
757 */
758 struct drm_property *acm_lut_data_prop;
759 /**
760 * @post_csc_data_prop: post csc data interaction with userspace
761 */
762 struct drm_property *post_csc_data_prop;
763 /**
764 * @output_width_prop: vp max output width prop
765 */
766 struct drm_property *output_width_prop;
767 /**
768 * @output_dclk_prop: vp max output dclk prop
769 */
770 struct drm_property *output_dclk_prop;
771
772 /**
773 * @primary_plane_phy_id: vp primary plane phy id, the primary plane
774 * will be used to show uboot logo and kernel logo
775 */
776 enum vop2_layer_phy_id primary_plane_phy_id;
777
778 struct post_acm acm_info;
779 struct post_csc csc_info;
780
781 /**
782 * @refresh_rate_change: indicate whether refresh rate change
783 */
784 bool refresh_rate_change;
785 };
786
787 struct vop2_extend_pll {
788 struct list_head list;
789 struct clk *clk;
790 char clk_name[32];
791 u32 vp_mask;
792 };
793
794 struct vop2 {
795 u32 version;
796 struct device *dev;
797 struct drm_device *drm_dev;
798 struct vop2_dsc dscs[ROCKCHIP_MAX_CRTC];
799 struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
800 struct vop2_wb wb;
801 struct dentry *debugfs;
802 struct drm_info_list *debugfs_files;
803 struct drm_prop_enum_list *plane_name_list;
804 bool is_iommu_enabled;
805 bool is_iommu_needed;
806 bool is_enabled;
807 bool support_multi_area;
808 bool disable_afbc_win;
809
810 /* no move win from one vp to another */
811 bool disable_win_move;
812 /*
813 * Usually we increase old fb refcount at
814 * atomic_flush and decrease it when next
815 * vsync come, this can make user the fb
816 * not been releasced before vop finish use
817 * it.
818 *
819 * But vop decrease fb refcount by a thread
820 * vop2_unref_fb_work, which may run a little
821 * slow sometimes, so when userspace do a rmfb,
822 *
823 * see drm_mode_rmfb,
824 * it will find the fb refcount is still > 1,
825 * than goto a fallback to init drm_mode_rmfb_work_fn,
826 * this will cost a long time(>10 ms maybe) and block
827 * rmfb work. Some userspace don't have with this(such as vo).
828 *
829 * Don't reference framebuffer refcount by
830 * drm_framebuffer_get as some userspace want
831 * rmfb as soon as possible(nvr vo). And the userspace
832 * should make sure release fb after it receive the vsync.
833 */
834 bool skip_ref_fb;
835
836 bool loader_protect;
837
838 bool aclk_rate_reset;
839 unsigned long aclk_rate;
840
841 const struct vop2_data *data;
842 /* Number of win that registered as plane,
843 * maybe less than the total number of hardware
844 * win.
845 */
846 uint32_t registered_num_wins;
847 uint8_t used_mixers;
848 uint8_t esmart_lb_mode;
849 /**
850 * @active_vp_mask: Bitmask of active video ports;
851 */
852 uint8_t active_vp_mask;
853 uint16_t port_mux_cfg;
854
855 uint32_t *regsbak;
856 struct resource *res;
857 void __iomem *regs;
858 struct regmap *grf;
859 struct regmap *sys_grf;
860 struct regmap *vo0_grf;
861 struct regmap *vo1_grf;
862 struct regmap *sys_pmu;
863
864 /* physical map length of vop2 register */
865 uint32_t len;
866
867 void __iomem *lut_regs;
868 void __iomem *acm_regs;
869 /* one time only one process allowed to config the register */
870 spinlock_t reg_lock;
871 /* lock vop2 irq reg */
872 spinlock_t irq_lock;
873 /* protects crtc enable/disable */
874 struct mutex vop2_lock;
875
876 int irq;
877
878 /*
879 * Some globle resource are shared between all
880 * the vidoe ports(crtcs), so we need a ref counter here.
881 */
882 unsigned int enable_count;
883 struct clk *hclk;
884 struct clk *aclk;
885 struct clk *pclk;
886 struct reset_control *ahb_rst;
887 struct reset_control *axi_rst;
888
889 /* list_head of extend clk */
890 struct list_head extend_clk_list_head;
891 /* list_head of internal clk */
892 struct list_head clk_list_head;
893 struct list_head pd_list_head;
894 struct work_struct post_buf_empty_work;
895 struct workqueue_struct *workqueue;
896
897 struct vop2_layer layers[ROCKCHIP_MAX_LAYER];
898 /* must put at the end of the struct */
899 struct vop2_win win[];
900 };
901
902 struct vop2_clk {
903 struct vop2 *vop2;
904 struct list_head list;
905 unsigned long rate;
906 struct clk_hw hw;
907 struct clk_divider div;
908 int div_val;
909 u8 parent_index;
910 };
911
912 #define to_vop2_clk(_hw) container_of(_hw, struct vop2_clk, hw)
913
914 /*
915 * bus-format types.
916 */
917 struct drm_bus_format_enum_list {
918 int type;
919 const char *name;
920 };
921
922 static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
923 { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
924 { MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" },
925 { MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" },
926 { MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" },
927 { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" },
928 { MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" },
929 { MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
930 { MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
931 { MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
932 { MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
933 { MEDIA_BUS_FMT_RGB888_DUMMY_4X8, "RGB888_DUMMY_4X8" },
934 { MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
935 { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" },
936 { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" },
937 { MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" },
938 { MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" },
939 { MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" },
940 { MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" },
941 { MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" },
942 };
943
DRM_ENUM_NAME_FN(drm_get_bus_format_name,drm_bus_format_enum_list)944 static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
945
946 static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
947 {
948 struct rockchip_crtc *rockchip_crtc;
949
950 rockchip_crtc = container_of(crtc, struct rockchip_crtc, crtc);
951
952 return container_of(rockchip_crtc, struct vop2_video_port, rockchip_crtc);
953 }
954
vop2_lock(struct vop2 * vop2)955 static void vop2_lock(struct vop2 *vop2)
956 {
957 mutex_lock(&vop2->vop2_lock);
958 rockchip_dmcfreq_lock();
959 }
960
vop2_unlock(struct vop2 * vop2)961 static void vop2_unlock(struct vop2 *vop2)
962 {
963 rockchip_dmcfreq_unlock();
964 mutex_unlock(&vop2->vop2_lock);
965 }
966
vop2_grf_writel(struct regmap * regmap,struct vop_reg reg,u32 v)967 static inline void vop2_grf_writel(struct regmap *regmap, struct vop_reg reg, u32 v)
968 {
969 u32 val = 0;
970
971 if (IS_ERR_OR_NULL(regmap))
972 return;
973
974 if (reg.mask) {
975 val = (v << reg.shift) | (reg.mask << (reg.shift + 16));
976 regmap_write(regmap, reg.offset, val);
977 }
978 }
979
vop2_grf_readl(struct regmap * regmap,const struct vop_reg * reg)980 static inline uint32_t vop2_grf_readl(struct regmap *regmap, const struct vop_reg *reg)
981 {
982 uint32_t v;
983
984 regmap_read(regmap, reg->offset, &v);
985
986 return v;
987 }
988
vop2_writel(struct vop2 * vop2,uint32_t offset,uint32_t v)989 static inline void vop2_writel(struct vop2 *vop2, uint32_t offset, uint32_t v)
990 {
991 writel(v, vop2->regs + offset);
992 vop2->regsbak[offset >> 2] = v;
993 }
994
vop2_readl(struct vop2 * vop2,uint32_t offset)995 static inline uint32_t vop2_readl(struct vop2 *vop2, uint32_t offset)
996 {
997 return readl(vop2->regs + offset);
998 }
999
vop2_read_reg(struct vop2 * vop2,uint32_t base,const struct vop_reg * reg)1000 static inline uint32_t vop2_read_reg(struct vop2 *vop2, uint32_t base,
1001 const struct vop_reg *reg)
1002 {
1003 return (vop2_readl(vop2, base + reg->offset) >> reg->shift) & reg->mask;
1004 }
1005
vop2_read_reg_bak(struct vop2 * vop2,uint32_t base,const struct vop_reg * reg)1006 static inline uint32_t vop2_read_reg_bak(struct vop2 *vop2, uint32_t base,
1007 const struct vop_reg *reg)
1008 {
1009 return (vop2->regsbak[(base + reg->offset) >> 2] >> reg->shift) & reg->mask;
1010 }
1011
vop2_read_grf_reg(struct regmap * regmap,const struct vop_reg * reg)1012 static inline uint32_t vop2_read_grf_reg(struct regmap *regmap, const struct vop_reg *reg)
1013 {
1014 return (vop2_grf_readl(regmap, reg) >> reg->shift) & reg->mask;
1015 }
1016
vop2_write_reg_uncached(struct vop2 * vop2,const struct vop_reg * reg,uint32_t v)1017 static inline void vop2_write_reg_uncached(struct vop2 *vop2, const struct vop_reg *reg, uint32_t v)
1018 {
1019 uint32_t offset = reg->offset;
1020 uint32_t cached_val = vop2->regsbak[offset >> 2];
1021
1022 v = (cached_val & ~(reg->mask << reg->shift)) | ((v & reg->mask) << reg->shift);
1023 writel(v, vop2->regs + offset);
1024 }
1025
vop2_mask_write(struct vop2 * vop2,uint32_t offset,uint32_t mask,uint32_t shift,uint32_t v,bool write_mask,bool relaxed)1026 static inline void vop2_mask_write(struct vop2 *vop2, uint32_t offset,
1027 uint32_t mask, uint32_t shift, uint32_t v,
1028 bool write_mask, bool relaxed)
1029 {
1030 uint32_t cached_val;
1031
1032 if (!mask)
1033 return;
1034
1035 if (write_mask) {
1036 v = ((v & mask) << shift) | (mask << (shift + 16));
1037 } else {
1038 cached_val = vop2->regsbak[offset >> 2];
1039
1040 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
1041 vop2->regsbak[offset >> 2] = v;
1042 }
1043
1044 if (relaxed)
1045 writel_relaxed(v, vop2->regs + offset);
1046 else
1047 writel(v, vop2->regs + offset);
1048 }
1049
vop2_line_to_time(struct drm_display_mode * mode,int line)1050 static inline u32 vop2_line_to_time(struct drm_display_mode *mode, int line)
1051 {
1052 u64 val = 1000000000ULL * mode->crtc_htotal * line;
1053
1054 do_div(val, mode->crtc_clock);
1055 do_div(val, 1000000);
1056
1057 return val; /* us */
1058 }
1059
vop2_plane_active(struct drm_plane_state * pstate)1060 static inline bool vop2_plane_active(struct drm_plane_state *pstate)
1061 {
1062 if (!pstate || !pstate->fb)
1063 return false;
1064 else
1065 return true;
1066 }
1067
is_vop3(struct vop2 * vop2)1068 static inline bool is_vop3(struct vop2 *vop2)
1069 {
1070 if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588)
1071 return false;
1072 else
1073 return true;
1074 }
1075
vop2_soc_is_rk3566(void)1076 static bool vop2_soc_is_rk3566(void)
1077 {
1078 return soc_is_rk3566();
1079 }
1080
vop2_is_mirror_win(struct vop2_win * win)1081 static bool vop2_is_mirror_win(struct vop2_win *win)
1082 {
1083 return soc_is_rk3566() && (win->feature & WIN_FEATURE_MIRROR);
1084 }
1085
vop2_soc_id_fixup(uint64_t soc_id)1086 static uint64_t vop2_soc_id_fixup(uint64_t soc_id)
1087 {
1088 switch (soc_id) {
1089 case 0x3566:
1090 if (rockchip_get_cpu_version())
1091 return 0x3566A;
1092 else
1093 return 0x3566;
1094 case 0x3568:
1095 if (rockchip_get_cpu_version())
1096 return 0x3568A;
1097 else
1098 return 0x3568;
1099 default:
1100 return soc_id;
1101 }
1102 }
1103
vop2_crtc_standby(struct drm_crtc * crtc,bool standby)1104 static void vop2_crtc_standby(struct drm_crtc *crtc, bool standby)
1105 {
1106 struct vop2_video_port *vp = to_vop2_video_port(crtc);
1107 struct vop2 *vop2 = vp->vop2;
1108
1109 if (standby) {
1110 VOP_MODULE_SET(vop2, vp, standby, 1);
1111 mdelay(20);
1112 } else {
1113 VOP_MODULE_SET(vop2, vp, standby, 0);
1114 }
1115 }
1116
vop2_get_win_regs(struct vop2_win * win,const struct vop_reg * reg)1117 static inline const struct vop2_win_regs *vop2_get_win_regs(struct vop2_win *win,
1118 const struct vop_reg *reg)
1119 {
1120 if (!reg->mask && win->parent)
1121 return win->parent->regs;
1122
1123 return win->regs;
1124 }
1125
vop2_get_intr_type(struct vop2 * vop2,const struct vop_intr * intr,const struct vop_reg * reg,int type)1126 static inline uint32_t vop2_get_intr_type(struct vop2 *vop2, const struct vop_intr *intr,
1127 const struct vop_reg *reg, int type)
1128 {
1129 uint32_t val, i;
1130 uint32_t ret = 0;
1131
1132 val = vop2_read_reg(vop2, 0, reg);
1133
1134 for (i = 0; i < intr->nintrs; i++) {
1135 if ((type & intr->intrs[i]) && (val & 1 << i))
1136 ret |= intr->intrs[i];
1137 }
1138
1139 return ret;
1140 }
1141
1142 /*
1143 * phys_id is used to identify a main window(Cluster Win/Smart Win, not
1144 * include the sub win of a cluster or the multi area) that can do
1145 * overlay in main overlay stage.
1146 */
vop2_find_win_by_phys_id(struct vop2 * vop2,uint8_t phys_id)1147 static struct vop2_win *vop2_find_win_by_phys_id(struct vop2 *vop2, uint8_t phys_id)
1148 {
1149 struct vop2_win *win;
1150 int i;
1151
1152 for (i = 0; i < vop2->registered_num_wins; i++) {
1153 win = &vop2->win[i];
1154 if (win->phys_id == phys_id)
1155 return win;
1156 }
1157
1158 return NULL;
1159 }
1160
vop2_find_pd_by_id(struct vop2 * vop2,uint8_t id)1161 static struct vop2_power_domain *vop2_find_pd_by_id(struct vop2 *vop2, uint8_t id)
1162 {
1163 struct vop2_power_domain *pd, *n;
1164
1165 list_for_each_entry_safe(pd, n, &vop2->pd_list_head, list) {
1166 if (pd->data->id == id)
1167 return pd;
1168 }
1169
1170 return NULL;
1171 }
1172
vop2_find_connector_if_data(struct vop2 * vop2,int id)1173 static const struct vop2_connector_if_data *vop2_find_connector_if_data(struct vop2 *vop2, int id)
1174 {
1175 const struct vop2_connector_if_data *if_data;
1176 int i;
1177
1178 for (i = 0; i < vop2->data->nr_conns; i++) {
1179 if_data = &vop2->data->conn[i];
1180 if (if_data->id == id)
1181 return if_data;
1182 }
1183
1184 return NULL;
1185 }
1186
vop2_find_crtc_by_plane_mask(struct vop2 * vop2,uint8_t phys_id)1187 static struct drm_crtc *vop2_find_crtc_by_plane_mask(struct vop2 *vop2, uint8_t phys_id)
1188 {
1189 struct vop2_video_port *vp;
1190 int i;
1191
1192 for (i = 0; i < vop2->data->nr_vps; i++) {
1193 vp = &vop2->vps[i];
1194 if (vp->plane_mask & BIT(phys_id))
1195 return &vp->rockchip_crtc.crtc;
1196 }
1197
1198 return NULL;
1199 }
1200
vop2_clk_reset(struct reset_control * rstc)1201 static int vop2_clk_reset(struct reset_control *rstc)
1202 {
1203 int ret;
1204
1205 if (!rstc)
1206 return 0;
1207
1208 ret = reset_control_assert(rstc);
1209 if (ret < 0)
1210 DRM_WARN("failed to assert reset\n");
1211 udelay(10);
1212 ret = reset_control_deassert(rstc);
1213 if (ret < 0)
1214 DRM_WARN("failed to deassert reset\n");
1215
1216 return ret;
1217 }
1218
vop2_load_hdr2sdr_table(struct vop2_video_port * vp)1219 static void vop2_load_hdr2sdr_table(struct vop2_video_port *vp)
1220 {
1221 struct vop2 *vop2 = vp->vop2;
1222 const struct vop2_data *vop2_data = vop2->data;
1223 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
1224 const struct vop_hdr_table *table = vp_data->hdr_table;
1225 const struct vop2_video_port_regs *regs = vp->regs;
1226 uint32_t hdr2sdr_eetf_oetf_yn[33];
1227 int i;
1228
1229 for (i = 0; i < 33; i++)
1230 hdr2sdr_eetf_oetf_yn[i] = table->hdr2sdr_eetf_yn[i] +
1231 (table->hdr2sdr_bt1886oetf_yn[i] << 16);
1232
1233 for (i = 0; i < 33; i++)
1234 vop2_writel(vop2, regs->hdr2sdr_eetf_oetf_y0_offset + i * 4,
1235 hdr2sdr_eetf_oetf_yn[i]);
1236
1237 for (i = 0; i < 9; i++)
1238 vop2_writel(vop2, regs->hdr2sdr_sat_y0_offset + i * 4,
1239 table->hdr2sdr_sat_yn[i]);
1240 }
1241
vop2_load_sdr2hdr_table(struct vop2_video_port * vp,int sdr2hdr_tf)1242 static void vop2_load_sdr2hdr_table(struct vop2_video_port *vp, int sdr2hdr_tf)
1243 {
1244 struct vop2 *vop2 = vp->vop2;
1245 const struct vop2_data *vop2_data = vop2->data;
1246 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
1247 const struct vop_hdr_table *table = vp_data->hdr_table;
1248 const struct vop2_video_port_regs *regs = vp->regs;
1249 uint32_t sdr2hdr_eotf_oetf_yn[65];
1250 uint32_t sdr2hdr_oetf_dx_dxpow[64];
1251 int i;
1252
1253 for (i = 0; i < 65; i++) {
1254 if (sdr2hdr_tf == SDR2HDR_FOR_BT2020)
1255 sdr2hdr_eotf_oetf_yn[i] =
1256 table->sdr2hdr_bt1886eotf_yn_for_bt2020[i] +
1257 (table->sdr2hdr_st2084oetf_yn_for_bt2020[i] << 18);
1258 else if (sdr2hdr_tf == SDR2HDR_FOR_HDR)
1259 sdr2hdr_eotf_oetf_yn[i] =
1260 table->sdr2hdr_bt1886eotf_yn_for_hdr[i] +
1261 (table->sdr2hdr_st2084oetf_yn_for_hdr[i] << 18);
1262 else if (sdr2hdr_tf == SDR2HDR_FOR_HLG_HDR)
1263 sdr2hdr_eotf_oetf_yn[i] =
1264 table->sdr2hdr_bt1886eotf_yn_for_hlg_hdr[i] +
1265 (table->sdr2hdr_st2084oetf_yn_for_hlg_hdr[i] << 18);
1266 }
1267
1268 for (i = 0; i < 65; i++)
1269 vop2_writel(vop2, regs->sdr2hdr_eotf_oetf_y0_offset + i * 4,
1270 sdr2hdr_eotf_oetf_yn[i]);
1271
1272 for (i = 0; i < 64; i++) {
1273 sdr2hdr_oetf_dx_dxpow[i] = table->sdr2hdr_st2084oetf_dxn[i] +
1274 (table->sdr2hdr_st2084oetf_dxn_pow2[i] << 16);
1275 vop2_writel(vop2, regs->sdr2hdr_oetf_dx_pow1_offset + i * 4,
1276 sdr2hdr_oetf_dx_dxpow[i]);
1277 }
1278
1279 for (i = 0; i < 63; i++)
1280 vop2_writel(vop2, regs->sdr2hdr_oetf_xn1_offset + i * 4,
1281 table->sdr2hdr_st2084oetf_xn[i]);
1282 }
1283
vop2_fs_irq_is_pending(struct vop2_video_port * vp)1284 static bool vop2_fs_irq_is_pending(struct vop2_video_port *vp)
1285 {
1286 struct vop2 *vop2 = vp->vop2;
1287 const struct vop2_data *vop2_data = vop2->data;
1288 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
1289 const struct vop_intr *intr = vp_data->intr;
1290
1291 return VOP_INTR_GET_TYPE(vop2, intr, status, FS_FIELD_INTR);
1292 }
1293
vop2_read_vcnt(struct vop2_video_port * vp)1294 static uint32_t vop2_read_vcnt(struct vop2_video_port *vp)
1295 {
1296 uint32_t offset = RK3568_SYS_STATUS0 + (vp->id << 2);
1297 uint32_t vcnt0, vcnt1;
1298 int i = 0;
1299
1300 for (i = 0; i < 10; i++) {
1301 vcnt0 = vop2_readl(vp->vop2, offset) >> 16;
1302 vcnt1 = vop2_readl(vp->vop2, offset) >> 16;
1303
1304 if ((vcnt1 - vcnt0) <= 1)
1305 break;
1306 }
1307
1308 if (i == 10) {
1309 DRM_DEV_ERROR(vp->vop2->dev, "read VP%d vcnt error: %d %d\n", vp->id, vcnt0, vcnt1);
1310 vcnt1 = vop2_readl(vp->vop2, offset) >> 16;
1311 }
1312
1313 return vcnt1;
1314 }
1315
vop2_wait_for_irq_handler(struct drm_crtc * crtc)1316 static void vop2_wait_for_irq_handler(struct drm_crtc *crtc)
1317 {
1318 struct vop2_video_port *vp = to_vop2_video_port(crtc);
1319 struct vop2 *vop2 = vp->vop2;
1320 bool pending;
1321 int ret;
1322
1323 /*
1324 * Spin until frame start interrupt status bit goes low, which means
1325 * that interrupt handler was invoked and cleared it. The timeout of
1326 * 10 msecs is really too long, but it is just a safety measure if
1327 * something goes really wrong. The wait will only happen in the very
1328 * unlikely case of a vblank happening exactly at the same time and
1329 * shouldn't exceed microseconds range.
1330 */
1331 ret = readx_poll_timeout_atomic(vop2_fs_irq_is_pending, vp, pending,
1332 !pending, 0, 10 * 1000);
1333 if (ret)
1334 DRM_DEV_ERROR(vop2->dev, "VOP vblank IRQ stuck for 10 ms\n");
1335
1336 synchronize_irq(vop2->irq);
1337 }
1338
vop2_vp_done_bit_status(struct vop2_video_port * vp)1339 static bool vop2_vp_done_bit_status(struct vop2_video_port *vp)
1340 {
1341 struct vop2 *vop2 = vp->vop2;
1342 u32 done_bits = vop2_readl(vop2, RK3568_REG_CFG_DONE) & BIT(vp->id);
1343
1344 /*
1345 * When done bit is 0, indicate current frame is take effect.
1346 */
1347 return done_bits == 0 ? true : false;
1348 }
1349
vop2_wait_for_fs_by_done_bit_status(struct vop2_video_port * vp)1350 static void vop2_wait_for_fs_by_done_bit_status(struct vop2_video_port *vp)
1351 {
1352 struct vop2 *vop2 = vp->vop2;
1353 bool done_bit;
1354 int ret;
1355
1356 ret = readx_poll_timeout_atomic(vop2_vp_done_bit_status, vp, done_bit,
1357 done_bit, 0, 50 * 1000);
1358 if (ret)
1359 DRM_DEV_ERROR(vop2->dev, "wait vp%d done bit status timeout, vcnt: %d\n",
1360 vp->id, vop2_read_vcnt(vp));
1361 }
1362
vop2_read_port_mux(struct vop2 * vop2)1363 static uint16_t vop2_read_port_mux(struct vop2 *vop2)
1364 {
1365 return vop2_readl(vop2, RK3568_OVL_PORT_SEL) & 0xffff;
1366 }
1367
vop2_wait_for_port_mux_done(struct vop2 * vop2)1368 static void vop2_wait_for_port_mux_done(struct vop2 *vop2)
1369 {
1370 uint16_t port_mux_cfg;
1371 int ret;
1372
1373 /*
1374 * Spin until the previous port_mux figuration
1375 * is done.
1376 */
1377 ret = readx_poll_timeout_atomic(vop2_read_port_mux, vop2, port_mux_cfg,
1378 port_mux_cfg == vop2->port_mux_cfg, 0, 50 * 1000);
1379 if (ret)
1380 DRM_DEV_ERROR(vop2->dev, "wait port_mux done timeout: 0x%x--0x%x\n",
1381 port_mux_cfg, vop2->port_mux_cfg);
1382 }
1383
vop2_read_layer_cfg(struct vop2 * vop2)1384 static u32 vop2_read_layer_cfg(struct vop2 *vop2)
1385 {
1386 return vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
1387 }
1388
vop2_wait_for_layer_cfg_done(struct vop2 * vop2,u32 cfg)1389 static void vop2_wait_for_layer_cfg_done(struct vop2 *vop2, u32 cfg)
1390 {
1391 u32 atv_layer_cfg;
1392 int ret;
1393
1394 /*
1395 * Spin until the previous layer configuration is done.
1396 */
1397 ret = readx_poll_timeout_atomic(vop2_read_layer_cfg, vop2, atv_layer_cfg,
1398 atv_layer_cfg == cfg, 0, 50 * 1000);
1399 if (ret)
1400 DRM_DEV_ERROR(vop2->dev, "wait layer cfg done timeout: 0x%x--0x%x\n",
1401 atv_layer_cfg, cfg);
1402 }
1403
vop2_pending_done_bits(struct vop2_video_port * vp)1404 static int32_t vop2_pending_done_bits(struct vop2_video_port *vp)
1405 {
1406 struct vop2 *vop2 = vp->vop2;
1407 struct drm_display_mode *adjusted_mode;
1408 struct vop2_video_port *done_vp;
1409 uint32_t done_bits, done_bits_bak;
1410 uint32_t vp_id;
1411 uint32_t vcnt;
1412
1413 done_bits = vop2_readl(vop2, RK3568_REG_CFG_DONE) & 0x7;
1414 done_bits_bak = done_bits;
1415
1416 /* no done bit, so no need to wait config done take effect */
1417 if (done_bits == 0)
1418 return 0;
1419
1420 vp_id = ffs(done_bits) - 1;
1421 /* done bit is same with current vp config done, so no need to wait */
1422 if (hweight32(done_bits) == 1 && vp_id == vp->id)
1423 return 0;
1424
1425 /* have the other one different vp, wait for config done take effect */
1426 if (hweight32(done_bits) == 1 ||
1427 (hweight32(done_bits) == 2 && (done_bits & BIT(vp->id)))) {
1428 /* two done bit, clear current vp done bit and find the other done bit vp */
1429 if (done_bits & BIT(vp->id))
1430 done_bits &= ~BIT(vp->id);
1431 vp_id = ffs(done_bits) - 1;
1432 done_vp = &vop2->vps[vp_id];
1433 adjusted_mode = &done_vp->rockchip_crtc.crtc.state->adjusted_mode;
1434 vcnt = vop2_read_vcnt(done_vp);
1435 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
1436 vcnt >>= 1;
1437 /* if close to the last 1/8 frame, wait to next frame */
1438 if (vcnt > (adjusted_mode->crtc_vtotal * 7 >> 3)) {
1439 vop2_wait_for_fs_by_done_bit_status(done_vp);
1440 done_bits = 0;
1441 }
1442 } else { /* exist the other two vp done bit */
1443 struct drm_display_mode *first_mode, *second_mode;
1444 struct vop2_video_port *first_done_vp, *second_done_vp, *wait_vp;
1445 uint32_t first_vp_id, second_vp_id;
1446 uint32_t first_vp_vcnt, second_vp_vcnt;
1447 uint32_t first_vp_left_vcnt, second_vp_left_vcnt;
1448 uint32_t first_vp_left_time, second_vp_left_time;
1449 uint32_t first_vp_safe_time, second_vp_safe_time;
1450 unsigned int vrefresh;
1451
1452 first_vp_id = ffs(done_bits) - 1;
1453 first_done_vp = &vop2->vps[first_vp_id];
1454 first_mode = &first_done_vp->rockchip_crtc.crtc.state->adjusted_mode;
1455 /* set last 1/8 frame time as safe section */
1456 vrefresh = drm_mode_vrefresh(first_mode);
1457 if (!vrefresh) {
1458 WARN(1, "%s first vp:%d vrefresh is zero\n", __func__, first_vp_id);
1459 vrefresh = 60;
1460 }
1461 first_vp_safe_time = (1000000 / vrefresh) >> 3;
1462
1463 done_bits &= ~BIT(first_vp_id);
1464 second_vp_id = ffs(done_bits) - 1;
1465 second_done_vp = &vop2->vps[second_vp_id];
1466 second_mode = &second_done_vp->rockchip_crtc.crtc.state->adjusted_mode;
1467 /* set last 1/8 frame time as safe section */
1468 vrefresh = drm_mode_vrefresh(second_mode);
1469 if (!vrefresh) {
1470 WARN(1, "%s second vp:%d vrefresh is zero\n", __func__, second_vp_id);
1471 vrefresh = 60;
1472 }
1473 second_vp_safe_time = (1000000 / vrefresh) >> 3;
1474
1475 first_vp_vcnt = vop2_read_vcnt(first_done_vp);
1476 if (first_mode->flags & DRM_MODE_FLAG_INTERLACE)
1477 first_vp_vcnt >>= 1;
1478 second_vp_vcnt = vop2_read_vcnt(second_done_vp);
1479 if (second_mode->flags & DRM_MODE_FLAG_INTERLACE)
1480 second_vp_vcnt >>= 1;
1481
1482 first_vp_left_vcnt = first_mode->crtc_vtotal - first_vp_vcnt;
1483 second_vp_left_vcnt = second_mode->crtc_vtotal - second_vp_vcnt;
1484 first_vp_left_time = vop2_line_to_time(first_mode, first_vp_left_vcnt);
1485 second_vp_left_time = vop2_line_to_time(second_mode, second_vp_left_vcnt);
1486
1487 /* if the two vp both at safe section, no need to wait */
1488 if (first_vp_left_time > first_vp_safe_time &&
1489 second_vp_left_time > second_vp_safe_time)
1490 return done_bits_bak;
1491
1492 if (first_vp_left_time > second_vp_left_time) {
1493 if ((first_vp_left_time - second_vp_left_time) > first_vp_safe_time)
1494 wait_vp = second_done_vp;
1495 else
1496 wait_vp = first_done_vp;
1497 } else {
1498 if ((second_vp_left_time - first_vp_left_time) > second_vp_safe_time)
1499 wait_vp = first_done_vp;
1500 else
1501 wait_vp = second_done_vp;
1502 }
1503
1504 vop2_wait_for_fs_by_done_bit_status(wait_vp);
1505
1506 done_bits = vop2_readl(vop2, RK3568_REG_CFG_DONE) & 0x7;
1507 }
1508 return done_bits;
1509 }
1510
rk3588_vop2_dsc_cfg_done(struct drm_crtc * crtc)1511 static inline void rk3588_vop2_dsc_cfg_done(struct drm_crtc *crtc)
1512 {
1513 struct vop2_video_port *vp = to_vop2_video_port(crtc);
1514 struct vop2 *vop2 = vp->vop2;
1515 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1516 struct vop2_dsc *dsc = &vop2->dscs[vcstate->dsc_id];
1517
1518 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
1519 dsc = &vop2->dscs[0];
1520 if (vcstate->dsc_enable)
1521 VOP_MODULE_SET(vop2, dsc, dsc_cfg_done, 1);
1522 dsc = &vop2->dscs[1];
1523 if (vcstate->dsc_enable)
1524 VOP_MODULE_SET(vop2, dsc, dsc_cfg_done, 1);
1525 } else {
1526 if (vcstate->dsc_enable)
1527 VOP_MODULE_SET(vop2, dsc, dsc_cfg_done, 1);
1528 }
1529 }
1530
rk3568_vop2_cfg_done(struct drm_crtc * crtc)1531 static inline void rk3568_vop2_cfg_done(struct drm_crtc *crtc)
1532 {
1533 struct vop2_video_port *vp = to_vop2_video_port(crtc);
1534 struct vop2 *vop2 = vp->vop2;
1535 uint32_t done_bits;
1536 uint32_t val;
1537 u32 old_layer_sel_val, cfg_layer_sel_val;
1538 struct vop2_layer *layer = &vop2->layers[0];
1539 u32 layer_sel_offset = layer->regs->layer_sel.offset;
1540
1541 /*
1542 * This is a workaround, the config done bits of VP0,
1543 * VP1, VP2 on RK3568 stands on the first three bits
1544 * on REG_CFG_DONE register without mask bit.
1545 * If two or three config done events happens one after
1546 * another in a very shot time, the flowing config done
1547 * write may override the previous config done bit before
1548 * it take effect:
1549 * 1: config done 0x8001 for VP0
1550 * 2: config done 0x8002 for VP1
1551 *
1552 * 0x8002 may override 0x8001 before it take effect.
1553 *
1554 * So we do a read | write here.
1555 *
1556 */
1557 done_bits = vop2_pending_done_bits(vp);
1558 val = RK3568_VOP2_GLB_CFG_DONE_EN | BIT(vp->id) | done_bits;
1559 old_layer_sel_val = vop2_readl(vop2, layer_sel_offset);
1560 cfg_layer_sel_val = vop2->regsbak[layer_sel_offset >> 2];
1561 /**
1562 * This is rather low probability for miss some done bit.
1563 */
1564 val |= vop2_readl(vop2, RK3568_REG_CFG_DONE) & 0x7;
1565
1566 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_CFG_DONE, "cfg_done: 0x%x\n", val);
1567
1568 vop2_writel(vop2, 0, val);
1569
1570 /**
1571 * Make sure the layer sel is take effect when it's updated.
1572 */
1573 if (old_layer_sel_val != cfg_layer_sel_val) {
1574 vp->layer_sel_update = true;
1575 vop2_wait_for_fs_by_done_bit_status(vp);
1576 DRM_DEV_DEBUG(vop2->dev, "vp%d need to wait fs as old layer_sel val[0x%x] != new val[0x%x]\n",
1577 vp->id, old_layer_sel_val, cfg_layer_sel_val);
1578 }
1579 }
1580
rk3588_vop2_cfg_done(struct drm_crtc * crtc)1581 static inline void rk3588_vop2_cfg_done(struct drm_crtc *crtc)
1582 {
1583 struct vop2_video_port *vp = to_vop2_video_port(crtc);
1584 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1585 const struct vop2_video_port_data *vp_data = &vp->vop2->data->vp[vp->id];
1586 struct vop2 *vop2 = vp->vop2;
1587 uint32_t val;
1588
1589 val = RK3568_VOP2_GLB_CFG_DONE_EN | BIT(vp->id) | (BIT(vp->id) << 16);
1590 if (vcstate->splice_mode)
1591 val |= BIT(vp_data->splice_vp_id) | (BIT(vp_data->splice_vp_id) << 16);
1592
1593 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_CFG_DONE, "cfg_done: 0x%x\n", val);
1594
1595 vop2_writel(vop2, 0, val);
1596 }
1597
vop2_wb_cfg_done(struct vop2_video_port * vp)1598 static inline void vop2_wb_cfg_done(struct vop2_video_port *vp)
1599 {
1600 struct vop2 *vop2 = vp->vop2;
1601 uint32_t val = RK3568_VOP2_WB_CFG_DONE | (RK3568_VOP2_WB_CFG_DONE << 16) |
1602 RK3568_VOP2_GLB_CFG_DONE_EN;
1603 uint32_t done_bits;
1604 unsigned long flags;
1605
1606 if (vop2->version == VOP_VERSION_RK3568) {
1607 spin_lock_irqsave(&vop2->irq_lock, flags);
1608 done_bits = vop2_pending_done_bits(vp);
1609 val |= done_bits;
1610 vop2_writel(vop2, 0, val);
1611 spin_unlock_irqrestore(&vop2->irq_lock, flags);
1612 } else {
1613 vop2_writel(vop2, 0, val);
1614 }
1615
1616 }
1617
vop2_cfg_done(struct drm_crtc * crtc)1618 static inline void vop2_cfg_done(struct drm_crtc *crtc)
1619 {
1620 struct vop2_video_port *vp = to_vop2_video_port(crtc);
1621 struct vop2 *vop2 = vp->vop2;
1622
1623 if (vop2->version == VOP_VERSION_RK3568)
1624 return rk3568_vop2_cfg_done(crtc);
1625 else
1626 return rk3588_vop2_cfg_done(crtc);
1627 }
1628
1629 /*
1630 * A PD can power off by vsync when it's module attached to
1631 * a activated VP.
1632 */
vop2_power_domain_can_off_by_vsync(struct vop2_power_domain * pd)1633 static uint32_t vop2_power_domain_can_off_by_vsync(struct vop2_power_domain *pd)
1634 {
1635 struct vop2 *vop2 = pd->vop2;
1636
1637 if (vop2->active_vp_mask & pd->vp_mask)
1638 return true;
1639 else
1640 return false;
1641 }
1642
1643 /*
1644 * Read VOP internal power domain on/off status.
1645 * We should query BISR_STS register in PMU for
1646 * power up/down status when memory repair is enabled.
1647 * Return value: 1 for power on, 0 for power off;
1648 */
vop2_power_domain_status(struct vop2_power_domain * pd)1649 static uint32_t vop2_power_domain_status(struct vop2_power_domain *pd)
1650 {
1651 struct vop2 *vop2 = pd->vop2;
1652
1653 if (vop2_read_grf_reg(vop2->sys_pmu, &pd->data->regs->bisr_en_status))
1654 return vop2_read_grf_reg(vop2->sys_pmu, &pd->data->regs->pmu_status);
1655 else
1656 return vop2_read_reg(vop2, 0, &pd->data->regs->status) ? 0 : 1;
1657 }
1658
vop2_wait_power_domain_off(struct vop2_power_domain * pd)1659 static void vop2_wait_power_domain_off(struct vop2_power_domain *pd)
1660 {
1661 struct vop2 *vop2 = pd->vop2;
1662 int val;
1663 int ret;
1664
1665 ret = readx_poll_timeout_atomic(vop2_power_domain_status, pd, val, !val, 0, 50 * 1000);
1666
1667 if (ret)
1668 DRM_DEV_ERROR(vop2->dev, "wait pd%d off timeout power_ctrl: 0x%x\n",
1669 ffs(pd->data->id) - 1, vop2_readl(vop2, 0x34));
1670 }
1671
vop2_wait_power_domain_on(struct vop2_power_domain * pd)1672 static void vop2_wait_power_domain_on(struct vop2_power_domain *pd)
1673 {
1674 struct vop2 *vop2 = pd->vop2;
1675 int val;
1676 int ret;
1677
1678 ret = readx_poll_timeout_atomic(vop2_power_domain_status, pd, val, val, 0, 50 * 1000);
1679 if (ret)
1680 DRM_DEV_ERROR(vop2->dev, "wait pd%d on timeout power_ctrl: 0x%x\n",
1681 ffs(pd->data->id) - 1, vop2_readl(vop2, 0x34));
1682 }
1683
1684 /*
1685 * Power domain on take effect immediately
1686 */
vop2_power_domain_on(struct vop2_power_domain * pd)1687 static void vop2_power_domain_on(struct vop2_power_domain *pd)
1688 {
1689 struct vop2 *vop2 = pd->vop2;
1690
1691 if (!pd->on) {
1692 dev_dbg(vop2->dev, "pd%d on\n", ffs(pd->data->id) - 1);
1693 vop2_wait_power_domain_off(pd);
1694 VOP_MODULE_SET(vop2, pd->data, pd, 0);
1695 vop2_wait_power_domain_on(pd);
1696 pd->on = true;
1697 }
1698 }
1699
1700 /*
1701 * Power domain off take effect by vsync.
1702 */
vop2_power_domain_off(struct vop2_power_domain * pd)1703 static void vop2_power_domain_off(struct vop2_power_domain *pd)
1704 {
1705 struct vop2 *vop2 = pd->vop2;
1706
1707 dev_dbg(vop2->dev, "pd%d off\n", ffs(pd->data->id) - 1);
1708 pd->on = false;
1709 VOP_MODULE_SET(vop2, pd->data, pd, 1);
1710 }
1711
vop2_power_domain_get(struct vop2_power_domain * pd)1712 static void vop2_power_domain_get(struct vop2_power_domain *pd)
1713 {
1714 if (pd->parent)
1715 vop2_power_domain_get(pd->parent);
1716
1717 spin_lock(&pd->lock);
1718 if (pd->ref_count == 0) {
1719 if (pd->vop2->data->delayed_pd)
1720 cancel_delayed_work(&pd->power_off_work);
1721 vop2_power_domain_on(pd);
1722 }
1723 pd->ref_count++;
1724 spin_unlock(&pd->lock);
1725 }
1726
vop2_power_domain_put(struct vop2_power_domain * pd)1727 static void vop2_power_domain_put(struct vop2_power_domain *pd)
1728 {
1729 spin_lock(&pd->lock);
1730
1731 /*
1732 * For a nested power domain(PD_Cluster0 is the parent of PD_CLuster1/2/3)
1733 * the parent power domain must be enabled before child power domain
1734 * is on.
1735 *
1736 * So we may met this condition: Cluster0 is not on a activated VP,
1737 * but PD_Cluster0 must enabled as one of the child PD_CLUSTER1/2/3 is enabled.
1738 * when all child PD is disabled, we want disable the parent
1739 * PD(PD_CLUSTER0), but as module CLUSTER0 is not attcthed on a activated VP,
1740 * the turn off operation(which is take effect by vsync) will never take effect.
1741 * so we will see a "wait pd0 off timeout" log when we turn on PD_CLUSTER0 next time.
1742 *
1743 * So we have a check here
1744 */
1745 if (--pd->ref_count == 0 && vop2_power_domain_can_off_by_vsync(pd)) {
1746 if (pd->vop2->data->delayed_pd)
1747 schedule_delayed_work(&pd->power_off_work, msecs_to_jiffies(2500));
1748 else
1749 vop2_power_domain_off(pd);
1750 }
1751
1752 spin_unlock(&pd->lock);
1753 if (pd->parent)
1754 vop2_power_domain_put(pd->parent);
1755 }
1756
1757 /*
1758 * Called if the pd ref_count reach 0 after 2.5
1759 * seconds.
1760 */
vop2_power_domain_off_work(struct work_struct * work)1761 static void vop2_power_domain_off_work(struct work_struct *work)
1762 {
1763 struct vop2_power_domain *pd;
1764
1765 pd = container_of(to_delayed_work(work), struct vop2_power_domain, power_off_work);
1766
1767 spin_lock(&pd->lock);
1768 if (pd->ref_count == 0)
1769 vop2_power_domain_off(pd);
1770 spin_unlock(&pd->lock);
1771 }
1772
vop2_win_enable(struct vop2_win * win)1773 static void vop2_win_enable(struct vop2_win *win)
1774 {
1775 /*
1776 * a win such as cursor update by async:
1777 * first frame enable win pd, enable win, return without wait vsync
1778 * second frame come, but the first frame may still not enabled
1779 * in this case, the win pd is turn on by fist frame, so we don't
1780 * need get pd again.
1781 *
1782 * another case:
1783 * first frame: disable win, disable pd, return without wait vsync
1784 * second frame come very soon, the previous win disable may still not
1785 * take effect, but the pd is disable in progress, we should do pd_get
1786 * at this situation.
1787 *
1788 * check the backup register for previous enable operation.
1789 */
1790 if (!VOP_WIN_GET_REG_BAK(win->vop2, win, enable)) {
1791 if (win->pd) {
1792 if (win->pd->data->id == VOP2_PD_ESMART)
1793 return;
1794
1795 vop2_power_domain_get(win->pd);
1796 win->pd->vp_mask |= win->vp_mask;
1797 }
1798 }
1799 }
1800
vop2_win_multi_area_disable(struct vop2_win * parent)1801 static void vop2_win_multi_area_disable(struct vop2_win *parent)
1802 {
1803 struct vop2 *vop2 = parent->vop2;
1804 struct vop2_win *area;
1805 int i;
1806
1807 for (i = 0; i < vop2->registered_num_wins; i++) {
1808 area = &vop2->win[i];
1809 if (area->parent == parent)
1810 VOP_WIN_SET(vop2, area, enable, 0);
1811 }
1812 }
1813
vop2_win_disable(struct vop2_win * win,bool skip_splice_win)1814 static void vop2_win_disable(struct vop2_win *win, bool skip_splice_win)
1815 {
1816 struct vop2 *vop2 = win->vop2;
1817
1818 /* Disable the right splice win */
1819 if (win->splice_win && !skip_splice_win) {
1820 vop2_win_disable(win->splice_win, false);
1821 win->splice_win = NULL;
1822 }
1823
1824 if (VOP_WIN_GET(vop2, win, enable) || VOP_WIN_GET_REG_BAK(vop2, win, enable)) {
1825 VOP_WIN_SET(vop2, win, enable, 0);
1826 if (win->feature & WIN_FEATURE_CLUSTER_MAIN) {
1827 struct vop2_win *sub_win;
1828 int i = 0;
1829
1830 for (i = 0; i < vop2->registered_num_wins; i++) {
1831 sub_win = &vop2->win[i];
1832
1833 if ((sub_win->phys_id == win->phys_id) &&
1834 (sub_win->feature & WIN_FEATURE_CLUSTER_SUB))
1835 VOP_WIN_SET(vop2, sub_win, enable, 0);
1836 }
1837
1838 VOP_CLUSTER_SET(vop2, win, enable, 0);
1839 }
1840
1841 /*
1842 * disable all other multi area win if we want disable area0 here
1843 */
1844 if (!win->parent && (win->feature & WIN_FEATURE_MULTI_AREA))
1845 vop2_win_multi_area_disable(win);
1846
1847 if (win->pd) {
1848
1849 /*
1850 * Don't dynamic turn on/off PD_ESMART.
1851 * (1) There is a design issue for PD_EMSART when attached
1852 * on VP1/2/3, we found it will trigger POST_BUF_EMPTY irq at vp0
1853 * in splice mode.
1854 * (2) PD_ESMART will be closed at esmart layers attathed on VPs
1855 * config done + FS, but different VP FS time is different, this
1856 * maybe lead to PD_ESMART closed at wrong time and display error.
1857 * (3) PD_ESMART power up maybe have 4 us delay, this will lead to POST_BUF_EMPTY.
1858 */
1859 if (win->pd->data->id == VOP2_PD_ESMART)
1860 return;
1861
1862 vop2_power_domain_put(win->pd);
1863 win->pd->vp_mask &= ~win->vp_mask;
1864 }
1865 }
1866
1867 if (win->left_win && win->splice_mode_right) {
1868 win->left_win = NULL;
1869 win->splice_mode_right = false;
1870 }
1871 }
1872
vop2_write_lut(struct vop2 * vop2,uint32_t offset,uint32_t v)1873 static inline void vop2_write_lut(struct vop2 *vop2, uint32_t offset, uint32_t v)
1874 {
1875 writel(v, vop2->lut_regs + offset);
1876 }
1877
vop2_read_lut(struct vop2 * vop2,uint32_t offset)1878 static inline uint32_t vop2_read_lut(struct vop2 *vop2, uint32_t offset)
1879 {
1880 return readl(vop2->lut_regs + offset);
1881 }
1882
is_linear_10bit_yuv(uint32_t format)1883 static bool is_linear_10bit_yuv(uint32_t format)
1884 {
1885 switch (format) {
1886 case DRM_FORMAT_NV15:
1887 case DRM_FORMAT_NV20:
1888 case DRM_FORMAT_NV30:
1889 return true;
1890 default:
1891 return false;
1892 }
1893 }
1894
vop2_convert_format(uint32_t format)1895 static enum vop2_data_format vop2_convert_format(uint32_t format)
1896 {
1897 switch (format) {
1898 case DRM_FORMAT_XRGB2101010:
1899 case DRM_FORMAT_ARGB2101010:
1900 case DRM_FORMAT_XBGR2101010:
1901 case DRM_FORMAT_ABGR2101010:
1902 return VOP2_FMT_XRGB101010;
1903 case DRM_FORMAT_XRGB8888:
1904 case DRM_FORMAT_ARGB8888:
1905 case DRM_FORMAT_XBGR8888:
1906 case DRM_FORMAT_ABGR8888:
1907 return VOP2_FMT_ARGB8888;
1908 case DRM_FORMAT_RGB888:
1909 case DRM_FORMAT_BGR888:
1910 return VOP2_FMT_RGB888;
1911 case DRM_FORMAT_RGB565:
1912 case DRM_FORMAT_BGR565:
1913 return VOP2_FMT_RGB565;
1914 case DRM_FORMAT_NV12:
1915 case DRM_FORMAT_NV21:
1916 case DRM_FORMAT_YUV420_8BIT:
1917 return VOP2_FMT_YUV420SP;
1918 case DRM_FORMAT_NV15:
1919 case DRM_FORMAT_YUV420_10BIT:
1920 return VOP2_FMT_YUV420SP_10;
1921 case DRM_FORMAT_NV16:
1922 case DRM_FORMAT_NV61:
1923 return VOP2_FMT_YUV422SP;
1924 case DRM_FORMAT_NV20:
1925 case DRM_FORMAT_Y210:
1926 return VOP2_FMT_YUV422SP_10;
1927 case DRM_FORMAT_NV24:
1928 case DRM_FORMAT_NV42:
1929 return VOP2_FMT_YUV444SP;
1930 case DRM_FORMAT_NV30:
1931 return VOP2_FMT_YUV444SP_10;
1932 case DRM_FORMAT_YUYV:
1933 case DRM_FORMAT_YVYU:
1934 return VOP2_FMT_VYUY422;
1935 case DRM_FORMAT_VYUY:
1936 case DRM_FORMAT_UYVY:
1937 return VOP2_FMT_YUYV422;
1938 default:
1939 DRM_ERROR("unsupported format[%08x]\n", format);
1940 return -EINVAL;
1941 }
1942 }
1943
vop2_convert_afbc_format(uint32_t format)1944 static enum vop2_afbc_format vop2_convert_afbc_format(uint32_t format)
1945 {
1946 switch (format) {
1947 case DRM_FORMAT_XRGB2101010:
1948 case DRM_FORMAT_ARGB2101010:
1949 case DRM_FORMAT_XBGR2101010:
1950 case DRM_FORMAT_ABGR2101010:
1951 return VOP2_AFBC_FMT_ARGB2101010;
1952 case DRM_FORMAT_XRGB8888:
1953 case DRM_FORMAT_ARGB8888:
1954 case DRM_FORMAT_XBGR8888:
1955 case DRM_FORMAT_ABGR8888:
1956 return VOP2_AFBC_FMT_ARGB8888;
1957 case DRM_FORMAT_RGB888:
1958 case DRM_FORMAT_BGR888:
1959 return VOP2_AFBC_FMT_RGB888;
1960 case DRM_FORMAT_RGB565:
1961 case DRM_FORMAT_BGR565:
1962 return VOP2_AFBC_FMT_RGB565;
1963 case DRM_FORMAT_YUV420_8BIT:
1964 return VOP2_AFBC_FMT_YUV420;
1965 case DRM_FORMAT_YUV420_10BIT:
1966 return VOP2_AFBC_FMT_YUV420_10BIT;
1967 case DRM_FORMAT_YVYU:
1968 case DRM_FORMAT_YUYV:
1969 case DRM_FORMAT_VYUY:
1970 case DRM_FORMAT_UYVY:
1971 return VOP2_AFBC_FMT_YUV422;
1972 case DRM_FORMAT_Y210:
1973 return VOP2_AFBC_FMT_YUV422_10BIT;
1974
1975 /* either of the below should not be reachable */
1976 default:
1977 DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format);
1978 return VOP2_AFBC_FMT_INVALID;
1979 }
1980
1981 return VOP2_AFBC_FMT_INVALID;
1982 }
1983
vop2_convert_tiled_format(uint32_t format)1984 static enum vop2_tiled_format vop2_convert_tiled_format(uint32_t format)
1985 {
1986 switch (format) {
1987 case DRM_FORMAT_NV12:
1988 case DRM_FORMAT_NV21:
1989 return VOP2_TILED_8X8_FMT_YUV420SP;
1990 case DRM_FORMAT_NV16:
1991 case DRM_FORMAT_NV61:
1992 return VOP2_TILED_8X8_FMT_YUV422SP;
1993 case DRM_FORMAT_NV24:
1994 case DRM_FORMAT_NV42:
1995 return VOP2_TILED_8X8_FMT_YUV444SP;
1996 case DRM_FORMAT_NV15:
1997 return VOP2_TILED_8X8_FMT_YUV420SP_10;
1998 case DRM_FORMAT_NV20:
1999 return VOP2_TILED_8X8_FMT_YUV422SP_10;
2000 case DRM_FORMAT_NV30:
2001 return VOP2_TILED_8X8_FMT_YUV444SP_10;
2002 default:
2003 DRM_WARN_ONCE("unsupported tiled format[%08x]\n", format);
2004 return VOP2_TILED_FMT_INVALID;
2005 }
2006
2007 return VOP2_TILED_FMT_INVALID;
2008 }
2009
vop3_convert_tiled_format(uint32_t format,uint32_t tile_mode)2010 static enum vop3_tiled_format vop3_convert_tiled_format(uint32_t format, uint32_t tile_mode)
2011 {
2012 switch (format) {
2013 case DRM_FORMAT_NV12:
2014 case DRM_FORMAT_NV21:
2015 return tile_mode == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ?
2016 VOP3_TILED_8X8_FMT_YUV420SP : VOP3_TILED_4X4_FMT_YUV420SP;
2017 case DRM_FORMAT_NV16:
2018 case DRM_FORMAT_NV61:
2019 return tile_mode == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ?
2020 VOP3_TILED_8X8_FMT_YUV422SP : VOP3_TILED_4X4_FMT_YUV422SP;
2021 case DRM_FORMAT_NV24:
2022 case DRM_FORMAT_NV42:
2023 return tile_mode == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ?
2024 VOP3_TILED_8X8_FMT_YUV444SP : VOP3_TILED_4X4_FMT_YUV444SP;
2025 case DRM_FORMAT_NV15:
2026 return tile_mode == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ?
2027 VOP3_TILED_8X8_FMT_YUV420SP_10 : VOP3_TILED_4X4_FMT_YUV420SP_10;
2028 case DRM_FORMAT_NV20:
2029 return tile_mode == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ?
2030 VOP3_TILED_8X8_FMT_YUV422SP_10 : VOP3_TILED_4X4_FMT_YUV422SP_10;
2031 case DRM_FORMAT_NV30:
2032 return tile_mode == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ?
2033 VOP3_TILED_8X8_FMT_YUV444SP_10 : VOP3_TILED_4X4_FMT_YUV444SP_10;
2034 default:
2035 DRM_WARN_ONCE("unsupported tiled format[%08x]\n", format);
2036 return VOP3_TILED_FMT_INVALID;
2037 }
2038
2039 return VOP3_TILED_FMT_INVALID;
2040 }
2041
vop2_convert_wb_format(uint32_t format)2042 static enum vop2_wb_format vop2_convert_wb_format(uint32_t format)
2043 {
2044 switch (format) {
2045 case DRM_FORMAT_ARGB8888:
2046 return VOP2_WB_ARGB8888;
2047 case DRM_FORMAT_BGR888:
2048 return VOP2_WB_BGR888;
2049 case DRM_FORMAT_RGB565:
2050 return VOP2_WB_RGB565;
2051 case DRM_FORMAT_NV12:
2052 return VOP2_WB_YUV420SP;
2053 default:
2054 DRM_ERROR("unsupported wb format[%08x]\n", format);
2055 return VOP2_WB_INVALID;
2056 }
2057 }
2058
vop2_set_system_status(struct vop2 * vop2)2059 static void vop2_set_system_status(struct vop2 *vop2)
2060 {
2061 if (hweight8(vop2->active_vp_mask) > 1)
2062 rockchip_set_system_status(SYS_STATUS_DUALVIEW);
2063 else
2064 rockchip_clear_system_status(SYS_STATUS_DUALVIEW);
2065 }
2066
vop2_win_rb_swap(uint32_t format)2067 static bool vop2_win_rb_swap(uint32_t format)
2068 {
2069 switch (format) {
2070 case DRM_FORMAT_XBGR2101010:
2071 case DRM_FORMAT_ABGR2101010:
2072 case DRM_FORMAT_XBGR8888:
2073 case DRM_FORMAT_ABGR8888:
2074 case DRM_FORMAT_BGR888:
2075 case DRM_FORMAT_BGR565:
2076 return true;
2077 default:
2078 return false;
2079 }
2080 }
2081
vop2_afbc_rb_swap(uint32_t format)2082 static bool vop2_afbc_rb_swap(uint32_t format)
2083 {
2084 switch (format) {
2085 case DRM_FORMAT_NV24:
2086 case DRM_FORMAT_NV30:
2087 return true;
2088 default:
2089 return false;
2090 }
2091 }
2092
vop2_afbc_uv_swap(uint32_t format)2093 static bool vop2_afbc_uv_swap(uint32_t format)
2094 {
2095 switch (format) {
2096 case DRM_FORMAT_NV12:
2097 case DRM_FORMAT_NV16:
2098 case DRM_FORMAT_YUYV:
2099 case DRM_FORMAT_Y210:
2100 case DRM_FORMAT_YUV420_8BIT:
2101 case DRM_FORMAT_YUV420_10BIT:
2102 return true;
2103 default:
2104 return false;
2105 }
2106 }
2107
vop2_win_uv_swap(uint32_t format)2108 static bool vop2_win_uv_swap(uint32_t format)
2109 {
2110 switch (format) {
2111 case DRM_FORMAT_NV12:
2112 case DRM_FORMAT_NV16:
2113 case DRM_FORMAT_NV24:
2114 case DRM_FORMAT_NV15:
2115 case DRM_FORMAT_NV20:
2116 case DRM_FORMAT_NV30:
2117 case DRM_FORMAT_YUYV:
2118 case DRM_FORMAT_UYVY:
2119 return true;
2120 default:
2121 return false;
2122 }
2123 }
2124
vop2_win_dither_up(uint32_t format)2125 static bool vop2_win_dither_up(uint32_t format)
2126 {
2127 switch (format) {
2128 case DRM_FORMAT_BGR565:
2129 case DRM_FORMAT_RGB565:
2130 return true;
2131 default:
2132 return false;
2133 }
2134 }
2135
vop2_output_uv_swap(uint32_t bus_format,uint32_t output_mode)2136 static bool vop2_output_uv_swap(uint32_t bus_format, uint32_t output_mode)
2137 {
2138 /*
2139 * FIXME:
2140 *
2141 * There is no media type for YUV444 output,
2142 * so when out_mode is AAAA or P888, assume output is YUV444 on
2143 * yuv format.
2144 *
2145 * From H/W testing, YUV444 mode need a rb swap.
2146 */
2147 if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
2148 bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
2149 bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
2150 bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
2151 ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
2152 bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
2153 (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
2154 output_mode == ROCKCHIP_OUT_MODE_P888)))
2155 return true;
2156 else
2157 return false;
2158 }
2159
vop3_output_rb_swap(uint32_t bus_format,uint32_t output_mode)2160 static bool vop3_output_rb_swap(uint32_t bus_format, uint32_t output_mode)
2161 {
2162 /*
2163 * The default component order of serial rgb3x8 formats
2164 * is BGR. So it is needed to enable RB swap.
2165 */
2166 if (bus_format == MEDIA_BUS_FMT_RGB888_3X8 ||
2167 bus_format == MEDIA_BUS_FMT_RGB888_DUMMY_4X8)
2168 return true;
2169 else
2170 return false;
2171 }
2172
vop2_output_yc_swap(uint32_t bus_format)2173 static bool vop2_output_yc_swap(uint32_t bus_format)
2174 {
2175 switch (bus_format) {
2176 case MEDIA_BUS_FMT_YUYV8_1X16:
2177 case MEDIA_BUS_FMT_YVYU8_1X16:
2178 case MEDIA_BUS_FMT_YUYV8_2X8:
2179 case MEDIA_BUS_FMT_YVYU8_2X8:
2180 return true;
2181 default:
2182 return false;
2183 }
2184 }
2185
is_yuv_output(uint32_t bus_format)2186 static bool is_yuv_output(uint32_t bus_format)
2187 {
2188 switch (bus_format) {
2189 case MEDIA_BUS_FMT_YUV8_1X24:
2190 case MEDIA_BUS_FMT_YUV10_1X30:
2191 case MEDIA_BUS_FMT_YUYV10_1X20:
2192 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
2193 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
2194 case MEDIA_BUS_FMT_YUYV8_2X8:
2195 case MEDIA_BUS_FMT_YVYU8_2X8:
2196 case MEDIA_BUS_FMT_UYVY8_2X8:
2197 case MEDIA_BUS_FMT_VYUY8_2X8:
2198 case MEDIA_BUS_FMT_YUYV8_1X16:
2199 case MEDIA_BUS_FMT_YVYU8_1X16:
2200 case MEDIA_BUS_FMT_UYVY8_1X16:
2201 case MEDIA_BUS_FMT_VYUY8_1X16:
2202 return true;
2203 default:
2204 return false;
2205 }
2206 }
2207
is_alpha_support(uint32_t format)2208 static bool is_alpha_support(uint32_t format)
2209 {
2210 switch (format) {
2211 case DRM_FORMAT_ARGB8888:
2212 case DRM_FORMAT_ABGR8888:
2213 return true;
2214 default:
2215 return false;
2216 }
2217 }
2218
rockchip_afbc(struct drm_plane * plane,u64 modifier)2219 static inline bool rockchip_afbc(struct drm_plane *plane, u64 modifier)
2220 {
2221 int i;
2222
2223 if (modifier == DRM_FORMAT_MOD_LINEAR)
2224 return false;
2225
2226 if (!drm_is_afbc(modifier))
2227 return false;
2228
2229 for (i = 0 ; i < plane->modifier_count; i++)
2230 if (plane->modifiers[i] == modifier)
2231 break;
2232
2233 return (i < plane->modifier_count) ? true : false;
2234 }
2235
rockchip_tiled(struct drm_plane * plane,u64 modifier)2236 static inline bool rockchip_tiled(struct drm_plane *plane, u64 modifier)
2237 {
2238 int i;
2239
2240 if (modifier == DRM_FORMAT_MOD_LINEAR)
2241 return false;
2242
2243 if (!IS_ROCKCHIP_TILED_MOD(modifier))
2244 return false;
2245
2246 for (i = 0 ; i < plane->modifier_count; i++)
2247 if (plane->modifiers[i] == modifier)
2248 break;
2249
2250 return (i < plane->modifier_count) ? true : false;
2251 }
2252
rockchip_vop2_mod_supported(struct drm_plane * plane,u32 format,u64 modifier)2253 static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format, u64 modifier)
2254 {
2255 if (modifier == DRM_FORMAT_MOD_INVALID)
2256 return false;
2257
2258 if (modifier == DRM_FORMAT_MOD_LINEAR)
2259 return true;
2260
2261 if (!rockchip_afbc(plane, modifier) && !rockchip_tiled(plane, modifier)) {
2262 DRM_ERROR("Unsupported format modifier 0x%llx\n", modifier);
2263
2264 return false;
2265 }
2266
2267 return vop2_convert_afbc_format(format) >= 0 ||
2268 vop2_convert_tiled_format(format) >= 0 ||
2269 vop3_convert_tiled_format(format, 0) >= 0;
2270 }
2271
vop2_multi_area_sub_window(struct vop2_win * win)2272 static inline bool vop2_multi_area_sub_window(struct vop2_win *win)
2273 {
2274 return (win->parent && (win->feature & WIN_FEATURE_MULTI_AREA));
2275 }
2276
vop2_cluster_window(struct vop2_win * win)2277 static inline bool vop2_cluster_window(struct vop2_win *win)
2278 {
2279 return (win->feature & (WIN_FEATURE_CLUSTER_MAIN | WIN_FEATURE_CLUSTER_SUB));
2280 }
2281
vop2_cluster_sub_window(struct vop2_win * win)2282 static inline bool vop2_cluster_sub_window(struct vop2_win *win)
2283 {
2284 return (win->feature & WIN_FEATURE_CLUSTER_SUB);
2285 }
2286
vop2_has_feature(struct vop2 * vop2,uint64_t feature)2287 static inline bool vop2_has_feature(struct vop2 *vop2, uint64_t feature)
2288 {
2289 return (vop2->data->feature & feature);
2290 }
2291
2292 /*
2293 * 0: Full mode, 16 lines for one tail
2294 * 1: half block mode
2295 */
vop2_afbc_half_block_enable(struct vop2_plane_state * vpstate)2296 static int vop2_afbc_half_block_enable(struct vop2_plane_state *vpstate)
2297 {
2298 if (vpstate->rotate_270_en || vpstate->rotate_90_en)
2299 return 0;
2300 else
2301 return 1;
2302 }
2303
2304 /*
2305 * @xoffset: the src x offset of the right win in splice mode, other wise it
2306 * must be zero.
2307 */
vop2_afbc_transform_offset(struct vop2_plane_state * vpstate,int xoffset)2308 static uint32_t vop2_afbc_transform_offset(struct vop2_plane_state *vpstate, int xoffset)
2309 {
2310 struct drm_rect *src = &vpstate->src;
2311 struct drm_framebuffer *fb = vpstate->base.fb;
2312 uint32_t bpp = rockchip_drm_get_bpp(fb->format);
2313 uint32_t vir_width = (fb->pitches[0] << 3) / (bpp ? bpp : 1);
2314 uint32_t width = drm_rect_width(src) >> 16;
2315 uint32_t height = drm_rect_height(src) >> 16;
2316 uint32_t act_xoffset = src->x1 >> 16;
2317 uint32_t act_yoffset = src->y1 >> 16;
2318 uint32_t align16_crop = 0;
2319 uint32_t align64_crop = 0;
2320 uint32_t height_tmp = 0;
2321 uint32_t transform_tmp = 0;
2322 uint8_t transform_xoffset = 0;
2323 uint8_t transform_yoffset = 0;
2324 uint8_t top_crop = 0;
2325 uint8_t top_crop_line_num = 0;
2326 uint8_t bottom_crop_line_num = 0;
2327
2328 act_xoffset += xoffset;
2329 /* 16 pixel align */
2330 if (height & 0xf)
2331 align16_crop = 16 - (height & 0xf);
2332
2333 height_tmp = height + align16_crop;
2334
2335 /* 64 pixel align */
2336 if (height_tmp & 0x3f)
2337 align64_crop = 64 - (height_tmp & 0x3f);
2338
2339 top_crop_line_num = top_crop << 2;
2340 if (top_crop == 0)
2341 bottom_crop_line_num = align16_crop + align64_crop;
2342 else if (top_crop == 1)
2343 bottom_crop_line_num = align16_crop + align64_crop + 12;
2344 else if (top_crop == 2)
2345 bottom_crop_line_num = align16_crop + align64_crop + 8;
2346
2347 if (vpstate->xmirror_en) {
2348 if (vpstate->ymirror_en) {
2349 if (vpstate->afbc_half_block_en) {
2350 transform_tmp = act_xoffset + width;
2351 transform_xoffset = 16 - (transform_tmp & 0xf);
2352 transform_tmp = bottom_crop_line_num - act_yoffset;
2353 transform_yoffset = transform_tmp & 0x7;
2354 } else { //FULL MODEL
2355 transform_tmp = act_xoffset + width;
2356 transform_xoffset = 16 - (transform_tmp & 0xf);
2357 transform_tmp = bottom_crop_line_num - act_yoffset;
2358 transform_yoffset = (transform_tmp & 0xf);
2359 }
2360 } else if (vpstate->rotate_90_en) {
2361 transform_tmp = bottom_crop_line_num - act_yoffset;
2362 transform_xoffset = transform_tmp & 0xf;
2363 transform_tmp = vir_width - width - act_xoffset;
2364 transform_yoffset = transform_tmp & 0xf;
2365 } else if (vpstate->rotate_270_en) {
2366 transform_tmp = top_crop_line_num + act_yoffset;
2367 transform_xoffset = transform_tmp & 0xf;
2368 transform_tmp = act_xoffset;
2369 transform_yoffset = transform_tmp & 0xf;
2370
2371 } else { //xmir
2372 if (vpstate->afbc_half_block_en) {
2373 transform_tmp = act_xoffset + width;
2374 transform_xoffset = 16 - (transform_tmp & 0xf);
2375 transform_tmp = top_crop_line_num + act_yoffset;
2376 transform_yoffset = transform_tmp & 0x7;
2377 } else {
2378 transform_tmp = act_xoffset + width;
2379 transform_xoffset = 16 - (transform_tmp & 0xf);
2380 transform_tmp = top_crop_line_num + act_yoffset;
2381 transform_yoffset = transform_tmp & 0xf;
2382 }
2383 }
2384 } else if (vpstate->ymirror_en) {
2385 if (vpstate->afbc_half_block_en) {
2386 transform_tmp = act_xoffset;
2387 transform_xoffset = transform_tmp & 0xf;
2388 transform_tmp = bottom_crop_line_num - act_yoffset;
2389 transform_yoffset = transform_tmp & 0x7;
2390 } else { //full_mode
2391 transform_tmp = act_xoffset;
2392 transform_xoffset = transform_tmp & 0xf;
2393 transform_tmp = bottom_crop_line_num - act_yoffset;
2394 transform_yoffset = transform_tmp & 0xf;
2395 }
2396 } else if (vpstate->rotate_90_en) {
2397 transform_tmp = bottom_crop_line_num - act_yoffset;
2398 transform_xoffset = transform_tmp & 0xf;
2399 transform_tmp = act_xoffset;
2400 transform_yoffset = transform_tmp & 0xf;
2401 } else if (vpstate->rotate_270_en) {
2402 transform_tmp = top_crop_line_num + act_yoffset;
2403 transform_xoffset = transform_tmp & 0xf;
2404 transform_tmp = vir_width - width - act_xoffset;
2405 transform_yoffset = transform_tmp & 0xf;
2406 } else { //normal
2407 if (vpstate->afbc_half_block_en) {
2408 transform_tmp = act_xoffset;
2409 transform_xoffset = transform_tmp & 0xf;
2410 transform_tmp = top_crop_line_num + act_yoffset;
2411 transform_yoffset = transform_tmp & 0x7;
2412 } else { //full_mode
2413 transform_tmp = act_xoffset;
2414 transform_xoffset = transform_tmp & 0xf;
2415 transform_tmp = top_crop_line_num + act_yoffset;
2416 transform_yoffset = transform_tmp & 0xf;
2417 }
2418 }
2419
2420 return (transform_xoffset & 0xf) | ((transform_yoffset & 0xf) << 16);
2421 }
2422
vop2_tile_transform_offset(struct vop2_plane_state * vpstate,uint8_t tiled_en)2423 static uint32_t vop2_tile_transform_offset(struct vop2_plane_state *vpstate, uint8_t tiled_en)
2424 {
2425 struct drm_rect *src = &vpstate->src;
2426 uint32_t act_xoffset = src->x1 >> 16;
2427 uint32_t act_yoffset = src->y1 >> 16;
2428 uint8_t transform_xoffset = 0;
2429 uint8_t transform_yoffset = 0;
2430 uint32_t tile_size = 1;
2431
2432 if (tiled_en == 0)
2433 return 0;
2434
2435 tile_size = tiled_en == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ? 8 : 4;
2436 transform_xoffset = act_xoffset & (tile_size - 1);
2437 transform_yoffset = act_yoffset & (tile_size - 1);
2438
2439 return (transform_xoffset & 0xf) | ((transform_yoffset & 0xf) << 16);
2440 }
2441
2442 /*
2443 * A Cluster window has 2048 x 16 line buffer, which can
2444 * works at 2048 x 16(Full) or 4096 x 8 (Half) mode.
2445 * for Cluster_lb_mode register:
2446 * 0: half mode, for plane input width range 2048 ~ 4096
2447 * 1: half mode, for cluster work at 2 * 2048 plane mode
2448 * 2: half mode, for rotate_90/270 mode
2449 *
2450 */
vop2_get_cluster_lb_mode(struct vop2_win * win,struct vop2_plane_state * vpstate)2451 static int vop2_get_cluster_lb_mode(struct vop2_win *win, struct vop2_plane_state *vpstate)
2452 {
2453 if (vpstate->rotate_270_en || vpstate->rotate_90_en)
2454 return 2;
2455 else if (win->feature & WIN_FEATURE_CLUSTER_SUB)
2456 return 1;
2457 else
2458 return 0;
2459 }
2460
2461 /*
2462 * bli_sd_factor = (src - 1) / (dst - 1) << 12;
2463 * avg_sd_factor:
2464 * bli_su_factor:
2465 * bic_su_factor:
2466 * = (src - 1) / (dst - 1) << 16;
2467 *
2468 * ygt2 enable: dst get one line from two line of the src
2469 * ygt4 enable: dst get one line from four line of the src.
2470 *
2471 */
2472 #define VOP2_BILI_SCL_DN(src, dst) (((src - 1) << 12) / (dst - 1))
2473 #define VOP2_COMMON_SCL(src, dst) (((src - 1) << 16) / (dst - 1))
2474
2475 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac) \
2476 (fac * (dst - 1) >> 12 < (src - 1))
2477 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \
2478 (fac * (dst - 1) >> 16 < (src - 1))
2479 #define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \
2480 (fac * (dst - 1) >> 16 < (src - 1))
2481
vop2_scale_factor(enum scale_mode mode,int32_t filter_mode,uint32_t src,uint32_t dst)2482 static uint16_t vop2_scale_factor(enum scale_mode mode,
2483 int32_t filter_mode,
2484 uint32_t src, uint32_t dst)
2485 {
2486 uint32_t fac = 0;
2487 int i = 0;
2488
2489 if (mode == SCALE_NONE)
2490 return 0;
2491
2492 /*
2493 * A workaround to avoid zero div.
2494 */
2495 if ((dst == 1) || (src == 1)) {
2496 dst = dst + 1;
2497 src = src + 1;
2498 }
2499
2500 if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) {
2501 fac = VOP2_BILI_SCL_DN(src, dst);
2502 for (i = 0; i < 100; i++) {
2503 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
2504 break;
2505 fac -= 1;
2506 DRM_DEBUG("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
2507 }
2508 } else {
2509 fac = VOP2_COMMON_SCL(src, dst);
2510 for (i = 0; i < 100; i++) {
2511 if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac))
2512 break;
2513 fac -= 1;
2514 DRM_DEBUG("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
2515 }
2516 }
2517
2518 return fac;
2519 }
2520
vop3_scale_up_fac_check(uint32_t src,uint32_t dst,uint32_t fac,bool is_hor)2521 static bool vop3_scale_up_fac_check(uint32_t src, uint32_t dst, uint32_t fac, bool is_hor)
2522 {
2523 if (is_hor)
2524 return VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac);
2525 return VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac);
2526 }
2527
vop3_scale_factor(enum scale_mode mode,uint32_t src,uint32_t dst,bool is_hor)2528 static uint16_t vop3_scale_factor(enum scale_mode mode,
2529 uint32_t src, uint32_t dst, bool is_hor)
2530 {
2531 uint32_t fac = 0;
2532 int i = 0;
2533
2534 if (mode == SCALE_NONE)
2535 return 0;
2536
2537 /*
2538 * A workaround to avoid zero div.
2539 */
2540 if ((dst == 1) || (src == 1)) {
2541 dst = dst + 1;
2542 src = src + 1;
2543 }
2544
2545 if (mode == SCALE_DOWN) {
2546 fac = VOP2_BILI_SCL_DN(src, dst);
2547 for (i = 0; i < 100; i++) {
2548 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
2549 break;
2550 fac -= 1;
2551 DRM_DEBUG("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
2552 }
2553 } else {
2554 fac = VOP2_COMMON_SCL(src, dst);
2555 for (i = 0; i < 100; i++) {
2556 if (vop3_scale_up_fac_check(src, dst, fac, is_hor))
2557 break;
2558 fac -= 1;
2559 DRM_DEBUG("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
2560 }
2561 }
2562
2563 return fac;
2564 }
2565
vop2_setup_scale(struct vop2 * vop2,struct vop2_win * win,uint32_t src_w,uint32_t src_h,uint32_t dst_w,uint32_t dst_h,struct drm_plane_state * pstate)2566 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win *win,
2567 uint32_t src_w, uint32_t src_h, uint32_t dst_w,
2568 uint32_t dst_h, struct drm_plane_state *pstate)
2569 {
2570 const struct vop2_data *vop2_data = vop2->data;
2571 const struct vop2_win_data *win_data = &vop2_data->win[win->win_id];
2572 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
2573 struct drm_framebuffer *fb = pstate->fb;
2574 uint32_t pixel_format = fb->format->format;
2575 const struct drm_format_info *info = drm_format_info(pixel_format);
2576 uint8_t hsub = info->hsub;
2577 uint8_t vsub = info->vsub;
2578 uint16_t cbcr_src_w = src_w / hsub;
2579 uint16_t cbcr_src_h = src_h / vsub;
2580 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
2581 uint16_t cbcr_hor_scl_mode, cbcr_ver_scl_mode;
2582 uint16_t hscl_filter_mode, vscl_filter_mode;
2583 uint8_t xgt2 = 0, xgt4 = 0;
2584 uint8_t ygt2 = 0, ygt4 = 0;
2585 uint32_t val;
2586
2587 if (is_vop3(vop2)) {
2588 if (src_w >= (4 * dst_w)) {
2589 xgt4 = 1;
2590 src_w >>= 2;
2591 } else if (src_w >= (2 * dst_w)) {
2592 xgt2 = 1;
2593 src_w >>= 1;
2594 }
2595 }
2596
2597 /**
2598 * The rk3528 is processed as 2 pixel/cycle,
2599 * so ygt2/ygt4 needs to be triggered in advance to improve performance
2600 * when src_w is bigger than 1920.
2601 * dst_h / src_h is at [1, 0.65) ygt2=0; ygt4=0;
2602 * dst_h / src_h is at [0.65, 0.35) ygt2=1; ygt4=0;
2603 * dst_h / src_h is at [0.35, 0) ygt2=0; ygt4=1;
2604 */
2605 if (vop2->version == VOP_VERSION_RK3528 && src_w > 1920) {
2606 if (src_h >= (100 * dst_h / 35)) {
2607 ygt4 = 1;
2608 src_h >>= 2;
2609 } else if ((src_h >= 100 * dst_h / 65) && (src_h < 100 * dst_h / 35)) {
2610 ygt2 = 1;
2611 src_h >>= 1;
2612 }
2613 } else {
2614 if (src_h >= (4 * dst_h)) {
2615 ygt4 = 1;
2616 src_h >>= 2;
2617 } else if (src_h >= (2 * dst_h)) {
2618 ygt2 = 1;
2619 src_h >>= 1;
2620 }
2621 }
2622
2623 yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
2624 yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
2625
2626 if (yrgb_hor_scl_mode == SCALE_UP)
2627 hscl_filter_mode = win_data->hsu_filter_mode;
2628 else
2629 hscl_filter_mode = win_data->hsd_filter_mode;
2630
2631 if (yrgb_ver_scl_mode == SCALE_UP)
2632 vscl_filter_mode = win_data->vsu_filter_mode;
2633 else
2634 vscl_filter_mode = win_data->vsd_filter_mode;
2635
2636 /*
2637 * RK3568 VOP Esmart/Smart dsp_w should be even pixel
2638 * at scale down mode
2639 */
2640 if (!(win->feature & WIN_FEATURE_AFBDC) && !is_vop3(vop2)) {
2641 if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) {
2642 dev_dbg(vop2->dev, "%s dst_w[%d] should align as 2 pixel\n", win->name, dst_w);
2643 dst_w += 1;
2644 }
2645 }
2646
2647 if (is_vop3(vop2)) {
2648 bool xgt_en = false, xavg_en = false;
2649
2650 val = vop3_scale_factor(yrgb_hor_scl_mode, src_w, dst_w, true);
2651 VOP_SCL_SET(vop2, win, scale_yrgb_x, val);
2652 val = vop3_scale_factor(yrgb_ver_scl_mode, src_h, dst_h, false);
2653 VOP_SCL_SET(vop2, win, scale_yrgb_y, val);
2654
2655 if (win_data->hsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_AVG)
2656 xavg_en = xgt2 || xgt4;
2657 else
2658 xgt_en = xgt2 || xgt4;
2659
2660 VOP_SCL_SET(vop2, win, xgt_en, xgt_en);
2661 VOP_SCL_SET(vop2, win, xavg_en, xavg_en);
2662 VOP_SCL_SET(vop2, win, xgt_mode, xgt2 ? 0 : 1);
2663 } else {
2664 val = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w);
2665 VOP_SCL_SET(vop2, win, scale_yrgb_x, val);
2666 val = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h);
2667 VOP_SCL_SET(vop2, win, scale_yrgb_y, val);
2668 }
2669
2670 /* vop2 and linear mode only can support gt */
2671 if (!is_vop3(vop2) ||
2672 (!vpstate->afbc_en && !vpstate->tiled_en) ||
2673 win_data->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) {
2674 VOP_SCL_SET(vop2, win, vsd_yrgb_gt4, ygt4);
2675 VOP_SCL_SET(vop2, win, vsd_yrgb_gt2, ygt2);
2676 VOP_SCL_SET(vop2, win, vsd_avg4, 0);
2677 VOP_SCL_SET(vop2, win, vsd_avg2, 0);
2678 } else {
2679 VOP_SCL_SET(vop2, win, vsd_yrgb_gt4, 0);
2680 VOP_SCL_SET(vop2, win, vsd_yrgb_gt2, 0);
2681 VOP_SCL_SET(vop2, win, vsd_avg4, ygt4);
2682 VOP_SCL_SET(vop2, win, vsd_avg2, ygt2);
2683 }
2684
2685 VOP_SCL_SET(vop2, win, yrgb_hor_scl_mode, yrgb_hor_scl_mode);
2686 VOP_SCL_SET(vop2, win, yrgb_ver_scl_mode, yrgb_ver_scl_mode);
2687
2688 VOP_SCL_SET(vop2, win, yrgb_hscl_filter_mode, hscl_filter_mode);
2689 VOP_SCL_SET(vop2, win, yrgb_vscl_filter_mode, vscl_filter_mode);
2690
2691 if (info->is_yuv) {
2692 ygt4 = ygt2 = 0;
2693
2694 if (!is_vop3(vop2) ||
2695 (!vpstate->afbc_en && !vpstate->tiled_en) ||
2696 win_data->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) {
2697 if (vop2->version == VOP_VERSION_RK3528 && src_w > 1920) {
2698 if (cbcr_src_h >= (100 * dst_h / 35))
2699 ygt4 = 1;
2700 else if ((cbcr_src_h >= 100 * dst_h / 65) && (cbcr_src_h < 100 * dst_h / 35))
2701 ygt2 = 1;
2702 } else {
2703 if (cbcr_src_h >= (4 * dst_h))
2704 ygt4 = 1;
2705 else if (cbcr_src_h >= (2 * dst_h))
2706 ygt2 = 1;
2707 }
2708
2709 if (ygt4)
2710 cbcr_src_h >>= 2;
2711 else if (ygt2)
2712 cbcr_src_h >>= 1;
2713 }
2714 VOP_SCL_SET(vop2, win, vsd_cbcr_gt4, ygt4);
2715 VOP_SCL_SET(vop2, win, vsd_cbcr_gt2, ygt2);
2716
2717 if (!is_vop3(vop2)) {
2718 cbcr_hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w);
2719 cbcr_ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h);
2720
2721 val = vop2_scale_factor(cbcr_hor_scl_mode, hscl_filter_mode,
2722 cbcr_src_w, dst_w);
2723 VOP_SCL_SET(vop2, win, scale_cbcr_x, val);
2724 val = vop2_scale_factor(cbcr_ver_scl_mode, vscl_filter_mode,
2725 cbcr_src_h, dst_h);
2726 VOP_SCL_SET(vop2, win, scale_cbcr_y, val);
2727
2728 VOP_SCL_SET(vop2, win, cbcr_hor_scl_mode, cbcr_hor_scl_mode);
2729 VOP_SCL_SET(vop2, win, cbcr_ver_scl_mode, cbcr_ver_scl_mode);
2730 VOP_SCL_SET(vop2, win, cbcr_hscl_filter_mode, hscl_filter_mode);
2731 VOP_SCL_SET(vop2, win, cbcr_vscl_filter_mode, vscl_filter_mode);
2732 }
2733 }
2734 }
2735
vop2_convert_csc_mode(int csc_mode,int bit_depth)2736 static int vop2_convert_csc_mode(int csc_mode, int bit_depth)
2737 {
2738 switch (csc_mode) {
2739 case V4L2_COLORSPACE_SMPTE170M:
2740 case V4L2_COLORSPACE_470_SYSTEM_M:
2741 case V4L2_COLORSPACE_470_SYSTEM_BG:
2742 return CSC_BT601L;
2743 case V4L2_COLORSPACE_REC709:
2744 case V4L2_COLORSPACE_SMPTE240M:
2745 case V4L2_COLORSPACE_DEFAULT:
2746 if (bit_depth == CSC_13BIT_DEPTH)
2747 return CSC_BT709L_13BIT;
2748 else
2749 return CSC_BT709L;
2750 case V4L2_COLORSPACE_JPEG:
2751 return CSC_BT601F;
2752 case V4L2_COLORSPACE_BT2020:
2753 if (bit_depth == CSC_13BIT_DEPTH)
2754 return CSC_BT2020L_13BIT;
2755 else
2756 return CSC_BT2020;
2757 case V4L2_COLORSPACE_BT709F:
2758 if (bit_depth == CSC_10BIT_DEPTH) {
2759 DRM_WARN("Unsupported bt709f at 10bit csc depth, use bt601f instead\n");
2760 return CSC_BT601F;
2761 } else {
2762 return CSC_BT709F_13BIT;
2763 }
2764 case V4L2_COLORSPACE_BT2020F:
2765 if (bit_depth == CSC_10BIT_DEPTH) {
2766 DRM_WARN("Unsupported bt2020f at 10bit csc depth, use bt601f instead\n");
2767 return CSC_BT601F;
2768 } else {
2769 return CSC_BT2020F_13BIT;
2770 }
2771 default:
2772 return CSC_BT709L;
2773 }
2774 }
2775
vop2_is_allwin_disabled(struct drm_crtc * crtc)2776 static bool vop2_is_allwin_disabled(struct drm_crtc *crtc)
2777 {
2778 struct vop2_video_port *vp = to_vop2_video_port(crtc);
2779 struct vop2 *vop2 = vp->vop2;
2780 unsigned long win_mask = vp->win_mask;
2781 struct vop2_win *win;
2782 int phys_id;
2783
2784 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
2785 win = vop2_find_win_by_phys_id(vop2, phys_id);
2786 if (VOP_WIN_GET(vop2, win, enable) != 0)
2787 return false;
2788 }
2789
2790 return true;
2791 }
2792
vop2_disable_all_planes_for_crtc(struct drm_crtc * crtc)2793 static void vop2_disable_all_planes_for_crtc(struct drm_crtc *crtc)
2794 {
2795 struct vop2_video_port *vp = to_vop2_video_port(crtc);
2796 struct vop2 *vop2 = vp->vop2;
2797 struct vop2_win *win;
2798 unsigned long win_mask = vp->win_mask;
2799 int phys_id, ret;
2800 bool active, need_wait_win_disabled = false;
2801
2802 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
2803 win = vop2_find_win_by_phys_id(vop2, phys_id);
2804 need_wait_win_disabled |= VOP_WIN_GET(vop2, win, enable);
2805 vop2_win_disable(win, false);
2806 }
2807
2808 if (need_wait_win_disabled) {
2809 vop2_cfg_done(crtc);
2810 ret = readx_poll_timeout_atomic(vop2_is_allwin_disabled, crtc,
2811 active, active, 0, 500 * 1000);
2812 if (ret)
2813 DRM_DEV_ERROR(vop2->dev, "wait win close timeout\n");
2814 }
2815 }
2816
2817 /*
2818 * colorspace path:
2819 * Input Win csc Output
2820 * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
2821 * RGB --> R2Y __/
2822 *
2823 * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020)
2824 * RGB --> 709To2020->R2Y __/
2825 *
2826 * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709)
2827 * RGB --> R2Y __/
2828 *
2829 * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
2830 * RGB --> 709To2020->R2Y __/
2831 *
2832 * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709)
2833 * RGB --> R2Y __/
2834 *
2835 * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601)
2836 * RGB --> R2Y(601) __/
2837 *
2838 * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709)
2839 * RGB --> bypass __/
2840 *
2841 * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020)
2842 *
2843 * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709)
2844 *
2845 * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601)
2846 *
2847 * 11. RGB --> bypass --> RGB_OUTPUT(709)
2848 */
2849
vop2_setup_csc_mode(struct vop2_video_port * vp,struct vop2_plane_state * vpstate)2850 static void vop2_setup_csc_mode(struct vop2_video_port *vp,
2851 struct vop2_plane_state *vpstate)
2852 {
2853 struct drm_plane_state *pstate = &vpstate->base;
2854 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->rockchip_crtc.crtc.state);
2855 int is_input_yuv = pstate->fb->format->is_yuv;
2856 int is_output_yuv = vcstate->yuv_overlay;
2857 int input_csc = vpstate->color_space;
2858 int output_csc = vcstate->color_space;
2859 struct vop2_win *win = to_vop2_win(pstate->plane);
2860 int csc_y2r_bit_depth = CSC_10BIT_DEPTH;
2861
2862 if (win->feature & WIN_FEATURE_Y2R_13BIT_DEPTH)
2863 csc_y2r_bit_depth = CSC_13BIT_DEPTH;
2864
2865 vpstate->y2r_en = 0;
2866 vpstate->r2y_en = 0;
2867 vpstate->csc_mode = 0;
2868
2869 if (is_vop3(vp->vop2)) {
2870 if (vpstate->hdr_in) {
2871 if (is_input_yuv) {
2872 vpstate->y2r_en = 1;
2873 vpstate->csc_mode = vop2_convert_csc_mode(input_csc,
2874 CSC_13BIT_DEPTH);
2875 }
2876 return;
2877 } else if (vp->sdr2hdr_en) {
2878 if (is_input_yuv) {
2879 vpstate->y2r_en = 1;
2880 vpstate->csc_mode = vop2_convert_csc_mode(input_csc,
2881 csc_y2r_bit_depth);
2882 }
2883 return;
2884 }
2885 } else {
2886 /* hdr2sdr and sdr2hdr will do csc itself */
2887 if (vpstate->hdr2sdr_en) {
2888 /*
2889 * This is hdr2sdr enabled plane
2890 * If it's RGB layer do hdr2sdr, we need to do r2y before send to hdr2sdr,
2891 * because hdr2sdr only support yuv input.
2892 */
2893 if (!is_input_yuv) {
2894 vpstate->r2y_en = 1;
2895 vpstate->csc_mode = vop2_convert_csc_mode(output_csc,
2896 CSC_10BIT_DEPTH);
2897 }
2898 return;
2899 } else if (!vpstate->hdr_in && vp->sdr2hdr_en) {
2900 /*
2901 * This is sdr2hdr enabled plane
2902 * If it's YUV layer do sdr2hdr, we need to do y2r before send to sdr2hdr,
2903 * because sdr2hdr only support rgb input.
2904 */
2905 if (is_input_yuv) {
2906 vpstate->y2r_en = 1;
2907 vpstate->csc_mode = vop2_convert_csc_mode(input_csc,
2908 csc_y2r_bit_depth);
2909 }
2910 return;
2911 }
2912 }
2913
2914 if (is_input_yuv && !is_output_yuv) {
2915 vpstate->y2r_en = 1;
2916 vpstate->csc_mode = vop2_convert_csc_mode(input_csc, csc_y2r_bit_depth);
2917 } else if (!is_input_yuv && is_output_yuv) {
2918 vpstate->r2y_en = 1;
2919 vpstate->csc_mode = vop2_convert_csc_mode(output_csc, CSC_10BIT_DEPTH);
2920 }
2921 }
2922
vop2_axi_irqs_enable(struct vop2 * vop2)2923 static void vop2_axi_irqs_enable(struct vop2 *vop2)
2924 {
2925 const struct vop2_data *vop2_data = vop2->data;
2926 const struct vop_intr *intr;
2927 uint32_t irqs = BUS_ERROR_INTR;
2928 uint32_t i;
2929
2930 for (i = 0; i < vop2_data->nr_axi_intr; i++) {
2931 intr = &vop2_data->axi_intr[i];
2932 VOP_INTR_SET_TYPE(vop2, intr, clear, irqs, 1);
2933 VOP_INTR_SET_TYPE(vop2, intr, enable, irqs, 1);
2934 }
2935 }
2936
vop2_read_and_clear_axi_irqs(struct vop2 * vop2,int index)2937 static uint32_t vop2_read_and_clear_axi_irqs(struct vop2 *vop2, int index)
2938 {
2939 const struct vop2_data *vop2_data = vop2->data;
2940 const struct vop_intr *intr = &vop2_data->axi_intr[index];
2941 uint32_t irqs = BUS_ERROR_INTR;
2942 uint32_t val;
2943
2944 val = VOP_INTR_GET_TYPE(vop2, intr, status, irqs);
2945 if (val)
2946 VOP_INTR_SET_TYPE(vop2, intr, clear, val, 1);
2947
2948 return val;
2949 }
2950
vop2_dsp_hold_valid_irq_enable(struct drm_crtc * crtc)2951 static void vop2_dsp_hold_valid_irq_enable(struct drm_crtc *crtc)
2952 {
2953 struct vop2_video_port *vp = to_vop2_video_port(crtc);
2954 struct vop2 *vop2 = vp->vop2;
2955 const struct vop2_data *vop2_data = vop2->data;
2956 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
2957 const struct vop_intr *intr = vp_data->intr;
2958
2959 unsigned long flags;
2960
2961 if (WARN_ON(!vop2->is_enabled))
2962 return;
2963
2964 spin_lock_irqsave(&vop2->irq_lock, flags);
2965
2966 VOP_INTR_SET_TYPE(vop2, intr, clear, DSP_HOLD_VALID_INTR, 1);
2967 VOP_INTR_SET_TYPE(vop2, intr, enable, DSP_HOLD_VALID_INTR, 1);
2968
2969 spin_unlock_irqrestore(&vop2->irq_lock, flags);
2970 }
2971
vop2_dsp_hold_valid_irq_disable(struct drm_crtc * crtc)2972 static void vop2_dsp_hold_valid_irq_disable(struct drm_crtc *crtc)
2973 {
2974 struct vop2_video_port *vp = to_vop2_video_port(crtc);
2975 struct vop2 *vop2 = vp->vop2;
2976 const struct vop2_data *vop2_data = vop2->data;
2977 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
2978 const struct vop_intr *intr = vp_data->intr;
2979 unsigned long flags;
2980
2981 if (WARN_ON(!vop2->is_enabled))
2982 return;
2983
2984 spin_lock_irqsave(&vop2->irq_lock, flags);
2985
2986 VOP_INTR_SET_TYPE(vop2, intr, enable, DSP_HOLD_VALID_INTR, 0);
2987
2988 spin_unlock_irqrestore(&vop2->irq_lock, flags);
2989 }
2990
vop2_debug_irq_enable(struct drm_crtc * crtc)2991 static void vop2_debug_irq_enable(struct drm_crtc *crtc)
2992 {
2993 struct vop2_video_port *vp = to_vop2_video_port(crtc);
2994 struct vop2 *vop2 = vp->vop2;
2995 const struct vop2_data *vop2_data = vop2->data;
2996 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
2997 const struct vop_intr *intr = vp_data->intr;
2998 uint32_t irqs = POST_BUF_EMPTY_INTR;
2999
3000 VOP_INTR_SET_TYPE(vop2, intr, clear, irqs, 1);
3001 VOP_INTR_SET_TYPE(vop2, intr, enable, irqs, 1);
3002 }
3003
3004 /*
3005 * (1) each frame starts at the start of the Vsync pulse which is signaled by
3006 * the "FRAME_SYNC" interrupt.
3007 * (2) the active data region of each frame ends at dsp_vact_end
3008 * (3) we should program this same number (dsp_vact_end) into dsp_line_frag_num,
3009 * to get "LINE_FLAG" interrupt at the end of the active on screen data.
3010 *
3011 * VOP_INTR_CTRL0.dsp_line_frag_num = VOP_DSP_VACT_ST_END.dsp_vact_end
3012 * Interrupts
3013 * LINE_FLAG -------------------------------+
3014 * FRAME_SYNC ----+ |
3015 * | |
3016 * v v
3017 * | Vsync | Vbp | Vactive | Vfp |
3018 * ^ ^ ^ ^
3019 * | | | |
3020 * | | | |
3021 * dsp_vs_end ------------+ | | | VOP_DSP_VTOTAL_VS_END
3022 * dsp_vact_start --------------+ | | VOP_DSP_VACT_ST_END
3023 * dsp_vact_end ----------------------------+ | VOP_DSP_VACT_ST_END
3024 * dsp_total -------------------------------------+ VOP_DSP_VTOTAL_VS_END
3025 */
3026
vop2_core_clks_enable(struct vop2 * vop2)3027 static int vop2_core_clks_enable(struct vop2 *vop2)
3028 {
3029 int ret;
3030
3031 ret = clk_enable(vop2->hclk);
3032 if (ret < 0)
3033 return ret;
3034
3035 ret = clk_enable(vop2->aclk);
3036 if (ret < 0)
3037 goto err_disable_hclk;
3038
3039 ret = clk_enable(vop2->pclk);
3040 if (ret < 0)
3041 goto err_disable_aclk;
3042
3043 return 0;
3044
3045 err_disable_aclk:
3046 clk_disable(vop2->aclk);
3047 err_disable_hclk:
3048 clk_disable(vop2->hclk);
3049 return ret;
3050 }
3051
vop2_core_clks_disable(struct vop2 * vop2)3052 static void vop2_core_clks_disable(struct vop2 *vop2)
3053 {
3054 clk_disable(vop2->pclk);
3055 clk_disable(vop2->aclk);
3056 clk_disable(vop2->hclk);
3057 }
3058
vop2_wb_connector_reset(struct drm_connector * connector)3059 static void vop2_wb_connector_reset(struct drm_connector *connector)
3060 {
3061 struct vop2_wb_connector_state *wb_state;
3062
3063 if (connector->state) {
3064 __drm_atomic_helper_connector_destroy_state(connector->state);
3065 kfree(connector->state);
3066 connector->state = NULL;
3067 }
3068
3069 wb_state = kzalloc(sizeof(*wb_state), GFP_KERNEL);
3070 if (wb_state)
3071 __drm_atomic_helper_connector_reset(connector, &wb_state->base);
3072 }
3073
3074 static enum drm_connector_status
vop2_wb_connector_detect(struct drm_connector * connector,bool force)3075 vop2_wb_connector_detect(struct drm_connector *connector, bool force)
3076 {
3077 return connector_status_connected;
3078 }
3079
vop2_wb_connector_destroy(struct drm_connector * connector)3080 static void vop2_wb_connector_destroy(struct drm_connector *connector)
3081 {
3082 drm_connector_cleanup(connector);
3083 }
3084
3085 static struct drm_connector_state *
vop2_wb_connector_duplicate_state(struct drm_connector * connector)3086 vop2_wb_connector_duplicate_state(struct drm_connector *connector)
3087 {
3088 struct vop2_wb_connector_state *wb_state;
3089
3090 if (WARN_ON(!connector->state))
3091 return NULL;
3092
3093 wb_state = kzalloc(sizeof(*wb_state), GFP_KERNEL);
3094 if (!wb_state)
3095 return NULL;
3096
3097 __drm_atomic_helper_connector_duplicate_state(connector, &wb_state->base);
3098
3099 return &wb_state->base;
3100 }
3101
3102 static const struct drm_connector_funcs vop2_wb_connector_funcs = {
3103 .reset = vop2_wb_connector_reset,
3104 .detect = vop2_wb_connector_detect,
3105 .fill_modes = drm_helper_probe_single_connector_modes,
3106 .destroy = vop2_wb_connector_destroy,
3107 .atomic_duplicate_state = vop2_wb_connector_duplicate_state,
3108 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
3109 };
3110
vop2_wb_connector_get_modes(struct drm_connector * connector)3111 static int vop2_wb_connector_get_modes(struct drm_connector *connector)
3112 {
3113 struct drm_display_mode *mode;
3114 int i;
3115
3116 for (i = 0; i < 2; i++) {
3117 mode = drm_mode_create(connector->dev);
3118 if (!mode)
3119 break;
3120
3121 mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
3122 mode->clock = 148500 >> i;
3123 mode->hdisplay = 1920 >> i;
3124 mode->hsync_start = 1930 >> i;
3125 mode->hsync_end = 1940 >> i;
3126 mode->htotal = 1990 >> i;
3127 mode->vdisplay = 1080 >> i;
3128 mode->vsync_start = 1090 >> i;
3129 mode->vsync_end = 1100 >> i;
3130 mode->vtotal = 1110 >> i;
3131 mode->flags = 0;
3132
3133 drm_mode_set_name(mode);
3134 drm_mode_probed_add(connector, mode);
3135 }
3136 return i;
3137 }
3138
3139 static enum drm_mode_status
vop2_wb_connector_mode_valid(struct drm_connector * connector,struct drm_display_mode * mode)3140 vop2_wb_connector_mode_valid(struct drm_connector *connector,
3141 struct drm_display_mode *mode)
3142 {
3143
3144 struct drm_writeback_connector *wb_conn;
3145 struct vop2_wb *wb;
3146 struct vop2 *vop2;
3147 int w, h;
3148
3149 wb_conn = container_of(connector, struct drm_writeback_connector, base);
3150 wb = container_of(wb_conn, struct vop2_wb, conn);
3151 vop2 = container_of(wb, struct vop2, wb);
3152 w = mode->hdisplay;
3153 h = mode->vdisplay;
3154
3155
3156 if (w > vop2->data->wb->max_output.width)
3157 return MODE_BAD_HVALUE;
3158
3159 if (h > vop2->data->wb->max_output.height)
3160 return MODE_BAD_VVALUE;
3161
3162 return MODE_OK;
3163 }
3164
3165 static inline bool
vop2_wb_connector_changed_only(struct drm_crtc_state * cstate,struct drm_connector * conn)3166 vop2_wb_connector_changed_only(struct drm_crtc_state *cstate, struct drm_connector *conn)
3167 {
3168 struct drm_crtc_state *old_state;
3169 u32 changed_connectors;
3170
3171 old_state = drm_atomic_get_old_crtc_state(cstate->state, cstate->crtc);
3172 changed_connectors = cstate->connector_mask ^ old_state->connector_mask;
3173
3174 return BIT(drm_connector_index(conn)) == changed_connectors;
3175 }
3176
vop2_wb_encoder_atomic_check(struct drm_encoder * encoder,struct drm_crtc_state * cstate,struct drm_connector_state * conn_state)3177 static int vop2_wb_encoder_atomic_check(struct drm_encoder *encoder,
3178 struct drm_crtc_state *cstate,
3179 struct drm_connector_state *conn_state)
3180 {
3181 struct vop2_wb_connector_state *wb_state = to_wb_state(conn_state);
3182 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(cstate);
3183 struct vop2_video_port *vp = to_vop2_video_port(cstate->crtc);
3184 struct drm_framebuffer *fb;
3185 struct drm_gem_object *obj, *uv_obj;
3186 struct rockchip_gem_object *rk_obj, *rk_uv_obj;
3187
3188 /*
3189 * No need for a full modested when the only connector changed is the
3190 * writeback connector.
3191 */
3192 if (cstate->connectors_changed &&
3193 vop2_wb_connector_changed_only(cstate, conn_state->connector)) {
3194 cstate->connectors_changed = false;
3195 DRM_DEBUG("VP%d force change connectors_changed to false when only wb changed\n", vp->id);
3196 }
3197 if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
3198 return 0;
3199
3200 fb = conn_state->writeback_job->fb;
3201 DRM_DEV_DEBUG(vp->vop2->dev, "%d x % d\n", fb->width, fb->height);
3202
3203 if (!fb->format->is_yuv && is_yuv_output(vcstate->bus_format)) {
3204 DRM_ERROR("YUV2RGB is not supported by writeback\n");
3205 return -EINVAL;
3206 }
3207
3208 if ((fb->width > cstate->mode.hdisplay) ||
3209 ((fb->height < cstate->mode.vdisplay) &&
3210 (fb->height != (cstate->mode.vdisplay >> 1)))) {
3211 DRM_DEBUG_KMS("Invalid framebuffer size %ux%u, Only support x scale down and 1/2 y scale down\n",
3212 fb->width, fb->height);
3213 return -EINVAL;
3214 }
3215
3216 wb_state->scale_x_factor = vop2_scale_factor(SCALE_DOWN, VOP2_SCALE_DOWN_BIL,
3217 cstate->mode.hdisplay, fb->width);
3218 wb_state->scale_x_en = (fb->width < cstate->mode.hdisplay) ? 1 : 0;
3219 wb_state->scale_y_en = (fb->height < cstate->mode.vdisplay) ? 1 : 0;
3220
3221 wb_state->format = vop2_convert_wb_format(fb->format->format);
3222 if (wb_state->format < 0) {
3223 struct drm_format_name_buf format_name;
3224
3225 DRM_DEBUG_KMS("Invalid pixel format %s\n",
3226 drm_get_format_name(fb->format->format,
3227 &format_name));
3228 return -EINVAL;
3229 }
3230
3231 wb_state->vp_id = vp->id;
3232 obj = fb->obj[0];
3233 rk_obj = to_rockchip_obj(obj);
3234 wb_state->yrgb_addr = rk_obj->dma_addr + fb->offsets[0];
3235
3236 if (fb->format->is_yuv) {
3237 uv_obj = fb->obj[1];
3238 rk_uv_obj = to_rockchip_obj(uv_obj);
3239
3240 wb_state->uv_addr = rk_uv_obj->dma_addr + fb->offsets[1];
3241 }
3242
3243 return 0;
3244 }
3245
3246 static const struct drm_encoder_helper_funcs vop2_wb_encoder_helper_funcs = {
3247 .atomic_check = vop2_wb_encoder_atomic_check,
3248 };
3249
3250 static const struct drm_connector_helper_funcs vop2_wb_connector_helper_funcs = {
3251 .get_modes = vop2_wb_connector_get_modes,
3252 .mode_valid = vop2_wb_connector_mode_valid,
3253 };
3254
3255
vop2_wb_connector_init(struct vop2 * vop2,int nr_crtcs)3256 static int vop2_wb_connector_init(struct vop2 *vop2, int nr_crtcs)
3257 {
3258 const struct vop2_data *vop2_data = vop2->data;
3259 int ret;
3260
3261 vop2->wb.regs = vop2_data->wb->regs;
3262 vop2->wb.conn.encoder.possible_crtcs = (1 << nr_crtcs) - 1;
3263 spin_lock_init(&vop2->wb.job_lock);
3264 drm_connector_helper_add(&vop2->wb.conn.base, &vop2_wb_connector_helper_funcs);
3265
3266 ret = drm_writeback_connector_init(vop2->drm_dev, &vop2->wb.conn,
3267 &vop2_wb_connector_funcs,
3268 &vop2_wb_encoder_helper_funcs,
3269 vop2_data->wb->formats,
3270 vop2_data->wb->nformats);
3271 if (ret)
3272 DRM_DEV_ERROR(vop2->dev, "writeback connector init failed\n");
3273 return ret;
3274 }
3275
vop2_wb_connector_destory(struct vop2 * vop2)3276 static void vop2_wb_connector_destory(struct vop2 *vop2)
3277 {
3278 drm_encoder_cleanup(&vop2->wb.conn.encoder);
3279 drm_connector_cleanup(&vop2->wb.conn.base);
3280 }
3281
vop2_wb_irqs_enable(struct vop2 * vop2)3282 static void vop2_wb_irqs_enable(struct vop2 *vop2)
3283 {
3284 const struct vop2_data *vop2_data = vop2->data;
3285 const struct vop_intr *intr = &vop2_data->axi_intr[0];
3286 uint32_t irqs = WB_UV_FIFO_FULL_INTR | WB_YRGB_FIFO_FULL_INTR;
3287
3288 VOP_INTR_SET_TYPE(vop2, intr, clear, irqs, 1);
3289 VOP_INTR_SET_TYPE(vop2, intr, enable, irqs, 1);
3290 }
3291
vop2_read_and_clear_wb_irqs(struct vop2 * vop2)3292 static uint32_t vop2_read_and_clear_wb_irqs(struct vop2 *vop2)
3293 {
3294 const struct vop2_data *vop2_data = vop2->data;
3295 const struct vop_intr *intr = &vop2_data->axi_intr[0];
3296 uint32_t irqs = WB_UV_FIFO_FULL_INTR | WB_YRGB_FIFO_FULL_INTR;
3297 uint32_t val;
3298
3299 val = VOP_INTR_GET_TYPE(vop2, intr, status, irqs);
3300 if (val)
3301 VOP_INTR_SET_TYPE(vop2, intr, clear, val, 1);
3302
3303
3304 return val;
3305 }
3306
vop2_wb_commit(struct drm_crtc * crtc)3307 static void vop2_wb_commit(struct drm_crtc *crtc)
3308 {
3309 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
3310 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3311 struct vop2 *vop2 = vp->vop2;
3312 struct vop2_wb *wb = &vop2->wb;
3313 struct drm_writeback_connector *wb_conn = &wb->conn;
3314 struct drm_connector_state *conn_state = wb_conn->base.state;
3315 struct vop2_wb_connector_state *wb_state;
3316 unsigned long flags;
3317 uint32_t fifo_throd;
3318 uint8_t r2y;
3319
3320 if (!conn_state)
3321 return;
3322 wb_state = to_wb_state(conn_state);
3323
3324 if (wb_state->vp_id != vp->id)
3325 return;
3326
3327 if (conn_state->writeback_job && conn_state->writeback_job->fb) {
3328 struct drm_framebuffer *fb = conn_state->writeback_job->fb;
3329
3330 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_WB,
3331 "Enable wb %ux%u fmt: %u pitches: %d addr: %pad\n",
3332 fb->width, fb->height, wb_state->format,
3333 fb->pitches[0], &wb_state->yrgb_addr);
3334
3335 drm_writeback_queue_job(wb_conn, conn_state);
3336 conn_state->writeback_job = NULL;
3337
3338 spin_lock_irqsave(&wb->job_lock, flags);
3339 wb->jobs[wb->job_index].pending = true;
3340 wb->job_index++;
3341 if (wb->job_index >= VOP2_WB_JOB_MAX)
3342 wb->job_index = 0;
3343 spin_unlock_irqrestore(&wb->job_lock, flags);
3344
3345 fifo_throd = fb->pitches[0] >> 4;
3346 if (fifo_throd >= vop2->data->wb->fifo_depth)
3347 fifo_throd = vop2->data->wb->fifo_depth;
3348 r2y = !vcstate->yuv_overlay && fb->format->is_yuv;
3349
3350 /*
3351 * the vp_id register config done immediately
3352 */
3353 VOP_MODULE_SET(vop2, wb, vp_id, wb_state->vp_id);
3354 VOP_MODULE_SET(vop2, wb, format, wb_state->format);
3355 VOP_MODULE_SET(vop2, wb, yrgb_mst, wb_state->yrgb_addr);
3356 VOP_MODULE_SET(vop2, wb, uv_mst, wb_state->uv_addr);
3357 VOP_MODULE_SET(vop2, wb, fifo_throd, fifo_throd);
3358 VOP_MODULE_SET(vop2, wb, scale_x_factor, wb_state->scale_x_factor);
3359 VOP_MODULE_SET(vop2, wb, scale_x_en, wb_state->scale_x_en);
3360 VOP_MODULE_SET(vop2, wb, scale_y_en, wb_state->scale_y_en);
3361 VOP_MODULE_SET(vop2, wb, r2y_en, r2y);
3362 VOP_MODULE_SET(vop2, wb, enable, 1);
3363 vop2_wb_irqs_enable(vop2);
3364 VOP_CTRL_SET(vop2, wb_dma_finish_and_en, 1);
3365 }
3366 }
3367
rk3568_crtc_load_lut(struct drm_crtc * crtc)3368 static void rk3568_crtc_load_lut(struct drm_crtc *crtc)
3369 {
3370 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3371 struct vop2 *vop2 = vp->vop2;
3372 int dle = 0, i = 0;
3373 u8 vp_enable_gamma_nr = 0;
3374
3375 for (i = 0; i < vop2->data->nr_vps; i++) {
3376 struct vop2_video_port *_vp = &vop2->vps[i];
3377
3378 if (VOP_MODULE_GET(vop2, _vp, dsp_lut_en))
3379 vp_enable_gamma_nr++;
3380 }
3381
3382 if (vop2->data->nr_gammas &&
3383 vp_enable_gamma_nr >= vop2->data->nr_gammas &&
3384 VOP_MODULE_GET(vop2, vp, dsp_lut_en) == 0) {
3385 DRM_INFO("only support %d gamma\n", vop2->data->nr_gammas);
3386
3387 return;
3388 }
3389
3390 spin_lock(&vop2->reg_lock);
3391 VOP_MODULE_SET(vop2, vp, dsp_lut_en, 0);
3392 vop2_cfg_done(crtc);
3393 spin_unlock(&vop2->reg_lock);
3394
3395 #define CTRL_GET(name) VOP_MODULE_GET(vop2, vp, name)
3396 readx_poll_timeout(CTRL_GET, dsp_lut_en, dle, !dle, 5, 33333);
3397
3398 VOP_CTRL_SET(vop2, gamma_port_sel, vp->id);
3399 for (i = 0; i < vp->gamma_lut_len; i++)
3400 vop2_write_lut(vop2, i << 2, vp->lut[i]);
3401
3402 spin_lock(&vop2->reg_lock);
3403
3404 VOP_MODULE_SET(vop2, vp, dsp_lut_en, 1);
3405 vop2_write_reg_uncached(vop2, &vp->regs->gamma_update_en, 1);
3406 vp->gamma_lut_active = true;
3407
3408 spin_unlock(&vop2->reg_lock);
3409 #undef CTRL_GET
3410 }
3411
rk3588_crtc_load_lut(struct drm_crtc * crtc,u32 * lut)3412 static void rk3588_crtc_load_lut(struct drm_crtc *crtc, u32 *lut)
3413 {
3414 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3415 struct vop2 *vop2 = vp->vop2;
3416 int i = 0;
3417
3418 spin_lock(&vop2->reg_lock);
3419
3420 VOP_CTRL_SET(vop2, gamma_port_sel, vp->id);
3421 for (i = 0; i < vp->gamma_lut_len; i++)
3422 vop2_write_lut(vop2, i << 2, lut[i]);
3423
3424 VOP_MODULE_SET(vop2, vp, dsp_lut_en, 1);
3425 vop2_write_reg_uncached(vop2, &vp->regs->gamma_update_en, 1);
3426 vp->gamma_lut_active = true;
3427
3428 spin_unlock(&vop2->reg_lock);
3429 }
3430
vop2_crtc_load_lut(struct drm_crtc * crtc)3431 static void vop2_crtc_load_lut(struct drm_crtc *crtc)
3432 {
3433 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3434 struct vop2 *vop2 = vp->vop2;
3435
3436 if (!vop2->is_enabled || !vp->lut || !vop2->lut_regs)
3437 return;
3438
3439 if (WARN_ON(!drm_modeset_is_locked(&crtc->mutex)))
3440 return;
3441
3442 if (vop2->version == VOP_VERSION_RK3568) {
3443 rk3568_crtc_load_lut(crtc);
3444 } else {
3445 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
3446 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
3447 struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
3448
3449 rk3588_crtc_load_lut(&vp->rockchip_crtc.crtc, vp->lut);
3450 if (vcstate->splice_mode)
3451 rk3588_crtc_load_lut(&splice_vp->rockchip_crtc.crtc, vp->lut);
3452 }
3453 }
3454
rockchip_vop2_crtc_fb_gamma_set(struct drm_crtc * crtc,u16 red,u16 green,u16 blue,int regno)3455 static void rockchip_vop2_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red,
3456 u16 green, u16 blue, int regno)
3457 {
3458 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3459 u32 lut_len = vp->gamma_lut_len;
3460 u32 r, g, b;
3461
3462 if (regno >= lut_len || !vp->lut)
3463 return;
3464
3465 r = red * (lut_len - 1) / 0xffff;
3466 g = green * (lut_len - 1) / 0xffff;
3467 b = blue * (lut_len - 1) / 0xffff;
3468 vp->lut[regno] = b * lut_len * lut_len + g * lut_len + r;
3469 }
3470
rockchip_vop2_crtc_fb_gamma_get(struct drm_crtc * crtc,u16 * red,u16 * green,u16 * blue,int regno)3471 static void rockchip_vop2_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red,
3472 u16 *green, u16 *blue, int regno)
3473 {
3474 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3475 u32 lut_len = vp->gamma_lut_len;
3476 u32 r, g, b;
3477
3478 if (regno >= lut_len || !vp->lut)
3479 return;
3480
3481 b = (vp->lut[regno] / lut_len / lut_len) & (lut_len - 1);
3482 g = (vp->lut[regno] / lut_len) & (lut_len - 1);
3483 r = vp->lut[regno] & (lut_len - 1);
3484 *red = r * 0xffff / (lut_len - 1);
3485 *green = g * 0xffff / (lut_len - 1);
3486 *blue = b * 0xffff / (lut_len - 1);
3487 }
3488
vop2_crtc_legacy_gamma_set(struct drm_crtc * crtc,u16 * red,u16 * green,u16 * blue,uint32_t size,struct drm_modeset_acquire_ctx * ctx)3489 static int vop2_crtc_legacy_gamma_set(struct drm_crtc *crtc, u16 *red,
3490 u16 *green, u16 *blue, uint32_t size,
3491 struct drm_modeset_acquire_ctx *ctx)
3492 {
3493 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3494 struct vop2 *vop2 = vp->vop2;
3495 int i;
3496
3497 if (!vp->lut)
3498 return -EINVAL;
3499
3500 if (size > vp->gamma_lut_len) {
3501 DRM_ERROR("gamma size[%d] out of video port%d gamma lut len[%d]\n",
3502 size, vp->id, vp->gamma_lut_len);
3503 return -ENOMEM;
3504 }
3505 for (i = 0; i < size; i++)
3506 rockchip_vop2_crtc_fb_gamma_set(crtc, red[i], green[i],
3507 blue[i], i);
3508 vop2_crtc_load_lut(crtc);
3509 vop2_cfg_done(crtc);
3510 /*
3511 * maybe appear the following case:
3512 * -> set gamma
3513 * -> config done
3514 * -> atomic commit
3515 * --> update win format
3516 * --> update win address
3517 * ---> here maybe meet vop hardware frame start, and triggle some config take affect.
3518 * ---> as only some config take affect, this maybe lead to iommu pagefault.
3519 * --> update win size
3520 * --> update win other parameters
3521 * -> config done
3522 *
3523 * so we add vop2_wait_for_fs_by_done_bit_status() to make sure the first config done take
3524 * effect and then to do next frame config.
3525 */
3526 if (VOP_MODULE_GET(vop2, vp, standby) == 0)
3527 vop2_wait_for_fs_by_done_bit_status(vp);
3528
3529 return 0;
3530 }
3531
vop2_crtc_atomic_gamma_set(struct drm_crtc * crtc,struct drm_crtc_state * old_state)3532 static int vop2_crtc_atomic_gamma_set(struct drm_crtc *crtc,
3533 struct drm_crtc_state *old_state)
3534 {
3535 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3536 struct drm_color_lut *lut = vp->gamma_lut;
3537 unsigned int i;
3538
3539 for (i = 0; i < vp->gamma_lut_len; i++)
3540 rockchip_vop2_crtc_fb_gamma_set(crtc, lut[i].red, lut[i].green,
3541 lut[i].blue, i);
3542 vop2_crtc_load_lut(crtc);
3543
3544 return 0;
3545 }
3546
vop2_crtc_atomic_cubic_lut_set(struct drm_crtc * crtc,struct drm_crtc_state * old_state)3547 static int vop2_crtc_atomic_cubic_lut_set(struct drm_crtc *crtc,
3548 struct drm_crtc_state *old_state)
3549 {
3550 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
3551 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3552 struct rockchip_drm_private *private = crtc->dev->dev_private;
3553 struct drm_color_lut *lut = vp->cubic_lut;
3554 struct vop2 *vop2 = vp->vop2;
3555 u32 *cubic_lut_kvaddr;
3556 dma_addr_t cubic_lut_mst;
3557 unsigned int i;
3558
3559 if (!vp->cubic_lut_len) {
3560 DRM_ERROR("Video Port%d unsupported 3D lut\n", vp->id);
3561 return -ENODEV;
3562 }
3563
3564 if (!private->cubic_lut[vp->id].enable) {
3565 if (!vp->cubic_lut_gem_obj) {
3566 size_t size = (vp->cubic_lut_len + 1) / 2 * 16;
3567
3568 vp->cubic_lut_gem_obj = rockchip_gem_create_object(crtc->dev, size, true, 0);
3569 if (IS_ERR(vp->cubic_lut_gem_obj))
3570 return -ENOMEM;
3571 }
3572
3573 cubic_lut_kvaddr = (u32 *)vp->cubic_lut_gem_obj->kvaddr;
3574 cubic_lut_mst = vp->cubic_lut_gem_obj->dma_addr;
3575 } else {
3576 cubic_lut_kvaddr = private->cubic_lut[vp->id].offset + private->cubic_lut_kvaddr;
3577 cubic_lut_mst = private->cubic_lut[vp->id].offset + private->cubic_lut_dma_addr;
3578 }
3579
3580 for (i = 0; i < vp->cubic_lut_len / 2; i++) {
3581 *cubic_lut_kvaddr++ = (lut[2 * i].red & 0xfff) +
3582 ((lut[2 * i].green & 0xfff) << 12) +
3583 ((lut[2 * i].blue & 0xff) << 24);
3584 *cubic_lut_kvaddr++ = ((lut[2 * i].blue & 0xf00) >> 8) +
3585 ((lut[2 * i + 1].red & 0xfff) << 4) +
3586 ((lut[2 * i + 1].green & 0xfff) << 16) +
3587 ((lut[2 * i + 1].blue & 0xf) << 28);
3588 *cubic_lut_kvaddr++ = (lut[2 * i + 1].blue & 0xff0) >> 4;
3589 *cubic_lut_kvaddr++ = 0;
3590 }
3591
3592 if (vp->cubic_lut_len % 2) {
3593 *cubic_lut_kvaddr++ = (lut[2 * i].red & 0xfff) +
3594 ((lut[2 * i].green & 0xfff) << 12) +
3595 ((lut[2 * i].blue & 0xff) << 24);
3596 *cubic_lut_kvaddr++ = (lut[2 * i].blue & 0xf00) >> 8;
3597 *cubic_lut_kvaddr++ = 0;
3598 *cubic_lut_kvaddr = 0;
3599 }
3600
3601 VOP_MODULE_SET(vop2, vp, lut_dma_rid, vp->lut_dma_rid);
3602 VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst);
3603 VOP_MODULE_SET(vop2, vp, cubic_lut_update_en, 1);
3604 VOP_MODULE_SET(vop2, vp, cubic_lut_en, 1);
3605 VOP_CTRL_SET(vop2, lut_dma_en, 1);
3606
3607 if (vcstate->splice_mode) {
3608 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
3609 struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
3610
3611 VOP_MODULE_SET(vop2, splice_vp, cubic_lut_mst, cubic_lut_mst);
3612 VOP_MODULE_SET(vop2, splice_vp, cubic_lut_update_en, 1);
3613 VOP_MODULE_SET(vop2, splice_vp, cubic_lut_en, 1);
3614 }
3615
3616 return 0;
3617 }
3618
vop2_attach_cubic_lut_prop(struct drm_crtc * crtc,unsigned int cubic_lut_size)3619 static void vop2_attach_cubic_lut_prop(struct drm_crtc *crtc, unsigned int cubic_lut_size)
3620 {
3621 struct rockchip_drm_private *private = crtc->dev->dev_private;
3622
3623 drm_object_attach_property(&crtc->base, private->cubic_lut_prop, 0);
3624 drm_object_attach_property(&crtc->base, private->cubic_lut_size_prop, cubic_lut_size);
3625 }
3626
vop2_cubic_lut_init(struct vop2 * vop2)3627 static void vop2_cubic_lut_init(struct vop2 *vop2)
3628 {
3629 const struct vop2_data *vop2_data = vop2->data;
3630 const struct vop2_video_port_data *vp_data;
3631 struct vop2_video_port *vp;
3632 struct drm_crtc *crtc;
3633 int i;
3634
3635 for (i = 0; i < vop2_data->nr_vps; i++) {
3636 vp = &vop2->vps[i];
3637 crtc = &vp->rockchip_crtc.crtc;
3638 if (!crtc->dev)
3639 continue;
3640 vp_data = &vop2_data->vp[vp->id];
3641 vp->cubic_lut_len = vp_data->cubic_lut_len;
3642
3643 if (vp->cubic_lut_len)
3644 vop2_attach_cubic_lut_prop(crtc, vp->cubic_lut_len);
3645 }
3646 }
3647
vop2_core_clks_prepare_enable(struct vop2 * vop2)3648 static int vop2_core_clks_prepare_enable(struct vop2 *vop2)
3649 {
3650 int ret;
3651
3652 ret = clk_prepare_enable(vop2->hclk);
3653 if (ret < 0) {
3654 dev_err(vop2->dev, "failed to enable hclk - %d\n", ret);
3655 return ret;
3656 }
3657
3658 ret = clk_prepare_enable(vop2->aclk);
3659 if (ret < 0) {
3660 dev_err(vop2->dev, "failed to enable aclk - %d\n", ret);
3661 goto err;
3662 }
3663
3664 ret = clk_prepare_enable(vop2->pclk);
3665 if (ret < 0) {
3666 dev_err(vop2->dev, "failed to enable pclk - %d\n", ret);
3667 goto err1;
3668 }
3669
3670 return 0;
3671 err1:
3672 clk_disable_unprepare(vop2->aclk);
3673 err:
3674 clk_disable_unprepare(vop2->hclk);
3675
3676 return ret;
3677 }
3678
3679 /*
3680 * VOP2 architecture
3681 *
3682 +----------+ +-------------+
3683 | Cluster | | Sel 1 from 6
3684 | window0 | | Layer0 | +---------------+ +-------------+ +-----------+
3685 +----------+ +-------------+ |N from 6 layers| | | | 1 from 3 |
3686 +----------+ +-------------+ | Overlay0 | | Video Port0 | | RGB |
3687 | Cluster | | Sel 1 from 6| | | | | +-----------+
3688 | window1 | | Layer1 | +---------------+ +-------------+
3689 +----------+ +-------------+ +-----------+
3690 +----------+ +-------------+ +--> | 1 from 3 |
3691 | Esmart | | Sel 1 from 6| +---------------+ +-------------+ | LVDS |
3692 | window0 | | Layer2 | |N from 6 Layers | | +-----------+
3693 +----------+ +-------------+ | Overlay1 + | Video Port1 | +--->
3694 +----------+ +-------------+ --------> | | | | +-----------+
3695 | Esmart | | Sel 1 from 6| --------> +---------------+ +-------------+ | 1 from 3 |
3696 | Window1 | | Layer3 | +--> | MIPI |
3697 +----------+ +-------------+ +-----------+
3698 +----------+ +-------------+ +---------------+ +-------------+
3699 | Smart | | Sel 1 from 6| |N from 6 Layers| | | +-----------+
3700 | Window0 | | Layer4 | | Overlay2 | | Video Port2 | | 1 from 3 |
3701 +----------+ +-------------+ | | | | | HDMI |
3702 +----------+ +-------------+ +---------------+ +-------------+ +-----------+
3703 | Smart | | Sel 1 from 6| +-----------+
3704 | Window1 | | Layer5 | | 1 from 3 |
3705 +----------+ +-------------+ | eDP |
3706 * +-----------+
3707 */
vop3_layer_map_initial(struct vop2 * vop2,uint32_t current_vp_id)3708 static void vop3_layer_map_initial(struct vop2 *vop2, uint32_t current_vp_id)
3709 {
3710 uint16_t vp_id;
3711 struct drm_plane *plane = NULL;
3712
3713 drm_for_each_plane(plane, vop2->drm_dev) {
3714 struct vop2_win *win = to_vop2_win(plane);
3715
3716 vp_id = VOP_CTRL_GET(vop2, win_vp_id[win->phys_id]);
3717 win->vp_mask = BIT(vp_id);
3718 win->old_vp_mask = win->vp_mask;
3719 vop2->vps[vp_id].win_mask |= BIT(win->phys_id);
3720 }
3721 }
3722
vop2_layer_map_initial(struct vop2 * vop2,uint32_t current_vp_id)3723 static void vop2_layer_map_initial(struct vop2 *vop2, uint32_t current_vp_id)
3724 {
3725 struct vop2_layer *layer;
3726 struct vop2_video_port *vp;
3727 struct vop2_win *win;
3728 unsigned long win_mask;
3729 uint32_t used_layers = 0;
3730 uint16_t port_mux_cfg = 0;
3731 uint16_t port_mux;
3732 uint16_t vp_id;
3733 uint8_t nr_layers;
3734 int phys_id;
3735 int i, j;
3736
3737 if (is_vop3(vop2)) {
3738 vop3_layer_map_initial(vop2, current_vp_id);
3739 return;
3740 }
3741
3742 for (i = 0; i < vop2->data->nr_vps; i++) {
3743 vp_id = i;
3744 j = 0;
3745 vp = &vop2->vps[vp_id];
3746 vp->win_mask = vp->plane_mask;
3747 nr_layers = hweight32(vp->win_mask);
3748 win_mask = vp->win_mask;
3749 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
3750 layer = &vop2->layers[used_layers + j];
3751 win = vop2_find_win_by_phys_id(vop2, phys_id);
3752 VOP_CTRL_SET(vop2, win_vp_id[phys_id], vp_id);
3753 VOP_MODULE_SET(vop2, layer, layer_sel, win->layer_sel_id[vp_id]);
3754 win->vp_mask = BIT(i);
3755 win->old_vp_mask = win->vp_mask;
3756 layer->win_phys_id = win->phys_id;
3757 win->layer_id = layer->id;
3758 j++;
3759 DRM_DEV_DEBUG(vop2->dev, "layer%d select %s for vp%d phys_id: %d\n",
3760 layer->id, win->name, vp_id, phys_id);
3761 }
3762 used_layers += nr_layers;
3763 }
3764
3765 /*
3766 * The last Video Port(VP2 for RK3568, VP3 for RK3588) is fixed
3767 * at the last level of the all the mixers by hardware design,
3768 * so we just need to handle (nr_vps - 1) vps here.
3769 */
3770 used_layers = 0;
3771 for (i = 0; i < vop2->data->nr_vps - 1; i++) {
3772 vp = &vop2->vps[i];
3773 used_layers += hweight32(vp->win_mask);
3774 if (used_layers == 0)
3775 port_mux = 8;
3776 else
3777 port_mux = used_layers - 1;
3778 port_mux_cfg |= port_mux << (vp->id * 4);
3779 }
3780
3781 /* the last VP is fixed */
3782 if (vop2->data->nr_vps >= 1)
3783 port_mux_cfg |= 7 << (4 * (vop2->data->nr_vps - 1));
3784 vop2->port_mux_cfg = port_mux_cfg;
3785 VOP_CTRL_SET(vop2, ovl_port_mux_cfg, port_mux_cfg);
3786
3787 }
3788
rk3588_vop2_regsbak(struct vop2 * vop2)3789 static void rk3588_vop2_regsbak(struct vop2 *vop2)
3790 {
3791 uint32_t *base = vop2->regs;
3792 int i;
3793
3794 /*
3795 * No need to backup DSC/GAMMA_LUT/BPP_LUT/MMU
3796 */
3797 for (i = 0; i < (0x2000 >> 2); i++)
3798 vop2->regsbak[i] = base[i];
3799 }
3800
vop2_initial(struct drm_crtc * crtc)3801 static void vop2_initial(struct drm_crtc *crtc)
3802 {
3803 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3804 struct vop2 *vop2 = vp->vop2;
3805 uint32_t current_vp_id = vp->id;
3806 struct vop2_wb *wb = &vop2->wb;
3807 int ret;
3808
3809 if (vop2->enable_count == 0) {
3810 ret = pm_runtime_get_sync(vop2->dev);
3811 if (ret < 0) {
3812 DRM_DEV_ERROR(vop2->dev, "failed to get pm runtime: %d\n", ret);
3813 return;
3814 }
3815
3816 ret = vop2_core_clks_prepare_enable(vop2);
3817 if (ret) {
3818 pm_runtime_put_sync(vop2->dev);
3819 return;
3820 }
3821
3822 if (vop2_soc_is_rk3566())
3823 VOP_CTRL_SET(vop2, otp_en, 1);
3824
3825 /*
3826 * rk3588 don't support access mmio by memcpy
3827 */
3828 if (vop2->version == VOP_VERSION_RK3588)
3829 rk3588_vop2_regsbak(vop2);
3830 else
3831 memcpy(vop2->regsbak, vop2->regs, vop2->len);
3832
3833 VOP_MODULE_SET(vop2, wb, axi_yrgb_id, 0xd);
3834 VOP_MODULE_SET(vop2, wb, axi_uv_id, 0xe);
3835 vop2_wb_cfg_done(vp);
3836
3837 if (is_vop3(vop2)) {
3838 VOP_CTRL_SET(vop2, dsp_vs_t_sel, 0);
3839 VOP_CTRL_SET(vop2, esmart_lb_mode, vop2->esmart_lb_mode);
3840 }
3841
3842 /*
3843 * This is unused and error init value for rk3528/rk3562 vp1, if less of this config,
3844 * vp1 can't display normally.
3845 */
3846 if (vop2->version == VOP_VERSION_RK3528 || vop2->version == VOP_VERSION_RK3562)
3847 vop2_mask_write(vop2, 0x700, 0x3, 4, 0, 0, true);
3848
3849 VOP_CTRL_SET(vop2, cfg_done_en, 1);
3850 /*
3851 * Disable auto gating, this is a workaround to
3852 * avoid display image shift when a window enabled.
3853 */
3854 VOP_CTRL_SET(vop2, auto_gating_en, 0);
3855
3856 VOP_CTRL_SET(vop2, aclk_pre_auto_gating_en, 0);
3857
3858 /*
3859 * Register OVERLAY_LAYER_SEL and OVERLAY_PORT_SEL should take effect immediately,
3860 * than windows configuration(CLUSTER/ESMART/SMART) can take effect according the
3861 * video port mux configuration as we wished.
3862 */
3863 VOP_CTRL_SET(vop2, ovl_port_mux_cfg_done_imd, 1);
3864 /*
3865 * Let SYS_DSP_INFACE_EN/SYS_DSP_INFACE_CTRL/SYS_DSP_INFACE_POL take effect
3866 * immediately.
3867 */
3868 VOP_CTRL_SET(vop2, if_ctrl_cfg_done_imd, 1);
3869
3870 /* Close dynamic turn on/off rk3588 PD_ESMART and keep esmart pd on when enable */
3871 if (vop2->version == VOP_VERSION_RK3588) {
3872 struct vop2_power_domain *esmart_pd = vop2_find_pd_by_id(vop2, VOP2_PD_ESMART);
3873
3874 if (vop2_power_domain_status(esmart_pd))
3875 esmart_pd->on = true;
3876 else
3877 vop2_power_domain_on(esmart_pd);
3878 }
3879 vop2_layer_map_initial(vop2, current_vp_id);
3880 vop2_axi_irqs_enable(vop2);
3881 vop2->is_enabled = true;
3882 }
3883
3884 vop2_debug_irq_enable(crtc);
3885
3886 vop2->enable_count++;
3887
3888 ret = clk_prepare_enable(vp->dclk);
3889 if (ret < 0)
3890 DRM_DEV_ERROR(vop2->dev, "failed to enable dclk for video port%d - %d\n",
3891 vp->id, ret);
3892 }
3893
3894 /*
3895 * The internal PD of VOP2 on rk3588 take effect immediately
3896 * for power up and take effect by vsync for power down.
3897 *
3898 * And the PD_CLUSTER0 is a parent PD of PD_CLUSTER1/2/3,
3899 * we may have this use case:
3900 * Cluster0 is attached to VP0 for HDMI output,
3901 * Cluster1 is attached to VP1 for MIPI DSI,
3902
3903 * When we enable Cluster1 on VP1, we should enable PD_CLUSTER0 as
3904 * it is the parent PD, event though HDMI is plugout, VP1 is disabled,
3905 * the PD of Cluster0 should keep power on.
3906
3907 * When system go to suspend:
3908 * (1) Power down PD of Cluster1 before VP1 standby(the power down is take
3909 * effect by vsync)
3910 * (2) Power down PD of Cluster0
3911 *
3912 * But we have problem at step (2), Cluster0 is attached to VP0. but VP0
3913 * is in standby mode, as it is never used or hdmi plugout. So there is
3914 * no vsync, the power down will never take effect.
3915
3916 * According to IC designer: We must power down all internal PD of VOP
3917 * before we power down the global PD_VOP.
3918
3919 * So we get this workaround:
3920 * If we found a VP is in standby mode when we want power down a PD is
3921 * attached to it, we release the VP from standby mode, than it will
3922 * run a default timing and generate vsync. Than we can power down the
3923 * PD by this vsync. After all this is done, we standby the VP at last.
3924 */
vop2_power_domain_off_by_disabled_vp(struct vop2_power_domain * pd)3925 static void vop2_power_domain_off_by_disabled_vp(struct vop2_power_domain *pd)
3926 {
3927 struct vop2_video_port *vp = NULL;
3928 struct vop2 *vop2 = pd->vop2;
3929 struct vop2_win *win;
3930 struct drm_crtc *crtc;
3931 uint32_t vp_id;
3932 uint8_t phys_id;
3933 int ret;
3934
3935 if (pd->data->id == VOP2_PD_CLUSTER0 || pd->data->id == VOP2_PD_CLUSTER1 ||
3936 pd->data->id == VOP2_PD_CLUSTER2 || pd->data->id == VOP2_PD_CLUSTER3 ||
3937 pd->data->id == VOP2_PD_ESMART) {
3938 phys_id = ffs(pd->data->module_id_mask) - 1;
3939 win = vop2_find_win_by_phys_id(vop2, phys_id);
3940 vp_id = ffs(win->vp_mask) - 1;
3941 vp = &vop2->vps[vp_id];
3942 } else {
3943 DRM_DEV_ERROR(vop2->dev, "unexpected power on pd%d\n", ffs(pd->data->id) - 1);
3944 }
3945
3946 if (vp) {
3947 ret = clk_prepare_enable(vp->dclk);
3948 if (ret < 0)
3949 DRM_DEV_ERROR(vop2->dev, "failed to enable dclk for video port%d - %d\n",
3950 vp->id, ret);
3951 crtc = &vp->rockchip_crtc.crtc;
3952 VOP_MODULE_SET(vop2, vp, standby, 0);
3953 vop2_power_domain_off(pd);
3954 vop2_cfg_done(crtc);
3955 vop2_wait_power_domain_off(pd);
3956
3957 reinit_completion(&vp->dsp_hold_completion);
3958 vop2_dsp_hold_valid_irq_enable(crtc);
3959 VOP_MODULE_SET(vop2, vp, standby, 1);
3960 ret = wait_for_completion_timeout(&vp->dsp_hold_completion, msecs_to_jiffies(50));
3961 if (!ret)
3962 DRM_DEV_INFO(vop2->dev, "wait for vp%d dsp_hold timeout\n", vp->id);
3963
3964 vop2_dsp_hold_valid_irq_disable(crtc);
3965 clk_disable_unprepare(vp->dclk);
3966 }
3967 }
3968
vop2_power_off_all_pd(struct vop2 * vop2)3969 static void vop2_power_off_all_pd(struct vop2 *vop2)
3970 {
3971 struct vop2_power_domain *pd, *n;
3972
3973 list_for_each_entry_safe_reverse(pd, n, &vop2->pd_list_head, list) {
3974 if (vop2_power_domain_status(pd))
3975 vop2_power_domain_off_by_disabled_vp(pd);
3976 pd->on = false;
3977 pd->vp_mask = 0;
3978 }
3979 }
3980
vop2_disable(struct drm_crtc * crtc)3981 static void vop2_disable(struct drm_crtc *crtc)
3982 {
3983 struct vop2_video_port *vp = to_vop2_video_port(crtc);
3984 struct vop2 *vop2 = vp->vop2;
3985
3986 clk_disable_unprepare(vp->dclk);
3987
3988 if (--vop2->enable_count > 0)
3989 return;
3990
3991 if (vop2->is_iommu_enabled) {
3992 /*
3993 * vop2 standby complete, so iommu detach is safe.
3994 */
3995 VOP_CTRL_SET(vop2, dma_stop, 1);
3996 rockchip_drm_dma_detach_device(vop2->drm_dev, vop2->dev);
3997 vop2->is_iommu_enabled = false;
3998 }
3999 if (vop2->version == VOP_VERSION_RK3588)
4000 vop2_power_off_all_pd(vop2);
4001
4002 vop2->is_enabled = false;
4003 pm_runtime_put_sync(vop2->dev);
4004
4005 clk_disable_unprepare(vop2->pclk);
4006 clk_disable_unprepare(vop2->aclk);
4007 clk_disable_unprepare(vop2->hclk);
4008 }
4009
vop2_crtc_disable_dsc(struct vop2 * vop2,u8 dsc_id)4010 static void vop2_crtc_disable_dsc(struct vop2 *vop2, u8 dsc_id)
4011 {
4012 struct vop2_dsc *dsc = &vop2->dscs[dsc_id];
4013
4014 VOP_MODULE_SET(vop2, dsc, dsc_mer, 1);
4015 VOP_MODULE_SET(vop2, dsc, dsc_interface_mode, 0);
4016 VOP_MODULE_SET(vop2, dsc, dsc_en, 0);
4017 VOP_MODULE_SET(vop2, dsc, rst_deassert, 0);
4018 }
4019
vop2_clk_get(struct vop2 * vop2,const char * name)4020 static struct vop2_clk *vop2_clk_get(struct vop2 *vop2, const char *name)
4021 {
4022 struct vop2_clk *clk, *n;
4023
4024 if (!name)
4025 return NULL;
4026
4027 list_for_each_entry_safe(clk, n, &vop2->clk_list_head, list) {
4028 if (!strcmp(clk_hw_get_name(&clk->hw), name))
4029 return clk;
4030 }
4031
4032 return NULL;
4033 }
4034
vop2_clk_set_parent(struct clk * clk,struct clk * parent)4035 static void vop2_clk_set_parent(struct clk *clk, struct clk *parent)
4036 {
4037 int ret = 0;
4038
4039 if (parent)
4040 ret = clk_set_parent(clk, parent);
4041 if (ret < 0)
4042 DRM_WARN("failed to set %s as parent for %s\n",
4043 __clk_get_name(parent), __clk_get_name(clk));
4044 }
4045
vop2_extend_clk_init(struct vop2 * vop2)4046 static int vop2_extend_clk_init(struct vop2 *vop2)
4047 {
4048 const char * const extend_clk_name[] = {
4049 "hdmi0_phy_pll", "hdmi1_phy_pll"};
4050 struct drm_device *drm_dev = vop2->drm_dev;
4051 struct clk *clk;
4052 struct vop2_extend_pll *extend_pll;
4053 int i;
4054
4055 INIT_LIST_HEAD(&vop2->extend_clk_list_head);
4056
4057 if (vop2->version != VOP_VERSION_RK3588)
4058 return 0;
4059
4060 for (i = 0; i < ARRAY_SIZE(extend_clk_name); i++) {
4061 clk = devm_clk_get_optional(drm_dev->dev, extend_clk_name[i]);
4062 if (IS_ERR(clk)) {
4063 dev_warn(drm_dev->dev, "failed to get %s: %ld\n",
4064 extend_clk_name[i], PTR_ERR(clk));
4065 continue;
4066 }
4067
4068 if (!clk)
4069 continue;
4070
4071 extend_pll = devm_kzalloc(drm_dev->dev, sizeof(*extend_pll), GFP_KERNEL);
4072 if (!extend_pll)
4073 return -ENOMEM;
4074
4075 extend_pll->clk = clk;
4076 extend_pll->vp_mask = 0;
4077 strncpy(extend_pll->clk_name, extend_clk_name[i], sizeof(extend_pll->clk_name));
4078 list_add_tail(&extend_pll->list, &vop2->extend_clk_list_head);
4079 }
4080
4081 return 0;
4082 }
4083
vop2_extend_clk_find_by_name(struct vop2 * vop2,char * clk_name)4084 static struct vop2_extend_pll *vop2_extend_clk_find_by_name(struct vop2 *vop2, char *clk_name)
4085 {
4086 struct vop2_extend_pll *extend_pll;
4087
4088 list_for_each_entry(extend_pll, &vop2->extend_clk_list_head, list) {
4089 if (!strcmp(extend_pll->clk_name, clk_name))
4090 return extend_pll;
4091 }
4092
4093 return NULL;
4094 }
4095
vop2_extend_clk_switch_pll(struct vop2 * vop2,struct vop2_extend_pll * src,struct vop2_extend_pll * dst)4096 static int vop2_extend_clk_switch_pll(struct vop2 *vop2, struct vop2_extend_pll *src,
4097 struct vop2_extend_pll *dst)
4098 {
4099 struct vop2_clk *dclk;
4100 u32 vp_mask;
4101 int i = 0;
4102 char clk_name[32];
4103
4104 if (!src->vp_mask)
4105 return -EINVAL;
4106
4107 if (dst->vp_mask)
4108 return -EBUSY;
4109
4110 vp_mask = src->vp_mask;
4111
4112 while (vp_mask) {
4113 if ((BIT(i) & src->vp_mask)) {
4114 snprintf(clk_name, sizeof(clk_name), "dclk%d", i);
4115 dclk = vop2_clk_get(vop2, clk_name);
4116 clk_set_rate(dst->clk, dclk->rate);
4117 vop2_clk_set_parent(vop2->vps[i].dclk, dst->clk);
4118 src->vp_mask &= ~BIT(i);
4119 dst->vp_mask |= BIT(i);
4120 }
4121 i++;
4122 vp_mask = vp_mask >> 1;
4123 }
4124
4125 return 0;
4126 }
4127
vop2_extend_clk_get_vp_id(struct vop2_extend_pll * ext_pll)4128 static inline int vop2_extend_clk_get_vp_id(struct vop2_extend_pll *ext_pll)
4129 {
4130 return ffs(ext_pll->vp_mask) - 1;
4131 }
4132
4133 /*
4134 * Here are 2 hdmi phy pll can use for video port dclk. The strategies of how to use hdmi phy pll
4135 * as follow:
4136 *
4137 * 1. hdmi phy pll can be used for video port0/1/2 when output format under 4K@60Hz;
4138 *
4139 * 2. When a video port connect both hdmi0 and hdmi1(may also connect other output interface),
4140 * it must hold the hdmi0 and hdmi1 phy pll, and other video port can't use it. if request dclk
4141 * is under 4K@60Hz, set the video port dlk parent as hdmi0 phy pll.if hdmi0 or hdmi1 phy pll
4142 * is used by other video port, report a error.
4143 *
4144 * 3. When a video port(A) connect hdmi0(may also connect other output interface but not hdmi1),
4145 * it must hold the hdmi0 phy pll, and other video port can't use it. If both hdmi0 and hdmi1
4146 * phy pll is used by other video port, report a error. If hdmi0 phy pll is used by another
4147 * video port(B) and hdmi1 phy pll is free, set hdmi1 phy pll as video port(B) dclk parent and
4148 * video port(A) hold hdmi0 phy pll. If hdmi0 phy pll is free, video port(A) hold hdmi0 pll.If
4149 * video port(A) hold hdmi0 phy pll and request dclk is under 4k@60Hz, set hdmi0 phy pll as
4150 * video port(A) dclk parent.
4151 *
4152 * 4. When a video port(A) connect hdmi1(may also connect other output interface but not hdmi0),
4153 * it must hold the hdmi1 phy pll, and other video port can't use it. If both hdmi0 and hdmi1
4154 * phy pll is used by other video port, report a error. If hdmi1 phy pll is used by another
4155 * video port(B) and hdmi0 phy pll is free, set hdmi0 phy pll as video port(B) dclk parent and
4156 * video port(A) hold hdmi1 phy pll. If hdmi1 phy pll is free, video port(A) hold hdmi1 pll. If
4157 * video port(A) hold hdmi1 phy pll and request dclk is under 4k@60Hz, set hdmi1 phy pll as
4158 * video port(A) dclk parent.
4159 *
4160 * 5. When a video port connect dp(0, 1, or both, may also connect other output type but not hdmi0
4161 * and hdmi1). If the request dclk is higher than 4K@60Hz or video port id is 2, do nothing.
4162 * Otherwise get a free hdmi phy pll as video port dclk parent. If no free hdmi phy pll can be
4163 * get, report a error.
4164 */
4165
vop2_clk_set_parent_extend(struct vop2_video_port * vp,struct rockchip_crtc_state * vcstate,bool enable)4166 static int vop2_clk_set_parent_extend(struct vop2_video_port *vp,
4167 struct rockchip_crtc_state *vcstate, bool enable)
4168 {
4169 struct vop2 *vop2 = vp->vop2;
4170 struct vop2_extend_pll *hdmi0_phy_pll, *hdmi1_phy_pll;
4171 struct drm_crtc *crtc = &vp->rockchip_crtc.crtc;
4172 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
4173
4174 hdmi0_phy_pll = vop2_extend_clk_find_by_name(vop2, "hdmi0_phy_pll");
4175 hdmi1_phy_pll = vop2_extend_clk_find_by_name(vop2, "hdmi1_phy_pll");
4176
4177 if (hdmi0_phy_pll)
4178 clk_get_rate(hdmi0_phy_pll->clk);
4179 if (hdmi1_phy_pll)
4180 clk_get_rate(hdmi1_phy_pll->clk);
4181
4182 if ((!hdmi0_phy_pll && !hdmi1_phy_pll) ||
4183 ((vcstate->output_if & VOP_OUTPUT_IF_HDMI0) && !hdmi0_phy_pll) ||
4184 ((vcstate->output_if & VOP_OUTPUT_IF_HDMI1) && !hdmi1_phy_pll))
4185 return 0;
4186
4187 if (enable) {
4188 if ((vcstate->output_if & VOP_OUTPUT_IF_HDMI0) &&
4189 (vcstate->output_if & VOP_OUTPUT_IF_HDMI1)) {
4190 if (hdmi0_phy_pll->vp_mask) {
4191 DRM_ERROR("hdmi0 phy pll is used by vp%d\n",
4192 vop2_extend_clk_get_vp_id(hdmi0_phy_pll));
4193 return -EBUSY;
4194 }
4195
4196 if (hdmi1_phy_pll->vp_mask) {
4197 DRM_ERROR("hdmi1 phy pll is used by vp%d\n",
4198 vop2_extend_clk_get_vp_id(hdmi1_phy_pll));
4199 return -EBUSY;
4200 }
4201
4202 if (adjusted_mode->crtc_clock > VOP2_MAX_DCLK_RATE)
4203 vop2_clk_set_parent(vp->dclk, vp->dclk_parent);
4204 else
4205 vop2_clk_set_parent(vp->dclk, hdmi0_phy_pll->clk);
4206
4207 hdmi0_phy_pll->vp_mask |= BIT(vp->id);
4208 hdmi1_phy_pll->vp_mask |= BIT(vp->id);
4209 } else if ((vcstate->output_if & VOP_OUTPUT_IF_HDMI0) &&
4210 !(vcstate->output_if & VOP_OUTPUT_IF_HDMI1)) {
4211 if (hdmi0_phy_pll->vp_mask) {
4212 if (hdmi1_phy_pll) {
4213 if (hdmi1_phy_pll->vp_mask) {
4214 DRM_ERROR("hdmi0: phy pll is used by vp%d:vp%d\n",
4215 vop2_extend_clk_get_vp_id(hdmi0_phy_pll),
4216 vop2_extend_clk_get_vp_id(hdmi1_phy_pll));
4217 return -EBUSY;
4218 }
4219
4220 vop2_extend_clk_switch_pll(vop2, hdmi0_phy_pll,
4221 hdmi1_phy_pll);
4222 } else {
4223 DRM_ERROR("hdmi0: phy pll is used by vp%d\n",
4224 vop2_extend_clk_get_vp_id(hdmi0_phy_pll));
4225 return -EBUSY;
4226 }
4227 }
4228
4229 if (adjusted_mode->crtc_clock > VOP2_MAX_DCLK_RATE)
4230 vop2_clk_set_parent(vp->dclk, vp->dclk_parent);
4231 else
4232 vop2_clk_set_parent(vp->dclk, hdmi0_phy_pll->clk);
4233
4234 hdmi0_phy_pll->vp_mask |= BIT(vp->id);
4235 } else if (!(vcstate->output_if & VOP_OUTPUT_IF_HDMI0) &&
4236 (vcstate->output_if & VOP_OUTPUT_IF_HDMI1)) {
4237 if (hdmi1_phy_pll->vp_mask) {
4238 if (hdmi0_phy_pll) {
4239 if (hdmi0_phy_pll->vp_mask) {
4240 DRM_ERROR("hdmi1: phy pll is used by vp%d:vp%d\n",
4241 vop2_extend_clk_get_vp_id(hdmi0_phy_pll),
4242 vop2_extend_clk_get_vp_id(hdmi1_phy_pll));
4243 return -EBUSY;
4244 }
4245
4246 vop2_extend_clk_switch_pll(vop2, hdmi1_phy_pll,
4247 hdmi0_phy_pll);
4248 } else {
4249 DRM_ERROR("hdmi1: phy pll is used by vp%d\n",
4250 vop2_extend_clk_get_vp_id(hdmi1_phy_pll));
4251 return -EBUSY;
4252 }
4253 }
4254
4255 if (adjusted_mode->crtc_clock > VOP2_MAX_DCLK_RATE)
4256 vop2_clk_set_parent(vp->dclk, vp->dclk_parent);
4257 else
4258 vop2_clk_set_parent(vp->dclk, hdmi1_phy_pll->clk);
4259
4260 hdmi1_phy_pll->vp_mask |= BIT(vp->id);
4261 } else if (output_if_is_dp(vcstate->output_if)) {
4262 if (vp->id == 2) {
4263 vop2_clk_set_parent(vp->dclk, vp->dclk_parent);
4264 return 0;
4265 }
4266
4267 if (hdmi0_phy_pll && !hdmi0_phy_pll->vp_mask) {
4268 vop2_clk_set_parent(vp->dclk, hdmi0_phy_pll->clk);
4269 hdmi0_phy_pll->vp_mask |= BIT(vp->id);
4270 } else if (hdmi1_phy_pll && !hdmi1_phy_pll->vp_mask) {
4271 vop2_clk_set_parent(vp->dclk, hdmi1_phy_pll->clk);
4272 hdmi1_phy_pll->vp_mask |= BIT(vp->id);
4273 } else {
4274 vop2_clk_set_parent(vp->dclk, vp->dclk_parent);
4275 DRM_INFO("No free hdmi phy pll for DP, use default parent\n");
4276 }
4277 }
4278 } else {
4279 if (hdmi0_phy_pll && (BIT(vp->id) & hdmi0_phy_pll->vp_mask))
4280 hdmi0_phy_pll->vp_mask &= ~BIT(vp->id);
4281
4282 if (hdmi1_phy_pll && (BIT(vp->id) & hdmi1_phy_pll->vp_mask))
4283 hdmi1_phy_pll->vp_mask &= ~BIT(vp->id);
4284 }
4285
4286 return 0;
4287 }
4288
vop2_crtc_atomic_enter_psr(struct drm_crtc * crtc,struct drm_crtc_state * old_state)4289 static void vop2_crtc_atomic_enter_psr(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
4290 {
4291 struct vop2_video_port *vp = to_vop2_video_port(crtc);
4292 struct vop2 *vop2 = vp->vop2;
4293 struct vop2_win *win;
4294 unsigned long win_mask = vp->enabled_win_mask;
4295 int phys_id;
4296
4297 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
4298 win = vop2_find_win_by_phys_id(vop2, phys_id);
4299 VOP_WIN_SET(vop2, win, enable, 0);
4300
4301 if (win->feature & WIN_FEATURE_CLUSTER_MAIN)
4302 VOP_CLUSTER_SET(vop2, win, enable, 0);
4303 }
4304
4305 vop2_cfg_done(crtc);
4306 vop2_wait_for_fs_by_done_bit_status(vp);
4307 drm_crtc_vblank_off(crtc);
4308 if (hweight8(vop2->active_vp_mask) == 1) {
4309 u32 adjust_aclk_rate = 0;
4310 u32 htotal = (VOP_MODULE_GET(vop2, vp, htotal_pw) >> 16) & 0xffff;
4311 u32 pre_scan_dly = VOP_MODULE_GET(vop2, vp, pre_scan_htiming);
4312 u32 pre_scan_hblank = pre_scan_dly & 0x1fff;
4313 u32 pre_scan_hactive = (pre_scan_dly >> 16) & 0x1fff;
4314 u32 dclk_rate = crtc->state->adjusted_mode.crtc_clock / 1000;
4315 /**
4316 * (pre_scan_hblank + pre_scan_hactive) x aclk_margin / adjust_aclk_rate = hotal / dclk_rate
4317 * aclk_margin = 1.2, so
4318 * adjust_aclk_rate = (pre_scan_hblank + pre_scan_hactive) x 1.2 * aclk_margin / htotal
4319 */
4320
4321 adjust_aclk_rate = (pre_scan_hblank + pre_scan_hactive) * dclk_rate * 12 / 10 / htotal;
4322
4323 vop2->aclk_rate = clk_get_rate(vop2->aclk);
4324 clk_set_rate(vop2->aclk, adjust_aclk_rate * 1000000L);
4325 vop2->aclk_rate_reset = true;
4326 }
4327 }
4328
vop2_crtc_atomic_exit_psr(struct drm_crtc * crtc,struct drm_crtc_state * old_state)4329 static void vop2_crtc_atomic_exit_psr(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
4330 {
4331 struct vop2_video_port *vp = to_vop2_video_port(crtc);
4332 struct vop2 *vop2 = vp->vop2;
4333 u32 phys_id;
4334 struct vop2_win *win;
4335 unsigned long enabled_win_mask = vp->enabled_win_mask;
4336
4337 drm_crtc_vblank_on(crtc);
4338 if (vop2->aclk_rate_reset)
4339 clk_set_rate(vop2->aclk, vop2->aclk_rate);
4340 vop2->aclk_rate_reset = false;
4341
4342 for_each_set_bit(phys_id, &enabled_win_mask, ROCKCHIP_MAX_LAYER) {
4343 win = vop2_find_win_by_phys_id(vop2, phys_id);
4344 VOP_WIN_SET(vop2, win, enable, 1);
4345 if (win->feature & WIN_FEATURE_CLUSTER_MAIN)
4346 VOP_CLUSTER_SET(vop2, win, enable, 1);
4347 }
4348
4349 vop2_cfg_done(crtc);
4350 vop2_wait_for_fs_by_done_bit_status(vp);
4351 }
4352
vop2_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_crtc_state * old_state)4353 static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
4354 struct drm_crtc_state *old_state)
4355 {
4356 struct vop2_video_port *vp = to_vop2_video_port(crtc);
4357 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
4358 struct vop2 *vop2 = vp->vop2;
4359 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
4360 struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
4361 bool dual_channel = !!(vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE);
4362 int ret;
4363
4364 WARN_ON(vp->event);
4365
4366 if (crtc->state->self_refresh_active) {
4367 vop2_crtc_atomic_enter_psr(crtc, old_state);
4368 goto out;
4369 }
4370
4371 vop2_lock(vop2);
4372 DRM_DEV_INFO(vop2->dev, "Crtc atomic disable vp%d\n", vp->id);
4373 VOP_MODULE_SET(vop2, vp, almost_full_or_en, 0);
4374 VOP_MODULE_SET(vop2, vp, line_flag_or_en, 0);
4375 drm_crtc_vblank_off(crtc);
4376 if (vop2->dscs[vcstate->dsc_id].enabled &&
4377 vop2->dscs[vcstate->dsc_id].attach_vp_id == vp->id &&
4378 vop2->data->nr_dscs) {
4379 if (dual_channel) {
4380 vop2_crtc_disable_dsc(vop2, 0);
4381 vop2_crtc_disable_dsc(vop2, 1);
4382 } else {
4383 vop2_crtc_disable_dsc(vop2, vcstate->dsc_id);
4384 }
4385 }
4386
4387 if (vp->cubic_lut) {
4388 VOP_MODULE_SET(vop2, vp, cubic_lut_update_en, 0);
4389 VOP_MODULE_SET(vop2, vp, cubic_lut_en, 0);
4390 }
4391
4392 if (vp_data->feature & VOP_FEATURE_VIVID_HDR)
4393 VOP_MODULE_SET(vop2, vp, hdr_lut_update_en, 0);
4394 vop2_disable_all_planes_for_crtc(crtc);
4395
4396 if (vop2->dscs[vcstate->dsc_id].enabled &&
4397 vop2->dscs[vcstate->dsc_id].attach_vp_id == vp->id &&
4398 vop2->data->nr_dscs && vop2->dscs[vcstate->dsc_id].pd) {
4399 if (dual_channel) {
4400 vop2_power_domain_put(vop2->dscs[0].pd);
4401 vop2_power_domain_put(vop2->dscs[1].pd);
4402 vop2->dscs[0].pd->vp_mask = 0;
4403 vop2->dscs[1].pd->vp_mask = 0;
4404 vop2->dscs[0].attach_vp_id = -1;
4405 vop2->dscs[1].attach_vp_id = -1;
4406 } else {
4407 vop2_power_domain_put(vop2->dscs[vcstate->dsc_id].pd);
4408 vop2->dscs[vcstate->dsc_id].pd->vp_mask = 0;
4409 vop2->dscs[vcstate->dsc_id].attach_vp_id = -1;
4410 }
4411 vop2->dscs[vcstate->dsc_id].enabled = false;
4412 vcstate->dsc_enable = false;
4413 }
4414
4415 if (vp->output_if & VOP_OUTPUT_IF_eDP0)
4416 VOP_GRF_SET(vop2, grf, grf_edp0_en, 0);
4417
4418 if (vp->output_if & VOP_OUTPUT_IF_eDP1) {
4419 VOP_GRF_SET(vop2, grf, grf_edp1_en, 0);
4420 if (dual_channel)
4421 VOP_CTRL_SET(vop2, edp_dual_en, 0);
4422 }
4423
4424 if (vp->output_if & VOP_OUTPUT_IF_HDMI0) {
4425 VOP_GRF_SET(vop2, grf, grf_hdmi0_dsc_en, 0);
4426 VOP_GRF_SET(vop2, grf, grf_hdmi0_en, 0);
4427 }
4428
4429 if (vp->output_if & VOP_OUTPUT_IF_HDMI1) {
4430 VOP_GRF_SET(vop2, grf, grf_hdmi1_dsc_en, 0);
4431 VOP_GRF_SET(vop2, grf, grf_hdmi1_en, 0);
4432 if (dual_channel)
4433 VOP_CTRL_SET(vop2, hdmi_dual_en, 0);
4434 }
4435
4436 if ((vcstate->output_if & VOP_OUTPUT_IF_DP1) && dual_channel)
4437 VOP_CTRL_SET(vop2, dp_dual_en, 0);
4438
4439 if ((vcstate->output_if & VOP_OUTPUT_IF_MIPI1) && dual_channel)
4440 VOP_CTRL_SET(vop2, mipi_dual_en, 0);
4441
4442 VOP_MODULE_SET(vop2, vp, dual_channel_en, 0);
4443 VOP_MODULE_SET(vop2, vp, dual_channel_swap, 0);
4444
4445 vp->output_if = 0;
4446
4447 vop2_clk_set_parent_extend(vp, vcstate, false);
4448 /*
4449 * Vop standby will take effect at end of current frame,
4450 * if dsp hold valid irq happen, it means standby complete.
4451 *
4452 * we must wait standby complete when we want to disable aclk,
4453 * if not, memory bus maybe dead.
4454 */
4455 reinit_completion(&vp->dsp_hold_completion);
4456 vop2_dsp_hold_valid_irq_enable(crtc);
4457
4458 spin_lock(&vop2->reg_lock);
4459
4460 VOP_MODULE_SET(vop2, vp, splice_en, 0);
4461
4462 VOP_MODULE_SET(vop2, vp, standby, 1);
4463
4464 spin_unlock(&vop2->reg_lock);
4465
4466 ret = wait_for_completion_timeout(&vp->dsp_hold_completion, msecs_to_jiffies(50));
4467 if (!ret)
4468 DRM_DEV_INFO(vop2->dev, "wait for vp%d dsp_hold timeout\n", vp->id);
4469
4470 vop2_dsp_hold_valid_irq_disable(crtc);
4471
4472 vop2_disable(crtc);
4473
4474 vop2->active_vp_mask &= ~BIT(vp->id);
4475 if (vcstate->splice_mode)
4476 vop2->active_vp_mask &= ~BIT(splice_vp->id);
4477 vcstate->splice_mode = false;
4478 vcstate->output_flags = 0;
4479 vp->splice_mode_right = false;
4480 vp->loader_protect = false;
4481 splice_vp->splice_mode_right = false;
4482 memset(&vp->active_tv_state, 0, sizeof(vp->active_tv_state));
4483 vop2_unlock(vop2);
4484
4485 vop2_set_system_status(vop2);
4486
4487 out:
4488 if (crtc->state->event && !crtc->state->active) {
4489 spin_lock_irq(&crtc->dev->event_lock);
4490 drm_crtc_send_vblank_event(crtc, crtc->state->event);
4491 spin_unlock_irq(&crtc->dev->event_lock);
4492
4493 crtc->state->event = NULL;
4494 }
4495 }
4496
vop2_cluster_two_win_mode_check(struct drm_plane_state * pstate)4497 static int vop2_cluster_two_win_mode_check(struct drm_plane_state *pstate)
4498 {
4499 struct drm_atomic_state *state = pstate->state;
4500 struct drm_plane *plane = pstate->plane;
4501 struct vop2_win *win = to_vop2_win(plane);
4502 struct vop2 *vop2 = win->vop2;
4503 struct vop2_win *main_win = vop2_find_win_by_phys_id(vop2, win->phys_id);
4504 struct drm_plane_state *main_pstate;
4505 int actual_w = drm_rect_width(&pstate->src) >> 16;
4506 int xoffset;
4507
4508 if (pstate->fb->modifier == DRM_FORMAT_MOD_LINEAR)
4509 xoffset = 0;
4510 else
4511 xoffset = pstate->src.x1 >> 16;
4512
4513 if ((actual_w + xoffset % 16) > 2048) {
4514 DRM_ERROR("%s act_w(%d) + xoffset(%d) / 16 << 2048 in two win mode\n",
4515 win->name, actual_w, xoffset);
4516 return -EINVAL;
4517 }
4518
4519 main_pstate = drm_atomic_get_new_plane_state(state, &main_win->base);
4520
4521 if (pstate->fb->modifier != main_pstate->fb->modifier) {
4522 DRM_ERROR("%s(fb->modifier: 0x%llx) must use same data layout as %s(fb->modifier: 0x%llx)\n",
4523 win->name, pstate->fb->modifier, main_win->name, main_pstate->fb->modifier);
4524 return -EINVAL;
4525 }
4526
4527 if (main_pstate->fb->modifier == DRM_FORMAT_MOD_LINEAR)
4528 xoffset = 0;
4529 else
4530 xoffset = main_pstate->src.x1 >> 16;
4531 actual_w = drm_rect_width(&main_pstate->src) >> 16;
4532
4533 if ((actual_w + xoffset % 16) > 2048) {
4534 DRM_ERROR("%s act_w(%d) + xoffset(%d) / 16 << 2048 in two win mode\n",
4535 main_win->name, actual_w, xoffset);
4536 return -EINVAL;
4537 }
4538
4539 return 0;
4540 }
4541
vop2_cluter_splice_scale_check(struct vop2_win * win,struct drm_plane_state * pstate,u16 hdisplay)4542 static int vop2_cluter_splice_scale_check(struct vop2_win *win, struct drm_plane_state *pstate,
4543 u16 hdisplay)
4544 {
4545 struct drm_rect src = drm_plane_state_src(pstate);
4546 struct drm_rect dst = drm_plane_state_dest(pstate);
4547 u16 half_hdisplay = hdisplay >> 1;
4548
4549 /* scale up is ok */
4550 if ((drm_rect_width(&src) >> 16) <= drm_rect_width(&dst))
4551 return 0;
4552
4553 if ((drm_rect_width(&src) >> 16) <= VOP2_MAX_VP_OUTPUT_WIDTH)
4554 return 0;
4555 /*
4556 * Cluster scale down limitation in splice mode:
4557 * If scale down, must display at horizontal center
4558 */
4559 if ((dst.x1 < half_hdisplay) && (dst.x2 > half_hdisplay)) {
4560 if ((dst.x2 + dst.x1) != hdisplay) {
4561 DRM_ERROR("%s src_w: %d dst_w %d dst(%d %d) must scale down at center in splice mode\n",
4562 win->name, drm_rect_width(&src) >> 16,
4563 drm_rect_width(&dst), dst.x1, dst.x2);
4564 return -EINVAL;
4565 }
4566
4567 if (drm_rect_calc_hscale(&src, &dst, 1, FRAC_16_16(6, 5)) < 0) {
4568 DRM_ERROR("%s %d --> %d scale down factor should < 1.2 in splice mode\n",
4569 win->name, drm_rect_width(&src) >> 16, drm_rect_width(&dst));
4570 return -EINVAL;
4571 }
4572 }
4573
4574 return 0;
4575 }
4576
vop2_plane_splice_check(struct drm_plane * plane,struct drm_plane_state * pstate,struct drm_display_mode * mode)4577 static int vop2_plane_splice_check(struct drm_plane *plane, struct drm_plane_state *pstate,
4578 struct drm_display_mode *mode)
4579 {
4580 struct vop2_win *win = to_vop2_win(plane);
4581 int ret = 0;
4582
4583 if (!(win->feature & WIN_FEATURE_SPLICE_LEFT)) {
4584 DRM_ERROR("%s can't be left win in splice mode\n", win->name);
4585 return -EINVAL;
4586 }
4587
4588 if (win->feature & WIN_FEATURE_CLUSTER_SUB) {
4589 DRM_ERROR("%s can't use two win mode in splice mode\n", win->name);
4590 return -EINVAL;
4591 }
4592
4593 if ((pstate->rotation & DRM_MODE_ROTATE_270) ||
4594 (pstate->rotation & DRM_MODE_ROTATE_90) ||
4595 (pstate->rotation & DRM_MODE_REFLECT_X)) {
4596 DRM_ERROR("%s can't rotate 270/90 and xmirror in splice mode\n", win->name);
4597 return -EINVAL;
4598 }
4599
4600 /* check for cluster splice scale down */
4601 if (win->feature & WIN_FEATURE_CLUSTER_MAIN)
4602 ret = vop2_cluter_splice_scale_check(win, pstate, mode->hdisplay);
4603
4604 return ret;
4605 }
4606
4607 /*
4608 * 1. NV12/NV16/YUYV xoffset must aligned as 2 pixel;
4609 * 2. NV12/NV15 yoffset must aligned as 2 pixel;
4610 * 3. NV30 xoffset must aligned as 4 pixel;
4611 * 4. NV15/NV20 xoffset must aligend as 8 pixel at rk3568/rk3588/rk3528/rk3562,
4612 * others must aligned as 4 pixel;
4613 */
vop2_linear_yuv_format_check(struct drm_plane * plane,struct drm_plane_state * state)4614 static int vop2_linear_yuv_format_check(struct drm_plane *plane, struct drm_plane_state *state)
4615 {
4616 struct vop2_plane_state *vpstate = to_vop2_plane_state(state);
4617 struct drm_crtc *crtc = state->crtc;
4618 struct vop2_video_port *vp = to_vop2_video_port(crtc);
4619 struct vop2_win *win = to_vop2_win(plane);
4620 struct drm_framebuffer *fb = state->fb;
4621 struct drm_rect *src = &vpstate->src;
4622 u32 val = 0;
4623
4624 if (vpstate->afbc_en || vpstate->tiled_en || !fb->format->is_yuv)
4625 return 0;
4626
4627 switch (fb->format->format) {
4628 case DRM_FORMAT_NV12:
4629 case DRM_FORMAT_NV21:
4630 val = src->x1 >> 16;
4631 if (val % 2) {
4632 src->x1 = ALIGN(val, 2) << 16;
4633 DRM_WARN("VP%d %s src x offset[%d] must aligned as 2 pixel at NV12 fmt, and adjust to: %d\n", vp->id, win->name, val, src->x1 >> 16);
4634 }
4635 val = src->y1 >> 16;
4636 if (val % 2) {
4637 src->y1 = ALIGN(val, 2) << 16;
4638 DRM_WARN("VP%d %s src y offset[%d] must aligned as 2 pixel at NV12 fmt, and adjust to: %d\n", vp->id, win->name, val, src->y1 >> 16);
4639 }
4640 break;
4641 case DRM_FORMAT_NV15:
4642 val = src->y1 >> 16;
4643 if (val % 2) {
4644 src->y1 = ALIGN(val, 2) << 16;
4645 DRM_WARN("VP%d %s src y offset[%d] must aligned as 2 pixel at NV15 fmt, and adjust to: %d\n", vp->id, win->name, val, src->y1 >> 16);
4646 }
4647 if (vp->vop2->version == VOP_VERSION_RK3568 ||
4648 vp->vop2->version == VOP_VERSION_RK3588 ||
4649 vp->vop2->version == VOP_VERSION_RK3528 ||
4650 vp->vop2->version == VOP_VERSION_RK3562) {
4651 val = src->x1 >> 16;
4652 if (val % 8) {
4653 src->x1 = ALIGN(val, 8) << 16;
4654 DRM_WARN("VP%d %s src x offset[%d] must aligned as 8 pixel at NV15 fmt, and adjust to: %d\n", vp->id, win->name, val, src->x1 >> 16);
4655 }
4656 } else {
4657 val = src->x1 >> 16;
4658 if (val % 4) {
4659 src->x1 = ALIGN(val, 4) << 16;
4660 DRM_WARN("VP%d %s src x offset[%d] must aligned as 4 pixel at NV15 fmt, and adjust to: %d\n", vp->id, win->name, val, src->x1 >> 16);
4661 }
4662 }
4663 break;
4664 case DRM_FORMAT_NV16:
4665 case DRM_FORMAT_NV61:
4666 case DRM_FORMAT_YUYV:
4667 case DRM_FORMAT_YVYU:
4668 case DRM_FORMAT_VYUY:
4669 case DRM_FORMAT_UYVY:
4670 val = src->x1 >> 16;
4671 if (val % 2) {
4672 src->x1 = ALIGN(val, 2) << 16;
4673 DRM_WARN("VP%d %s src x offset[%d] must aligned as 2 pixel at YUYV fmt, and adjust to: %d\n", vp->id, win->name, val, src->x1 >> 16);
4674 }
4675 break;
4676 case DRM_FORMAT_NV20:
4677 if (vp->vop2->version == VOP_VERSION_RK3568 ||
4678 vp->vop2->version == VOP_VERSION_RK3588 ||
4679 vp->vop2->version == VOP_VERSION_RK3528 ||
4680 vp->vop2->version == VOP_VERSION_RK3562) {
4681 val = src->x1 >> 16;
4682 if (val % 8) {
4683 src->x1 = ALIGN(val, 8) << 16;
4684 DRM_WARN("VP%d %s src x offset[%d] must aligned as 8 pixel at NV20 fmt, and adjust to: %d\n", vp->id, win->name, val, src->x1 >> 16);
4685 }
4686 } else {
4687 val = src->x1 >> 16;
4688 if (val % 4) {
4689 src->x1 = ALIGN(val, 4) << 16;
4690 DRM_WARN("VP%d %s src x offset[%d] must aligned as 4 pixel at NV20 fmt, and adjust to: %d\n", vp->id, win->name, val, src->x1 >> 16);
4691 }
4692 }
4693 break;
4694 case DRM_FORMAT_NV30:
4695 val = src->x1 >> 16;
4696 if (val % 4) {
4697 src->x1 = ALIGN(val, 4) << 16;
4698 DRM_WARN("VP%d %s src x offset[%d] must aligned as 4 pixel at NV30 fmt, and adjust to: %d\n", vp->id, win->name, val, src->x1 >> 16);
4699 }
4700 break;
4701 default:
4702 return 0;
4703 }
4704
4705 return 0;
4706 }
4707
vop2_plane_atomic_check(struct drm_plane * plane,struct drm_plane_state * state)4708 static int vop2_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
4709 {
4710 struct vop2_plane_state *vpstate = to_vop2_plane_state(state);
4711 struct vop2_win *win = to_vop2_win(plane);
4712 struct vop2_win *splice_win;
4713 struct vop2 *vop2 = win->vop2;
4714 struct drm_framebuffer *fb = state->fb;
4715 struct drm_display_mode *mode;
4716 struct drm_crtc *crtc = state->crtc;
4717 struct drm_crtc_state *cstate;
4718 struct rockchip_crtc_state *vcstate;
4719 struct vop2_video_port *vp;
4720 const struct vop2_data *vop2_data;
4721 struct drm_rect *dest = &vpstate->dest;
4722 struct drm_rect *src = &vpstate->src;
4723 struct drm_gem_object *obj, *uv_obj;
4724 struct rockchip_gem_object *rk_obj, *rk_uv_obj;
4725 int min_scale = win->regs->scl ? FRAC_16_16(1, 8) : DRM_PLANE_HELPER_NO_SCALING;
4726 int max_scale = win->regs->scl ? FRAC_16_16(8, 1) : DRM_PLANE_HELPER_NO_SCALING;
4727 uint32_t tile_size = 1;
4728 int max_input_w;
4729 int max_input_h;
4730 unsigned long offset;
4731 dma_addr_t dma_addr;
4732 int ret;
4733
4734 crtc = crtc ? crtc : plane->state->crtc;
4735 if (!crtc || !fb) {
4736 plane->state->visible = false;
4737 return 0;
4738 }
4739
4740 vp = to_vop2_video_port(crtc);
4741 vop2_data = vp->vop2->data;
4742
4743 cstate = drm_atomic_get_existing_crtc_state(state->state, crtc);
4744 if (WARN_ON(!cstate))
4745 return -EINVAL;
4746
4747 mode = &cstate->mode;
4748 vcstate = to_rockchip_crtc_state(cstate);
4749
4750 max_input_w = vop2_data->max_input.width;
4751 max_input_h = vop2_data->max_input.height;
4752
4753 if (vop2_has_feature(win->vop2, VOP_FEATURE_SPLICE)) {
4754 if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
4755 vcstate->splice_mode = true;
4756 ret = vop2_plane_splice_check(plane, state, mode);
4757 if (ret < 0)
4758 return ret;
4759 splice_win = vop2_find_win_by_phys_id(vop2, win->splice_win_id);
4760 splice_win->splice_mode_right = true;
4761 splice_win->left_win = win;
4762 win->splice_win = splice_win;
4763 max_input_w <<= 1;
4764 }
4765 }
4766
4767 vpstate->xmirror_en = (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0;
4768 vpstate->ymirror_en = (state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0;
4769 vpstate->rotate_270_en = (state->rotation & DRM_MODE_ROTATE_270) ? 1 : 0;
4770 vpstate->rotate_90_en = (state->rotation & DRM_MODE_ROTATE_90) ? 1 : 0;
4771
4772 if (vpstate->rotate_270_en && vpstate->rotate_90_en) {
4773 DRM_ERROR("Can't rotate 90 and 270 at the same time\n");
4774 return -EINVAL;
4775 }
4776
4777 ret = drm_atomic_helper_check_plane_state(state, cstate,
4778 min_scale, max_scale,
4779 true, true);
4780 if (ret)
4781 return ret;
4782
4783 if (!state->visible) {
4784 DRM_ERROR("%s is invisible(src: pos[%d, %d] rect[%d x %d] dst: pos[%d, %d] rect[%d x %d]\n",
4785 plane->name, state->src_x >> 16, state->src_y >> 16, state->src_w >> 16,
4786 state->src_h >> 16, state->crtc_x, state->crtc_y, state->crtc_w,
4787 state->crtc_h);
4788 return 0;
4789 }
4790
4791 src->x1 = state->src.x1;
4792 src->y1 = state->src.y1;
4793 src->x2 = state->src.x2;
4794 src->y2 = state->src.y2;
4795 dest->x1 = state->dst.x1;
4796 dest->y1 = state->dst.y1;
4797 dest->x2 = state->dst.x2;
4798 dest->y2 = state->dst.y2;
4799
4800 vpstate->zpos = state->zpos;
4801 vpstate->global_alpha = state->alpha >> 8;
4802 vpstate->blend_mode = state->pixel_blend_mode;
4803 vpstate->format = vop2_convert_format(fb->format->format);
4804 if (vpstate->format < 0)
4805 return vpstate->format;
4806
4807 if (drm_rect_width(src) >> 16 < 4 || drm_rect_height(src) >> 16 < 4 ||
4808 drm_rect_width(dest) < 4 || drm_rect_width(dest) < 4) {
4809 DRM_ERROR("Invalid size: %dx%d->%dx%d, min size is 4x4\n",
4810 drm_rect_width(src) >> 16, drm_rect_height(src) >> 16,
4811 drm_rect_width(dest), drm_rect_height(dest));
4812 state->visible = false;
4813 return 0;
4814 }
4815
4816 if (drm_rect_width(src) >> 16 > max_input_w ||
4817 drm_rect_height(src) >> 16 > max_input_h) {
4818 DRM_ERROR("Invalid source: %dx%d. max input: %dx%d\n",
4819 drm_rect_width(src) >> 16,
4820 drm_rect_height(src) >> 16,
4821 max_input_w,
4822 max_input_h);
4823 return -EINVAL;
4824 }
4825
4826 if (rockchip_afbc(plane, fb->modifier))
4827 vpstate->afbc_en = true;
4828 else
4829 vpstate->afbc_en = false;
4830
4831 vpstate->tiled_en = rockchip_tiled(plane, fb->modifier) ?
4832 fb->modifier & ROCKCHIP_TILED_BLOCK_SIZE_MASK : 0;
4833 if (vpstate->tiled_en && vpstate->afbc_en) {
4834 DRM_ERROR("%s afbc and tiled format can't be enabled at same time(modifier: 0x%llx)\n",
4835 win->name, fb->modifier);
4836 return -EINVAL;
4837 }
4838 if (vpstate->tiled_en)
4839 tile_size = vpstate->tiled_en == ROCKCHIP_TILED_BLOCK_SIZE_8x8 ? 8 : 4;
4840
4841 /*
4842 * This is special feature at rk356x, the cluster layer only can support
4843 * afbc format and can't support linear format;
4844 */
4845 if (vp->vop2->version == VOP_VERSION_RK3568) {
4846 if (vop2_cluster_window(win) && !vpstate->afbc_en) {
4847 DRM_ERROR("Unsupported linear format at %s\n", win->name);
4848 return -EINVAL;
4849 }
4850 }
4851
4852 if (vp->vop2->version > VOP_VERSION_RK3568) {
4853 if (vop2_cluster_window(win) && !vpstate->afbc_en && fb->format->is_yuv && !is_vop3(vop2)) {
4854 DRM_ERROR("Unsupported linear yuv format at %s\n", win->name);
4855 return -EINVAL;
4856 }
4857
4858 if (vop2_cluster_window(win) && !vpstate->afbc_en &&
4859 (win->supported_rotations & state->rotation)) {
4860 DRM_ERROR("Unsupported linear rotation(%d) format at %s\n",
4861 state->rotation, win->name);
4862 return -EINVAL;
4863 }
4864 }
4865
4866 if (win->feature & WIN_FEATURE_CLUSTER_SUB) {
4867 ret = vop2_cluster_two_win_mode_check(state);
4868 if (ret < 0)
4869 return ret;
4870 }
4871
4872 if (vop2_linear_yuv_format_check(plane, state))
4873 return -EINVAL;
4874
4875 if (fb->format->char_per_block[0] == 0)
4876 offset = ALIGN_DOWN(src->x1 >> 16, tile_size) * fb->format->cpp[0] * tile_size;
4877 else
4878 offset = drm_format_info_min_pitch(fb->format, 0, ALIGN_DOWN(src->x1 >> 16, tile_size)) * tile_size;
4879 vpstate->offset = offset + fb->offsets[0];
4880
4881 /*
4882 * AFBC HDR_PTR must set to the zero offset of the framebuffer.
4883 */
4884 if (vpstate->afbc_en)
4885 offset = 0;
4886 else if (vpstate->ymirror_en)
4887 offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
4888 else
4889 offset += ALIGN_DOWN(src->y1 >> 16, tile_size) * fb->pitches[0];
4890
4891 obj = fb->obj[0];
4892 rk_obj = to_rockchip_obj(obj);
4893
4894 vpstate->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
4895 if (fb->format->is_yuv && fb->format->num_planes > 1) {
4896 int hsub = fb->format->hsub;
4897 int vsub = fb->format->vsub;
4898
4899 if (fb->format->char_per_block[0] == 0)
4900 offset = ALIGN_DOWN(src->x1 >> 16, tile_size) * fb->format->cpp[1] / hsub * tile_size;
4901 else
4902 offset = drm_format_info_min_pitch(fb->format, 1, ALIGN_DOWN(src->x1 >> 16, tile_size)) * tile_size / hsub;
4903
4904 if (vpstate->tiled_en)
4905 offset /= vsub;
4906 offset += ALIGN_DOWN(src->y1 >> 16, tile_size) * fb->pitches[1] / vsub;
4907
4908 uv_obj = fb->obj[1];
4909 rk_uv_obj = to_rockchip_obj(uv_obj);
4910
4911 if (vpstate->ymirror_en && !vpstate->afbc_en)
4912 offset += fb->pitches[1] * ((state->src_h >> 16) - 2) / vsub;
4913 dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
4914 vpstate->uv_mst = dma_addr;
4915 /* tile 4x4 m0 format, y and uv is packed together */
4916 if (vpstate->tiled_en == ROCKCHIP_TILED_BLOCK_SIZE_4x4_MODE0)
4917 vpstate->yrgb_mst += offset;
4918 }
4919
4920 return 0;
4921 }
4922
vop2_plane_atomic_disable(struct drm_plane * plane,struct drm_plane_state * old_state)4923 static void vop2_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state)
4924 {
4925 struct vop2_win *win = to_vop2_win(plane);
4926 struct vop2 *vop2 = win->vop2;
4927 struct drm_crtc *crtc;
4928 struct vop2_video_port *vp;
4929
4930 #if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
4931 struct vop2_plane_state *vpstate = to_vop2_plane_state(plane->state);
4932 #endif
4933
4934 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_PLANE, "%s disable %s\n",
4935 win->name, current->comm);
4936
4937 if (!old_state->crtc)
4938 return;
4939
4940 spin_lock(&vop2->reg_lock);
4941
4942 crtc = old_state->crtc;
4943 vp = to_vop2_video_port(crtc);
4944
4945 vop2_win_disable(win, false);
4946 vp->enabled_win_mask &= ~BIT(win->phys_id);
4947 if (win->splice_win) {
4948 vop2_win_disable(win->splice_win, false);
4949 vp->enabled_win_mask &= ~BIT(win->splice_win->phys_id);
4950 }
4951
4952 #if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
4953 kfree(vpstate->planlist);
4954 vpstate->planlist = NULL;
4955 #endif
4956
4957 spin_unlock(&vop2->reg_lock);
4958 }
4959
4960 /*
4961 * The color key is 10 bit, so all format should
4962 * convert to 10 bit here.
4963 */
vop2_plane_setup_color_key(struct drm_plane * plane)4964 static void vop2_plane_setup_color_key(struct drm_plane *plane)
4965 {
4966 struct drm_plane_state *pstate = plane->state;
4967 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
4968 struct drm_framebuffer *fb = pstate->fb;
4969 struct vop2_win *win = to_vop2_win(plane);
4970 struct vop2 *vop2 = win->vop2;
4971 uint32_t color_key_en = 0;
4972 uint32_t color_key;
4973 uint32_t r = 0;
4974 uint32_t g = 0;
4975 uint32_t b = 0;
4976
4977 if (!(vpstate->color_key & VOP_COLOR_KEY_MASK) || fb->format->is_yuv) {
4978 VOP_WIN_SET(vop2, win, color_key_en, 0);
4979 return;
4980 }
4981
4982 switch (fb->format->format) {
4983 case DRM_FORMAT_RGB565:
4984 case DRM_FORMAT_BGR565:
4985 r = (vpstate->color_key & 0xf800) >> 11;
4986 g = (vpstate->color_key & 0x7e0) >> 5;
4987 b = (vpstate->color_key & 0x1f);
4988 r <<= 5;
4989 g <<= 4;
4990 b <<= 5;
4991 color_key_en = 1;
4992 break;
4993 case DRM_FORMAT_XRGB8888:
4994 case DRM_FORMAT_ARGB8888:
4995 case DRM_FORMAT_XBGR8888:
4996 case DRM_FORMAT_ABGR8888:
4997 case DRM_FORMAT_RGB888:
4998 case DRM_FORMAT_BGR888:
4999 r = (vpstate->color_key & 0xff0000) >> 16;
5000 g = (vpstate->color_key & 0xff00) >> 8;
5001 b = (vpstate->color_key & 0xff);
5002 r <<= 2;
5003 g <<= 2;
5004 b <<= 2;
5005 color_key_en = 1;
5006 break;
5007 }
5008
5009 color_key = (r << 20) | (g << 10) | b;
5010 VOP_WIN_SET(vop2, win, color_key_en, color_key_en);
5011 VOP_WIN_SET(vop2, win, color_key, color_key);
5012 }
5013
vop2_calc_drm_rect_for_splice(struct vop2_plane_state * vpstate,struct drm_rect * left_src,struct drm_rect * left_dst,struct drm_rect * right_src,struct drm_rect * right_dst)5014 static void vop2_calc_drm_rect_for_splice(struct vop2_plane_state *vpstate,
5015 struct drm_rect *left_src, struct drm_rect *left_dst,
5016 struct drm_rect *right_src, struct drm_rect *right_dst)
5017 {
5018 struct drm_crtc *crtc = vpstate->base.crtc;
5019 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
5020 struct drm_rect *dst = &vpstate->dest;
5021 struct drm_rect *src = &vpstate->src;
5022 u16 half_hdisplay = mode->crtc_hdisplay >> 1;
5023 int hscale = drm_rect_calc_hscale(src, dst, 0, INT_MAX);
5024 int dst_w = drm_rect_width(dst);
5025 int src_w = drm_rect_width(src) >> 16;
5026 int left_src_w, left_dst_w, right_dst_w;
5027 struct drm_plane_state *pstate = &vpstate->base;
5028 struct drm_framebuffer *fb = pstate->fb;
5029
5030 left_dst_w = min_t(u16, half_hdisplay, dst->x2) - dst->x1;
5031 if (left_dst_w < 0)
5032 left_dst_w = 0;
5033 right_dst_w = dst_w - left_dst_w;
5034
5035 if (!right_dst_w)
5036 left_src_w = src_w;
5037 else
5038 left_src_w = (left_dst_w * hscale) >> 16;
5039
5040 /*
5041 * Make sure the yrgb/uv mst of right win are byte aligned
5042 * with full pixel.
5043 */
5044 if (right_dst_w) {
5045 if (fb->format->format == DRM_FORMAT_NV15)
5046 left_src_w &= ~0x7;
5047 else if (fb->format->format == DRM_FORMAT_NV12)
5048 left_src_w &= ~0x1;
5049 }
5050 left_src->x1 = src->x1;
5051 left_src->x2 = src->x1 + (left_src_w << 16);
5052 left_dst->x1 = dst->x1;
5053 left_dst->x2 = dst->x1 + left_dst_w;
5054 right_src->x1 = left_src->x2;
5055 right_src->x2 = src->x2;
5056 right_dst->x1 = dst->x1 + left_dst_w - half_hdisplay;
5057 if (right_dst->x1 < 0)
5058 right_dst->x1 = 0;
5059
5060 right_dst->x2 = right_dst->x1 + right_dst_w;
5061
5062 left_src->y1 = src->y1;
5063 left_src->y2 = src->y2;
5064 left_dst->y1 = dst->y1;
5065 left_dst->y2 = dst->y2;
5066 right_src->y1 = src->y1;
5067 right_src->y2 = src->y2;
5068 right_dst->y1 = dst->y1;
5069 right_dst->y2 = dst->y2;
5070 }
5071
rk3588_vop2_win_cfg_axi(struct vop2_win * win)5072 static void rk3588_vop2_win_cfg_axi(struct vop2_win *win)
5073 {
5074 struct vop2 *vop2 = win->vop2;
5075
5076 /*
5077 * No need to set multi area sub windows as it
5078 * share the same axi bus and read_id with main window.
5079 */
5080 if (vop2_multi_area_sub_window(win))
5081 return;
5082 /*
5083 * No need to set Cluster sub windows axi_id as it
5084 * share the same axi bus with main window.
5085 */
5086 if (!vop2_cluster_sub_window(win))
5087 VOP_WIN_SET(vop2, win, axi_id, win->axi_id);
5088 VOP_WIN_SET(vop2, win, axi_yrgb_id, win->axi_yrgb_id);
5089 VOP_WIN_SET(vop2, win, axi_uv_id, win->axi_uv_id);
5090 }
5091
modifier_to_string(uint64_t modifier)5092 static const char *modifier_to_string(uint64_t modifier)
5093 {
5094 switch (modifier) {
5095 case DRM_FORMAT_MOD_ROCKCHIP_TILED(ROCKCHIP_TILED_BLOCK_SIZE_8x8):
5096 return "[TILE_8x8]";
5097 case DRM_FORMAT_MOD_ROCKCHIP_TILED(ROCKCHIP_TILED_BLOCK_SIZE_4x4_MODE0):
5098 return "[TILE_4x4_M0]";
5099 case DRM_FORMAT_MOD_ROCKCHIP_TILED(ROCKCHIP_TILED_BLOCK_SIZE_4x4_MODE1):
5100 return "[TILE_4x4_M1]";
5101 default:
5102 return drm_is_afbc(modifier) ? "[AFBC]" : "";
5103 }
5104 }
5105
vop2_win_atomic_update(struct vop2_win * win,struct drm_rect * src,struct drm_rect * dst,struct drm_plane_state * pstate)5106 static void vop2_win_atomic_update(struct vop2_win *win, struct drm_rect *src, struct drm_rect *dst,
5107 struct drm_plane_state *pstate)
5108 {
5109 struct drm_crtc *crtc = pstate->crtc;
5110 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5111 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
5112 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
5113 struct vop2 *vop2 = win->vop2;
5114 struct drm_framebuffer *fb = pstate->fb;
5115 struct drm_rect *left_src = &vpstate->src;
5116 uint32_t bpp = rockchip_drm_get_bpp(fb->format);
5117 uint32_t actual_w, actual_h, dsp_w, dsp_h;
5118 uint32_t dsp_stx, dsp_sty;
5119 uint32_t act_info, dsp_info, dsp_st;
5120 uint32_t format, check_size;
5121 uint32_t afbc_format;
5122 uint32_t rb_swap;
5123 uint32_t uv_swap;
5124 uint32_t afbc_half_block_en;
5125 uint32_t afbc_tile_num;
5126 uint32_t lb_mode;
5127 uint32_t stride, uv_stride = 0;
5128 uint32_t transform_offset;
5129 /* offset of the right window in splice mode */
5130 uint32_t splice_pixel_offset = 0;
5131 uint32_t splice_yrgb_offset = 0;
5132 uint32_t splice_uv_offset = 0;
5133 uint32_t afbc_xoffset;
5134 uint32_t hsub;
5135 dma_addr_t yrgb_mst;
5136 dma_addr_t uv_mst;
5137
5138 struct drm_format_name_buf format_name;
5139 bool dither_up;
5140 bool tile_4x4_m0 = vpstate->tiled_en == ROCKCHIP_TILED_BLOCK_SIZE_4x4_MODE0 ? true : false;
5141
5142 actual_w = drm_rect_width(src) >> 16;
5143 actual_h = drm_rect_height(src) >> 16;
5144
5145 if (!actual_w || !actual_h) {
5146 vop2_win_disable(win, true);
5147 return;
5148 }
5149
5150 dsp_w = drm_rect_width(dst);
5151 /*
5152 * This win is for the right part of the plane,
5153 * we need calculate the fb offset for it.
5154 */
5155 if (win->splice_mode_right) {
5156 splice_pixel_offset = (src->x1 - left_src->x1) >> 16;
5157 splice_yrgb_offset = drm_format_info_min_pitch(fb->format, 0, splice_pixel_offset);
5158 if (fb->format->is_yuv && fb->format->num_planes > 1) {
5159 hsub = fb->format->hsub;
5160 splice_uv_offset = drm_format_info_min_pitch(fb->format, 1, splice_pixel_offset / hsub);
5161 }
5162 }
5163
5164 if (dst->x1 + dsp_w > adjusted_mode->crtc_hdisplay) {
5165 DRM_ERROR("vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
5166 vp->id, win->name, dst->x1, dsp_w, adjusted_mode->crtc_hdisplay);
5167 dsp_w = adjusted_mode->crtc_hdisplay - dst->x1;
5168 if (dsp_w < 4)
5169 dsp_w = 4;
5170 actual_w = dsp_w * actual_w / drm_rect_width(dst);
5171 }
5172 dsp_h = drm_rect_height(dst);
5173 check_size = adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE ? adjusted_mode->vdisplay : adjusted_mode->crtc_vdisplay;
5174 if (dst->y1 + dsp_h > check_size) {
5175 DRM_ERROR("vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
5176 vp->id, win->name, dst->y1, dsp_h, adjusted_mode->crtc_vdisplay);
5177 dsp_h = adjusted_mode->crtc_vdisplay - dst->y1;
5178 if (dsp_h < 4)
5179 dsp_h = 4;
5180 actual_h = dsp_h * actual_h / drm_rect_height(dst);
5181 }
5182
5183 /*
5184 * Workaround only for rk3568 vop
5185 */
5186 if (vop2->version == VOP_VERSION_RK3568) {
5187 /*
5188 * This is workaround solution for IC design:
5189 * esmart can't support scale down when actual_w % 16 == 1;
5190 * esmart can't support scale down when dsp_w % 2 == 1;
5191 * esmart actual_w should align as 4 pixel when is linear 10 bit yuv format;
5192 *
5193 * cluster actual_w should align as 4 pixel when enable afbc;
5194 */
5195 if (!vop2_cluster_window(win)) {
5196 if (actual_w > dsp_w && (actual_w & 0xf) == 1) {
5197 DRM_WARN("vp%d %s act_w[%d] MODE 16 == 1 at scale down mode\n", vp->id, win->name, actual_w);
5198 actual_w -= 1;
5199 }
5200 if (actual_w > dsp_w && (dsp_w & 0x1) == 1) {
5201 DRM_WARN("vp%d %s dsp_w[%d] MODE 2 == 1 at scale down mode\n", vp->id, win->name, dsp_w);
5202 dsp_w -= 1;
5203 }
5204 }
5205
5206 if (vop2_cluster_window(win) && actual_w % 4) {
5207 DRM_WARN("vp%d %s actual_w[%d] should align as 4 pixel when enable afbc\n",
5208 vp->id, win->name, actual_w);
5209 actual_w = ALIGN_DOWN(actual_w, 4);
5210 }
5211 }
5212
5213 if (is_linear_10bit_yuv(fb->format->format) && actual_w & 0x3) {
5214 DRM_WARN("vp%d %s actual_w[%d] should align as 4 pixel when is linear 10 bit yuv format\n", vp->id, win->name, actual_w);
5215 actual_w = ALIGN_DOWN(actual_w, 4);
5216 }
5217
5218 act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
5219 dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff);
5220 stride = DIV_ROUND_UP(fb->pitches[0], 4);
5221 dsp_stx = dst->x1;
5222 dsp_sty = dst->y1;
5223 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
5224
5225 if (vpstate->tiled_en) {
5226 if (is_vop3(vop2))
5227 format = vop3_convert_tiled_format(fb->format->format, vpstate->tiled_en);
5228 else
5229 format = vop2_convert_tiled_format(fb->format->format);
5230 } else {
5231 format = vop2_convert_format(fb->format->format);
5232 }
5233
5234 vop2_setup_csc_mode(vp, vpstate);
5235
5236 afbc_half_block_en = vop2_afbc_half_block_enable(vpstate);
5237
5238 vop2_win_enable(win);
5239 spin_lock(&vop2->reg_lock);
5240 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_PLANE,
5241 "vp%d update %s[%dx%d->%dx%d@(%d, %d)] fmt[%.4s%s] addr[%pad] by %s\n",
5242 vp->id, win->name, actual_w, actual_h, dsp_w, dsp_h,
5243 dsp_stx, dsp_sty,
5244 drm_get_format_name(fb->format->format, &format_name),
5245 modifier_to_string(fb->modifier), &vpstate->yrgb_mst, current->comm);
5246
5247 if (vop2->version != VOP_VERSION_RK3568)
5248 rk3588_vop2_win_cfg_axi(win);
5249
5250 if (!win->parent && !vop2_cluster_window(win) && is_vop3(vop2))
5251 VOP_WIN_SET(vop2, win, scale_engine_num, win->scale_engine_num);
5252
5253 if (vpstate->afbc_en) {
5254 /* the afbc superblock is 16 x 16 */
5255 afbc_format = vop2_convert_afbc_format(fb->format->format);
5256 /* Enable color transform for YTR */
5257 if (fb->modifier & AFBC_FORMAT_MOD_YTR)
5258 afbc_format |= (1 << 4);
5259 afbc_tile_num = ALIGN(actual_w, 16) >> 4;
5260
5261 /* The right win should have a src offset in splice mode */
5262 afbc_xoffset = (src->x1 >> 16);
5263 /* AFBC pic_vir_width is count by pixel, this is different
5264 * with WIN_VIR_STRIDE.
5265 */
5266 if (!bpp) {
5267 WARN(1, "bpp is zero\n");
5268 bpp = 1;
5269 }
5270 stride = (fb->pitches[0] << 3) / bpp;
5271 if ((stride & 0x3f) &&
5272 (vpstate->xmirror_en || vpstate->rotate_90_en || vpstate->rotate_270_en))
5273 DRM_ERROR("vp%d %s stride[%d] must align as 64 pixel when enable xmirror/rotate_90/rotate_270[0x%x]\n",
5274 vp->id, win->name, stride, pstate->rotation);
5275
5276 rb_swap = vop2_afbc_rb_swap(fb->format->format);
5277 uv_swap = vop2_afbc_uv_swap(fb->format->format);
5278 vpstate->afbc_half_block_en = afbc_half_block_en;
5279
5280 transform_offset = vop2_afbc_transform_offset(vpstate, splice_pixel_offset);
5281 VOP_CLUSTER_SET(vop2, win, afbc_enable, 1);
5282 VOP_AFBC_SET(vop2, win, format, afbc_format);
5283 VOP_AFBC_SET(vop2, win, rb_swap, rb_swap);
5284 VOP_AFBC_SET(vop2, win, uv_swap, uv_swap);
5285
5286 if (vop2->version == VOP_VERSION_RK3568)
5287 VOP_AFBC_SET(vop2, win, auto_gating_en, 0);
5288 else
5289 VOP_AFBC_SET(vop2, win, auto_gating_en, 1);
5290 VOP_AFBC_SET(vop2, win, block_split_en, 0);
5291 VOP_AFBC_SET(vop2, win, hdr_ptr, vpstate->yrgb_mst);
5292 VOP_AFBC_SET(vop2, win, pic_size, act_info);
5293 VOP_AFBC_SET(vop2, win, transform_offset, transform_offset);
5294 VOP_AFBC_SET(vop2, win, pic_offset, (afbc_xoffset | src->y1));
5295 VOP_AFBC_SET(vop2, win, dsp_offset, (dst->x1 | (dst->y1 << 16)));
5296 VOP_AFBC_SET(vop2, win, pic_vir_width, stride);
5297 VOP_AFBC_SET(vop2, win, tile_num, afbc_tile_num);
5298 VOP_AFBC_SET(vop2, win, xmirror, vpstate->xmirror_en);
5299 VOP_AFBC_SET(vop2, win, ymirror, vpstate->ymirror_en);
5300 VOP_AFBC_SET(vop2, win, rotate_270, vpstate->rotate_270_en);
5301 VOP_AFBC_SET(vop2, win, rotate_90, vpstate->rotate_90_en);
5302 } else {
5303 VOP_CLUSTER_SET(vop2, win, afbc_enable, 0);
5304 transform_offset = vop2_tile_transform_offset(vpstate, vpstate->tiled_en);
5305 VOP_AFBC_SET(vop2, win, transform_offset, transform_offset);
5306 VOP_WIN_SET(vop2, win, ymirror, vpstate->ymirror_en);
5307 VOP_WIN_SET(vop2, win, xmirror, vpstate->xmirror_en);
5308 }
5309
5310 if (vpstate->rotate_90_en || vpstate->rotate_270_en) {
5311 act_info = swahw32(act_info);
5312 actual_w = drm_rect_height(src) >> 16;
5313 actual_h = drm_rect_width(src) >> 16;
5314 }
5315
5316 yrgb_mst = vpstate->yrgb_mst + splice_yrgb_offset;
5317 uv_mst = vpstate->uv_mst + splice_uv_offset;
5318 /* rk3588 should set half_blocK_en to 1 in line and tile mode */
5319 VOP_AFBC_SET(vop2, win, half_block_en, afbc_half_block_en);
5320
5321 VOP_WIN_SET(vop2, win, format, format);
5322 VOP_WIN_SET(vop2, win, yrgb_mst, yrgb_mst);
5323
5324 rb_swap = vop2_win_rb_swap(fb->format->format);
5325 uv_swap = vop2_win_uv_swap(fb->format->format);
5326 if (vpstate->tiled_en) {
5327 uv_swap = 1;
5328 if (vpstate->tiled_en == ROCKCHIP_TILED_BLOCK_SIZE_8x8)
5329 stride <<= 3;
5330 else
5331 stride <<= 2;
5332 }
5333 VOP_WIN_SET(vop2, win, rb_swap, rb_swap);
5334 VOP_WIN_SET(vop2, win, uv_swap, uv_swap);
5335
5336 if (fb->format->is_yuv) {
5337 uv_stride = DIV_ROUND_UP(fb->pitches[1], 4);
5338 if (vpstate->tiled_en) {
5339 int vsub = fb->format->vsub;
5340
5341 if (vpstate->tiled_en == ROCKCHIP_TILED_BLOCK_SIZE_8x8)
5342 uv_stride = uv_stride * 8 / vsub;
5343 else
5344 uv_stride = uv_stride * 4 / vsub;
5345 VOP_WIN_SET(vop2, win, tile_mode, tile_4x4_m0);
5346 }
5347
5348 VOP_WIN_SET(vop2, win, uv_vir, uv_stride);
5349 VOP_WIN_SET(vop2, win, uv_mst, uv_mst);
5350 }
5351
5352 /* tile 4x4 m0 format, y and uv is packed together */
5353 if (tile_4x4_m0)
5354 VOP_WIN_SET(vop2, win, yrgb_vir, stride + uv_stride);
5355 else
5356 VOP_WIN_SET(vop2, win, yrgb_vir, stride);
5357
5358 vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, pstate);
5359 vop2_plane_setup_color_key(&win->base);
5360 VOP_WIN_SET(vop2, win, act_info, act_info);
5361 VOP_WIN_SET(vop2, win, dsp_info, dsp_info);
5362 VOP_WIN_SET(vop2, win, dsp_st, dsp_st);
5363
5364 VOP_WIN_SET(vop2, win, y2r_en, vpstate->y2r_en);
5365 VOP_WIN_SET(vop2, win, r2y_en, vpstate->r2y_en);
5366 VOP_WIN_SET(vop2, win, csc_mode, vpstate->csc_mode);
5367
5368 if (win->feature & WIN_FEATURE_Y2R_13BIT_DEPTH && !vop2_cluster_window(win))
5369 VOP_WIN_SET(vop2, win, csc_13bit_en, !!(vpstate->csc_mode & CSC_BT709L_13BIT));
5370
5371 dither_up = vop2_win_dither_up(fb->format->format);
5372 VOP_WIN_SET(vop2, win, dither_up, dither_up);
5373
5374 VOP_WIN_SET(vop2, win, enable, 1);
5375 vp->enabled_win_mask |= BIT(win->phys_id);
5376 if (vop2_cluster_window(win)) {
5377 lb_mode = vop2_get_cluster_lb_mode(win, vpstate);
5378 VOP_CLUSTER_SET(vop2, win, lb_mode, lb_mode);
5379 VOP_CLUSTER_SET(vop2, win, scl_lb_mode, lb_mode == 1 ? 3 : 0);
5380 VOP_CLUSTER_SET(vop2, win, enable, 1);
5381 VOP_CLUSTER_SET(vop2, win, frm_reset_en, 1);
5382 }
5383 spin_unlock(&vop2->reg_lock);
5384 }
5385
vop2_plane_atomic_update(struct drm_plane * plane,struct drm_plane_state * old_state)5386 static void vop2_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state)
5387 {
5388 struct drm_plane_state *pstate = plane->state;
5389 struct drm_crtc *crtc = pstate->crtc;
5390 struct vop2_win *win = to_vop2_win(plane);
5391 struct vop2_win *splice_win;
5392 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5393 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
5394 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
5395 struct drm_framebuffer *fb = pstate->fb;
5396 struct drm_format_name_buf format_name;
5397 struct vop2 *vop2 = win->vop2;
5398 struct drm_rect wsrc;
5399 struct drm_rect wdst;
5400 /* right part in splice mode */
5401 struct drm_rect right_wsrc;
5402 struct drm_rect right_wdst;
5403
5404 #if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
5405 struct drm_rect *psrc = &vpstate->src;
5406 bool AFBC_flag = false;
5407 struct vop_dump_list *planlist;
5408 unsigned long num_pages;
5409 struct page **pages;
5410 struct drm_gem_object *obj;
5411 struct rockchip_gem_object *rk_obj;
5412
5413 num_pages = 0;
5414 pages = NULL;
5415 obj = fb->obj[0];
5416 rk_obj = to_rockchip_obj(obj);
5417 if (rk_obj) {
5418 num_pages = rk_obj->num_pages;
5419 pages = rk_obj->pages;
5420 }
5421 if (rockchip_afbc(plane, fb->modifier))
5422 AFBC_flag = true;
5423 else
5424 AFBC_flag = false;
5425 #endif
5426
5427 /*
5428 * can't update plane when vop2 is disabled.
5429 */
5430 if (WARN_ON(!crtc))
5431 return;
5432
5433 if (WARN_ON(!vop2->is_enabled))
5434 return;
5435
5436 if (!pstate->visible) {
5437 vop2_plane_atomic_disable(plane, old_state);
5438 return;
5439 }
5440
5441 /*
5442 * This means this window is moved from another vp
5443 * so the VOP2_PORT_SEL register is changed and
5444 * take effect by vop2_wait_for_port_mux_done
5445 * in this commit. so we can continue configure
5446 * the window and report vsync
5447 */
5448 if (win->old_vp_mask != win->vp_mask) {
5449 win->old_vp_mask = win->vp_mask;
5450 if (!is_vop3(vop2))
5451 vp->skip_vsync = false;
5452 }
5453
5454 if (vcstate->splice_mode) {
5455 DRM_DEV_DEBUG(vop2->dev, "vp%d update %s[%dx%d->%dx%d@(%d,%d)] fmt[%.4s%s] addr[%pad]\n",
5456 vp->id, win->name, drm_rect_width(&vpstate->src) >> 16,
5457 drm_rect_height(&vpstate->src) >> 16,
5458 drm_rect_width(&vpstate->dest), drm_rect_height(&vpstate->dest),
5459 vpstate->dest.x1, vpstate->dest.y1,
5460 drm_get_format_name(fb->format->format, &format_name),
5461 modifier_to_string(fb->modifier), &vpstate->yrgb_mst);
5462
5463 vop2_calc_drm_rect_for_splice(vpstate, &wsrc, &wdst, &right_wsrc, &right_wdst);
5464 splice_win = win->splice_win;
5465 vop2_win_atomic_update(splice_win, &right_wsrc, &right_wdst, pstate);
5466 } else {
5467 memcpy(&wsrc, &vpstate->src, sizeof(struct drm_rect));
5468 memcpy(&wdst, &vpstate->dest, sizeof(struct drm_rect));
5469 }
5470
5471 vop2_win_atomic_update(win, &wsrc, &wdst, pstate);
5472
5473 vop2->is_iommu_needed = true;
5474 #if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
5475 kfree(vpstate->planlist);
5476 vpstate->planlist = NULL;
5477
5478 planlist = kmalloc(sizeof(*planlist), GFP_KERNEL);
5479 if (planlist) {
5480 planlist->dump_info.AFBC_flag = AFBC_flag;
5481 planlist->dump_info.area_id = win->area_id;
5482 planlist->dump_info.win_id = win->win_id;
5483 planlist->dump_info.yuv_format = fb->format->is_yuv;
5484 planlist->dump_info.num_pages = num_pages;
5485 planlist->dump_info.pages = pages;
5486 planlist->dump_info.offset = vpstate->offset;
5487 planlist->dump_info.pitches = fb->pitches[0];
5488 planlist->dump_info.height = drm_rect_height(psrc) >> 16;
5489 planlist->dump_info.format = fb->format;
5490 list_add_tail(&planlist->entry, &vp->rockchip_crtc.vop_dump_list_head);
5491 vpstate->planlist = planlist;
5492 } else {
5493 DRM_ERROR("can't alloc a node of planlist %p\n", planlist);
5494 return;
5495 }
5496 if (vp->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
5497 vp->rockchip_crtc.vop_dump_times > 0) {
5498 rockchip_drm_dump_plane_buffer(&planlist->dump_info, vp->rockchip_crtc.frame_count);
5499 vp->rockchip_crtc.vop_dump_times--;
5500 }
5501 #endif
5502 }
5503
5504 static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = {
5505 .atomic_check = vop2_plane_atomic_check,
5506 .atomic_update = vop2_plane_atomic_update,
5507 .atomic_disable = vop2_plane_atomic_disable,
5508 };
5509
5510 /**
5511 * rockchip_atomic_helper_update_plane copy from drm_atomic_helper_update_plane
5512 * be designed to support async commit at ioctl DRM_IOCTL_MODE_SETPLANE.
5513 * @plane: plane object to update
5514 * @crtc: owning CRTC of owning plane
5515 * @fb: framebuffer to flip onto plane
5516 * @crtc_x: x offset of primary plane on crtc
5517 * @crtc_y: y offset of primary plane on crtc
5518 * @crtc_w: width of primary plane rectangle on crtc
5519 * @crtc_h: height of primary plane rectangle on crtc
5520 * @src_x: x offset of @fb for panning
5521 * @src_y: y offset of @fb for panning
5522 * @src_w: width of source rectangle in @fb
5523 * @src_h: height of source rectangle in @fb
5524 * @ctx: lock acquire context
5525 *
5526 * Provides a default plane update handler using the atomic driver interface.
5527 *
5528 * RETURNS:
5529 * Zero on success, error code on failure
5530 */
5531 static int __maybe_unused
rockchip_atomic_helper_update_plane(struct drm_plane * plane,struct drm_crtc * crtc,struct drm_framebuffer * fb,int crtc_x,int crtc_y,unsigned int crtc_w,unsigned int crtc_h,uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h,struct drm_modeset_acquire_ctx * ctx)5532 rockchip_atomic_helper_update_plane(struct drm_plane *plane,
5533 struct drm_crtc *crtc,
5534 struct drm_framebuffer *fb,
5535 int crtc_x, int crtc_y,
5536 unsigned int crtc_w, unsigned int crtc_h,
5537 uint32_t src_x, uint32_t src_y,
5538 uint32_t src_w, uint32_t src_h,
5539 struct drm_modeset_acquire_ctx *ctx)
5540 {
5541 struct drm_atomic_state *state;
5542 struct drm_plane_state *pstate;
5543 struct vop2_plane_state *vpstate;
5544 int ret = 0;
5545
5546 state = drm_atomic_state_alloc(plane->dev);
5547 if (!state)
5548 return -ENOMEM;
5549
5550 state->acquire_ctx = ctx;
5551 pstate = drm_atomic_get_plane_state(state, plane);
5552 if (IS_ERR(pstate)) {
5553 ret = PTR_ERR(pstate);
5554 goto fail;
5555 }
5556
5557 vpstate = to_vop2_plane_state(pstate);
5558
5559 ret = drm_atomic_set_crtc_for_plane(pstate, crtc);
5560 if (ret != 0)
5561 goto fail;
5562 drm_atomic_set_fb_for_plane(pstate, fb);
5563 pstate->crtc_x = crtc_x;
5564 pstate->crtc_y = crtc_y;
5565 pstate->crtc_w = crtc_w;
5566 pstate->crtc_h = crtc_h;
5567 pstate->src_x = src_x;
5568 pstate->src_y = src_y;
5569 pstate->src_w = src_w;
5570 pstate->src_h = src_h;
5571
5572 if (plane == crtc->cursor || vpstate->async_commit)
5573 state->legacy_cursor_update = true;
5574
5575 ret = drm_atomic_commit(state);
5576 fail:
5577 drm_atomic_state_put(state);
5578 return ret;
5579 }
5580
5581 /**
5582 * drm_atomic_helper_disable_plane copy from drm_atomic_helper_disable_plane
5583 * be designed to support async commit at ioctl DRM_IOCTL_MODE_SETPLANE.
5584 *
5585 * @plane: plane to disable
5586 * @ctx: lock acquire context
5587 *
5588 * Provides a default plane disable handler using the atomic driver interface.
5589 *
5590 * RETURNS:
5591 * Zero on success, error code on failure
5592 */
5593 static int __maybe_unused
rockchip_atomic_helper_disable_plane(struct drm_plane * plane,struct drm_modeset_acquire_ctx * ctx)5594 rockchip_atomic_helper_disable_plane(struct drm_plane *plane,
5595 struct drm_modeset_acquire_ctx *ctx)
5596 {
5597 struct drm_atomic_state *state;
5598 struct drm_plane_state *pstate;
5599 struct vop2_plane_state *vpstate;
5600 int ret = 0;
5601
5602 state = drm_atomic_state_alloc(plane->dev);
5603 if (!state)
5604 return -ENOMEM;
5605
5606 state->acquire_ctx = ctx;
5607 pstate = drm_atomic_get_plane_state(state, plane);
5608 if (IS_ERR(pstate)) {
5609 ret = PTR_ERR(pstate);
5610 goto fail;
5611 }
5612 vpstate = to_vop2_plane_state(pstate);
5613
5614 if ((pstate->crtc && pstate->crtc->cursor == plane) ||
5615 vpstate->async_commit)
5616 pstate->state->legacy_cursor_update = true;
5617
5618 ret = __drm_atomic_helper_disable_plane(plane, pstate);
5619 if (ret != 0)
5620 goto fail;
5621
5622 ret = drm_atomic_commit(state);
5623 fail:
5624 drm_atomic_state_put(state);
5625 return ret;
5626 }
5627
vop2_plane_destroy(struct drm_plane * plane)5628 static void vop2_plane_destroy(struct drm_plane *plane)
5629 {
5630 drm_plane_cleanup(plane);
5631 }
5632
vop2_atomic_plane_reset(struct drm_plane * plane)5633 static void vop2_atomic_plane_reset(struct drm_plane *plane)
5634 {
5635 struct vop2_plane_state *vpstate = to_vop2_plane_state(plane->state);
5636 struct vop2_win *win = to_vop2_win(plane);
5637
5638 if (plane->state && plane->state->fb)
5639 __drm_atomic_helper_plane_destroy_state(plane->state);
5640 kfree(vpstate);
5641 vpstate = kzalloc(sizeof(*vpstate), GFP_KERNEL);
5642 if (!vpstate)
5643 return;
5644
5645 __drm_atomic_helper_plane_reset(plane, &vpstate->base);
5646 vpstate->base.zpos = win->zpos;
5647 }
5648
vop2_atomic_plane_duplicate_state(struct drm_plane * plane)5649 static struct drm_plane_state *vop2_atomic_plane_duplicate_state(struct drm_plane *plane)
5650 {
5651 struct vop2_plane_state *old_vpstate;
5652 struct vop2_plane_state *vpstate;
5653
5654 if (WARN_ON(!plane->state))
5655 return NULL;
5656
5657 old_vpstate = to_vop2_plane_state(plane->state);
5658 vpstate = kmemdup(old_vpstate, sizeof(*vpstate), GFP_KERNEL);
5659 if (!vpstate)
5660 return NULL;
5661
5662 vpstate->hdr_in = 0;
5663 vpstate->hdr2sdr_en = 0;
5664
5665 __drm_atomic_helper_plane_duplicate_state(plane, &vpstate->base);
5666
5667 return &vpstate->base;
5668 }
5669
vop2_atomic_plane_destroy_state(struct drm_plane * plane,struct drm_plane_state * state)5670 static void vop2_atomic_plane_destroy_state(struct drm_plane *plane,
5671 struct drm_plane_state *state)
5672 {
5673 struct vop2_plane_state *vpstate = to_vop2_plane_state(state);
5674
5675 __drm_atomic_helper_plane_destroy_state(state);
5676
5677 kfree(vpstate);
5678 }
5679
vop2_atomic_plane_set_property(struct drm_plane * plane,struct drm_plane_state * state,struct drm_property * property,uint64_t val)5680 static int vop2_atomic_plane_set_property(struct drm_plane *plane,
5681 struct drm_plane_state *state,
5682 struct drm_property *property,
5683 uint64_t val)
5684 {
5685 struct rockchip_drm_private *private = plane->dev->dev_private;
5686 struct vop2_plane_state *vpstate = to_vop2_plane_state(state);
5687 struct vop2_win *win = to_vop2_win(plane);
5688
5689 if (property == private->eotf_prop) {
5690 vpstate->eotf = val;
5691 return 0;
5692 }
5693
5694 if (property == private->color_space_prop) {
5695 vpstate->color_space = val;
5696 return 0;
5697 }
5698
5699 if (property == private->async_commit_prop) {
5700 vpstate->async_commit = val;
5701 return 0;
5702 }
5703
5704 if (property == win->color_key_prop) {
5705 vpstate->color_key = val;
5706 return 0;
5707 }
5708
5709 DRM_ERROR("failed to set vop2 plane property id:%d, name:%s\n",
5710 property->base.id, property->name);
5711
5712 return -EINVAL;
5713 }
5714
vop2_atomic_plane_get_property(struct drm_plane * plane,const struct drm_plane_state * state,struct drm_property * property,uint64_t * val)5715 static int vop2_atomic_plane_get_property(struct drm_plane *plane,
5716 const struct drm_plane_state *state,
5717 struct drm_property *property,
5718 uint64_t *val)
5719 {
5720 struct rockchip_drm_private *private = plane->dev->dev_private;
5721 struct vop2_plane_state *vpstate = to_vop2_plane_state(state);
5722 struct vop2_win *win = to_vop2_win(plane);
5723
5724 if (property == private->eotf_prop) {
5725 *val = vpstate->eotf;
5726 return 0;
5727 }
5728
5729 if (property == private->color_space_prop) {
5730 *val = vpstate->color_space;
5731 return 0;
5732 }
5733
5734 if (property == private->async_commit_prop) {
5735 *val = vpstate->async_commit;
5736 return 0;
5737 }
5738
5739 if (property == private->share_id_prop) {
5740 int i;
5741 struct drm_mode_object *obj = &plane->base;
5742
5743 for (i = 0; i < obj->properties->count; i++) {
5744 if (obj->properties->properties[i] == property) {
5745 *val = obj->properties->values[i];
5746 return 0;
5747 }
5748 }
5749 }
5750
5751 if (property == win->color_key_prop) {
5752 *val = vpstate->color_key;
5753 return 0;
5754 }
5755
5756 DRM_ERROR("failed to get vop2 plane property id:%d, name:%s\n",
5757 property->base.id, property->name);
5758
5759 return -EINVAL;
5760 }
5761
5762 static const struct drm_plane_funcs vop2_plane_funcs = {
5763 .update_plane = rockchip_atomic_helper_update_plane,
5764 .disable_plane = rockchip_atomic_helper_disable_plane,
5765 .destroy = vop2_plane_destroy,
5766 .reset = vop2_atomic_plane_reset,
5767 .atomic_duplicate_state = vop2_atomic_plane_duplicate_state,
5768 .atomic_destroy_state = vop2_atomic_plane_destroy_state,
5769 .atomic_set_property = vop2_atomic_plane_set_property,
5770 .atomic_get_property = vop2_atomic_plane_get_property,
5771 .format_mod_supported = rockchip_vop2_mod_supported,
5772 };
5773
vop2_crtc_enable_vblank(struct drm_crtc * crtc)5774 static int vop2_crtc_enable_vblank(struct drm_crtc *crtc)
5775 {
5776 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5777 struct vop2 *vop2 = vp->vop2;
5778 const struct vop2_data *vop2_data = vop2->data;
5779 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
5780 const struct vop_intr *intr = vp_data->intr;
5781 unsigned long flags;
5782
5783 if (WARN_ON(!vop2->is_enabled))
5784 return -EPERM;
5785
5786 spin_lock_irqsave(&vop2->irq_lock, flags);
5787
5788 VOP_INTR_SET_TYPE(vop2, intr, clear, FS_FIELD_INTR, 1);
5789 VOP_INTR_SET_TYPE(vop2, intr, enable, FS_FIELD_INTR, 1);
5790
5791 spin_unlock_irqrestore(&vop2->irq_lock, flags);
5792
5793 return 0;
5794 }
5795
vop2_crtc_disable_vblank(struct drm_crtc * crtc)5796 static void vop2_crtc_disable_vblank(struct drm_crtc *crtc)
5797 {
5798 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5799 struct vop2 *vop2 = vp->vop2;
5800 const struct vop2_data *vop2_data = vop2->data;
5801 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
5802 const struct vop_intr *intr = vp_data->intr;
5803 unsigned long flags;
5804
5805 if (WARN_ON(!vop2->is_enabled))
5806 return;
5807
5808 spin_lock_irqsave(&vop2->irq_lock, flags);
5809
5810 VOP_INTR_SET_TYPE(vop2, intr, enable, FS_FIELD_INTR, 0);
5811
5812 spin_unlock_irqrestore(&vop2->irq_lock, flags);
5813 }
5814
vop2_crtc_cancel_pending_vblank(struct drm_crtc * crtc,struct drm_file * file_priv)5815 static void vop2_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
5816 struct drm_file *file_priv)
5817 {
5818 struct drm_device *drm = crtc->dev;
5819 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5820 struct drm_pending_vblank_event *e;
5821 unsigned long flags;
5822
5823 spin_lock_irqsave(&drm->event_lock, flags);
5824 e = vp->event;
5825 if (e && e->base.file_priv == file_priv) {
5826 vp->event = NULL;
5827
5828 //e->base.destroy(&e->base);//todo
5829 file_priv->event_space += sizeof(e->event);
5830 }
5831 spin_unlock_irqrestore(&drm->event_lock, flags);
5832 }
5833
vop2_crtc_line_flag_irq_is_enabled(struct vop2_video_port * vp)5834 static bool vop2_crtc_line_flag_irq_is_enabled(struct vop2_video_port *vp)
5835 {
5836 struct vop2 *vop2 = vp->vop2;
5837 const struct vop2_data *vop2_data = vop2->data;
5838 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
5839 const struct vop_intr *intr = vp_data->intr;
5840 uint32_t line_flag_irq;
5841 unsigned long flags;
5842
5843 spin_lock_irqsave(&vop2->irq_lock, flags);
5844 line_flag_irq = VOP_INTR_GET_TYPE(vop2, intr, enable, LINE_FLAG_INTR);
5845 spin_unlock_irqrestore(&vop2->irq_lock, flags);
5846
5847 return !!line_flag_irq;
5848 }
5849
vop2_crtc_line_flag_irq_enable(struct vop2_video_port * vp)5850 static void vop2_crtc_line_flag_irq_enable(struct vop2_video_port *vp)
5851 {
5852 struct vop2 *vop2 = vp->vop2;
5853 const struct vop2_data *vop2_data = vop2->data;
5854 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
5855 const struct vop_intr *intr = vp_data->intr;
5856 unsigned long flags;
5857
5858 if (!vop2->is_enabled)
5859 return;
5860
5861 spin_lock_irqsave(&vop2->irq_lock, flags);
5862 VOP_INTR_SET_TYPE(vop2, intr, clear, LINE_FLAG_INTR, 1);
5863 VOP_INTR_SET_TYPE(vop2, intr, enable, LINE_FLAG_INTR, 1);
5864 spin_unlock_irqrestore(&vop2->irq_lock, flags);
5865 }
5866
vop2_crtc_line_flag_irq_disable(struct vop2_video_port * vp)5867 static void vop2_crtc_line_flag_irq_disable(struct vop2_video_port *vp)
5868 {
5869 struct vop2 *vop2 = vp->vop2;
5870 const struct vop2_data *vop2_data = vop2->data;
5871 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
5872 const struct vop_intr *intr = vp_data->intr;
5873 unsigned long flags;
5874
5875 if (!vop2->is_enabled)
5876 return;
5877
5878 spin_lock_irqsave(&vop2->irq_lock, flags);
5879 VOP_INTR_SET_TYPE(vop2, intr, enable, LINE_FLAG_INTR, 0);
5880 spin_unlock_irqrestore(&vop2->irq_lock, flags);
5881 }
5882
vop3_mcu_mode_setup(struct drm_crtc * crtc)5883 static void vop3_mcu_mode_setup(struct drm_crtc *crtc)
5884 {
5885 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5886 struct vop2 *vop2 = vp->vop2;
5887
5888 VOP_MODULE_SET(vop2, vp, mcu_type, 1);
5889 VOP_MODULE_SET(vop2, vp, mcu_hold_mode, 1);
5890 VOP_MODULE_SET(vop2, vp, mcu_pix_total, vp->mcu_timing.mcu_pix_total);
5891 VOP_MODULE_SET(vop2, vp, mcu_cs_pst, vp->mcu_timing.mcu_cs_pst);
5892 VOP_MODULE_SET(vop2, vp, mcu_cs_pend, vp->mcu_timing.mcu_cs_pend);
5893 VOP_MODULE_SET(vop2, vp, mcu_rw_pst, vp->mcu_timing.mcu_rw_pst);
5894 VOP_MODULE_SET(vop2, vp, mcu_rw_pend, vp->mcu_timing.mcu_rw_pend);
5895 }
5896
vop3_mcu_bypass_mode_setup(struct drm_crtc * crtc)5897 static void vop3_mcu_bypass_mode_setup(struct drm_crtc *crtc)
5898 {
5899 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5900 struct vop2 *vop2 = vp->vop2;
5901
5902 VOP_MODULE_SET(vop2, vp, mcu_type, 1);
5903 VOP_MODULE_SET(vop2, vp, mcu_hold_mode, 1);
5904 VOP_MODULE_SET(vop2, vp, mcu_pix_total, 53);
5905 VOP_MODULE_SET(vop2, vp, mcu_cs_pst, 6);
5906 VOP_MODULE_SET(vop2, vp, mcu_cs_pend, 48);
5907 VOP_MODULE_SET(vop2, vp, mcu_rw_pst, 12);
5908 VOP_MODULE_SET(vop2, vp, mcu_rw_pend, 30);
5909 }
5910
vop3_mode_done(struct vop2_video_port * vp)5911 static u32 vop3_mode_done(struct vop2_video_port *vp)
5912 {
5913 return VOP_MODULE_GET(vp->vop2, vp, out_mode);
5914 }
5915
vop3_set_out_mode(struct drm_crtc * crtc,u32 out_mode)5916 static void vop3_set_out_mode(struct drm_crtc *crtc, u32 out_mode)
5917 {
5918 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5919 struct vop2 *vop2 = vp->vop2;
5920 int ret;
5921 u32 val;
5922
5923 VOP_MODULE_SET(vop2, vp, out_mode, out_mode);
5924 vop2_cfg_done(crtc);
5925 ret = readx_poll_timeout(vop3_mode_done, vp, val, val == out_mode,
5926 1000, 500 * 1000);
5927 if (ret)
5928 dev_err(vop2->dev, "wait mode 0x%x timeout\n", out_mode);
5929 }
5930
vop3_crtc_send_mcu_cmd(struct drm_crtc * crtc,u32 type,u32 value)5931 static void vop3_crtc_send_mcu_cmd(struct drm_crtc *crtc, u32 type, u32 value)
5932 {
5933 struct drm_crtc_state *crtc_state;
5934 struct drm_display_mode *adjusted_mode;
5935 struct vop2_video_port *vp;
5936 struct vop2 *vop2;
5937
5938 if (!crtc)
5939 return;
5940
5941 crtc_state = crtc->state;
5942 adjusted_mode = &crtc_state->adjusted_mode;
5943 vp = to_vop2_video_port(crtc);
5944 vop2 = vp->vop2;
5945
5946 /*
5947 * 1.set mcu bypass mode timing.
5948 * 2.set dclk rate to 150M.
5949 */
5950 if ((type == MCU_SETBYPASS) && value) {
5951 vop3_mcu_bypass_mode_setup(crtc);
5952 clk_set_rate(vp->dclk, 150000000);
5953 }
5954
5955 mutex_lock(&vop2->vop2_lock);
5956 if (vop2 && vop2->is_enabled) {
5957 switch (type) {
5958 case MCU_WRCMD:
5959 VOP_MODULE_SET(vop2, vp, mcu_rs, 0);
5960 VOP_MODULE_SET(vop2, vp, mcu_rw_bypass_port, value);
5961 VOP_MODULE_SET(vop2, vp, mcu_rs, 1);
5962 break;
5963 case MCU_WRDATA:
5964 VOP_MODULE_SET(vop2, vp, mcu_rs, 1);
5965 VOP_MODULE_SET(vop2, vp, mcu_rw_bypass_port, value);
5966 break;
5967 case MCU_SETBYPASS:
5968 VOP_MODULE_SET(vop2, vp, mcu_bypass, value ? 1 : 0);
5969 break;
5970 default:
5971 break;
5972 }
5973 }
5974 mutex_unlock(&vop2->vop2_lock);
5975
5976 /*
5977 * 1.restore mcu data mode timing.
5978 * 2.restore dclk rate to crtc_clock.
5979 */
5980 if ((type == MCU_SETBYPASS) && !value) {
5981 vop3_mcu_mode_setup(crtc);
5982 clk_set_rate(vp->dclk, adjusted_mode->crtc_clock * 1000);
5983 }
5984 }
5985
vop2_crtc_wait_vact_end(struct drm_crtc * crtc,unsigned int mstimeout)5986 static int vop2_crtc_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
5987 {
5988 struct vop2_video_port *vp = to_vop2_video_port(crtc);
5989 struct vop2 *vop2 = vp->vop2;
5990 unsigned long jiffies_left;
5991 int ret = 0;
5992
5993 if (!vop2->is_enabled)
5994 return -ENODEV;
5995
5996 mutex_lock(&vop2->vop2_lock);
5997
5998 if (vop2_crtc_line_flag_irq_is_enabled(vp)) {
5999 ret = -EBUSY;
6000 goto out;
6001 }
6002
6003 reinit_completion(&vp->line_flag_completion);
6004 vop2_crtc_line_flag_irq_enable(vp);
6005 jiffies_left = wait_for_completion_timeout(&vp->line_flag_completion,
6006 msecs_to_jiffies(mstimeout));
6007 vop2_crtc_line_flag_irq_disable(vp);
6008
6009 if (jiffies_left == 0) {
6010 DRM_DEV_ERROR(vop2->dev, "timeout waiting for lineflag IRQ\n");
6011 ret = -ETIMEDOUT;
6012 goto out;
6013 }
6014
6015 out:
6016 mutex_unlock(&vop2->vop2_lock);
6017 return ret;
6018 }
6019
vop2_crtc_enable_line_flag_event(struct drm_crtc * crtc,uint32_t line)6020 static int vop2_crtc_enable_line_flag_event(struct drm_crtc *crtc, uint32_t line)
6021 {
6022 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6023 struct vop2 *vop2 = vp->vop2;
6024 const struct vop2_data *vop2_data = vop2->data;
6025 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
6026 const struct vop_intr *intr = vp_data->intr;
6027 unsigned long flags;
6028
6029 if (WARN_ON(!vop2->is_enabled))
6030 return -EPERM;
6031
6032 spin_lock_irqsave(&vop2->irq_lock, flags);
6033
6034 VOP_INTR_SET(vop2, intr, line_flag_num[1], line);
6035
6036 VOP_INTR_SET_TYPE(vop2, intr, clear, LINE_FLAG1_INTR, 1);
6037 VOP_INTR_SET_TYPE(vop2, intr, enable, LINE_FLAG1_INTR, 1);
6038
6039 spin_unlock_irqrestore(&vop2->irq_lock, flags);
6040
6041 return 0;
6042 }
6043
vop2_crtc_disable_line_flag_event(struct drm_crtc * crtc)6044 static void vop2_crtc_disable_line_flag_event(struct drm_crtc *crtc)
6045 {
6046 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6047 struct vop2 *vop2 = vp->vop2;
6048 const struct vop2_data *vop2_data = vop2->data;
6049 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
6050 const struct vop_intr *intr = vp_data->intr;
6051 unsigned long flags;
6052
6053 if (WARN_ON(!vop2->is_enabled))
6054 return;
6055
6056 spin_lock_irqsave(&vop2->irq_lock, flags);
6057
6058 VOP_INTR_SET_TYPE(vop2, intr, enable, LINE_FLAG1_INTR, 0);
6059
6060 spin_unlock_irqrestore(&vop2->irq_lock, flags);
6061 }
6062
vop2_crtc_get_inital_acm_info(struct drm_crtc * crtc)6063 static int vop2_crtc_get_inital_acm_info(struct drm_crtc *crtc)
6064 {
6065 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6066 struct vop2 *vop2 = vp->vop2;
6067 struct post_acm *acm = &vp->acm_info;
6068 s16 *lut_y;
6069 s16 *lut_h;
6070 s16 *lut_s;
6071 u32 value;
6072 int i;
6073
6074 value = readl(vop2->acm_regs + RK3528_ACM_CTRL);
6075 acm->acm_enable = value & 0x1;
6076 value = readl(vop2->acm_regs + RK3528_ACM_DELTA_RANGE);
6077 acm->y_gain = value & 0x3ff;
6078 acm->h_gain = (value >> 10) & 0x3ff;
6079 acm->s_gain = (value >> 20) & 0x3ff;
6080
6081 lut_y = &acm->gain_lut_hy[0];
6082 lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH];
6083 lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2];
6084 for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) {
6085 value = readl(vop2->acm_regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2));
6086 lut_y[i] = value & 0xff;
6087 lut_h[i] = (value >> 8) & 0xff;
6088 lut_s[i] = (value >> 16) & 0xff;
6089 }
6090
6091 lut_y = &acm->gain_lut_hs[0];
6092 lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH];
6093 lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2];
6094 for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) {
6095 value = readl(vop2->acm_regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2));
6096 lut_y[i] = value & 0xff;
6097 lut_h[i] = (value >> 8) & 0xff;
6098 lut_s[i] = (value >> 16) & 0xff;
6099 }
6100
6101 lut_y = &acm->delta_lut_h[0];
6102 lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH];
6103 lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2];
6104 for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) {
6105 value = readl(vop2->acm_regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2));
6106 lut_y[i] = value & 0x3ff;
6107 lut_h[i] = (value >> 12) & 0xff;
6108 lut_s[i] = (value >> 20) & 0x3ff;
6109 }
6110
6111 return 0;
6112 }
6113
vop2_crtc_loader_protect(struct drm_crtc * crtc,bool on,void * data)6114 static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data)
6115 {
6116 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6117 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
6118 struct vop2 *vop2 = vp->vop2;
6119 struct rockchip_drm_private *private = crtc->dev->dev_private;
6120 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
6121 struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
6122 struct drm_crtc_state *crtc_state;
6123 struct drm_display_mode *mode;
6124 struct vop2_win *win, *splice_win;
6125 struct vop2_extend_pll *ext_pll;
6126 struct clk *parent_clk;
6127 const char *clk_name;
6128
6129 if (on == vp->loader_protect)
6130 return 0;
6131
6132 if (on) {
6133 vp->loader_protect = true;
6134 vop2->active_vp_mask |= BIT(vp->id);
6135 vop2_set_system_status(vop2);
6136 vop2_initial(crtc);
6137 if (crtc->primary) {
6138 win = to_vop2_win(crtc->primary);
6139 if (VOP_WIN_GET(vop2, win, enable)) {
6140 if (win->pd) {
6141 win->pd->ref_count++;
6142 win->pd->vp_mask |= BIT(vp->id);
6143 }
6144
6145 vp->enabled_win_mask |= BIT(win->phys_id);
6146 crtc_state = drm_atomic_get_crtc_state(crtc->state->state, crtc);
6147 mode = &crtc_state->adjusted_mode;
6148 if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
6149 vcstate->splice_mode = true;
6150 splice_win = vop2_find_win_by_phys_id(vop2,
6151 win->splice_win_id);
6152 splice_win->splice_mode_right = true;
6153 splice_win->left_win = win;
6154 win->splice_win = splice_win;
6155 splice_vp->win_mask |= BIT(splice_win->phys_id);
6156 splice_win->vp_mask = BIT(splice_vp->id);
6157 vop2->active_vp_mask |= BIT(splice_vp->id);
6158 vp->enabled_win_mask |= BIT(splice_win->phys_id);
6159
6160 if (splice_win->pd &&
6161 VOP_WIN_GET(vop2, splice_win, enable)) {
6162 splice_win->pd->ref_count++;
6163 splice_win->pd->vp_mask |= BIT(splice_vp->id);
6164 }
6165 }
6166 }
6167 }
6168 parent_clk = clk_get_parent(vp->dclk);
6169 clk_name = __clk_get_name(parent_clk);
6170 if (!strcmp(clk_name, "clk_hdmiphy_pixel0")) {
6171 ext_pll = vop2_extend_clk_find_by_name(vop2, "hdmi0_phy_pll");
6172 if (ext_pll)
6173 ext_pll->vp_mask |= BIT(vp->id);
6174 } else if (!strcmp(clk_name, "clk_hdmiphy_pixel1")) {
6175 ext_pll = vop2_extend_clk_find_by_name(vop2, "hdmi1_phy_pll");
6176 if (ext_pll)
6177 ext_pll->vp_mask |= BIT(vp->id);
6178 }
6179 drm_crtc_vblank_on(crtc);
6180 if (is_vop3(vop2)) {
6181 if (vp_data->feature & (VOP_FEATURE_POST_ACM))
6182 vop2_crtc_get_inital_acm_info(crtc);
6183 if (data && (vp_data->feature & VOP_FEATURE_POST_CSC))
6184 memcpy(&vp->csc_info, data, sizeof(struct post_csc));
6185 }
6186 if (private->cubic_lut[vp->id].enable) {
6187 dma_addr_t cubic_lut_mst;
6188 struct loader_cubic_lut *cubic_lut = &private->cubic_lut[vp->id];
6189
6190 cubic_lut_mst = cubic_lut->offset + private->cubic_lut_dma_addr;
6191 VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst);
6192 }
6193 } else {
6194 vop2_crtc_atomic_disable(crtc, NULL);
6195 }
6196
6197 return 0;
6198 }
6199
6200 #define DEBUG_PRINT(args...) \
6201 do { \
6202 if (s) \
6203 seq_printf(s, args); \
6204 else \
6205 pr_err(args); \
6206 } while (0)
6207
vop2_plane_info_dump(struct seq_file * s,struct drm_plane * plane)6208 static int vop2_plane_info_dump(struct seq_file *s, struct drm_plane *plane)
6209 {
6210 struct vop2_win *win = to_vop2_win(plane);
6211 struct drm_plane_state *pstate = plane->state;
6212 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
6213 struct drm_rect *src, *dest;
6214 struct drm_framebuffer *fb = pstate->fb;
6215 struct drm_format_name_buf format_name;
6216 struct drm_gem_object *obj;
6217 struct rockchip_gem_object *rk_obj;
6218 dma_addr_t fb_addr;
6219
6220 int i;
6221
6222 DEBUG_PRINT(" %s: %s\n", win->name, pstate->crtc ? "ACTIVE" : "DISABLED");
6223 if (!fb)
6224 return 0;
6225
6226 src = &vpstate->src;
6227 dest = &vpstate->dest;
6228
6229 DEBUG_PRINT("\twin_id: %d\n", win->win_id);
6230
6231 drm_get_format_name(fb->format->format, &format_name);
6232 DEBUG_PRINT("\tformat: %s%s%s[%d] color_space[%d] glb_alpha[0x%x]\n",
6233 format_name.str,
6234 modifier_to_string(fb->modifier),
6235 vpstate->eotf ? " HDR" : " SDR", vpstate->eotf,
6236 vpstate->color_space, vpstate->global_alpha);
6237 DEBUG_PRINT("\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n",
6238 vpstate->xmirror_en, vpstate->ymirror_en, vpstate->rotate_90_en,
6239 vpstate->rotate_270_en);
6240 DEBUG_PRINT("\tcsc: y2r[%d] r2y[%d] csc mode[%d]\n",
6241 vpstate->y2r_en, vpstate->r2y_en,
6242 vpstate->csc_mode);
6243 DEBUG_PRINT("\tzpos: %d\n", vpstate->zpos);
6244 DEBUG_PRINT("\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16,
6245 src->y1 >> 16, drm_rect_width(src) >> 16,
6246 drm_rect_height(src) >> 16);
6247 DEBUG_PRINT("\tdst: pos[%d, %d] rect[%d x %d]\n", dest->x1, dest->y1,
6248 drm_rect_width(dest), drm_rect_height(dest));
6249
6250 for (i = 0; i < fb->format->num_planes; i++) {
6251 obj = fb->obj[0];
6252 rk_obj = to_rockchip_obj(obj);
6253 fb_addr = rk_obj->dma_addr + fb->offsets[0];
6254
6255 DEBUG_PRINT("\tbuf[%d]: addr: %pad pitch: %d offset: %d\n",
6256 i, &fb_addr, fb->pitches[i], fb->offsets[i]);
6257 }
6258
6259 return 0;
6260 }
6261
vop2_dump_connector_on_crtc(struct drm_crtc * crtc,struct seq_file * s)6262 static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct seq_file *s)
6263 {
6264 struct drm_connector_list_iter conn_iter;
6265 struct drm_connector *connector;
6266
6267 drm_connector_list_iter_begin(crtc->dev, &conn_iter);
6268 drm_for_each_connector_iter(connector, &conn_iter) {
6269 if (crtc->state->connector_mask & drm_connector_mask(connector))
6270 DEBUG_PRINT(" Connector: %s\n", connector->name);
6271
6272 }
6273 drm_connector_list_iter_end(&conn_iter);
6274 }
6275
vop2_crtc_debugfs_dump(struct drm_crtc * crtc,struct seq_file * s)6276 static int vop2_crtc_debugfs_dump(struct drm_crtc *crtc, struct seq_file *s)
6277 {
6278 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6279 struct drm_crtc_state *crtc_state = crtc->state;
6280 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
6281 struct rockchip_crtc_state *state = to_rockchip_crtc_state(crtc->state);
6282 bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
6283 struct drm_plane *plane;
6284
6285 DEBUG_PRINT("Video Port%d: %s\n", vp->id, crtc_state->active ? "ACTIVE" : "DISABLED");
6286
6287 if (!crtc_state->active)
6288 return 0;
6289
6290 vop2_dump_connector_on_crtc(crtc, s);
6291 DEBUG_PRINT("\tbus_format[%x]: %s\n", state->bus_format,
6292 drm_get_bus_format_name(state->bus_format));
6293 DEBUG_PRINT("\toverlay_mode[%d] output_mode[%x]",
6294 state->yuv_overlay, state->output_mode);
6295 DEBUG_PRINT(" color_space[%d], eotf:%d\n",
6296 state->color_space, state->eotf);
6297 DEBUG_PRINT(" Display mode: %dx%d%s%d\n",
6298 mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
6299 drm_mode_vrefresh(mode));
6300 DEBUG_PRINT("\tclk[%d] real_clk[%d] type[%x] flag[%x]\n",
6301 mode->clock, mode->crtc_clock, mode->type, mode->flags);
6302 DEBUG_PRINT("\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
6303 mode->hsync_end, mode->htotal);
6304 DEBUG_PRINT("\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
6305 mode->vsync_end, mode->vtotal);
6306
6307 drm_atomic_crtc_for_each_plane(plane, crtc) {
6308 vop2_plane_info_dump(s, plane);
6309 }
6310
6311 return 0;
6312 }
6313
vop2_crtc_regs_dump(struct drm_crtc * crtc,struct seq_file * s)6314 static void vop2_crtc_regs_dump(struct drm_crtc *crtc, struct seq_file *s)
6315 {
6316 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6317 struct vop2 *vop2 = vp->vop2;
6318 const struct vop2_data *vop2_data = vop2->data;
6319 struct drm_crtc_state *cstate = crtc->state;
6320 const struct vop_dump_regs *regs = vop2->data->dump_regs;
6321 uint32_t buf[68];
6322 uint32_t len = ARRAY_SIZE(buf);
6323 unsigned int n, i, j;
6324 resource_size_t offset_addr;
6325 uint32_t base;
6326 struct drm_crtc *first_active_crtc = NULL;
6327
6328 if (!cstate->active)
6329 return;
6330
6331 /* only need to dump once at first active crtc for vop2 */
6332 for (i = 0; i < vop2_data->nr_vps; i++) {
6333 if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
6334 first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
6335 break;
6336 }
6337 }
6338 if (first_active_crtc != crtc)
6339 return;
6340
6341 n = vop2->data->dump_regs_size;
6342 for (i = 0; i < n; i++) {
6343 base = regs[i].offset;
6344 offset_addr = vop2->res->start + base;
6345 DEBUG_PRINT("\n%s:\n", regs[i].name);
6346 for (j = 0; j < len;) {
6347 DEBUG_PRINT("%08x: %08x %08x %08x %08x\n", (u32)offset_addr + j * 4,
6348 vop2_readl(vop2, base + (4 * j)),
6349 vop2_readl(vop2, base + (4 * (j + 1))),
6350 vop2_readl(vop2, base + (4 * (j + 2))),
6351 vop2_readl(vop2, base + (4 * (j + 3))));
6352 j += 4;
6353 }
6354 }
6355 }
6356
vop2_crtc_active_regs_dump(struct drm_crtc * crtc,struct seq_file * s)6357 static void vop2_crtc_active_regs_dump(struct drm_crtc *crtc, struct seq_file *s)
6358 {
6359 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6360 struct vop2 *vop2 = vp->vop2;
6361 const struct vop2_data *vop2_data = vop2->data;
6362 struct drm_crtc_state *cstate = crtc->state;
6363 const struct vop_dump_regs *regs = vop2->data->dump_regs;
6364 uint32_t buf[68];
6365 uint32_t len = ARRAY_SIZE(buf);
6366 unsigned int n, i, j;
6367 resource_size_t offset_addr;
6368 uint32_t base;
6369 struct drm_crtc *first_active_crtc = NULL;
6370
6371 if (!cstate->active)
6372 return;
6373
6374 /* only need to dump once at first active crtc for vop2 */
6375 for (i = 0; i < vop2_data->nr_vps; i++) {
6376 if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
6377 first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
6378 break;
6379 }
6380 }
6381 if (first_active_crtc != crtc)
6382 return;
6383
6384 n = vop2->data->dump_regs_size;
6385 for (i = 0; i < n; i++) {
6386 if (regs[i].state.mask &&
6387 REG_GET(vop2, regs[i].state) != regs[i].enable_state)
6388 continue;
6389 base = regs[i].offset;
6390 offset_addr = vop2->res->start + base;
6391 DEBUG_PRINT("\n%s:\n", regs[i].name);
6392 for (j = 0; j < len;) {
6393 DEBUG_PRINT("%08x: %08x %08x %08x %08x\n", (u32)offset_addr + j * 4,
6394 vop2_readl(vop2, base + (4 * j)),
6395 vop2_readl(vop2, base + (4 * (j + 1))),
6396 vop2_readl(vop2, base + (4 * (j + 2))),
6397 vop2_readl(vop2, base + (4 * (j + 3))));
6398 j += 4;
6399 }
6400 }
6401 }
6402
vop2_gamma_show(struct seq_file * s,void * data)6403 static int vop2_gamma_show(struct seq_file *s, void *data)
6404 {
6405 struct drm_info_node *node = s->private;
6406 struct vop2 *vop2 = node->info_ent->data;
6407 int i, j;
6408
6409 for (i = 0; i < vop2->data->nr_vps; i++) {
6410 struct vop2_video_port *vp = &vop2->vps[i];
6411
6412 if (!vp->lut || !vp->gamma_lut_active ||
6413 !vop2->lut_regs || !vp->rockchip_crtc.crtc.state->enable) {
6414 DEBUG_PRINT("Video port%d gamma disabled\n", vp->id);
6415 continue;
6416 }
6417 DEBUG_PRINT("Video port%d gamma:\n", vp->id);
6418 for (j = 0; j < vp->gamma_lut_len; j++) {
6419 if (j % 8 == 0)
6420 DEBUG_PRINT("\n");
6421 DEBUG_PRINT("0x%08x ", vp->lut[j]);
6422 }
6423 DEBUG_PRINT("\n");
6424 }
6425
6426 return 0;
6427 }
6428
vop2_cubic_lut_show(struct seq_file * s,void * data)6429 static int vop2_cubic_lut_show(struct seq_file *s, void *data)
6430 {
6431 struct drm_info_node *node = s->private;
6432 struct vop2 *vop2 = node->info_ent->data;
6433 struct rockchip_drm_private *private = vop2->drm_dev->dev_private;
6434 int i, j;
6435
6436 for (i = 0; i < vop2->data->nr_vps; i++) {
6437 struct vop2_video_port *vp = &vop2->vps[i];
6438
6439 if ((!vp->cubic_lut_gem_obj && !private->cubic_lut[vp->id].enable) ||
6440 !vp->cubic_lut || !vp->rockchip_crtc.crtc.state->enable) {
6441 DEBUG_PRINT("Video port%d cubic lut disabled\n", vp->id);
6442 continue;
6443 }
6444 DEBUG_PRINT("Video port%d cubic lut:\n", vp->id);
6445 for (j = 0; j < vp->cubic_lut_len; j++) {
6446 DEBUG_PRINT("%04d: 0x%04x 0x%04x 0x%04x\n", j,
6447 vp->cubic_lut[j].red,
6448 vp->cubic_lut[j].green,
6449 vp->cubic_lut[j].blue);
6450 }
6451 DEBUG_PRINT("\n");
6452 }
6453
6454 return 0;
6455 }
6456
6457 #undef DEBUG_PRINT
6458
6459 static struct drm_info_list vop2_debugfs_files[] = {
6460 { "gamma_lut", vop2_gamma_show, 0, NULL },
6461 { "cubic_lut", vop2_cubic_lut_show, 0, NULL },
6462 };
6463
vop2_crtc_debugfs_init(struct drm_minor * minor,struct drm_crtc * crtc)6464 static int vop2_crtc_debugfs_init(struct drm_minor *minor, struct drm_crtc *crtc)
6465 {
6466 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6467 struct vop2 *vop2 = vp->vop2;
6468 int ret, i;
6469 char name[12];
6470
6471 snprintf(name, sizeof(name), "video_port%d", vp->id);
6472 vop2->debugfs = debugfs_create_dir(name, minor->debugfs_root);
6473 if (!vop2->debugfs)
6474 return -ENOMEM;
6475
6476 vop2->debugfs_files = kmemdup(vop2_debugfs_files, sizeof(vop2_debugfs_files),
6477 GFP_KERNEL);
6478 if (!vop2->debugfs_files) {
6479 ret = -ENOMEM;
6480 goto remove;
6481 }
6482 #if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
6483 rockchip_drm_add_dump_buffer(crtc, vop2->debugfs);
6484 rockchip_drm_debugfs_add_color_bar(crtc, vop2->debugfs);
6485 #endif
6486 for (i = 0; i < ARRAY_SIZE(vop2_debugfs_files); i++)
6487 vop2->debugfs_files[i].data = vop2;
6488
6489 drm_debugfs_create_files(vop2->debugfs_files,
6490 ARRAY_SIZE(vop2_debugfs_files),
6491 vop2->debugfs,
6492 minor);
6493 return 0;
6494 remove:
6495 debugfs_remove(vop2->debugfs);
6496 vop2->debugfs = NULL;
6497 return ret;
6498 }
6499
6500 static enum drm_mode_status
vop2_crtc_mode_valid(struct drm_crtc * crtc,const struct drm_display_mode * mode)6501 vop2_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
6502 {
6503 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
6504 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6505 struct vop2 *vop2 = vp->vop2;
6506 const struct vop2_data *vop2_data = vop2->data;
6507 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
6508 int request_clock = mode->clock;
6509 int clock;
6510 unsigned long aclk_rate;
6511 uint8_t active_vp_mask = vop2->active_vp_mask;
6512
6513 /*
6514 * For RK3588, VP0 and VP1 will be both used in splice mode. All display
6515 * modes of the right VP should be set as invalid when vop2 is working in
6516 * splice mode.
6517 */
6518 if (vp->splice_mode_right)
6519 return MODE_BAD;
6520
6521 if ((active_vp_mask & BIT(ROCKCHIP_VOP_VP1)) && !vcstate->splice_mode &&
6522 mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
6523 DRM_DEV_DEBUG(vop2->dev, "can not support resolution %dx%d, vp1 is busy\n",
6524 mode->hdisplay, mode->vdisplay);
6525 return MODE_BAD;
6526 }
6527
6528 if (mode->hdisplay > vp_data->max_output.width)
6529 return MODE_BAD_HVALUE;
6530
6531 if (mode->flags & DRM_MODE_FLAG_DBLCLK || vcstate->output_if & VOP_OUTPUT_IF_BT656)
6532 request_clock *= 2;
6533
6534 aclk_rate = clk_get_rate(vop2->aclk) / 1000;
6535
6536 if (request_clock > VOP2_MAX_DCLK_RATE && aclk_rate <= VOP2_COMMON_ACLK_RATE)
6537 return MODE_BAD;
6538
6539 if ((request_clock <= VOP2_MAX_DCLK_RATE) &&
6540 (vop2_extend_clk_find_by_name(vop2, "hdmi0_phy_pll") ||
6541 vop2_extend_clk_find_by_name(vop2, "hdmi1_phy_pll"))) {
6542 clock = request_clock;
6543 } else {
6544 if (request_clock > VOP2_MAX_DCLK_RATE)
6545 request_clock = request_clock >> 2;
6546 clock = clk_round_rate(vp->dclk, request_clock * 1000) / 1000;
6547 }
6548
6549 /*
6550 * Hdmi or DisplayPort request a Accurate clock.
6551 */
6552 if (vcstate->output_type == DRM_MODE_CONNECTOR_HDMIA ||
6553 vcstate->output_type == DRM_MODE_CONNECTOR_DisplayPort)
6554 if (clock != request_clock)
6555 return MODE_CLOCK_RANGE;
6556
6557 return MODE_OK;
6558 }
6559
6560 struct vop2_bandwidth {
6561 size_t bandwidth;
6562 int y1;
6563 int y2;
6564 };
6565
vop2_bandwidth_cmp(const void * a,const void * b)6566 static int vop2_bandwidth_cmp(const void *a, const void *b)
6567 {
6568 struct vop2_bandwidth *pa = (struct vop2_bandwidth *)a;
6569 struct vop2_bandwidth *pb = (struct vop2_bandwidth *)b;
6570
6571 return pa->y1 - pb->y2;
6572 }
6573
vop2_plane_line_bandwidth(struct drm_plane_state * pstate)6574 static size_t vop2_plane_line_bandwidth(struct drm_plane_state *pstate)
6575 {
6576 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
6577 struct drm_framebuffer *fb = pstate->fb;
6578 struct drm_rect *dst = &vpstate->dest;
6579 struct drm_rect *src = &vpstate->src;
6580 int bpp = rockchip_drm_get_bpp(fb->format);
6581 int src_width = drm_rect_width(src) >> 16;
6582 int src_height = drm_rect_height(src) >> 16;
6583 int dst_width = drm_rect_width(dst);
6584 int dst_height = drm_rect_height(dst);
6585 int vskiplines = scl_get_vskiplines(src_height, dst_height);
6586 size_t bandwidth;
6587
6588 if (src_width <= 0 || src_height <= 0 || dst_width <= 0 ||
6589 dst_height <= 0)
6590 return 0;
6591
6592 bandwidth = src_width * bpp / 8;
6593
6594 bandwidth = bandwidth * src_width / dst_width;
6595 bandwidth = bandwidth * src_height / dst_height;
6596 if (vskiplines == 2 && vpstate->afbc_en == 0)
6597 bandwidth /= 2;
6598 else if (vskiplines == 4 && vpstate->afbc_en == 0)
6599 bandwidth /= 4;
6600
6601 return bandwidth;
6602 }
6603
vop2_calc_max_bandwidth(struct vop2_bandwidth * bw,int start,int count,int y2)6604 static u64 vop2_calc_max_bandwidth(struct vop2_bandwidth *bw, int start,
6605 int count, int y2)
6606 {
6607 u64 max_bandwidth = 0;
6608 int i;
6609
6610 for (i = start; i < count; i++) {
6611 u64 bandwidth = 0;
6612
6613 if (bw[i].y1 > y2)
6614 continue;
6615 bandwidth = bw[i].bandwidth;
6616 bandwidth += vop2_calc_max_bandwidth(bw, i + 1, count,
6617 min(bw[i].y2, y2));
6618
6619 if (bandwidth > max_bandwidth)
6620 max_bandwidth = bandwidth;
6621 }
6622
6623 return max_bandwidth;
6624 }
6625
vop2_crtc_bandwidth(struct drm_crtc * crtc,struct drm_crtc_state * crtc_state,struct dmcfreq_vop_info * vop_bw_info)6626 static size_t vop2_crtc_bandwidth(struct drm_crtc *crtc,
6627 struct drm_crtc_state *crtc_state,
6628 struct dmcfreq_vop_info *vop_bw_info)
6629 {
6630 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
6631 uint16_t htotal = adjusted_mode->crtc_htotal;
6632 uint16_t vdisplay = adjusted_mode->crtc_vdisplay;
6633 int clock = adjusted_mode->crtc_clock;
6634 struct drm_atomic_state *state = crtc_state->state;
6635 struct vop2_plane_state *vpstate;
6636 struct drm_plane_state *pstate;
6637 struct vop2_bandwidth *pbandwidth;
6638 struct drm_plane *plane;
6639 u64 line_bw_mbyte = 0;
6640 int8_t cnt = 0, plane_num = 0;
6641 int i = 0;
6642 #if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
6643 struct vop_dump_list *pos, *n;
6644 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6645 #endif
6646
6647 if (!htotal || !vdisplay)
6648 return 0;
6649
6650 #if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
6651 if (!vp->rockchip_crtc.vop_dump_list_init_flag) {
6652 INIT_LIST_HEAD(&vp->rockchip_crtc.vop_dump_list_head);
6653 vp->rockchip_crtc.vop_dump_list_init_flag = true;
6654 }
6655 list_for_each_entry_safe(pos, n, &vp->rockchip_crtc.vop_dump_list_head, entry) {
6656 list_del(&pos->entry);
6657 }
6658 if (vp->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
6659 vp->rockchip_crtc.vop_dump_times > 0) {
6660 vp->rockchip_crtc.frame_count++;
6661 }
6662 #endif
6663
6664 for_each_new_plane_in_state(state, plane, pstate, i) {
6665 if (pstate->crtc == crtc)
6666 plane_num++;
6667 }
6668
6669 vop_bw_info->plane_num += plane_num;
6670 pbandwidth = kmalloc_array(plane_num, sizeof(*pbandwidth),
6671 GFP_KERNEL);
6672 if (!pbandwidth)
6673 return -ENOMEM;
6674
6675 for_each_new_plane_in_state(state, plane, pstate, i) {
6676 int act_w, act_h, bpp, afbc_fac;
6677 int fps = drm_mode_vrefresh(adjusted_mode);
6678
6679 if (!pstate || pstate->crtc != crtc || !pstate->fb)
6680 continue;
6681
6682 /* This is an empirical value, if it's afbc format, the frame buffer size div 2 */
6683 afbc_fac = rockchip_afbc(plane, pstate->fb->modifier) ? 2 : 1;
6684
6685 vpstate = to_vop2_plane_state(pstate);
6686 pbandwidth[cnt].y1 = vpstate->dest.y1;
6687 pbandwidth[cnt].y2 = vpstate->dest.y2;
6688 pbandwidth[cnt++].bandwidth = vop2_plane_line_bandwidth(pstate) / afbc_fac;
6689
6690 act_w = drm_rect_width(&pstate->src) >> 16;
6691 act_h = drm_rect_height(&pstate->src) >> 16;
6692 if (pstate->fb->format->is_yuv && (act_w >= 3840 || act_h >= 3840))
6693 vop_bw_info->plane_num_4k++;
6694
6695 bpp = rockchip_drm_get_bpp(pstate->fb->format);
6696
6697 vop_bw_info->frame_bw_mbyte += act_w * act_h / 1000 * bpp / 8 * fps / 1000 / afbc_fac;
6698 }
6699
6700 sort(pbandwidth, cnt, sizeof(pbandwidth[0]), vop2_bandwidth_cmp, NULL);
6701
6702 line_bw_mbyte = vop2_calc_max_bandwidth(pbandwidth, 0, cnt, vdisplay);
6703 kfree(pbandwidth);
6704 /*
6705 * line_bandwidth(MB/s)
6706 * = line_bandwidth / line_time
6707 * = line_bandwidth(Byte) * clock(KHZ) / 1000 / htotal
6708 */
6709 line_bw_mbyte *= clock;
6710 do_div(line_bw_mbyte, htotal * 1000);
6711 vop_bw_info->line_bw_mbyte = line_bw_mbyte;
6712
6713 return 0;
6714 }
6715
vop2_crtc_close(struct drm_crtc * crtc)6716 static void vop2_crtc_close(struct drm_crtc *crtc)
6717 {
6718 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6719 struct vop2 *vop2 = vp->vop2;
6720
6721 if (!crtc)
6722 return;
6723
6724 mutex_lock(&vop2->vop2_lock);
6725 if (!vop2->is_enabled) {
6726 mutex_unlock(&vop2->vop2_lock);
6727 return;
6728 }
6729
6730 vop2_disable_all_planes_for_crtc(crtc);
6731 mutex_unlock(&vop2->vop2_lock);
6732 }
6733
vop2_crtc_te_handler(struct drm_crtc * crtc)6734 static void vop2_crtc_te_handler(struct drm_crtc *crtc)
6735 {
6736 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6737 struct vop2 *vop2 = vp->vop2;
6738
6739 if (!crtc || !crtc->state->active)
6740 return;
6741
6742 VOP_MODULE_SET(vop2, vp, edpi_wms_fs, 1);
6743 }
6744
vop2_crtc_set_color_bar(struct drm_crtc * crtc,enum rockchip_color_bar_mode mode)6745 static int vop2_crtc_set_color_bar(struct drm_crtc *crtc, enum rockchip_color_bar_mode mode)
6746 {
6747 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6748 struct vop2 *vop2 = vp->vop2;
6749 int ret = 0;
6750
6751 if (!crtc->state->active) {
6752 DRM_INFO("Video port%d disabled\n", vp->id);
6753 return -EINVAL;
6754 }
6755
6756 switch (mode) {
6757 case ROCKCHIP_COLOR_BAR_OFF:
6758 DRM_INFO("disable color bar in VP%d\n", vp->id);
6759 VOP_MODULE_SET(vop2, vp, color_bar_en, 0);
6760 vop2_cfg_done(crtc);
6761 break;
6762 case ROCKCHIP_COLOR_BAR_HORIZONTAL:
6763 DRM_INFO("enable horizontal color bar in VP%d\n", vp->id);
6764 VOP_MODULE_SET(vop2, vp, color_bar_mode, 0);
6765 VOP_MODULE_SET(vop2, vp, color_bar_en, 1);
6766 vop2_cfg_done(crtc);
6767 break;
6768 case ROCKCHIP_COLOR_BAR_VERTICAL:
6769 DRM_INFO("enable vertical color bar in VP%d\n", vp->id);
6770 VOP_MODULE_SET(vop2, vp, color_bar_mode, 1);
6771 VOP_MODULE_SET(vop2, vp, color_bar_en, 1);
6772 vop2_cfg_done(crtc);
6773 break;
6774 default:
6775 DRM_INFO("Unsupported color bar mode\n");
6776 ret = -EINVAL;
6777 break;
6778 }
6779
6780 return ret;
6781 }
6782
6783 static const struct rockchip_crtc_funcs private_crtc_funcs = {
6784 .loader_protect = vop2_crtc_loader_protect,
6785 .cancel_pending_vblank = vop2_crtc_cancel_pending_vblank,
6786 .debugfs_init = vop2_crtc_debugfs_init,
6787 .debugfs_dump = vop2_crtc_debugfs_dump,
6788 .regs_dump = vop2_crtc_regs_dump,
6789 .active_regs_dump = vop2_crtc_active_regs_dump,
6790 .bandwidth = vop2_crtc_bandwidth,
6791 .crtc_close = vop2_crtc_close,
6792 .te_handler = vop2_crtc_te_handler,
6793 .crtc_send_mcu_cmd = vop3_crtc_send_mcu_cmd,
6794 .wait_vact_end = vop2_crtc_wait_vact_end,
6795 .crtc_standby = vop2_crtc_standby,
6796 .crtc_set_color_bar = vop2_crtc_set_color_bar,
6797 };
6798
vop2_crtc_mode_fixup(struct drm_crtc * crtc,const struct drm_display_mode * mode,struct drm_display_mode * adj_mode)6799 static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc,
6800 const struct drm_display_mode *mode,
6801 struct drm_display_mode *adj_mode)
6802 {
6803 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6804 struct vop2 *vop2 = vp->vop2;
6805 struct drm_connector *connector;
6806 struct drm_connector_list_iter conn_iter;
6807 struct drm_crtc_state *new_crtc_state = container_of(mode, struct drm_crtc_state, mode);
6808 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(new_crtc_state);
6809
6810 /*
6811 * For RK3568 and RK3588, the hactive of video timing must
6812 * be 4-pixel aligned.
6813 */
6814 if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588) {
6815 if (adj_mode->hdisplay % 4) {
6816 u16 old_hdisplay = adj_mode->hdisplay;
6817 u16 align;
6818
6819 align = 4 - (adj_mode->hdisplay % 4);
6820 adj_mode->hdisplay += align;
6821 adj_mode->hsync_start += align;
6822 adj_mode->hsync_end += align;
6823 adj_mode->htotal += align;
6824
6825 DRM_WARN("VP%d: hactive need to be aligned with 4-pixel, %d -> %d\n",
6826 vp->id, old_hdisplay, adj_mode->hdisplay);
6827 }
6828 }
6829
6830 drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE);
6831
6832 if (mode->flags & DRM_MODE_FLAG_DBLCLK || vcstate->output_if & VOP_OUTPUT_IF_BT656)
6833 adj_mode->crtc_clock *= 2;
6834
6835 if (vp->mcu_timing.mcu_pix_total) {
6836 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_S888)
6837 adj_mode->crtc_clock *= 3;
6838 else if (vcstate->output_mode == ROCKCHIP_OUT_MODE_S888_DUMMY)
6839 adj_mode->crtc_clock *= 4;
6840 }
6841
6842 drm_connector_list_iter_begin(crtc->dev, &conn_iter);
6843 drm_for_each_connector_iter(connector, &conn_iter) {
6844 if ((new_crtc_state->connector_mask & drm_connector_mask(connector)) &&
6845 ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
6846 (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))) {
6847 drm_connector_list_iter_end(&conn_iter);
6848 return true;
6849 }
6850 }
6851 drm_connector_list_iter_end(&conn_iter);
6852
6853 if (adj_mode->crtc_clock <= VOP2_MAX_DCLK_RATE)
6854 adj_mode->crtc_clock = DIV_ROUND_UP(clk_round_rate(vp->dclk,
6855 adj_mode->crtc_clock * 1000), 1000);
6856 return true;
6857 }
6858
vop2_dither_setup(struct rockchip_crtc_state * vcstate,struct drm_crtc * crtc)6859 static void vop2_dither_setup(struct rockchip_crtc_state *vcstate, struct drm_crtc *crtc)
6860 {
6861 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6862 struct vop2 *vop2 = vp->vop2;
6863 bool pre_dither_down_en = false;
6864
6865 switch (vcstate->bus_format) {
6866 case MEDIA_BUS_FMT_RGB565_1X16:
6867 VOP_MODULE_SET(vop2, vp, dither_down_en, 1);
6868 VOP_MODULE_SET(vop2, vp, dither_down_mode, RGB888_TO_RGB565);
6869 pre_dither_down_en = true;
6870 break;
6871 case MEDIA_BUS_FMT_RGB666_1X18:
6872 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
6873 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
6874 VOP_MODULE_SET(vop2, vp, dither_down_en, 1);
6875 VOP_MODULE_SET(vop2, vp, dither_down_mode, RGB888_TO_RGB666);
6876 pre_dither_down_en = true;
6877 break;
6878 case MEDIA_BUS_FMT_YUYV8_1X16:
6879 case MEDIA_BUS_FMT_YUV8_1X24:
6880 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
6881 VOP_MODULE_SET(vop2, vp, dither_down_en, 0);
6882 pre_dither_down_en = true;
6883 break;
6884 case MEDIA_BUS_FMT_YUYV10_1X20:
6885 case MEDIA_BUS_FMT_YUV10_1X30:
6886 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
6887 case MEDIA_BUS_FMT_RGB101010_1X30:
6888 VOP_MODULE_SET(vop2, vp, dither_down_en, 0);
6889 pre_dither_down_en = false;
6890 break;
6891 case MEDIA_BUS_FMT_RGB888_3X8:
6892 case MEDIA_BUS_FMT_RGB888_DUMMY_4X8:
6893 case MEDIA_BUS_FMT_RGB888_1X24:
6894 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
6895 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
6896 default:
6897 VOP_MODULE_SET(vop2, vp, dither_down_en, 0);
6898 pre_dither_down_en = true;
6899 break;
6900 }
6901
6902 if (is_yuv_output(vcstate->bus_format))
6903 pre_dither_down_en = false;
6904
6905 VOP_MODULE_SET(vop2, vp, pre_dither_down_en, pre_dither_down_en);
6906 VOP_MODULE_SET(vop2, vp, dither_down_sel, DITHER_DOWN_ALLEGRO);
6907 }
6908
vop2_post_config(struct drm_crtc * crtc)6909 static void vop2_post_config(struct drm_crtc *crtc)
6910 {
6911 struct rockchip_crtc_state *vcstate =
6912 to_rockchip_crtc_state(crtc->state);
6913 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6914 struct vop2 *vop2 = vp->vop2;
6915 const struct vop2_data *vop2_data = vop2->data;
6916 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
6917 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
6918 u16 vtotal = mode->crtc_vtotal;
6919 u16 hdisplay = mode->crtc_hdisplay;
6920 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
6921 u16 vdisplay = mode->crtc_vdisplay;
6922 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
6923 u16 hsize = hdisplay * (vcstate->left_margin + vcstate->right_margin) / 200;
6924 u16 vsize = vdisplay * (vcstate->top_margin + vcstate->bottom_margin) / 200;
6925 u16 hact_end, vact_end;
6926 u32 val;
6927
6928 vsize = rounddown(vsize, 2);
6929 hsize = rounddown(hsize, 2);
6930 hact_st += hdisplay * (100 - vcstate->left_margin) / 200;
6931 hact_end = hact_st + hsize;
6932 val = hact_st << 16;
6933 val |= hact_end;
6934 VOP_MODULE_SET(vop2, vp, hpost_st_end, val);
6935 vact_st += vdisplay * (100 - vcstate->top_margin) / 200;
6936 vact_end = vact_st + vsize;
6937 val = vact_st << 16;
6938 val |= vact_end;
6939 VOP_MODULE_SET(vop2, vp, vpost_st_end, val);
6940 val = scl_cal_scale2(vdisplay, vsize) << 16;
6941 val |= scl_cal_scale2(hdisplay, hsize);
6942 VOP_MODULE_SET(vop2, vp, post_scl_factor, val);
6943
6944 #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0)
6945 #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1)
6946 VOP_MODULE_SET(vop2, vp, post_scl_ctrl,
6947 POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) |
6948 POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize));
6949 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
6950 u16 vact_st_f1 = vtotal + vact_st + 1;
6951 u16 vact_end_f1 = vact_st_f1 + vsize;
6952
6953 val = vact_st_f1 << 16 | vact_end_f1;
6954 VOP_MODULE_SET(vop2, vp, vpost_st_end_f1, val);
6955 }
6956
6957 /*
6958 * BCSH[R2Y] -> POST Linebuffer[post scale] -> the background R2Y will be deal by post_dsp_out_r2y
6959 *
6960 * POST Linebuffer[post scale] -> ACM[R2Y] -> the background R2Y will be deal by ACM[R2Y]
6961 */
6962 if (vp_data->feature & VOP_FEATURE_POST_ACM)
6963 VOP_MODULE_SET(vop2, vp, post_dsp_out_r2y, vcstate->yuv_overlay);
6964 else
6965 VOP_MODULE_SET(vop2, vp, post_dsp_out_r2y, is_yuv_output(vcstate->bus_format));
6966 }
6967
6968 /*
6969 * if adjusted mode update, return true, else return false
6970 */
vop2_crtc_mode_update(struct drm_crtc * crtc)6971 static bool vop2_crtc_mode_update(struct drm_crtc *crtc)
6972 {
6973 struct vop2_video_port *vp = to_vop2_video_port(crtc);
6974 struct vop2 *vop2 = vp->vop2;
6975 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
6976 u16 hsync_len = adjusted_mode->crtc_hsync_end -
6977 adjusted_mode->crtc_hsync_start;
6978 u16 hdisplay = adjusted_mode->crtc_hdisplay;
6979 u16 htotal = adjusted_mode->crtc_htotal;
6980 u16 hact_st = adjusted_mode->crtc_htotal -
6981 adjusted_mode->crtc_hsync_start;
6982 u16 hact_end = hact_st + hdisplay;
6983 u16 vdisplay = adjusted_mode->crtc_vdisplay;
6984 u16 vtotal = adjusted_mode->crtc_vtotal;
6985 u16 vsync_len = adjusted_mode->crtc_vsync_end -
6986 adjusted_mode->crtc_vsync_start;
6987 u16 vact_st = adjusted_mode->crtc_vtotal -
6988 adjusted_mode->crtc_vsync_start;
6989 u16 vact_end = vact_st + vdisplay;
6990 u32 htotal_sync = htotal << 16 | hsync_len;
6991 u32 hactive_st_end = hact_st << 16 | hact_end;
6992 u32 vactive_st_end = vact_st << 16 | vact_end;
6993 u32 crtc_clock = adjusted_mode->crtc_clock * 100;
6994
6995 if (htotal_sync != VOP_MODULE_GET(vop2, vp, htotal_pw) ||
6996 hactive_st_end != VOP_MODULE_GET(vop2, vp, hact_st_end) ||
6997 vtotal != VOP_MODULE_GET(vop2, vp, dsp_vtotal) ||
6998 vsync_len != VOP_MODULE_GET(vop2, vp, dsp_vs_end) ||
6999 vactive_st_end != VOP_MODULE_GET(vop2, vp, vact_st_end) ||
7000 crtc_clock != clk_get_rate(vp->dclk))
7001 return true;
7002
7003 return false;
7004 }
7005
vop2_cru_set_rate(struct vop2_clk * if_pixclk,struct vop2_clk * if_dclk)7006 static int vop2_cru_set_rate(struct vop2_clk *if_pixclk, struct vop2_clk *if_dclk)
7007 {
7008 int ret = 0;
7009
7010 if (if_pixclk) {
7011 ret = clk_set_rate(if_pixclk->hw.clk, if_pixclk->rate);
7012 if (ret < 0) {
7013 DRM_DEV_ERROR(if_pixclk->vop2->dev, "set %s to %ld failed: %d\n",
7014 clk_hw_get_name(&if_pixclk->hw), if_pixclk->rate, ret);
7015 return ret;
7016 }
7017 }
7018
7019 if (if_dclk) {
7020 ret = clk_set_rate(if_dclk->hw.clk, if_dclk->rate);
7021 if (ret < 0)
7022 DRM_DEV_ERROR(if_dclk->vop2->dev, "set %s to %ld failed %d\n",
7023 clk_hw_get_name(&if_dclk->hw), if_dclk->rate, ret);
7024 }
7025
7026 return ret;
7027 }
7028
vop2_set_dsc_clk(struct drm_crtc * crtc,u8 dsc_id)7029 static int vop2_set_dsc_clk(struct drm_crtc *crtc, u8 dsc_id)
7030 {
7031 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7032 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7033 struct vop2 *vop2 = vp->vop2;
7034 const struct vop2_data *vop2_data = vop2->data;
7035 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
7036 struct vop2_clk *dsc_txp_clk, *dsc_pxl_clk, *dsc_cds_clk, *dsc_txp_clk_parent;
7037 char clk_name[32];
7038 int ret = 0;
7039
7040 /* set clk parent */
7041 snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id);
7042 dsc_txp_clk = vop2_clk_get(vop2, dsc_data->dsc_txp_clk_src_name);
7043 dsc_txp_clk_parent = vop2_clk_get(vop2, clk_name);
7044 if (!dsc_txp_clk || !dsc_txp_clk_parent) {
7045 DRM_DEV_ERROR(vop2->dev, "failed to get dsc clk\n");
7046 return -ENODEV;
7047 }
7048 ret = clk_set_parent(dsc_txp_clk->hw.clk, dsc_txp_clk_parent->hw.clk);
7049 if (ret < 0) {
7050 DRM_DEV_ERROR(vop2->dev, "failed to set parent(%s) for %s: %d\n",
7051 __clk_get_name(dsc_txp_clk_parent->hw.clk),
7052 __clk_get_name(dsc_txp_clk->hw.clk), ret);
7053 return ret;
7054 }
7055
7056 /* set dsc txp clk rate */
7057 clk_set_rate(dsc_txp_clk->hw.clk, vcstate->dsc_txp_clk_rate);
7058
7059 /* set dsc pxl clk rate */
7060 dsc_pxl_clk = vop2_clk_get(vop2, dsc_data->dsc_pxl_clk_name);
7061 if (!dsc_pxl_clk) {
7062 DRM_DEV_ERROR(vop2->dev, "failed to get dsc_pxl_clk\n");
7063 return -ENODEV;
7064 }
7065 clk_set_rate(dsc_pxl_clk->hw.clk, vcstate->dsc_pxl_clk_rate);
7066
7067 /* set dsc cds clk rate */
7068 dsc_cds_clk = vop2_clk_get(vop2, dsc_data->dsc_cds_clk_name);
7069 if (!dsc_cds_clk) {
7070 DRM_DEV_ERROR(vop2->dev, "failed to get dsc_cds_clk\n");
7071 return -ENODEV;
7072 }
7073 clk_set_rate(dsc_cds_clk->hw.clk, vcstate->dsc_cds_clk_rate);
7074
7075 return 0;
7076 }
7077
vop2_calc_if_clk(struct drm_crtc * crtc,const struct vop2_connector_if_data * if_data,struct vop2_clk * if_pixclk,struct vop2_clk * if_dclk,int conn_id)7078 static int vop2_calc_if_clk(struct drm_crtc *crtc, const struct vop2_connector_if_data *if_data,
7079 struct vop2_clk *if_pixclk, struct vop2_clk *if_dclk, int conn_id)
7080 {
7081 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7082 struct vop2 *vop2 = vp->vop2;
7083 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
7084 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7085 u64 v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
7086 unsigned long dclk_core_rate, dclk_out_rate = 0;
7087 /*conn_dclk = conn_pixclk or conn_dclk = conn_pixclk / 2 */
7088 u64 hdmi_edp_pixclk, hdmi_edp_dclk, mipi_pixclk;
7089 char dclk_core_div_shift = 2;
7090 char K = 1;
7091 char clk_name[32];
7092 struct vop2_clk *dclk_core, *dclk_out, *dclk;
7093 int ret;
7094 bool dsc_txp_clk_is_biggest = false;
7095 u8 dsc_id = conn_id & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1;
7096
7097 dclk_core_div_shift = if_data->post_proc_div_shift;
7098 dclk_core_rate = v_pixclk >> dclk_core_div_shift;
7099
7100 if (!if_dclk && (output_if_is_hdmi(conn_id) || output_if_is_edp(conn_id)))
7101 return -EINVAL;
7102 if ((vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) &&
7103 (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420)) {
7104 DRM_DEV_ERROR(vop2->dev, "Dual channel and YUV420 can't work together\n");
7105 return -EINVAL;
7106 }
7107
7108 if ((vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) ||
7109 (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420))
7110 K = 2;
7111
7112 if (output_if_is_hdmi(conn_id)) {
7113 if (vcstate->dsc_enable) {
7114 hdmi_edp_pixclk = vcstate->dsc_cds_clk_rate << 1;
7115 hdmi_edp_dclk = vcstate->dsc_cds_clk_rate;
7116 } else {
7117 hdmi_edp_pixclk = (dclk_core_rate << 1) / K;
7118 hdmi_edp_dclk = dclk_core_rate / K;
7119 }
7120
7121 if_pixclk->rate = hdmi_edp_pixclk;
7122 if_dclk->rate = hdmi_edp_dclk;
7123 } else if (output_if_is_edp(conn_id)) {
7124 hdmi_edp_pixclk = v_pixclk;
7125 do_div(hdmi_edp_pixclk, K);
7126 hdmi_edp_dclk = hdmi_edp_pixclk;
7127
7128 if_pixclk->rate = hdmi_edp_pixclk;
7129 if_dclk->rate = hdmi_edp_dclk;
7130 } else if (output_if_is_dp(conn_id)) {
7131 dclk_out_rate = v_pixclk >> 2;
7132 dclk_out_rate = dclk_out_rate / K;
7133 if_pixclk->rate = dclk_out_rate;
7134 } else if (output_if_is_mipi(conn_id)) {
7135 if (vcstate->dsc_enable)
7136 /* dsc output is 96bit, dsi input is 192 bit */
7137 mipi_pixclk = vcstate->dsc_cds_clk_rate >> 1;
7138 else
7139 mipi_pixclk = dclk_core_rate / K;
7140
7141 dclk_out_rate = dclk_core_rate / K;
7142 if_pixclk->rate = mipi_pixclk;
7143 } else if (output_if_is_dpi(conn_id)) {
7144 if_pixclk->rate = v_pixclk;
7145 }
7146
7147 /*
7148 * RGB/eDP/HDMI: if_pixclk >= dclk_core
7149 * DP: dp_pixclk = dclk_out <= dclk_core
7150 * DSI: mipi_pixclk <= dclk_out <= dclk_core
7151 *
7152 */
7153 snprintf(clk_name, sizeof(clk_name), "dclk_core%d", vp->id);
7154 dclk_core = vop2_clk_get(vop2, clk_name);
7155
7156 snprintf(clk_name, sizeof(clk_name), "dclk_out%d", vp->id);
7157 dclk_out = vop2_clk_get(vop2, clk_name);
7158
7159 /*
7160 * HDMI use 1:1 dclk for rgb/yuv444, 1:2 for yuv420 when
7161 * pixclk <= 600
7162 * We want use HDMI PHY clk as dclk source for DP/HDMI.
7163 * The max freq of HDMI PHY CLK is 600 MHZ.
7164 * When used for HDMI, the input freq and v_pixclk must
7165 * keep 1:1 for rgb/yuv444, 1:2 for yuv420
7166 */
7167 if (output_if_is_hdmi(conn_id) || output_if_is_dp(conn_id) || output_if_is_mipi(conn_id)) {
7168 snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id);
7169 dclk = vop2_clk_get(vop2, clk_name);
7170 if (v_pixclk <= (VOP2_MAX_DCLK_RATE * 1000)) {
7171 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420 ||
7172 (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE))
7173 v_pixclk = v_pixclk >> 1;
7174 } else {
7175 v_pixclk = v_pixclk >> 2;
7176 }
7177 clk_set_rate(dclk->hw.clk, v_pixclk);
7178 }
7179
7180 if (vcstate->dsc_enable) {
7181 if ((vcstate->dsc_txp_clk_rate >= dclk_core_rate) &&
7182 (vcstate->dsc_txp_clk_rate >= if_pixclk->rate)) {
7183 dsc_txp_clk_is_biggest = true;
7184 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
7185 vop2_set_dsc_clk(crtc, 0);
7186 vop2_set_dsc_clk(crtc, 1);
7187 } else {
7188 vop2_set_dsc_clk(crtc, dsc_id);
7189 }
7190 }
7191 }
7192
7193 if (dclk_core_rate > if_pixclk->rate) {
7194 clk_set_rate(dclk_core->hw.clk, dclk_core_rate);
7195 if (output_if_is_mipi(conn_id))
7196 clk_set_rate(dclk_out->hw.clk, dclk_out_rate);
7197 ret = vop2_cru_set_rate(if_pixclk, if_dclk);
7198 } else {
7199 if (output_if_is_mipi(conn_id))
7200 clk_set_rate(dclk_out->hw.clk, dclk_out_rate);
7201 ret = vop2_cru_set_rate(if_pixclk, if_dclk);
7202 clk_set_rate(dclk_core->hw.clk, dclk_core_rate);
7203 }
7204
7205 if (!dsc_txp_clk_is_biggest && vcstate->dsc_enable) {
7206 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
7207 vop2_set_dsc_clk(crtc, 0);
7208 vop2_set_dsc_clk(crtc, 1);
7209 } else {
7210 vop2_set_dsc_clk(crtc, dsc_id);
7211 }
7212 }
7213
7214 return ret;
7215 }
7216
vop2_calc_dsc_clk(struct drm_crtc * crtc)7217 static int vop2_calc_dsc_clk(struct drm_crtc *crtc)
7218 {
7219 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7220 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7221 struct vop2 *vop2 = vp->vop2;
7222 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
7223 u64 v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
7224 u8 k = 1;
7225
7226 if (!vop2->data->nr_dscs) {
7227 DRM_WARN("Unsupported DSC\n");
7228
7229 return 0;
7230 }
7231
7232 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
7233 k = 2;
7234
7235 vcstate->dsc_txp_clk_rate = v_pixclk;
7236 do_div(vcstate->dsc_txp_clk_rate, (vcstate->dsc_pixel_num * k));
7237
7238 vcstate->dsc_pxl_clk_rate = v_pixclk;
7239 do_div(vcstate->dsc_pxl_clk_rate, (vcstate->dsc_slice_num * k));
7240
7241 /* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel)
7242 * cds_dat_width = 96;
7243 * bits_per_pixel = [8-12];
7244 * As cds clk is div from txp clk and only support 1/2/4 div,
7245 * so when txp_clk is equal to v_pixclk, we set dsc_cds = crtc_clock / 4,
7246 * otherwise dsc_cds = crtc_clock / 8;
7247 */
7248 vcstate->dsc_cds_clk_rate = v_pixclk / (vcstate->dsc_txp_clk_rate == v_pixclk ? 4 : 8);
7249
7250 return 0;
7251 }
7252
vop2_calc_cru_cfg(struct drm_crtc * crtc,int conn_id,struct vop2_clk ** if_pixclk,struct vop2_clk ** if_dclk)7253 static int vop2_calc_cru_cfg(struct drm_crtc *crtc, int conn_id,
7254 struct vop2_clk **if_pixclk, struct vop2_clk **if_dclk)
7255 {
7256 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7257 struct vop2 *vop2 = vp->vop2;
7258 const struct vop2_connector_if_data *if_data;
7259 struct vop2_clk *if_clk_src, *if_clk_parent;
7260 char clk_name[32];
7261 int ret;
7262
7263 if (vop2->version != VOP_VERSION_RK3588)
7264 return 0;
7265
7266 if_data = vop2_find_connector_if_data(vop2, conn_id);
7267 if_clk_src = vop2_clk_get(vop2, if_data->clk_src_name);
7268 snprintf(clk_name, sizeof(clk_name), "%s%d", if_data->clk_parent_name, vp->id);
7269 if_clk_parent = vop2_clk_get(vop2, clk_name);
7270 *if_pixclk = vop2_clk_get(vop2, if_data->pixclk_name);
7271 *if_dclk = vop2_clk_get(vop2, if_data->dclk_name);
7272 if (!(*if_pixclk) || !if_clk_parent) {
7273 DRM_DEV_ERROR(vop2->dev, "failed to get connector interface clk\n");
7274 return -ENODEV;
7275 }
7276
7277 ret = clk_set_parent(if_clk_src->hw.clk, if_clk_parent->hw.clk);
7278 if (ret < 0) {
7279 DRM_DEV_ERROR(vop2->dev, "failed to set parent(%s) for %s: %d\n",
7280 __clk_get_name(if_clk_parent->hw.clk),
7281 __clk_get_name(if_clk_src->hw.clk), ret);
7282 return ret;
7283 }
7284
7285 /* HDMI and eDP use independent if_pixclk and if_dclk, and others if_pixclk = if_dclk */
7286 if (output_if_is_hdmi(conn_id) || output_if_is_edp(conn_id))
7287 ret = vop2_calc_if_clk(crtc, if_data, *if_pixclk, *if_dclk, conn_id);
7288 else
7289 ret = vop2_calc_if_clk(crtc, if_data, *if_pixclk, NULL, conn_id);
7290
7291 return ret;
7292 }
7293
vop2_crtc_load_pps(struct drm_crtc * crtc,u8 dsc_id)7294 static void vop2_crtc_load_pps(struct drm_crtc *crtc, u8 dsc_id)
7295 {
7296 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7297 struct vop2 *vop2 = vp->vop2;
7298 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7299
7300 struct drm_dsc_picture_parameter_set *pps = &vcstate->pps;
7301 struct drm_dsc_picture_parameter_set config_pps;
7302 int i = 0;
7303 u32 *pps_val = (u32 *)&config_pps;
7304 u32 offset;
7305 struct vop2_dsc *dsc;
7306
7307 dsc = &vop2->dscs[dsc_id];
7308 offset = dsc->regs->dsc_pps0_3.offset;
7309
7310 memcpy(&config_pps, pps, sizeof(config_pps));
7311
7312 if ((config_pps.pps_3 & 0xf) > dsc->max_linebuf_depth) {
7313 config_pps.pps_3 &= 0xf0;
7314 config_pps.pps_3 |= dsc->max_linebuf_depth;
7315 DRM_WARN("DSC%d max_linebuf_depth is: %d, current set value is: %d\n",
7316 dsc_id, dsc->max_linebuf_depth, config_pps.pps_3 & 0xf);
7317 }
7318
7319 for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
7320 config_pps.rc_range_parameters[i] =
7321 (pps->rc_range_parameters[i] >> 3 & 0x1f) |
7322 ((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) |
7323 ((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) |
7324 ((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10);
7325 }
7326
7327 for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++)
7328 vop2_writel(vop2, offset + i * 4, *pps_val++);
7329 }
7330
vop2_crtc_enable_dsc(struct drm_crtc * crtc,struct drm_crtc_state * old_state,u8 dsc_id)7331 static void vop2_crtc_enable_dsc(struct drm_crtc *crtc, struct drm_crtc_state *old_state, u8 dsc_id)
7332 {
7333 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7334 struct vop2 *vop2 = vp->vop2;
7335 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7336 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
7337 struct rockchip_dsc_sink_cap *dsc_sink_cap = &vcstate->dsc_sink_cap;
7338 u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
7339 u16 hdisplay = adjusted_mode->crtc_hdisplay;
7340 u16 htotal = adjusted_mode->crtc_htotal;
7341 u16 hact_st = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_start;
7342 u16 vdisplay = adjusted_mode->crtc_vdisplay;
7343 u16 vtotal = adjusted_mode->crtc_vtotal;
7344 u16 vsync_len = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
7345 u16 vact_st = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
7346 u16 vact_end = vact_st + vdisplay;
7347 u8 dsc_interface_mode = 0;
7348 struct vop2_dsc *dsc;
7349 struct vop2_clk *dsc_cds_clk, *dsc_pxl_clk, *dsc_txp_clk;
7350 const struct vop2_data *vop2_data = vop2->data;
7351 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
7352 bool mipi_ds_mode = false;
7353 uint32_t *reg_base = vop2->regs;
7354 u32 offset = 0;
7355
7356 if (!vop2->data->nr_dscs) {
7357 DRM_WARN("Unsupported DSC\n");
7358
7359 return;
7360 }
7361
7362 if (vcstate->dsc_slice_num > dsc_data->max_slice_num)
7363 DRM_ERROR("DSC%d supported max slice is: %d, current is: %d\n",
7364 dsc_data->id, dsc_data->max_slice_num, vcstate->dsc_slice_num);
7365
7366 dsc = &vop2->dscs[dsc_id];
7367 if (dsc->pd) {
7368 dsc->pd->vp_mask = BIT(vp->id);
7369 vop2_power_domain_get(dsc->pd);
7370 }
7371
7372 VOP_MODULE_SET(vop2, dsc, scan_timing_para_imd_en, 1);
7373 VOP_MODULE_SET(vop2, dsc, dsc_port_sel, vp->id);
7374 if (vcstate->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
7375 dsc_interface_mode = VOP_DSC_IF_HDMI;
7376 } else {
7377 mipi_ds_mode = !!(vcstate->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE);
7378 if (mipi_ds_mode)
7379 dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE;
7380 else
7381 dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE;
7382 }
7383
7384 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
7385 VOP_MODULE_SET(vop2, dsc, dsc_man_mode, 0);
7386 else
7387 VOP_MODULE_SET(vop2, dsc, dsc_man_mode, 1);
7388 dsc_cds_clk = vop2_clk_get(vop2, dsc_data->dsc_cds_clk_name);
7389 dsc_pxl_clk = vop2_clk_get(vop2, dsc_data->dsc_pxl_clk_name);
7390 dsc_txp_clk = vop2_clk_get(vop2, dsc_data->dsc_txp_clk_name);
7391
7392 VOP_MODULE_SET(vop2, dsc, dsc_interface_mode, dsc_interface_mode);
7393 VOP_MODULE_SET(vop2, dsc, dsc_pixel_num, vcstate->dsc_pixel_num >> 1);
7394 VOP_MODULE_SET(vop2, dsc, dsc_txp_clk_div, dsc_txp_clk->div_val);
7395 VOP_MODULE_SET(vop2, dsc, dsc_pxl_clk_div, dsc_pxl_clk->div_val);
7396 VOP_MODULE_SET(vop2, dsc, dsc_cds_clk_div, dsc_cds_clk->div_val);
7397 VOP_MODULE_SET(vop2, dsc, dsc_scan_en, !mipi_ds_mode);
7398 VOP_MODULE_SET(vop2, dsc, dsc_halt_en, mipi_ds_mode);
7399
7400 if (!mipi_ds_mode) {
7401 u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end;
7402 u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16;
7403 u64 dsc_cds_rate = vcstate->dsc_cds_clk_rate;
7404 u32 v_pixclk_mhz = adjusted_mode->crtc_clock / 1000; /* video timing pixclk */
7405 u32 dly_num, dsc_cds_rate_mhz, val = 0;
7406 struct vop2_clk *dclk_core;
7407 char clk_name[32];
7408 int k = 1;
7409
7410 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
7411 k = 2;
7412
7413 snprintf(clk_name, sizeof(clk_name), "dclk_core%d", vp->id);
7414 dclk_core = vop2_clk_get(vop2, clk_name);
7415
7416 if (target_bpp >> 4 < dsc->min_bits_per_pixel)
7417 DRM_ERROR("Unsupported bpp less than: %d\n", dsc->min_bits_per_pixel);
7418
7419 /*
7420 * dly_num = delay_line_num * T(one-line) / T (dsc_cds)
7421 * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz
7422 * T (dsc_cds) = 1 / dsc_cds_rate_mhz
7423 *
7424 * HDMI:
7425 * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay
7426 * delay_line_num = 4 - BPP / 8
7427 * = (64 - target_bpp / 8) / 16
7428 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
7429 *
7430 * MIPI DSI[4320 and 9216 is buffer size for DSC]:
7431 * DSC0:delay_line_num = 4320 * 8 / slince_num / chunk_size;
7432 * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
7433 * DSC1:delay_line_num = 9216 * 2 / slince_num / chunk_size;
7434 * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
7435 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num
7436 */
7437 do_div(dsc_cds_rate, 1000000); /* hz to Mhz */
7438 dsc_cds_rate_mhz = dsc_cds_rate;
7439 dsc_hsync = hsync_len / 2;
7440 if (dsc_interface_mode == VOP_DSC_IF_HDMI) {
7441 dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
7442 } else {
7443 int dsc_buf_size = dsc->id == 0 ? 4320 * 8 : 9216 * 2;
7444 int delay_line_num = dsc_buf_size / vcstate->dsc_slice_num / be16_to_cpu(vcstate->pps.chunk_size);
7445
7446 delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
7447 dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num;
7448
7449 /* The dsc mipi video mode dsc_hsync minimum size is 8 pixels */
7450 if (dsc_hsync < 8)
7451 dsc_hsync = 8;
7452 }
7453 VOP_MODULE_SET(vop2, dsc, dsc_init_dly_mode, 0);
7454 VOP_MODULE_SET(vop2, dsc, dsc_init_dly_num, dly_num);
7455 /*
7456 * htotal / dclk_core = dsc_htotal /cds_clk
7457 *
7458 * dclk_core = DCLK / (1 << dclk_core->div_val)
7459 * cds_clk = txp_clk / (1 << dsc_cds_clk->div_val)
7460 * txp_clk = DCLK / (1 << dsc_txp_clk->div_val)
7461 *
7462 * dsc_htotal = htotal * (1 << dclk_core->div_val) /
7463 ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val))
7464 */
7465 dsc_htotal = htotal * (1 << dclk_core->div_val) /
7466 ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val));
7467 val = dsc_htotal << 16 | dsc_hsync;
7468 VOP_MODULE_SET(vop2, dsc, dsc_htotal_pw, val);
7469
7470 dsc_hact_st = hact_st / 2;
7471 dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st;
7472 val = dsc_hact_end << 16 | dsc_hact_st;
7473 VOP_MODULE_SET(vop2, dsc, dsc_hact_st_end, val);
7474
7475 VOP_MODULE_SET(vop2, dsc, dsc_vtotal, vtotal);
7476 VOP_MODULE_SET(vop2, dsc, dsc_vs_end, vsync_len);
7477 VOP_MODULE_SET(vop2, dsc, dsc_vact_st_end, vact_end << 16 | vact_st);
7478 }
7479
7480 VOP_MODULE_SET(vop2, dsc, rst_deassert, 1);
7481 udelay(10);
7482 /* read current dsc core register and backup to regsbak */
7483 offset = dsc->regs->dsc_en.offset;
7484 vop2->regsbak[offset >> 2] = reg_base[offset >> 2];
7485
7486 VOP_MODULE_SET(vop2, dsc, dsc_en, 1);
7487 vop2_crtc_load_pps(crtc, dsc_id);
7488
7489 VOP_MODULE_SET(vop2, dsc, dsc_rbit, 1);
7490 VOP_MODULE_SET(vop2, dsc, dsc_rbyt, 0);
7491 VOP_MODULE_SET(vop2, dsc, dsc_flal, 1);
7492 VOP_MODULE_SET(vop2, dsc, dsc_mer, 1);
7493 VOP_MODULE_SET(vop2, dsc, dsc_epb, 0);
7494 VOP_MODULE_SET(vop2, dsc, dsc_epl, 1);
7495 VOP_MODULE_SET(vop2, dsc, dsc_nslc, ilog2(vcstate->dsc_slice_num));
7496 VOP_MODULE_SET(vop2, dsc, dsc_sbo, 1);
7497 VOP_MODULE_SET(vop2, dsc, dsc_ifep, dsc_sink_cap->version_minor == 2 ? 1 : 0);
7498 VOP_MODULE_SET(vop2, dsc, dsc_pps_upd, 1);
7499
7500 DRM_DEV_INFO(vop2->dev, "DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n",
7501 dsc->id,
7502 vcstate->dsc_txp_clk_rate, dsc_txp_clk->div_val,
7503 vcstate->dsc_pxl_clk_rate, dsc_pxl_clk->div_val,
7504 vcstate->dsc_cds_clk_rate, dsc_cds_clk->div_val);
7505
7506 dsc->attach_vp_id = vp->id;
7507 dsc->enabled = true;
7508 }
7509
vop2_mark_as_left_panel(struct rockchip_crtc_state * vcstate,u32 output_if)7510 static inline bool vop2_mark_as_left_panel(struct rockchip_crtc_state *vcstate, u32 output_if)
7511 {
7512 return vcstate->output_if_left_panel & output_if;
7513 }
7514
vop2_setup_dual_channel_if(struct drm_crtc * crtc)7515 static void vop2_setup_dual_channel_if(struct drm_crtc *crtc)
7516 {
7517 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7518 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7519 struct vop2 *vop2 = vp->vop2;
7520
7521 VOP_MODULE_SET(vop2, vp, dual_channel_en, 1);
7522 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
7523 VOP_MODULE_SET(vop2, vp, dual_channel_swap, 1);
7524
7525 if (vcstate->output_if & VOP_OUTPUT_IF_DP1 &&
7526 !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_DP1))
7527 VOP_CTRL_SET(vop2, dp_dual_en, 1);
7528 else if (vcstate->output_if & VOP_OUTPUT_IF_eDP1 &&
7529 !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_eDP1))
7530 VOP_CTRL_SET(vop2, edp_dual_en, 1);
7531 else if (vcstate->output_if & VOP_OUTPUT_IF_HDMI1 &&
7532 !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_HDMI1))
7533 VOP_CTRL_SET(vop2, hdmi_dual_en, 1);
7534 else if (vcstate->output_if & VOP_OUTPUT_IF_MIPI1 &&
7535 !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_MIPI1))
7536 VOP_CTRL_SET(vop2, mipi_dual_en, 1);
7537 }
7538
7539 /*
7540 * MIPI port mux on rk3588:
7541 * 0: Video Port2
7542 * 1: Video Port3
7543 * 3: Video Port 1(MIPI1 only)
7544 */
vop2_get_mipi_port_mux(struct vop2 * vop2,int vp_id)7545 static int vop2_get_mipi_port_mux(struct vop2 *vop2, int vp_id)
7546 {
7547 if (vop2->version == VOP_VERSION_RK3588) {
7548 if (vp_id == 1)
7549 return 3;
7550 else if (vp_id == 3)
7551 return 1;
7552 else
7553 return 0;
7554 } else {
7555 return vp_id;
7556 }
7557 }
7558
vop2_get_hdmi_pol(struct vop2 * vop2,u32 flags)7559 static u32 vop2_get_hdmi_pol(struct vop2 *vop2, u32 flags)
7560 {
7561 u32 val;
7562
7563 if (vop2->version == VOP_VERSION_RK3588) {
7564 val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
7565 val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
7566 } else {
7567 val = (flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
7568 val |= (flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
7569 }
7570
7571 return val;
7572 }
7573
vop2_post_color_swap(struct drm_crtc * crtc)7574 static void vop2_post_color_swap(struct drm_crtc *crtc)
7575 {
7576 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7577 struct vop2 *vop2 = vp->vop2;
7578 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7579 u32 output_if = vcstate->output_if;
7580 u32 data_swap = 0;
7581
7582 if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode) ||
7583 vop3_output_rb_swap(vcstate->bus_format, vcstate->output_mode))
7584 data_swap = DSP_RB_SWAP;
7585
7586 if (vop2->version == VOP_VERSION_RK3588 &&
7587 (output_if_is_hdmi(output_if) || output_if_is_dp(output_if)) &&
7588 (vcstate->bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
7589 vcstate->bus_format == MEDIA_BUS_FMT_YUV10_1X30))
7590 data_swap |= DSP_RG_SWAP;
7591
7592 VOP_MODULE_SET(vop2, vp, dsp_data_swap, data_swap);
7593 }
7594
7595 /*
7596 * For vop3 video port0, if hdr_vivid is not enable, the pipe delay time as follow:
7597 * win_dly + config_win_dly + layer_mix_dly + sdr2hdr_dly + * hdr_mix_dly = config_bg_dly
7598 *
7599 * if hdr_vivid is enable, the hdr layer's pipe delay time as follow:
7600 * win_dly + config_win_dly +hdrvivid_dly + hdr_mix_dly = config_bg_dly
7601 *
7602 * If hdrvivid and sdr2hdr bot enable, the time arrivr hdr_mix should be the same:
7603 * win_dly + config_win_dly0 + hdrvivid_dly = win_dly + config_win_dly1 + laer_mix_dly +
7604 * sdr2hdr_dly
7605 *
7606 * For vop3 video port1, the pipe delay time as follow:
7607 * win_dly + config_win_dly + layer_mix_dly = config_bg_dly
7608 *
7609 * Here, win_dly, layer_mix_dly, sdr2hdr_dly, hdr_mix_dly, hdrvivid_dly is the hardware
7610 * delay cycles. Config_win_dly and config_bg_dly is the register value that we can config.
7611 * Different hdr vivid mode have different hdrvivid_dly. For sdr2hdr_dly, only sde2hdr
7612 * enable, it will delay, otherwise, the sdr2hdr_dly is 0.
7613 *
7614 * For default, the config_win_dly will be 0, it just user to make the pipe to arrive
7615 * hdr_mix at the same time.
7616 */
vop3_setup_pipe_dly(struct vop2_video_port * vp,const struct vop2_zpos * vop2_zpos)7617 static void vop3_setup_pipe_dly(struct vop2_video_port *vp, const struct vop2_zpos *vop2_zpos)
7618 {
7619 struct vop2 *vop2 = vp->vop2;
7620 struct drm_crtc *crtc = &vp->rockchip_crtc.crtc;
7621 const struct vop2_zpos *zpos;
7622 struct drm_plane *plane;
7623 struct vop2_plane_state *vpstate;
7624 struct vop2_win *win;
7625 const struct vop2_data *vop2_data = vop2->data;
7626 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
7627 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
7628 u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
7629 u16 hdisplay = adjusted_mode->crtc_hdisplay;
7630 int bg_dly = 0x0;
7631 int dly = 0x0;
7632 int hdr_win_dly;
7633 int sdr_win_dly;
7634 int sdr2hdr_dly;
7635 int pre_scan_dly;
7636 int i;
7637
7638 /**
7639 * config bg dly, select the max delay num of hdrvivid and sdr2hdr module
7640 * as the increase value of bg delay num. If hdrvivid and sdr2hdr is not
7641 * work, the default bg_dly is 0x10. and the default win delay num is 0.
7642 */
7643 if ((vp->hdr_en || vp->sdr2hdr_en) &&
7644 (vp->hdrvivid_mode >= 0 && vp->hdrvivid_mode <= SDR2HLG)) {
7645 /* set sdr2hdr_dly to 0 if sdr2hdr is disable */
7646 sdr2hdr_dly = vp->sdr2hdr_en ? vp_data->sdr2hdr_dly : 0;
7647
7648 /* set the max delay pipe's config_win_dly as 0 */
7649 if (vp_data->hdrvivid_dly[vp->hdrvivid_mode] >=
7650 sdr2hdr_dly + vp_data->layer_mix_dly) {
7651 bg_dly = vp_data->win_dly + vp_data->hdrvivid_dly[vp->hdrvivid_mode] +
7652 vp_data->hdr_mix_dly;
7653 hdr_win_dly = 0;
7654 sdr_win_dly = vp_data->hdrvivid_dly[vp->hdrvivid_mode] -
7655 vp_data->layer_mix_dly - sdr2hdr_dly;
7656 } else {
7657 bg_dly = vp_data->win_dly + vp_data->layer_mix_dly + sdr2hdr_dly +
7658 vp_data->hdr_mix_dly;
7659 hdr_win_dly = sdr2hdr_dly + vp_data->layer_mix_dly -
7660 vp_data->hdrvivid_dly[vp->hdrvivid_mode];
7661 sdr_win_dly = 0;
7662 }
7663 } else {
7664 bg_dly = vp_data->win_dly + vp_data->layer_mix_dly + vp_data->hdr_mix_dly;
7665 sdr_win_dly = 0;
7666 }
7667
7668 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
7669 pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
7670 VOP_MODULE_SET(vop2, vp, bg_dly, bg_dly);
7671 VOP_MODULE_SET(vop2, vp, pre_scan_htiming, pre_scan_dly);
7672
7673 /**
7674 * config win dly
7675 */
7676 if (!vop2_zpos)
7677 return;
7678
7679 for (i = 0; i < vp->nr_layers; i++) {
7680 zpos = &vop2_zpos[i];
7681 win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
7682 plane = &win->base;
7683 vpstate = to_vop2_plane_state(plane->state);
7684
7685 if ((vp->hdr_en || vp->sdr2hdr_en) &&
7686 (vp->hdrvivid_mode >= 0 && vp->hdrvivid_mode <= SDR2HLG)) {
7687 dly = vpstate->hdr_in ? hdr_win_dly : sdr_win_dly;
7688 }
7689 if (vop2_cluster_window(win))
7690 dly |= dly << 8;
7691
7692 VOP_CTRL_SET(vop2, win_dly[win->phys_id], dly);
7693 }
7694 }
7695
vop2_get_vrefresh(struct vop2_video_port * vp,const struct drm_display_mode * mode)7696 static int vop2_get_vrefresh(struct vop2_video_port *vp, const struct drm_display_mode *mode)
7697 {
7698 if (vp->mcu_timing.mcu_pix_total)
7699 return drm_mode_vrefresh(mode) / vp->mcu_timing.mcu_pix_total;
7700 else
7701 return drm_mode_vrefresh(mode);
7702 }
7703
vop2_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_crtc_state * old_state)7704 static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
7705 {
7706 struct vop2_video_port *vp = to_vop2_video_port(crtc);
7707 struct vop2_video_port *splice_vp;
7708 struct vop2 *vop2 = vp->vop2;
7709 const struct vop2_data *vop2_data = vop2->data;
7710 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
7711 const struct vop_intr *intr = vp_data->intr;
7712 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
7713 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
7714 struct rockchip_dsc_sink_cap *dsc_sink_cap = &vcstate->dsc_sink_cap;
7715 u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
7716 u16 hdisplay = adjusted_mode->crtc_hdisplay;
7717 u16 htotal = adjusted_mode->crtc_htotal;
7718 u16 hact_st = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_start;
7719 u16 hact_end = hact_st + hdisplay;
7720 u16 vdisplay = adjusted_mode->crtc_vdisplay;
7721 u16 vtotal = adjusted_mode->crtc_vtotal;
7722 u16 vsync_len = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
7723 u16 vact_st = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
7724 u16 vact_end = vact_st + vdisplay;
7725 bool interlaced = !!(adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE);
7726 bool dclk_inv, yc_swap = false;
7727 int act_end;
7728 uint32_t val;
7729 char clk_name[32];
7730 struct vop2_clk *if_pixclk = NULL;
7731 struct vop2_clk *if_dclk = NULL;
7732 struct vop2_clk *dclk, *dclk_out, *dclk_core;
7733 int splice_en = 0;
7734 int port_mux;
7735 int ret;
7736
7737 if (old_state && old_state->self_refresh_active) {
7738 vop2_crtc_atomic_exit_psr(crtc, old_state);
7739
7740 return;
7741 }
7742
7743 vop2->active_vp_mask |= BIT(vp->id);
7744 vop2_set_system_status(vop2);
7745
7746 vop2_lock(vop2);
7747 DRM_DEV_INFO(vop2->dev, "Update mode to %dx%d%s%d, type: %d(if:%x, flag:0x%x) for vp%d dclk: %d\n",
7748 hdisplay, adjusted_mode->vdisplay, interlaced ? "i" : "p",
7749 vop2_get_vrefresh(vp, adjusted_mode), vcstate->output_type, vcstate->output_if, vcstate->output_flags,
7750 vp->id, adjusted_mode->crtc_clock * 1000);
7751
7752 if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
7753 vcstate->splice_mode = true;
7754 splice_vp = &vop2->vps[vp_data->splice_vp_id];
7755 splice_vp->splice_mode_right = true;
7756 splice_vp->left_vp = vp;
7757 splice_en = 1;
7758 vop2->active_vp_mask |= BIT(splice_vp->id);
7759 }
7760
7761 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CONNECTOR_SPLIT_MODE)
7762 vcstate->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
7763
7764 if (vcstate->dsc_enable) {
7765 int k = 1;
7766
7767 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
7768 k = 2;
7769
7770 vcstate->dsc_id = vcstate->output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1;
7771 vcstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k;
7772 vcstate->dsc_pixel_num = vcstate->dsc_slice_num > 4 ? 4 : vcstate->dsc_slice_num;
7773
7774 vop2_calc_dsc_clk(crtc);
7775 DRM_DEV_INFO(vop2->dev, "Enable DSC%d slice:%dx%d, slice num:%d\n",
7776 vcstate->dsc_id, dsc_sink_cap->slice_width,
7777 dsc_sink_cap->slice_height, vcstate->dsc_slice_num);
7778 }
7779
7780 vop2_initial(crtc);
7781 vcstate->vdisplay = vdisplay;
7782 vcstate->mode_update = vop2_crtc_mode_update(crtc);
7783 if (vcstate->mode_update)
7784 vop2_disable_all_planes_for_crtc(crtc);
7785
7786 dclk_inv = (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
7787 val = (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
7788 val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
7789
7790 vp->output_if = vcstate->output_if;
7791
7792 if (vcstate->output_if & VOP_OUTPUT_IF_RGB) {
7793 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_RGB, &if_pixclk, &if_dclk);
7794 if (ret < 0)
7795 goto out;
7796
7797 VOP_CTRL_SET(vop2, rgb_en, 1);
7798 VOP_CTRL_SET(vop2, rgb_mux, vp_data->id);
7799 VOP_CTRL_SET(vop2, rgb_pin_pol, val);
7800 VOP_GRF_SET(vop2, sys_grf, grf_dclk_inv, dclk_inv);
7801 }
7802
7803 if (vcstate->output_if & VOP_OUTPUT_IF_BT1120) {
7804 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_RGB, &if_pixclk, &if_dclk);
7805 if (ret < 0)
7806 goto out;
7807
7808 if (vop2->version == VOP_VERSION_RK3588) {
7809 VOP_CTRL_SET(vop2, bt1120_en, 3);
7810 } else {
7811 VOP_CTRL_SET(vop2, rgb_en, 1);
7812 VOP_CTRL_SET(vop2, bt1120_en, 1);
7813 }
7814 VOP_CTRL_SET(vop2, rgb_mux, vp_data->id);
7815 VOP_GRF_SET(vop2, sys_grf, grf_bt1120_clk_inv, !dclk_inv);
7816 VOP_CTRL_SET(vop2, bt1120_dclk_pol, !dclk_inv);
7817 yc_swap = vop2_output_yc_swap(vcstate->bus_format);
7818 VOP_CTRL_SET(vop2, bt1120_yc_swap, yc_swap);
7819 }
7820
7821 if (vcstate->output_if & VOP_OUTPUT_IF_BT656) {
7822 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_RGB, &if_pixclk, &if_dclk);
7823 if (ret < 0)
7824 goto out;
7825
7826 if (vop2->version == VOP_VERSION_RK3588) {
7827 VOP_CTRL_SET(vop2, bt656_en, 1);
7828 } else {
7829 VOP_CTRL_SET(vop2, rgb_en, 1);
7830 VOP_CTRL_SET(vop2, bt656_en, 1);
7831 }
7832 VOP_CTRL_SET(vop2, rgb_mux, vp_data->id);
7833 VOP_GRF_SET(vop2, sys_grf, grf_bt656_clk_inv, !dclk_inv);
7834 VOP_CTRL_SET(vop2, bt656_dclk_pol, !dclk_inv);
7835 yc_swap = vop2_output_yc_swap(vcstate->bus_format);
7836 VOP_CTRL_SET(vop2, bt656_yc_swap, yc_swap);
7837 }
7838
7839 if (vcstate->output_if & VOP_OUTPUT_IF_LVDS0) {
7840 VOP_CTRL_SET(vop2, lvds0_en, 1);
7841 VOP_CTRL_SET(vop2, lvds0_mux, vp_data->id);
7842 VOP_CTRL_SET(vop2, lvds_pin_pol, val);
7843 VOP_CTRL_SET(vop2, lvds_dclk_pol, dclk_inv);
7844 }
7845
7846 if (vcstate->output_if & VOP_OUTPUT_IF_LVDS1) {
7847 VOP_CTRL_SET(vop2, lvds1_en, 1);
7848 VOP_CTRL_SET(vop2, lvds1_mux, vp_data->id);
7849 VOP_CTRL_SET(vop2, lvds_pin_pol, val);
7850 VOP_CTRL_SET(vop2, lvds_dclk_pol, dclk_inv);
7851 }
7852
7853 if (vcstate->output_flags & (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE |
7854 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) {
7855 VOP_CTRL_SET(vop2, lvds_dual_en, 1);
7856 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
7857 VOP_CTRL_SET(vop2, lvds_dual_mode, 1);
7858 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
7859 VOP_CTRL_SET(vop2, lvds_dual_channel_swap, 1);
7860 }
7861
7862 if (vcstate->output_if & VOP_OUTPUT_IF_MIPI0) {
7863 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_MIPI0, &if_pixclk, &if_dclk);
7864 if (ret < 0)
7865 goto out;
7866 if (if_pixclk)
7867 VOP_CTRL_SET(vop2, mipi0_pixclk_div, if_pixclk->div_val);
7868
7869 if (vcstate->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
7870 VOP_CTRL_SET(vop2, mipi0_ds_mode, 1);
7871
7872 port_mux = vop2_get_mipi_port_mux(vop2, vp_data->id);
7873 VOP_CTRL_SET(vop2, mipi0_en, 1);
7874 VOP_CTRL_SET(vop2, mipi0_mux, port_mux);
7875 VOP_CTRL_SET(vop2, mipi_pin_pol, val);
7876 VOP_CTRL_SET(vop2, mipi_dclk_pol, dclk_inv);
7877 if (vcstate->hold_mode) {
7878 VOP_MODULE_SET(vop2, vp, edpi_te_en, !vcstate->soft_te);
7879 VOP_MODULE_SET(vop2, vp, edpi_wms_hold_en, 1);
7880 }
7881 }
7882
7883 if (vcstate->output_if & VOP_OUTPUT_IF_MIPI1) {
7884 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_MIPI1, &if_pixclk, &if_dclk);
7885 if (ret < 0)
7886 goto out;
7887 if (if_pixclk)
7888 VOP_CTRL_SET(vop2, mipi1_pixclk_div, if_pixclk->div_val);
7889
7890 if (vcstate->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
7891 VOP_CTRL_SET(vop2, mipi1_ds_mode, 1);
7892
7893 port_mux = vop2_get_mipi_port_mux(vop2, vp_data->id);
7894
7895 VOP_CTRL_SET(vop2, mipi1_en, 1);
7896 VOP_CTRL_SET(vop2, mipi1_mux, port_mux);
7897 VOP_CTRL_SET(vop2, mipi_pin_pol, val);
7898 VOP_CTRL_SET(vop2, mipi_dclk_pol, dclk_inv);
7899 if (vcstate->hold_mode) {
7900 VOP_MODULE_SET(vop2, vp, edpi_te_en, !vcstate->soft_te);
7901 VOP_MODULE_SET(vop2, vp, edpi_wms_hold_en, 1);
7902 }
7903 }
7904
7905 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
7906 vop2_setup_dual_channel_if(crtc);
7907
7908 if (vcstate->output_if & VOP_OUTPUT_IF_eDP0) {
7909 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_eDP0, &if_pixclk, &if_dclk);
7910 if (ret < 0)
7911 goto out;
7912 if (if_pixclk && if_dclk) {
7913 VOP_CTRL_SET(vop2, edp0_pixclk_div, if_pixclk->div_val);
7914 VOP_CTRL_SET(vop2, edp0_dclk_div, if_dclk->div_val);
7915 }
7916
7917 VOP_CTRL_SET(vop2, edp0_en, 1);
7918 VOP_CTRL_SET(vop2, edp0_mux, vp_data->id);
7919 VOP_CTRL_SET(vop2, edp_pin_pol, val);
7920 VOP_CTRL_SET(vop2, edp_dclk_pol, dclk_inv);
7921 VOP_GRF_SET(vop2, grf, grf_edp0_en, 1);
7922 }
7923
7924 if (vcstate->output_if & VOP_OUTPUT_IF_eDP1) {
7925 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_eDP1, &if_pixclk, &if_dclk);
7926 if (ret < 0)
7927 goto out;
7928 if (if_pixclk && if_dclk) {
7929 VOP_CTRL_SET(vop2, edp1_pixclk_div, if_pixclk->div_val);
7930 VOP_CTRL_SET(vop2, edp1_dclk_div, if_dclk->div_val);
7931 }
7932
7933 VOP_CTRL_SET(vop2, edp1_en, 1);
7934 VOP_CTRL_SET(vop2, edp1_mux, vp_data->id);
7935 VOP_CTRL_SET(vop2, edp_pin_pol, val);
7936 VOP_CTRL_SET(vop2, edp_dclk_pol, dclk_inv);
7937 VOP_GRF_SET(vop2, grf, grf_edp1_en, 1);
7938 }
7939
7940 if (vcstate->output_if & VOP_OUTPUT_IF_DP0) {
7941 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_DP0, &if_pixclk, &if_dclk);
7942 if (ret < 0)
7943 goto out;
7944 VOP_CTRL_SET(vop2, dp0_en, 1);
7945 VOP_CTRL_SET(vop2, dp0_mux, vp_data->id);
7946 VOP_CTRL_SET(vop2, dp0_dclk_pol, 0);
7947 VOP_CTRL_SET(vop2, dp0_pin_pol, val);
7948 }
7949
7950 if (vcstate->output_if & VOP_OUTPUT_IF_DP1) {
7951 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_DP0, &if_pixclk, &if_dclk);
7952 if (ret < 0)
7953 goto out;
7954
7955 VOP_CTRL_SET(vop2, dp1_en, 1);
7956 VOP_CTRL_SET(vop2, dp1_mux, vp_data->id);
7957 VOP_CTRL_SET(vop2, dp1_dclk_pol, 0);
7958 VOP_CTRL_SET(vop2, dp1_pin_pol, val);
7959 }
7960
7961 if (vcstate->output_if & VOP_OUTPUT_IF_HDMI0) {
7962 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_HDMI0, &if_pixclk, &if_dclk);
7963 if (ret < 0)
7964 goto out;
7965 if (if_pixclk && if_dclk) {
7966 VOP_CTRL_SET(vop2, hdmi0_pixclk_div, if_pixclk->div_val);
7967 VOP_CTRL_SET(vop2, hdmi0_dclk_div, if_dclk->div_val);
7968 }
7969
7970 if (vcstate->dsc_enable)
7971 VOP_GRF_SET(vop2, grf, grf_hdmi0_dsc_en, 1);
7972
7973 val = vop2_get_hdmi_pol(vop2, adjusted_mode->flags);
7974 VOP_GRF_SET(vop2, grf, grf_hdmi0_en, 1);
7975 VOP_GRF_SET(vop2, vo1_grf, grf_hdmi0_pin_pol, val);
7976
7977 VOP_CTRL_SET(vop2, hdmi0_en, 1);
7978 VOP_CTRL_SET(vop2, hdmi0_mux, vp_data->id);
7979 VOP_CTRL_SET(vop2, hdmi_pin_pol, val);
7980 VOP_CTRL_SET(vop2, hdmi_dclk_pol, 1);
7981 }
7982
7983 if (vcstate->output_if & VOP_OUTPUT_IF_HDMI1) {
7984 ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_HDMI1, &if_pixclk, &if_dclk);
7985 if (ret < 0)
7986 goto out;
7987
7988 if (if_pixclk && if_dclk) {
7989 VOP_CTRL_SET(vop2, hdmi1_pixclk_div, if_pixclk->div_val);
7990 VOP_CTRL_SET(vop2, hdmi1_dclk_div, if_dclk->div_val);
7991 }
7992
7993 if (vcstate->dsc_enable)
7994 VOP_GRF_SET(vop2, grf, grf_hdmi1_dsc_en, 1);
7995
7996 val = vop2_get_hdmi_pol(vop2, adjusted_mode->flags);
7997 VOP_GRF_SET(vop2, grf, grf_hdmi1_en, 1);
7998 VOP_GRF_SET(vop2, vo1_grf, grf_hdmi1_pin_pol, val);
7999
8000 VOP_CTRL_SET(vop2, hdmi1_en, 1);
8001 VOP_CTRL_SET(vop2, hdmi1_mux, vp_data->id);
8002 VOP_CTRL_SET(vop2, hdmi_pin_pol, val);
8003 VOP_CTRL_SET(vop2, hdmi_dclk_pol, 1);
8004 }
8005
8006 VOP_MODULE_SET(vop2, vp, splice_en, splice_en);
8007
8008 VOP_MODULE_SET(vop2, vp, htotal_pw, (htotal << 16) | hsync_len);
8009 val = hact_st << 16;
8010 val |= hact_end;
8011 VOP_MODULE_SET(vop2, vp, hact_st_end, val);
8012
8013 val = vact_st << 16;
8014 val |= vact_end;
8015 VOP_MODULE_SET(vop2, vp, vact_st_end, val);
8016
8017 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
8018 u16 vact_st_f1 = vtotal + vact_st + 1;
8019 u16 vact_end_f1 = vact_st_f1 + vdisplay;
8020
8021 val = vact_st_f1 << 16 | vact_end_f1;
8022 VOP_MODULE_SET(vop2, vp, vact_st_end_f1, val);
8023
8024 val = vtotal << 16 | (vtotal + vsync_len);
8025 VOP_MODULE_SET(vop2, vp, vs_st_end_f1, val);
8026 VOP_MODULE_SET(vop2, vp, dsp_interlace, 1);
8027 VOP_MODULE_SET(vop2, vp, dsp_filed_pol, 1);
8028 VOP_MODULE_SET(vop2, vp, p2i_en, 1);
8029 vtotal += vtotal + 1;
8030 act_end = vact_end_f1;
8031 } else {
8032 VOP_MODULE_SET(vop2, vp, dsp_interlace, 0);
8033 VOP_MODULE_SET(vop2, vp, dsp_filed_pol, 0);
8034 VOP_MODULE_SET(vop2, vp, p2i_en, 0);
8035 act_end = vact_end;
8036 }
8037
8038 if (vp->xmirror_en)
8039 VOP_MODULE_SET(vop2, vp, dsp_x_mir_en, 1);
8040
8041 VOP_INTR_SET(vop2, intr, line_flag_num[0], act_end);
8042 VOP_INTR_SET(vop2, intr, line_flag_num[1], act_end);
8043
8044 VOP_MODULE_SET(vop2, vp, dsp_vtotal, vtotal);
8045 VOP_MODULE_SET(vop2, vp, dsp_vs_end, vsync_len);
8046 /**
8047 * when display interface support vrr, config vtotal valid immediately
8048 */
8049 if (vcstate->max_refresh_rate && vcstate->min_refresh_rate)
8050 VOP_MODULE_SET(vop2, vp, sw_dsp_vtotal_imd, 1);
8051
8052 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK ||
8053 vcstate->output_if & VOP_OUTPUT_IF_BT656)
8054 VOP_MODULE_SET(vop2, vp, core_dclk_div, 1);
8055 else
8056 VOP_MODULE_SET(vop2, vp, core_dclk_div, 0);
8057
8058 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
8059 VOP_MODULE_SET(vop2, vp, dclk_div2, 1);
8060 VOP_MODULE_SET(vop2, vp, dclk_div2_phase_lock, 1);
8061 } else {
8062 VOP_MODULE_SET(vop2, vp, dclk_div2, 0);
8063 VOP_MODULE_SET(vop2, vp, dclk_div2_phase_lock, 0);
8064 }
8065
8066 snprintf(clk_name, sizeof(clk_name), "dclk_out%d", vp->id);
8067 dclk_out = vop2_clk_get(vop2, clk_name);
8068 snprintf(clk_name, sizeof(clk_name), "dclk_core%d", vp->id);
8069 dclk_core = vop2_clk_get(vop2, clk_name);
8070 if (dclk_out && dclk_core) {
8071 DRM_DEV_INFO(vop2->dev, "%s div: %d %s div: %d\n",
8072 __clk_get_name(dclk_out->hw.clk), dclk_out->div_val,
8073 __clk_get_name(dclk_core->hw.clk), dclk_core->div_val);
8074 VOP_MODULE_SET(vop2, vp, dclk_src_sel, 0);
8075 VOP_MODULE_SET(vop2, vp, dclk_out_div, dclk_out->div_val);
8076 VOP_MODULE_SET(vop2, vp, dclk_core_div, dclk_core->div_val);
8077 }
8078
8079 snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id);
8080 dclk = vop2_clk_get(vop2, clk_name);
8081 if (dclk) {
8082 /*
8083 * use HDMI_PHY_PLL as dclk source under 4K@60 if it is available,
8084 * otherwise use system cru as dclk source.
8085 */
8086 ret = vop2_clk_set_parent_extend(vp, vcstate, true);
8087 if (ret < 0)
8088 goto out;
8089
8090 clk_set_rate(vp->dclk, dclk->rate);
8091 DRM_DEV_INFO(vop2->dev, "set %s to %ld, get %ld\n",
8092 __clk_get_name(vp->dclk), dclk->rate, clk_get_rate(vp->dclk));
8093 } else {
8094 /*
8095 * For RK3528, the path of CVBS output is like:
8096 * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
8097 * The vop2 dclk should be four times crtc_clock for CVBS sampling clock needs.
8098 */
8099 if (vop2->version == VOP_VERSION_RK3528 && vcstate->output_if & VOP_OUTPUT_IF_BT656)
8100 clk_set_rate(vp->dclk, 4 * adjusted_mode->crtc_clock * 1000);
8101 else
8102 clk_set_rate(vp->dclk, adjusted_mode->crtc_clock * 1000);
8103 }
8104
8105 if (vp_data->feature & VOP_FEATURE_OVERSCAN)
8106 vop2_post_config(crtc);
8107
8108 VOP_MODULE_SET(vop2, vp, almost_full_or_en, 1);
8109 VOP_MODULE_SET(vop2, vp, line_flag_or_en, 1);
8110 if (vcstate->dsc_enable) {
8111 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
8112 vop2_crtc_enable_dsc(crtc, old_state, 0);
8113 vop2_crtc_enable_dsc(crtc, old_state, 1);
8114 } else {
8115 vop2_crtc_enable_dsc(crtc, old_state, vcstate->dsc_id);
8116 }
8117 }
8118 /* For RK3588, the reset value of background is 0xa0080200,
8119 * which will enable background and output a grey image. But
8120 * the reset value is just valid in first frame and disable
8121 * in follow frames. If the panel backlight is valid before
8122 * follow frames. The screen may flick a grey image. To avoid
8123 * this phenomenon appear, setting black background after
8124 * reset vop
8125 */
8126 if (vop2->version == VOP_VERSION_RK3588)
8127 VOP_MODULE_SET(vop2, vp, dsp_background, 0x80000000);
8128 if (is_vop3(vop2))
8129 vop3_setup_pipe_dly(vp, NULL);
8130
8131 vop2_cfg_done(crtc);
8132
8133 /*
8134 * when clear standby bits, it will take effect immediately,
8135 * This means the vp will start scan out immediately with
8136 * the timing it been configured before.
8137 * So we must make sure release standby after the display
8138 * timing is correctly configured.
8139 * This is important when switch resolution, such as
8140 * 4K-->720P:
8141 * if we release standby before 720P timing is configured,
8142 * the VP will start scan out immediately with 4K timing,
8143 * when we switch dclk to 74.25MHZ, VP timing is still 4K,
8144 * so VP scan out with 4K timing at 74.25MHZ dclk, this is
8145 * very slow, than this will trigger vblank timeout.
8146 *
8147 */
8148 VOP_MODULE_SET(vop2, vp, standby, 0);
8149
8150 if (vp->mcu_timing.mcu_pix_total) {
8151 vop3_set_out_mode(crtc, vcstate->output_mode);
8152 vop3_mcu_mode_setup(crtc);
8153 }
8154
8155 if (!vp->loader_protect)
8156 vop2_clk_reset(vp->dclk_rst);
8157 if (vcstate->dsc_enable)
8158 rk3588_vop2_dsc_cfg_done(crtc);
8159 drm_crtc_vblank_on(crtc);
8160 /*
8161 * restore the lut table.
8162 */
8163 if (vp->gamma_lut_active) {
8164 vop2_crtc_load_lut(crtc);
8165 vop2_cfg_done(crtc);
8166 vop2_wait_for_fs_by_done_bit_status(vp);
8167 }
8168 out:
8169 vop2_unlock(vop2);
8170 }
8171
vop2_zpos_cmp(const void * a,const void * b)8172 static int vop2_zpos_cmp(const void *a, const void *b)
8173 {
8174 struct vop2_zpos *pa = (struct vop2_zpos *)a;
8175 struct vop2_zpos *pb = (struct vop2_zpos *)b;
8176
8177 if (pa->zpos != pb->zpos)
8178 return pa->zpos - pb->zpos;
8179 else
8180 return pa->plane->base.id - pb->plane->base.id;
8181 }
8182
vop2_crtc_atomic_check(struct drm_crtc * crtc,struct drm_crtc_state * crtc_state)8183 static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
8184 struct drm_crtc_state *crtc_state)
8185 {
8186 struct vop2_video_port *vp = to_vop2_video_port(crtc);
8187 struct vop2_video_port *splice_vp;
8188 struct vop2 *vop2 = vp->vop2;
8189 const struct vop2_data *vop2_data = vop2->data;
8190 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
8191 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
8192 struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(crtc_state);
8193 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
8194
8195 if (vop2_has_feature(vop2, VOP_FEATURE_SPLICE)) {
8196 if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
8197 vcstate->splice_mode = true;
8198 splice_vp = &vop2->vps[vp_data->splice_vp_id];
8199 splice_vp->splice_mode_right = true;
8200 splice_vp->left_vp = vp;
8201 }
8202 }
8203
8204 if ((vcstate->request_refresh_rate != new_vcstate->request_refresh_rate) ||
8205 crtc_state->active_changed || crtc_state->mode_changed)
8206 vp->refresh_rate_change = true;
8207 else
8208 vp->refresh_rate_change = false;
8209
8210 return 0;
8211 }
8212
vop3_disable_dynamic_hdr(struct vop2_video_port * vp,uint8_t win_phys_id)8213 static void vop3_disable_dynamic_hdr(struct vop2_video_port *vp, uint8_t win_phys_id)
8214 {
8215 struct vop2 *vop2 = vp->vop2;
8216 struct vop2_win *win = vop2_find_win_by_phys_id(vop2, win_phys_id);
8217 struct drm_plane *plane = &win->base;
8218 struct drm_plane_state *pstate = plane->state;
8219 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
8220
8221 VOP_MODULE_SET(vop2, vp, hdr10_en, 0);
8222 VOP_MODULE_SET(vop2, vp, hdr_vivid_en, 0);
8223 VOP_MODULE_SET(vop2, vp, hdr_vivid_bypass_en, 0);
8224 VOP_MODULE_SET(vop2, vp, hdr_lut_update_en, 0);
8225 VOP_MODULE_SET(vop2, vp, sdr2hdr_en, 0);
8226 VOP_MODULE_SET(vop2, vp, sdr2hdr_path_en, 0);
8227 VOP_MODULE_SET(vop2, vp, sdr2hdr_auto_gating_en, 1);
8228
8229 vp->hdr_en = false;
8230 vp->hdr_in = false;
8231 vp->hdr_out = false;
8232 vp->sdr2hdr_en = false;
8233 vpstate->hdr_in = false;
8234 vpstate->hdr2sdr_en = false;
8235 }
8236
vop3_setup_hdrvivid(struct vop2_video_port * vp,uint8_t win_phys_id)8237 static void vop3_setup_hdrvivid(struct vop2_video_port *vp, uint8_t win_phys_id)
8238 {
8239 struct vop2 *vop2 = vp->vop2;
8240 struct vop2_win *win = vop2_find_win_by_phys_id(vop2, win_phys_id);
8241 struct drm_plane *plane = &win->base;
8242 struct drm_plane_state *pstate = plane->state;
8243 struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
8244 struct drm_crtc_state *cstate = vp->rockchip_crtc.crtc.state;
8245 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(cstate);
8246 unsigned long win_mask = vp->win_mask;
8247 int phys_id;
8248 struct hdrvivid_regs *hdrvivid_data;
8249 struct hdr_extend *hdr_data;
8250 struct rockchip_gem_object *lut_gem_obj;
8251 bool have_sdr_layer = false;
8252 uint32_t hdr_mode;
8253 int i;
8254 u32 *tone_lut_kvaddr;
8255 dma_addr_t tone_lut_mst;
8256
8257 vp->hdr_en = false;
8258 vp->hdr_in = false;
8259 vp->hdr_out = false;
8260 vp->sdr2hdr_en = false;
8261 vpstate->hdr_in = false;
8262 vpstate->hdr2sdr_en = false;
8263
8264 hdr_data = (struct hdr_extend *)vcstate->hdr_ext_data->data;
8265 hdrvivid_data = &hdr_data->hdrvivid_data;
8266
8267 hdr_mode = hdrvivid_data->hdr_mode;
8268
8269 if (hdr_mode > SDR2HLG && hdr_mode != SDR2HDR10_USERSPACE &&
8270 hdr_mode != SDR2HLG_USERSPACE) {
8271 DRM_ERROR("Invalid HDR mode:%d, beyond the mode range\n", hdr_mode);
8272 return;
8273 }
8274
8275 /* adjust userspace hdr mode value to kernel value */
8276 if (hdr_mode == SDR2HDR10_USERSPACE)
8277 hdr_mode = SDR2HDR10;
8278 if (hdr_mode == SDR2HLG_USERSPACE)
8279 hdr_mode = SDR2HLG;
8280
8281 if (hdr_mode <= HDR102SDR && vpstate->eotf != HDMI_EOTF_SMPTE_ST2084 && vpstate->eotf != HDMI_EOTF_BT_2100_HLG) {
8282 DRM_ERROR("Invalid HDR mode:%d, mismatch plane eotf:%d\n", hdr_mode,
8283 vpstate->eotf);
8284 return;
8285 }
8286
8287 vp->hdrvivid_mode = hdr_mode;
8288 vcstate->yuv_overlay = false;
8289
8290 if (hdr_mode <= HDR102SDR) {
8291 vp->hdr_en = true;
8292 vp->hdr_in = true;
8293 vpstate->hdr_in = true;
8294 } else {
8295 vp->sdr2hdr_en = true;
8296 }
8297
8298 /*
8299 * To confirm whether need to enable sdr2hdr.
8300 */
8301 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
8302 win = vop2_find_win_by_phys_id(vop2, phys_id);
8303 plane = &win->base;
8304 pstate = plane->state;
8305 vpstate = to_vop2_plane_state(pstate);
8306
8307 /* skip inactive plane */
8308 if (!vop2_plane_active(pstate))
8309 continue;
8310
8311 if (vpstate->eotf != HDMI_EOTF_SMPTE_ST2084 &&
8312 vpstate->eotf != HDMI_EOTF_BT_2100_HLG) {
8313 have_sdr_layer = true;
8314 break;
8315 }
8316 }
8317
8318 if (hdr_mode == PQHDR2SDR_WITH_DYNAMIC || hdr_mode == HLG2SDR_WITH_DYNAMIC ||
8319 hdr_mode == HLG2SDR_WITHOUT_DYNAMIC || hdr_mode == HDR102SDR) {
8320 vpstate->hdr2sdr_en = true;
8321 } else {
8322 vp->hdr_out = true;
8323 if (have_sdr_layer)
8324 vp->sdr2hdr_en = true;
8325 }
8326
8327 /**
8328 * Config hdr ctrl registers
8329 */
8330 vop2_writel(vop2, RK3528_SDR2HDR_CTRL, hdrvivid_data->sdr2hdr_ctrl);
8331 vop2_writel(vop2, RK3528_HDRVIVID_CTRL, hdrvivid_data->hdrvivid_ctrl);
8332
8333 VOP_MODULE_SET(vop2, vp, hdr10_en, vp->hdr_en);
8334 if (vp->hdr_en) {
8335 VOP_MODULE_SET(vop2, vp, hdr_vivid_en, (hdr_mode == HDR_BYPASS) ? 0 : 1);
8336 VOP_MODULE_SET(vop2, vp, hdr_vivid_path_mode,
8337 (hdr_mode == HDR102SDR) ? PQHDR2SDR_WITH_DYNAMIC : hdr_mode);
8338 VOP_MODULE_SET(vop2, vp, hdr_vivid_bypass_en, (hdr_mode == HDR_BYPASS) ? 1 : 0);
8339 } else {
8340 VOP_MODULE_SET(vop2, vp, hdr_vivid_en, 0);
8341 }
8342 VOP_MODULE_SET(vop2, vp, sdr2hdr_en, vp->sdr2hdr_en);
8343 VOP_MODULE_SET(vop2, vp, sdr2hdr_path_en, vp->sdr2hdr_en);
8344 VOP_MODULE_SET(vop2, vp, sdr2hdr_auto_gating_en, vp->sdr2hdr_en ? 0 : 1);
8345
8346 vop2_writel(vop2, RK3528_SDR_CFG_COE0, hdrvivid_data->sdr2hdr_coe0);
8347 vop2_writel(vop2, RK3528_SDR_CFG_COE1, hdrvivid_data->sdr2hdr_coe1);
8348 vop2_writel(vop2, RK3528_SDR_CSC_COE00_01, hdrvivid_data->sdr2hdr_csc_coe00_01);
8349 vop2_writel(vop2, RK3528_SDR_CSC_COE02_10, hdrvivid_data->sdr2hdr_csc_coe02_10);
8350 vop2_writel(vop2, RK3528_SDR_CSC_COE11_12, hdrvivid_data->sdr2hdr_csc_coe11_12);
8351 vop2_writel(vop2, RK3528_SDR_CSC_COE20_21, hdrvivid_data->sdr2hdr_csc_coe20_21);
8352 vop2_writel(vop2, RK3528_SDR_CSC_COE22, hdrvivid_data->sdr2hdr_csc_coe22);
8353
8354 vop2_writel(vop2, RK3528_HDR_PQ_GAMMA, hdrvivid_data->hdr_pq_gamma);
8355 vop2_writel(vop2, RK3528_HLG_RFIX_SCALEFAC, hdrvivid_data->hlg_rfix_scalefac);
8356 vop2_writel(vop2, RK3528_HLG_MAXLUMA, hdrvivid_data->hlg_maxluma);
8357 vop2_writel(vop2, RK3528_HLG_R_TM_LIN2NON, hdrvivid_data->hlg_r_tm_lin2non);
8358
8359 vop2_writel(vop2, RK3528_HDR_CSC_COE00_01, hdrvivid_data->hdr_csc_coe00_01);
8360 vop2_writel(vop2, RK3528_HDR_CSC_COE02_10, hdrvivid_data->hdr_csc_coe02_10);
8361 vop2_writel(vop2, RK3528_HDR_CSC_COE11_12, hdrvivid_data->hdr_csc_coe11_12);
8362 vop2_writel(vop2, RK3528_HDR_CSC_COE20_21, hdrvivid_data->hdr_csc_coe20_21);
8363 vop2_writel(vop2, RK3528_HDR_CSC_COE22, hdrvivid_data->hdr_csc_coe22);
8364
8365 if (!vp->hdr_lut_gem_obj) {
8366 lut_gem_obj = rockchip_gem_create_object(vop2->drm_dev,
8367 RK_HDRVIVID_TONE_SCA_AXI_TAB_LENGTH * 4, true, 0);
8368 if (IS_ERR(lut_gem_obj)) {
8369 DRM_ERROR("create hdr lut obj failed\n");
8370 return;
8371 }
8372 vp->hdr_lut_gem_obj = lut_gem_obj;
8373 }
8374
8375 tone_lut_kvaddr = (u32 *)vp->hdr_lut_gem_obj->kvaddr;
8376 tone_lut_mst = vp->hdr_lut_gem_obj->dma_addr;
8377
8378 for (i = 0; i < RK_HDRVIVID_TONE_SCA_AXI_TAB_LENGTH; i++)
8379 *tone_lut_kvaddr++ = hdrvivid_data->tone_sca_axi_tab[i];
8380
8381 VOP_MODULE_SET(vop2, vp, lut_dma_rid, vp->lut_dma_rid - vp->id);
8382 VOP_MODULE_SET(vop2, vp, hdr_lut_mode, 1);
8383 VOP_MODULE_SET(vop2, vp, hdr_lut_mst, tone_lut_mst);
8384 VOP_MODULE_SET(vop2, vp, hdr_lut_update_en, 1);
8385 VOP_CTRL_SET(vop2, lut_dma_en, 1);
8386
8387 for (i = 0; i < RK_HDRVIVID_GAMMA_CURVE_LENGTH; i++)
8388 vop2_writel(vop2, RK3528_HDRGAMMA_CURVE + i * 4, hdrvivid_data->hdrgamma_curve[i]);
8389
8390 for (i = 0; i < RK_HDRVIVID_GAMMA_MDFVALUE_LENGTH; i++)
8391 vop2_writel(vop2, RK3528_HDRGAMMA_MDFVALUE + i * 4,
8392 hdrvivid_data->hdrgamma_mdfvalue[i]);
8393
8394 for (i = 0; i < RK_SDR2HDR_INVGAMMA_CURVE_LENGTH; i++)
8395 vop2_writel(vop2, RK3528_SDRINVGAMMA_CURVE + i * 4,
8396 hdrvivid_data->sdrinvgamma_curve[i]);
8397
8398 for (i = 0; i < RK_SDR2HDR_INVGAMMA_S_IDX_LENGTH; i++)
8399 vop2_writel(vop2, RK3528_SDRINVGAMMA_STARTIDX + i * 4,
8400 hdrvivid_data->sdrinvgamma_startidx[i]);
8401
8402 for (i = 0; i < RK_SDR2HDR_INVGAMMA_C_IDX_LENGTH; i++)
8403 vop2_writel(vop2, RK3528_SDRINVGAMMA_CHANGEIDX + i * 4,
8404 hdrvivid_data->sdrinvgamma_changeidx[i]);
8405
8406 for (i = 0; i < RK_SDR2HDR_SMGAIN_LENGTH; i++)
8407 vop2_writel(vop2, RK3528_SDR_SMGAIN + i * 4, hdrvivid_data->sdr_smgain[i]);
8408 }
8409
vop3_setup_dynamic_hdr(struct vop2_video_port * vp,uint8_t win_phys_id)8410 static void vop3_setup_dynamic_hdr(struct vop2_video_port *vp, uint8_t win_phys_id)
8411 {
8412 struct drm_crtc_state *cstate = vp->rockchip_crtc.crtc.state;
8413 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(cstate);
8414 struct hdr_extend *hdr_data;
8415 uint32_t hdr_format;
8416
8417 /* If hdr extend data is null, exit hdr mode */
8418 if (!vcstate->hdr_ext_data) {
8419 vop3_disable_dynamic_hdr(vp, win_phys_id);
8420 return;
8421 }
8422
8423 hdr_data = (struct hdr_extend *)vcstate->hdr_ext_data->data;
8424 hdr_format = hdr_data->hdr_type;
8425
8426 switch (hdr_format) {
8427 case HDR_NONE:
8428 case HDR_HDR10:
8429 case HDR_HLGSTATIC:
8430 case HDR_HDRVIVID:
8431 /*
8432 * hdr module support hdr10, hlg, vividhdr
8433 * sdr2hdr module support hdrnone for sdr2hdr
8434 */
8435 vop3_setup_hdrvivid(vp, win_phys_id);
8436 break;
8437 default:
8438 DRM_DEBUG("unsupprot hdr format:%u\n", hdr_format);
8439 break;
8440 }
8441 }
8442
vop2_setup_hdr10(struct vop2_video_port * vp,uint8_t win_phys_id)8443 static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id)
8444 {
8445 struct vop2 *vop2 = vp->vop2;
8446 struct vop2_win *win = vop2_find_win_by_phys_id(vop2, win_phys_id);
8447 struct drm_plane *plane = &win->base;
8448 struct drm_plane_state *pstate;
8449 struct drm_crtc_state *cstate = vp->rockchip_crtc.crtc.state;
8450 const struct vop2_data *vop2_data = vop2->data;
8451 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
8452 const struct vop_hdr_table *hdr_table = vp_data->hdr_table;
8453 struct rockchip_crtc_state *vcstate;
8454 struct vop2_plane_state *vpstate;
8455 uint32_t lut_mode = VOP2_HDR_LUT_MODE_AHB;
8456 uint32_t sdr2hdr_r2r_mode = 0;
8457 bool hdr_en = 0;
8458 bool hdr2sdr_en = 0;
8459 bool sdr2hdr_en = 0;
8460 bool sdr2hdr_tf = 0;
8461 bool hdr2sdr_tf_update = 1;
8462 bool sdr2hdr_tf_update = 0; /* default sdr2hdr curve is 1000 nit */
8463 unsigned long win_mask = vp->win_mask;
8464 int phys_id;
8465 bool have_sdr_layer = false;
8466
8467 /*
8468 * Check whether this video port support hdr or not
8469 */
8470 if (!hdr_table)
8471 return;
8472
8473 /*
8474 * right vp share the same crtc/plane state in splice mode
8475 */
8476 if (vp->splice_mode_right) {
8477 vcstate = to_rockchip_crtc_state(vp->left_vp->rockchip_crtc.crtc.state);
8478 pstate = win->left_win->base.state;
8479 } else {
8480 vcstate = to_rockchip_crtc_state(cstate);
8481 pstate = plane->state;
8482 }
8483
8484 vpstate = to_vop2_plane_state(pstate);
8485
8486 /*
8487 * HDR video plane input
8488 */
8489 if (vpstate->eotf == HDMI_EOTF_SMPTE_ST2084)
8490 hdr_en = 1;
8491
8492 vp->hdr_en = hdr_en;
8493 vp->hdr_in = hdr_en;
8494 vp->hdr_out = (vcstate->eotf == HDMI_EOTF_SMPTE_ST2084) ? true : false;
8495
8496 /*
8497 * only laryer0 support hdr2sdr
8498 * if we have more than one active win attached to the video port,
8499 * the other attached win must for ui, and should do sdr2hdr.
8500 *
8501 */
8502 if (vp->hdr_in && !vp->hdr_out)
8503 hdr2sdr_en = 1;
8504 vpstate->hdr_in = hdr_en;
8505 vpstate->hdr2sdr_en = hdr2sdr_en;
8506
8507 /*
8508 * To confirm whether need to enable sdr2hdr.
8509 */
8510 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
8511 win = vop2_find_win_by_phys_id(vop2, phys_id);
8512 if (vp->splice_mode_right) {
8513 if (win->left_win)
8514 pstate = win->left_win->base.state;
8515 else
8516 pstate = NULL; /* this win is not activated */
8517 } else {
8518 pstate = win->base.state;
8519 }
8520
8521 vpstate = pstate ? to_vop2_plane_state(pstate) : NULL;
8522
8523 if (!vop2_plane_active(pstate))
8524 continue;
8525
8526 if (vpstate->eotf != HDMI_EOTF_SMPTE_ST2084) {
8527 have_sdr_layer = true;
8528 break;
8529 }
8530 }
8531
8532 if (have_sdr_layer && vp->hdr_out) {
8533 sdr2hdr_en = 1;
8534 sdr2hdr_r2r_mode = BT709_TO_BT2020;
8535 sdr2hdr_tf = SDR2HDR_FOR_HDR;
8536 }
8537 vp->sdr2hdr_en = sdr2hdr_en;
8538
8539 VOP_MODULE_SET(vop2, vp, hdr10_en, hdr_en);
8540
8541 if (hdr2sdr_en || sdr2hdr_en) {
8542 /*
8543 * HDR2SDR and SDR2HDR must overlay in yuv color space
8544 */
8545 vcstate->yuv_overlay = false;
8546 VOP_MODULE_SET(vop2, vp, hdr_lut_mode, lut_mode);
8547 }
8548
8549 if (hdr2sdr_en) {
8550 if (hdr2sdr_tf_update)
8551 vop2_load_hdr2sdr_table(vp);
8552 VOP_MODULE_SET(vop2, vp, hdr2sdr_src_min, hdr_table->hdr2sdr_src_range_min);
8553 VOP_MODULE_SET(vop2, vp, hdr2sdr_src_max, hdr_table->hdr2sdr_src_range_max);
8554 VOP_MODULE_SET(vop2, vp, hdr2sdr_normfaceetf, hdr_table->hdr2sdr_normfaceetf);
8555 VOP_MODULE_SET(vop2, vp, hdr2sdr_dst_min, hdr_table->hdr2sdr_dst_range_min);
8556 VOP_MODULE_SET(vop2, vp, hdr2sdr_dst_max, hdr_table->hdr2sdr_dst_range_max);
8557 VOP_MODULE_SET(vop2, vp, hdr2sdr_normfacgamma, hdr_table->hdr2sdr_normfacgamma);
8558 }
8559 VOP_MODULE_SET(vop2, vp, hdr2sdr_en, hdr2sdr_en);
8560 VOP_MODULE_SET(vop2, vp, hdr2sdr_bypass_en, !hdr2sdr_en);
8561
8562 if (sdr2hdr_en) {
8563 if (sdr2hdr_tf_update)
8564 vop2_load_sdr2hdr_table(vp, sdr2hdr_tf);
8565 VOP_MODULE_SET(vop2, vp, sdr2hdr_r2r_mode, sdr2hdr_r2r_mode);
8566 }
8567 VOP_MODULE_SET(vop2, vp, sdr2hdr_path_en, sdr2hdr_en);
8568 VOP_MODULE_SET(vop2, vp, sdr2hdr_oetf_en, sdr2hdr_en);
8569 VOP_MODULE_SET(vop2, vp, sdr2hdr_eotf_en, sdr2hdr_en);
8570 VOP_MODULE_SET(vop2, vp, sdr2hdr_r2r_en, sdr2hdr_en);
8571 VOP_MODULE_SET(vop2, vp, sdr2hdr_bypass_en, !sdr2hdr_en);
8572 }
8573
vop2_parse_alpha(struct vop2_alpha_config * alpha_config,struct vop2_alpha * alpha)8574 static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
8575 struct vop2_alpha *alpha)
8576 {
8577 int src_glb_alpha_en = (alpha_config->src_glb_alpha_value == 0xff) ? 0 : 1;
8578 int dst_glb_alpha_en = (alpha_config->dst_glb_alpha_value == 0xff) ? 0 : 1;
8579 int src_color_mode = alpha_config->src_premulti_en ? ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
8580 int dst_color_mode = alpha_config->dst_premulti_en ? ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
8581
8582 alpha->src_color_ctrl.val = 0;
8583 alpha->dst_color_ctrl.val = 0;
8584 alpha->src_alpha_ctrl.val = 0;
8585 alpha->dst_alpha_ctrl.val = 0;
8586
8587 if (!alpha_config->src_pixel_alpha_en)
8588 alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
8589 else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
8590 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
8591 else
8592 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
8593
8594 alpha->src_color_ctrl.bits.alpha_en = 1;
8595
8596 if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
8597 alpha->src_color_ctrl.bits.color_mode = src_color_mode;
8598 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
8599 } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
8600 alpha->src_color_ctrl.bits.color_mode = src_color_mode;
8601 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
8602 } else {
8603 alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
8604 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
8605 }
8606 alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value;
8607 alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
8608 alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
8609
8610 alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
8611 alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
8612 alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
8613 alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value;
8614 alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
8615 alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
8616
8617 alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
8618 alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
8619 alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
8620 alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
8621
8622 alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
8623 if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
8624 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
8625 else
8626 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
8627 alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
8628 alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
8629 }
8630
vop2_find_start_mixer_id_for_vp(struct vop2 * vop2,uint8_t port_id)8631 static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, uint8_t port_id)
8632 {
8633 struct vop2_video_port *vp;
8634 int used_layer = 0;
8635 int i;
8636
8637 for (i = 0; i < port_id; i++) {
8638 vp = &vop2->vps[i];
8639 used_layer += hweight32(vp->win_mask);
8640 }
8641
8642 return used_layer;
8643 }
8644
8645 /*
8646 * src: top layer
8647 * dst: bottom layer.
8648 * Cluster mixer default use win1 as top layer
8649 */
vop2_setup_cluster_alpha(struct vop2 * vop2,struct vop2_cluster * cluster)8650 static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_cluster *cluster)
8651 {
8652 uint32_t src_color_ctrl_offset = cluster->main->regs->cluster->src_color_ctrl.offset;
8653 uint32_t dst_color_ctrl_offset = cluster->main->regs->cluster->dst_color_ctrl.offset;
8654 uint32_t src_alpha_ctrl_offset = cluster->main->regs->cluster->src_alpha_ctrl.offset;
8655 uint32_t dst_alpha_ctrl_offset = cluster->main->regs->cluster->dst_alpha_ctrl.offset;
8656 struct drm_framebuffer *fb;
8657 struct vop2_alpha_config alpha_config;
8658 struct vop2_alpha alpha;
8659 struct vop2_win *main_win = cluster->main;
8660 struct vop2_win *sub_win = cluster->sub;
8661 struct drm_plane *plane;
8662 struct vop2_plane_state *main_vpstate;
8663 struct vop2_plane_state *sub_vpstate;
8664 struct vop2_plane_state *top_win_vpstate;
8665 struct vop2_plane_state *bottom_win_vpstate;
8666 bool src_pixel_alpha_en = false;
8667 u16 src_glb_alpha_val = 0xff, dst_glb_alpha_val = 0xff;
8668 bool premulti_en = false;
8669 bool swap = false;
8670
8671 if (!sub_win) {
8672 /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
8673
8674 /*
8675 * right cluster share the same plane state in splice mode
8676 */
8677 if (cluster->splice_mode)
8678 plane = &main_win->left_win->base;
8679 else
8680 plane = &main_win->base;
8681
8682 top_win_vpstate = NULL;
8683 bottom_win_vpstate = to_vop2_plane_state(plane->state);
8684 src_glb_alpha_val = 0;
8685 dst_glb_alpha_val = bottom_win_vpstate->global_alpha;
8686 } else {
8687 plane = &sub_win->base;
8688 sub_vpstate = to_vop2_plane_state(plane->state);
8689 plane = &main_win->base;
8690 main_vpstate = to_vop2_plane_state(plane->state);
8691 if (main_vpstate->zpos > sub_vpstate->zpos) {
8692 swap = 1;
8693 top_win_vpstate = main_vpstate;
8694 bottom_win_vpstate = sub_vpstate;
8695 } else {
8696 swap = 0;
8697 top_win_vpstate = sub_vpstate;
8698 bottom_win_vpstate = main_vpstate;
8699 }
8700 src_glb_alpha_val = top_win_vpstate->global_alpha;
8701 dst_glb_alpha_val = bottom_win_vpstate->global_alpha;
8702 }
8703
8704 if (top_win_vpstate) {
8705 fb = top_win_vpstate->base.fb;
8706 if (!fb)
8707 return;
8708 if (top_win_vpstate->base.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
8709 premulti_en = true;
8710 else
8711 premulti_en = false;
8712 src_pixel_alpha_en = is_alpha_support(fb->format->format);
8713 }
8714 fb = bottom_win_vpstate->base.fb;
8715 if (!fb)
8716 return;
8717 alpha_config.src_premulti_en = premulti_en;
8718 alpha_config.dst_premulti_en = false;
8719 alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
8720 alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
8721 alpha_config.src_glb_alpha_value = src_glb_alpha_val;
8722 alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
8723 vop2_parse_alpha(&alpha_config, &alpha);
8724
8725 alpha.src_color_ctrl.bits.src_dst_swap = swap;
8726 vop2_writel(vop2, src_color_ctrl_offset, alpha.src_color_ctrl.val);
8727 vop2_writel(vop2, dst_color_ctrl_offset, alpha.dst_color_ctrl.val);
8728 vop2_writel(vop2, src_alpha_ctrl_offset, alpha.src_alpha_ctrl.val);
8729 vop2_writel(vop2, dst_alpha_ctrl_offset, alpha.dst_alpha_ctrl.val);
8730 }
8731
vop2_setup_alpha(struct vop2_video_port * vp,const struct vop2_zpos * vop2_zpos)8732 static void vop2_setup_alpha(struct vop2_video_port *vp,
8733 const struct vop2_zpos *vop2_zpos)
8734 {
8735 struct vop2 *vop2 = vp->vop2;
8736 uint32_t src_color_ctrl_offset = vop2->data->ctrl->src_color_ctrl.offset;
8737 uint32_t dst_color_ctrl_offset = vop2->data->ctrl->dst_color_ctrl.offset;
8738 uint32_t src_alpha_ctrl_offset = vop2->data->ctrl->src_alpha_ctrl.offset;
8739 uint32_t dst_alpha_ctrl_offset = vop2->data->ctrl->dst_alpha_ctrl.offset;
8740 unsigned long win_mask = vp->win_mask;
8741 const struct vop2_zpos *zpos;
8742 struct vop2_plane_state *vpstate;
8743 struct vop2_alpha_config alpha_config;
8744 struct vop2_alpha alpha;
8745 struct vop2_win *win;
8746 struct drm_plane_state *pstate;
8747 struct drm_framebuffer *fb;
8748 int pixel_alpha_en;
8749 int premulti_en = 1;
8750 int mixer_id;
8751 int phys_id;
8752 uint32_t offset;
8753 int i;
8754 bool bottom_layer_alpha_en = false;
8755 u32 dst_global_alpha = 0xff;
8756
8757 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
8758 win = vop2_find_win_by_phys_id(vop2, phys_id);
8759 if (win->splice_mode_right)
8760 pstate = win->left_win->base.state;
8761 else
8762 pstate = win->base.state;
8763
8764 vpstate = to_vop2_plane_state(pstate);
8765
8766 if (!vop2_plane_active(pstate))
8767 continue;
8768
8769 if (vpstate->zpos == 0 && vpstate->global_alpha != 0xff &&
8770 !vop2_cluster_window(win)) {
8771 /*
8772 * If bottom layer have global alpha effect [except cluster layer,
8773 * because cluster have deal with bottom layer global alpha value
8774 * at cluster mix], bottom layer mix need deal with global alpha.
8775 */
8776 bottom_layer_alpha_en = true;
8777 dst_global_alpha = vpstate->global_alpha;
8778 if (pstate->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
8779 premulti_en = 1;
8780 else
8781 premulti_en = 0;
8782
8783 break;
8784 }
8785 }
8786
8787 mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
8788
8789 if (vop2->version == VOP_VERSION_RK3588 &&
8790 vp->hdr10_at_splice_mode && vp->id == 0)
8791 mixer_id++;/* fixed path for rk3588: layer1 -> hdr10_1 */
8792
8793 alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
8794 for (i = 1; i < vp->nr_layers; i++) {
8795 zpos = &vop2_zpos[i];
8796 win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
8797 if (win->splice_mode_right)
8798 pstate = win->left_win->base.state;
8799 else
8800 pstate = win->base.state;
8801
8802 vpstate = to_vop2_plane_state(pstate);
8803 fb = pstate->fb;
8804 if (pstate->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
8805 premulti_en = 1;
8806 else
8807 premulti_en = 0;
8808 pixel_alpha_en = is_alpha_support(fb->format->format);
8809
8810 alpha_config.src_premulti_en = premulti_en;
8811 if (bottom_layer_alpha_en && i == 1) {/* Cd = Cs + (1 - As) * Cd * Agd */
8812 alpha_config.dst_premulti_en = false;
8813 alpha_config.src_pixel_alpha_en = pixel_alpha_en;
8814 alpha_config.src_glb_alpha_value = vpstate->global_alpha;
8815 alpha_config.dst_glb_alpha_value = dst_global_alpha;
8816 } else if (vop2_cluster_window(win)) {/* Mix output data only have pixel alpha */
8817 alpha_config.dst_premulti_en = true;
8818 alpha_config.src_pixel_alpha_en = true;
8819 alpha_config.src_glb_alpha_value = 0xff;
8820 alpha_config.dst_glb_alpha_value = 0xff;
8821 } else {/* Cd = Cs + (1 - As) * Cd */
8822 alpha_config.dst_premulti_en = true;
8823 alpha_config.src_pixel_alpha_en = pixel_alpha_en;
8824 alpha_config.src_glb_alpha_value = vpstate->global_alpha;
8825 alpha_config.dst_glb_alpha_value = 0xff;
8826 }
8827 vop2_parse_alpha(&alpha_config, &alpha);
8828
8829 offset = (mixer_id + i - 1) * 0x10;
8830 vop2_writel(vop2, src_color_ctrl_offset + offset, alpha.src_color_ctrl.val);
8831 vop2_writel(vop2, dst_color_ctrl_offset + offset, alpha.dst_color_ctrl.val);
8832 vop2_writel(vop2, src_alpha_ctrl_offset + offset, alpha.src_alpha_ctrl.val);
8833 vop2_writel(vop2, dst_alpha_ctrl_offset + offset, alpha.dst_alpha_ctrl.val);
8834 }
8835
8836 if (bottom_layer_alpha_en || vp->hdr_en) {
8837 /* Transfer pixel alpha to hdr mix */
8838 alpha_config.src_premulti_en = premulti_en;
8839 alpha_config.dst_premulti_en = true;
8840 alpha_config.src_pixel_alpha_en = true;
8841 alpha_config.src_glb_alpha_value = 0xff;
8842 alpha_config.dst_glb_alpha_value = 0xff;
8843 vop2_parse_alpha(&alpha_config, &alpha);
8844
8845 VOP_MODULE_SET(vop2, vp, hdr_src_color_ctrl,
8846 alpha.src_color_ctrl.val);
8847 VOP_MODULE_SET(vop2, vp, hdr_dst_color_ctrl,
8848 alpha.dst_color_ctrl.val);
8849 VOP_MODULE_SET(vop2, vp, hdr_src_alpha_ctrl,
8850 alpha.src_alpha_ctrl.val);
8851 VOP_MODULE_SET(vop2, vp, hdr_dst_alpha_ctrl,
8852 alpha.dst_alpha_ctrl.val);
8853 } else {
8854 VOP_MODULE_SET(vop2, vp, hdr_src_color_ctrl, 0);
8855 }
8856
8857 /* Transfer pixel alpha value to next mix */
8858 alpha_config.src_premulti_en = true;
8859 alpha_config.dst_premulti_en = true;
8860 alpha_config.src_pixel_alpha_en = false;
8861 alpha_config.src_glb_alpha_value = 0xff;
8862 alpha_config.dst_glb_alpha_value = 0xff;
8863 vop2_parse_alpha(&alpha_config, &alpha);
8864
8865 for (; i < hweight32(vp->win_mask); i++) {
8866 offset = (mixer_id + i - 1) * 0x10;
8867
8868 vop2_writel(vop2, src_color_ctrl_offset + offset, alpha.src_alpha_ctrl.val);
8869 vop2_writel(vop2, dst_color_ctrl_offset + offset, alpha.dst_color_ctrl.val);
8870 vop2_writel(vop2, src_alpha_ctrl_offset + offset, alpha.src_alpha_ctrl.val);
8871 vop2_writel(vop2, dst_alpha_ctrl_offset + offset, alpha.dst_alpha_ctrl.val);
8872 }
8873 }
8874
vop3_setup_alpha(struct vop2_video_port * vp,const struct vop2_zpos * vop2_zpos)8875 static void vop3_setup_alpha(struct vop2_video_port *vp,
8876 const struct vop2_zpos *vop2_zpos)
8877 {
8878 struct vop2 *vop2 = vp->vop2;
8879 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
8880 const struct vop3_ovl_regs *ovl_regs = vop2->data->vp[vp->id].ovl_regs;
8881 uint32_t src_color_ctrl_offset = ovl_regs->layer_mix_regs->src_color_ctrl.offset;
8882 uint32_t dst_color_ctrl_offset = ovl_regs->layer_mix_regs->dst_color_ctrl.offset;
8883 uint32_t src_alpha_ctrl_offset = ovl_regs->layer_mix_regs->src_alpha_ctrl.offset;
8884 uint32_t dst_alpha_ctrl_offset = ovl_regs->layer_mix_regs->dst_alpha_ctrl.offset;
8885 unsigned long win_mask = vp->win_mask;
8886 const struct vop2_zpos *zpos;
8887 struct vop2_plane_state *vpstate;
8888 struct vop2_alpha_config alpha_config;
8889 union vop2_bg_alpha_ctrl bg_alpha_ctrl;
8890 struct vop2_alpha alpha;
8891 struct vop2_win *win;
8892 struct drm_plane_state *pstate;
8893 struct drm_framebuffer *fb;
8894 int pixel_alpha_en;
8895 int premulti_en = 1;
8896 int phys_id;
8897 uint32_t offset;
8898 int i;
8899 bool bottom_layer_alpha_en = false;
8900 u32 dst_global_alpha = 0xff;
8901
8902 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
8903 win = vop2_find_win_by_phys_id(vop2, phys_id);
8904 pstate = win->base.state;
8905 vpstate = to_vop2_plane_state(pstate);
8906
8907 if (!vop2_plane_active(pstate))
8908 continue;
8909
8910 if (vpstate->zpos == 0 && vpstate->global_alpha != 0xff &&
8911 !vop2_cluster_window(win)) {
8912 /*
8913 * If bottom layer have global alpha effect [except cluster layer,
8914 * because cluster have deal with bottom layer global alpha value
8915 * at cluster mix], bottom layer mix need deal with global alpha.
8916 */
8917 bottom_layer_alpha_en = true;
8918 dst_global_alpha = vpstate->global_alpha;
8919 if (pstate->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
8920 premulti_en = 1;
8921 else
8922 premulti_en = 0;
8923
8924 break;
8925 }
8926 }
8927
8928 alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
8929 for (i = 1; i < vp->nr_layers; i++) {
8930 zpos = &vop2_zpos[i];
8931 win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
8932 pstate = win->base.state;
8933 vpstate = to_vop2_plane_state(pstate);
8934 fb = pstate->fb;
8935 if (pstate->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
8936 premulti_en = 1;
8937 else
8938 premulti_en = 0;
8939 pixel_alpha_en = is_alpha_support(fb->format->format);
8940
8941 alpha_config.src_premulti_en = premulti_en;
8942 if (bottom_layer_alpha_en && i == 1) {/* Cd = Cs + (1 - As) * Cd * Agd */
8943 alpha_config.dst_premulti_en = false;
8944 alpha_config.src_pixel_alpha_en = pixel_alpha_en;
8945 alpha_config.src_glb_alpha_value = vpstate->global_alpha;
8946 alpha_config.dst_glb_alpha_value = dst_global_alpha;
8947 } else if (vop2_cluster_window(win)) {/* Mix output data only have pixel alpha */
8948 alpha_config.dst_premulti_en = true;
8949 alpha_config.src_pixel_alpha_en = true;
8950 alpha_config.src_glb_alpha_value = 0xff;
8951 alpha_config.dst_glb_alpha_value = 0xff;
8952 } else {/* Cd = Cs + (1 - As) * Cd */
8953 alpha_config.dst_premulti_en = true;
8954 alpha_config.src_pixel_alpha_en = pixel_alpha_en;
8955 alpha_config.src_glb_alpha_value = vpstate->global_alpha;
8956 alpha_config.dst_glb_alpha_value = 0xff;
8957 }
8958 vop2_parse_alpha(&alpha_config, &alpha);
8959
8960 offset = (i - 1) * 0x10;
8961 vop2_writel(vop2, src_color_ctrl_offset + offset, alpha.src_color_ctrl.val);
8962 vop2_writel(vop2, dst_color_ctrl_offset + offset, alpha.dst_color_ctrl.val);
8963 vop2_writel(vop2, src_alpha_ctrl_offset + offset, alpha.src_alpha_ctrl.val);
8964 vop2_writel(vop2, dst_alpha_ctrl_offset + offset, alpha.dst_alpha_ctrl.val);
8965 }
8966
8967 /* Transfer pixel alpha value to next mix */
8968 alpha_config.src_premulti_en = true;
8969 alpha_config.dst_premulti_en = true;
8970 alpha_config.src_pixel_alpha_en = false;
8971 alpha_config.src_glb_alpha_value = 0xff;
8972 alpha_config.dst_glb_alpha_value = 0xff;
8973 vop2_parse_alpha(&alpha_config, &alpha);
8974
8975 for (; i < vop2->data->nr_layers; i++) {
8976 offset = (i - 1) * 0x10;
8977
8978 vop2_writel(vop2, src_color_ctrl_offset + offset, alpha.src_color_ctrl.val);
8979 vop2_writel(vop2, dst_color_ctrl_offset + offset, alpha.dst_color_ctrl.val);
8980 vop2_writel(vop2, src_alpha_ctrl_offset + offset, alpha.src_alpha_ctrl.val);
8981 vop2_writel(vop2, dst_alpha_ctrl_offset + offset, alpha.dst_alpha_ctrl.val);
8982 }
8983
8984 if (vp_data->feature & (VOP_FEATURE_HDR10 | VOP_FEATURE_VIVID_HDR)) {
8985 src_color_ctrl_offset = ovl_regs->hdr_mix_regs->src_color_ctrl.offset;
8986 dst_color_ctrl_offset = ovl_regs->hdr_mix_regs->dst_color_ctrl.offset;
8987 src_alpha_ctrl_offset = ovl_regs->hdr_mix_regs->src_alpha_ctrl.offset;
8988 dst_alpha_ctrl_offset = ovl_regs->hdr_mix_regs->dst_alpha_ctrl.offset;
8989
8990 if (bottom_layer_alpha_en || vp->hdr_en) {
8991 /* Transfer pixel alpha to hdr mix */
8992 alpha_config.src_premulti_en = premulti_en;
8993 alpha_config.dst_premulti_en = true;
8994 alpha_config.src_pixel_alpha_en = true;
8995 alpha_config.src_glb_alpha_value = 0xff;
8996 alpha_config.dst_glb_alpha_value = 0xff;
8997 vop2_parse_alpha(&alpha_config, &alpha);
8998
8999 vop2_writel(vop2, src_color_ctrl_offset, alpha.src_color_ctrl.val);
9000 vop2_writel(vop2, dst_color_ctrl_offset, alpha.dst_color_ctrl.val);
9001 vop2_writel(vop2, src_alpha_ctrl_offset, alpha.src_alpha_ctrl.val);
9002 vop2_writel(vop2, dst_alpha_ctrl_offset, alpha.dst_alpha_ctrl.val);
9003 } else {
9004 vop2_writel(vop2, src_color_ctrl_offset, 0);
9005 vop2_writel(vop2, dst_color_ctrl_offset, 0);
9006 vop2_writel(vop2, src_alpha_ctrl_offset, 0);
9007 vop2_writel(vop2, dst_alpha_ctrl_offset, 0);
9008 }
9009 }
9010
9011 bg_alpha_ctrl.bits.alpha_en = 0;
9012 VOP_MODULE_SET(vop2, vp, bg_mix_ctrl, bg_alpha_ctrl.val);
9013 }
9014
vop2_layer_cfg_update(struct vop2_layer * layer,u32 old_layer_cfg,u8 win_layer_id)9015 static u32 vop2_layer_cfg_update(struct vop2_layer *layer, u32 old_layer_cfg, u8 win_layer_id)
9016 {
9017 const struct vop_reg *reg = &layer->regs->layer_sel;
9018 u32 mask = reg->mask;
9019 u32 shift = reg->shift;
9020
9021 return (old_layer_cfg & ~(mask << shift)) | ((win_layer_id & mask) << shift);
9022 }
9023
vop2_calc_bg_ovl_and_port_mux(struct vop2_video_port * vp)9024 static u16 vop2_calc_bg_ovl_and_port_mux(struct vop2_video_port *vp)
9025 {
9026 struct vop2_video_port *prev_vp;
9027 struct vop2 *vop2 = vp->vop2;
9028 const struct vop2_data *vop2_data = vop2->data;
9029 u16 port_mux_cfg = 0;
9030 u8 port_mux;
9031 u8 used_layers = 0;
9032 int i;
9033
9034 for (i = 0; i < vop2_data->nr_vps - 1; i++) {
9035 prev_vp = &vop2->vps[i];
9036 used_layers += hweight32(prev_vp->win_mask);
9037 if (vop2->version == VOP_VERSION_RK3588) {
9038 if (vop2->vps[0].hdr10_at_splice_mode && i == 0)
9039 used_layers += 1;
9040 if (vop2->vps[0].hdr10_at_splice_mode && i == 1)
9041 used_layers -= 1;
9042 }
9043 /*
9044 * when a window move from vp0 to vp1, or vp0 to vp2,
9045 * it should flow these steps:
9046 * (1) first commit, disable this windows on VP0,
9047 * keep the win_mask of VP0.
9048 * (2) second commit, set this window to VP1, clear
9049 * the corresponding win_mask on VP0, and set the
9050 * corresponding win_mask on VP1.
9051 * This means we only know the decrease of the windows
9052 * number of VP0 until VP1 take it, so the port_mux of
9053 * VP0 should change at VP1's commit.
9054 */
9055 if (used_layers == 0)
9056 port_mux = 8;
9057 else
9058 port_mux = used_layers - 1;
9059
9060 port_mux_cfg |= port_mux << (prev_vp->id * 4);
9061
9062 if (port_mux > vop2_data->nr_mixers)
9063 prev_vp->bg_ovl_dly = 0;
9064 else
9065 prev_vp->bg_ovl_dly = (vop2_data->nr_mixers - port_mux) << 1;
9066 }
9067
9068 port_mux_cfg |= 7 << (4 * (vop2->data->nr_vps - 1));
9069
9070 return port_mux_cfg;
9071 }
9072
vop2_setup_port_mux(struct vop2_video_port * vp)9073 static void vop2_setup_port_mux(struct vop2_video_port *vp)
9074 {
9075 struct vop2 *vop2 = vp->vop2;
9076 u16 port_mux_cfg;
9077
9078 port_mux_cfg = vop2_calc_bg_ovl_and_port_mux(vp);
9079 spin_lock(&vop2->reg_lock);
9080 if (vop2->port_mux_cfg != port_mux_cfg) {
9081 VOP_CTRL_SET(vop2, ovl_port_mux_cfg, port_mux_cfg);
9082 vp->skip_vsync = true;
9083 vop2_cfg_done(&vp->rockchip_crtc.crtc);
9084 vop2->port_mux_cfg = port_mux_cfg;
9085 vop2_wait_for_port_mux_done(vop2);
9086 }
9087 spin_unlock(&vop2->reg_lock);
9088 }
9089
vop2_setup_layer_mixer_for_vp(struct vop2_video_port * vp,const struct vop2_zpos * vop2_zpos)9090 static void vop2_setup_layer_mixer_for_vp(struct vop2_video_port *vp,
9091 const struct vop2_zpos *vop2_zpos)
9092 {
9093 struct vop2_video_port *prev_vp;
9094 struct vop2 *vop2 = vp->vop2;
9095 struct vop2_layer *layer = &vop2->layers[0];
9096 u8 port_id = vp->id;
9097 const struct vop2_zpos *zpos;
9098 struct vop2_win *win;
9099 u8 used_layers = 0;
9100 u8 layer_id, win_phys_id;
9101 u32 layer_cfg_reg_offset = layer->regs->layer_sel.offset;
9102 u8 nr_layers = vp->nr_layers;
9103 u32 old_layer_cfg = 0;
9104 u32 new_layer_cfg = 0;
9105 u32 atv_layer_cfg;
9106 int i;
9107
9108 /*
9109 * Win and layer must map one by one, if a win is selected
9110 * by two layers, unexpected error may happen.
9111 * So when we attach a new win to a layer, we also move the
9112 * old win of the layer to the layer where the new win comes from.
9113 *
9114 */
9115 for (i = 0; i < port_id; i++) {
9116 prev_vp = &vop2->vps[i];
9117 used_layers += hweight32(prev_vp->win_mask);
9118 }
9119
9120 old_layer_cfg = vop2->regsbak[layer_cfg_reg_offset >> 2];
9121 new_layer_cfg = old_layer_cfg;
9122
9123 if (vp->hdr10_at_splice_mode)
9124 nr_layers *= 2;
9125
9126 for (i = 0; i < nr_layers; i++) {
9127 layer = &vop2->layers[used_layers + i];
9128 zpos = &vop2_zpos[i];
9129 win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
9130 layer_id = win->layer_id;
9131 win_phys_id = layer->win_phys_id;
9132 VOP_CTRL_SET(vop2, win_vp_id[win->phys_id], port_id);
9133 new_layer_cfg = vop2_layer_cfg_update(layer, new_layer_cfg, win->layer_sel_id[vp->id]);
9134 win->layer_id = layer->id;
9135 layer->win_phys_id = win->phys_id;
9136 layer = &vop2->layers[layer_id];
9137 win = vop2_find_win_by_phys_id(vop2, win_phys_id);
9138 new_layer_cfg = vop2_layer_cfg_update(layer, new_layer_cfg, win->layer_sel_id[vp->id]);
9139 win->layer_id = layer_id;
9140 layer->win_phys_id = win_phys_id;
9141 }
9142
9143 atv_layer_cfg = vop2_read_layer_cfg(vop2);
9144 if (new_layer_cfg != old_layer_cfg &&
9145 atv_layer_cfg != old_layer_cfg &&
9146 !vp->splice_mode_right) {
9147 dev_dbg(vop2->dev, "wait old_layer_sel: 0x%x\n", old_layer_cfg);
9148 vop2_wait_for_layer_cfg_done(vop2, old_layer_cfg);
9149 }
9150 vop2_writel(vop2, RK3568_OVL_LAYER_SEL, new_layer_cfg);
9151 if (new_layer_cfg != old_layer_cfg)
9152 VOP_CTRL_SET(vop2, ovl_cfg_done_port, vp->id);
9153 VOP_CTRL_SET(vop2, ovl_port_mux_cfg_done_imd, 0);
9154 }
9155
vop3_setup_layer_sel_for_vp(struct vop2_video_port * vp,const struct vop2_zpos * vop2_zpos)9156 static void vop3_setup_layer_sel_for_vp(struct vop2_video_port *vp,
9157 const struct vop2_zpos *vop2_zpos)
9158 {
9159 struct vop2 *vop2 = vp->vop2;
9160 const struct vop2_zpos *zpos;
9161 struct vop2_win *win;
9162 u32 layer_sel = 0;
9163 u8 port_id = vp->id;
9164 u8 layer_sel_id;
9165 u8 layer_sel_none = 0xff;
9166 int i;
9167
9168 for (i = 0; i < vop2->data->nr_layers; i++) {
9169 layer_sel_id = layer_sel_none;
9170 if (i < vp->nr_layers) {
9171 zpos = &vop2_zpos[i];
9172 win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
9173 if (win->old_vp_mask != win->vp_mask && VOP_WIN_GET(vop2, win, enable))
9174 DRM_ERROR("must wait %s disabled and change vp_mask[0x%x->0x%x]\n",
9175 win->name, win->old_vp_mask, win->vp_mask);
9176 VOP_CTRL_SET(vop2, win_vp_id[win->phys_id], port_id);
9177 layer_sel_id = win->layer_sel_id[vp->id];
9178 }
9179 layer_sel |= layer_sel_id << i * 4;
9180 }
9181 VOP_MODULE_SET(vop2, vp, layer_sel, layer_sel);
9182 }
9183
9184 /*
9185 * HDR window is fixed(not move in the overlay path with port_mux change)
9186 * and is the most slow window. And the bg is the fast. So other windows
9187 * and bg need to add delay number to keep align with the most slow window.
9188 * The delay number list in the trm is a relative value for port_mux set at
9189 * last level.
9190 */
vop2_setup_dly_for_vp(struct vop2_video_port * vp)9191 static void vop2_setup_dly_for_vp(struct vop2_video_port *vp)
9192 {
9193 struct vop2 *vop2 = vp->vop2;
9194 const struct vop2_data *vop2_data = vop2->data;
9195 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
9196 struct vop2_video_port *left_vp = vp->left_vp;
9197 struct drm_crtc *crtc = &vp->rockchip_crtc.crtc;
9198 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
9199 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
9200 u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
9201 u16 hdisplay = adjusted_mode->crtc_hdisplay;
9202 u32 bg_dly = vp_data->pre_scan_max_dly[0];
9203 u32 pre_scan_dly;
9204
9205 if (vp_data->hdr_table) {
9206 if (vp->hdr_in) {
9207 if (vp->hdr_out)
9208 bg_dly = vp_data->pre_scan_max_dly[2];
9209 } else {
9210 if (vp->hdr_out)
9211 bg_dly = vp_data->pre_scan_max_dly[1];
9212 else
9213 bg_dly = vp_data->pre_scan_max_dly[3];
9214 }
9215 }
9216
9217 if (!vp->hdr_in ||
9218 (vop2->version == VOP_VERSION_RK3588 && vp->hdr_out))
9219 bg_dly -= vp->bg_ovl_dly;
9220
9221 /*
9222 * right vp share the same crtc state in splice mode
9223 */
9224 if (vp->splice_mode_right) {
9225 vcstate = to_rockchip_crtc_state(left_vp->rockchip_crtc.crtc.state);
9226 adjusted_mode = &left_vp->rockchip_crtc.crtc.state->adjusted_mode;
9227 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
9228 hdisplay = adjusted_mode->crtc_hdisplay;
9229 }
9230
9231 if (vcstate->splice_mode)
9232 pre_scan_dly = bg_dly + (hdisplay >> 2) - 1;
9233 else
9234 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
9235
9236 if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8)
9237 hsync_len = 8;
9238
9239 pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
9240
9241 VOP_MODULE_SET(vop2, vp, bg_dly, bg_dly);
9242 VOP_MODULE_SET(vop2, vp, pre_scan_htiming, pre_scan_dly);
9243 }
9244
vop2_setup_dly_for_window(struct vop2_video_port * vp,const struct vop2_zpos * vop2_zpos)9245 static void vop2_setup_dly_for_window(struct vop2_video_port *vp, const struct vop2_zpos *vop2_zpos)
9246 {
9247 struct vop2 *vop2 = vp->vop2;
9248 struct vop2_plane_state *vpstate;
9249 const struct vop2_zpos *zpos;
9250 struct drm_plane *plane;
9251 struct vop2_win *win;
9252 uint32_t dly;
9253 int i = 0;
9254
9255 for (i = 0; i < vp->nr_layers; i++) {
9256 zpos = &vop2_zpos[i];
9257 win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
9258 /*
9259 * right vp share the same plane state in splice mode
9260 */
9261 if (vp->splice_mode_right) {
9262 plane = &win->left_win->base;
9263 vpstate = to_vop2_plane_state(plane->state);
9264 } else {
9265 plane = &win->base;
9266 vpstate = to_vop2_plane_state(plane->state);
9267 }
9268
9269 if (vp->hdr_in && !vp->hdr_out && !vpstate->hdr_in) {
9270 dly = win->dly[VOP2_DLY_MODE_HISO_S];
9271 dly += vp->bg_ovl_dly;
9272 } else if (vp->hdr_in && vp->hdr_out && vpstate->hdr_in) {
9273 dly = win->dly[VOP2_DLY_MODE_HIHO_H];
9274 dly -= vp->bg_ovl_dly;
9275 } else {
9276 dly = win->dly[VOP2_DLY_MODE_DEFAULT];
9277 }
9278 if (vop2_cluster_window(win))
9279 dly |= dly << 8;
9280
9281 VOP_CTRL_SET(vop2, win_dly[win->phys_id], dly);
9282 }
9283 }
9284
rk3588_vop2_setup_hdr10_splice_layer_mixer(struct drm_crtc * crtc,struct vop2_zpos * vop2_zpos,struct vop2_zpos * vop2_zpos_splice)9285 static void rk3588_vop2_setup_hdr10_splice_layer_mixer(struct drm_crtc *crtc,
9286 struct vop2_zpos *vop2_zpos,
9287 struct vop2_zpos *vop2_zpos_splice)
9288 {
9289 int zpos_id, i;
9290 struct vop2_zpos *vop2_zpos_splice_hdr;
9291 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9292 struct vop2 *vop2 = vp->vop2;
9293
9294 vop2_zpos_splice_hdr = kmalloc_array(vop2->data->win_size, sizeof(*vop2_zpos),
9295 GFP_KERNEL);
9296 if (!vop2_zpos_splice_hdr)
9297 goto out;
9298
9299 zpos_id = 0;
9300 vop2_zpos_splice_hdr[zpos_id].zpos = zpos_id;
9301 vop2_zpos_splice_hdr[zpos_id].win_phys_id = vop2_zpos[0].win_phys_id;
9302 vop2_zpos_splice_hdr[zpos_id].plane = vop2_zpos[0].plane;
9303
9304 zpos_id++;
9305 vop2_zpos_splice_hdr[zpos_id].zpos = zpos_id;
9306 vop2_zpos_splice_hdr[zpos_id].win_phys_id = vop2_zpos_splice[0].win_phys_id;
9307 vop2_zpos_splice_hdr[zpos_id].plane = vop2_zpos_splice[0].plane;
9308
9309 for (i = 1; i < vp->nr_layers; i++) {
9310 zpos_id++;
9311 vop2_zpos_splice_hdr[zpos_id].zpos = zpos_id;
9312 vop2_zpos_splice_hdr[zpos_id].win_phys_id = vop2_zpos[i].win_phys_id;
9313 vop2_zpos_splice_hdr[zpos_id].plane = vop2_zpos[i].plane;
9314 }
9315
9316 for (i = 1; i < vp->nr_layers; i++) {
9317 zpos_id++;
9318 vop2_zpos_splice_hdr[zpos_id].zpos = zpos_id;
9319 vop2_zpos_splice_hdr[zpos_id].win_phys_id = vop2_zpos_splice[i].win_phys_id;
9320 vop2_zpos_splice_hdr[zpos_id].plane = vop2_zpos_splice[i].plane;
9321 }
9322 vop2_setup_layer_mixer_for_vp(vp, vop2_zpos_splice_hdr);
9323
9324 out:
9325 kfree(vop2_zpos_splice_hdr);
9326 }
9327
vop2_crtc_update_vrr(struct drm_crtc * crtc)9328 static void vop2_crtc_update_vrr(struct drm_crtc *crtc)
9329 {
9330 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
9331 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9332 struct vop2 *vop2 = vp->vop2;
9333 struct drm_display_mode *adjust_mode = &crtc->state->adjusted_mode;
9334
9335 unsigned int vrefresh;
9336 unsigned int new_vtotal, vfp, new_vfp;
9337
9338 if (!vp->refresh_rate_change)
9339 return;
9340
9341 if (!vcstate->min_refresh_rate || !vcstate->max_refresh_rate)
9342 return;
9343
9344 if (vcstate->request_refresh_rate < vcstate->min_refresh_rate ||
9345 vcstate->request_refresh_rate > vcstate->max_refresh_rate) {
9346 DRM_ERROR("invalid rate:%d\n", vcstate->request_refresh_rate);
9347 return;
9348 }
9349
9350 vrefresh = drm_mode_vrefresh(adjust_mode);
9351
9352 /* calculate new vfp for new refresh rate */
9353 new_vtotal = adjust_mode->vtotal * vrefresh / vcstate->request_refresh_rate;
9354 vfp = adjust_mode->vsync_start - adjust_mode->vdisplay;
9355 new_vfp = vfp + new_vtotal - adjust_mode->vtotal;
9356
9357 /* config vop2 vtotal register */
9358 VOP_MODULE_SET(vop2, vp, dsp_vtotal, new_vtotal);
9359
9360 /* config dsc vtotal register */
9361 if (vcstate->dsc_enable) {
9362 struct vop2_dsc *dsc;
9363
9364 dsc = &vop2->dscs[vcstate->dsc_id];
9365 VOP_MODULE_SET(vop2, dsc, dsc_vtotal, new_vtotal);
9366
9367 if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
9368 dsc = &vop2->dscs[vcstate->dsc_id ? 0 : 1];
9369 VOP_MODULE_SET(vop2, dsc, dsc_vtotal, new_vtotal);
9370 }
9371 }
9372
9373 /* config all connectors attach to this crtc */
9374 rockchip_connector_update_vfp_for_vrr(crtc, adjust_mode, new_vfp);
9375 }
9376
vop2_crtc_atomic_begin(struct drm_crtc * crtc,struct drm_crtc_state * old_crtc_state)9377 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state)
9378 {
9379 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9380 struct vop2 *vop2 = vp->vop2;
9381 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
9382 struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
9383 struct drm_plane *plane;
9384 struct vop2_plane_state *vpstate;
9385 struct vop2_zpos *vop2_zpos;
9386 struct vop2_zpos *vop2_zpos_splice;
9387 struct vop2_cluster cluster;
9388 uint8_t nr_layers = 0;
9389 uint8_t splice_nr_layers = 0;
9390 bool hdr10_in = false;
9391 bool hdr10_at_splice_mode = false;
9392 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
9393
9394 vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format);
9395 vop2_zpos = kmalloc_array(vop2->data->win_size, sizeof(*vop2_zpos), GFP_KERNEL);
9396 if (!vop2_zpos)
9397 return;
9398 if (vcstate->splice_mode) {
9399 vop2_zpos_splice = kmalloc_array(vop2->data->win_size, sizeof(*vop2_zpos),
9400 GFP_KERNEL);
9401 if (!vop2_zpos_splice)
9402 goto out;
9403 }
9404
9405 if (vop2->version == VOP_VERSION_RK3588)
9406 vop2_crtc_update_vrr(crtc);
9407
9408 /* Process cluster sub windows overlay. */
9409 drm_atomic_crtc_for_each_plane(plane, crtc) {
9410 struct vop2_win *win = to_vop2_win(plane);
9411 struct vop2_win *main_win;
9412
9413 win->two_win_mode = false;
9414 if (!(win->feature & WIN_FEATURE_CLUSTER_SUB))
9415 continue;
9416 if (vcstate->splice_mode)
9417 DRM_ERROR("vp%d %s not supported two win mode at splice mode\n",
9418 vp->id, win->name);
9419 main_win = vop2_find_win_by_phys_id(vop2, win->phys_id);
9420 cluster.main = main_win;
9421 cluster.sub = win;
9422 cluster.splice_mode = false;
9423 win->two_win_mode = true;
9424 main_win->two_win_mode = true;
9425 vop2_setup_cluster_alpha(vop2, &cluster);
9426 if (abs(main_win->base.state->zpos - win->base.state->zpos) != 1)
9427 DRM_ERROR("vp%d Cluster%d win0[zpos:%d] must next to win1[zpos:%d]\n",
9428 vp->id, cluster.main->phys_id,
9429 main_win->base.state->zpos, win->base.state->zpos);
9430 }
9431
9432 drm_atomic_crtc_for_each_plane(plane, crtc) {
9433 struct vop2_win *win = to_vop2_win(plane);
9434 struct vop2_win *splice_win;
9435 struct vop2_video_port *old_vp;
9436 uint8_t old_vp_id;
9437
9438 /*
9439 * Sub win of a cluster will be handled by pre overlay module automatically
9440 * win in multi area share the same overlay zorder with it's parent.
9441 */
9442 if ((win->feature & WIN_FEATURE_CLUSTER_SUB) || win->parent)
9443 continue;
9444 old_vp_id = ffs(win->vp_mask);
9445 old_vp_id = (old_vp_id == 0) ? 0 : old_vp_id - 1;
9446 old_vp = &vop2->vps[old_vp_id];
9447 old_vp->win_mask &= ~BIT(win->phys_id);
9448 vp->win_mask |= BIT(win->phys_id);
9449 win->vp_mask = BIT(vp->id);
9450 vpstate = to_vop2_plane_state(plane->state);
9451 vop2_zpos[nr_layers].win_phys_id = win->phys_id;
9452 vop2_zpos[nr_layers].zpos = vpstate->zpos;
9453 vop2_zpos[nr_layers].plane = plane;
9454
9455 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_OVERLAY, "%s active zpos:%d for vp%d from vp%d\n",
9456 win->name, vpstate->zpos, vp->id, old_vp->id);
9457 /* left and right win may have different number */
9458 if (vcstate->splice_mode) {
9459 splice_win = vop2_find_win_by_phys_id(vop2, win->splice_win_id);
9460 splice_win->splice_mode_right = true;
9461 splice_win->left_win = win;
9462 win->splice_win = splice_win;
9463
9464 old_vp_id = ffs(splice_win->vp_mask);
9465 old_vp_id = (old_vp_id == 0) ? 0 : old_vp_id - 1;
9466 old_vp = &vop2->vps[old_vp_id];
9467 old_vp->win_mask &= ~BIT(splice_win->phys_id);
9468 splice_vp->win_mask |= BIT(splice_win->phys_id);
9469 splice_win->vp_mask = BIT(splice_vp->id);
9470 hdr10_in |= vpstate->eotf == HDMI_EOTF_SMPTE_ST2084 ? true : false;
9471 vop2_zpos_splice[splice_nr_layers].win_phys_id = splice_win->phys_id;
9472 vop2_zpos_splice[splice_nr_layers].zpos = vpstate->zpos;
9473 vop2_zpos_splice[splice_nr_layers].plane = &splice_win->base;
9474 splice_nr_layers++;
9475 DRM_DEV_DEBUG(vop2->dev, "%s active zpos:%d for vp%d from vp%d\n",
9476 splice_win->name, vpstate->zpos, splice_vp->id, old_vp->id);
9477 }
9478 nr_layers++;
9479 }
9480
9481 if (vcstate->splice_mode) {
9482 if (hdr10_in)
9483 hdr10_at_splice_mode = true;
9484
9485 splice_vp->hdr10_at_splice_mode = hdr10_at_splice_mode;
9486 }
9487 vp->hdr10_at_splice_mode = hdr10_at_splice_mode;
9488
9489 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_OVERLAY, "vp%d: %d windows, active layers %d\n",
9490 vp->id, hweight32(vp->win_mask), nr_layers);
9491 if (nr_layers) {
9492 vp->nr_layers = nr_layers;
9493
9494 sort(vop2_zpos, nr_layers, sizeof(vop2_zpos[0]), vop2_zpos_cmp, NULL);
9495
9496 if (!vp->hdr10_at_splice_mode) {
9497 if (is_vop3(vop2)) {
9498 vop3_setup_layer_sel_for_vp(vp, vop2_zpos);
9499 } else {
9500 vop2_setup_port_mux(vp);
9501 vop2_setup_layer_mixer_for_vp(vp, vop2_zpos);
9502 }
9503 }
9504
9505 if (is_vop3(vop2)) {
9506 if (vp_data->feature & VOP_FEATURE_VIVID_HDR)
9507 vop3_setup_dynamic_hdr(vp, vop2_zpos[0].win_phys_id);
9508 vop3_setup_alpha(vp, vop2_zpos);
9509 vop3_setup_pipe_dly(vp, vop2_zpos);
9510 } else {
9511 vop2_setup_hdr10(vp, vop2_zpos[0].win_phys_id);
9512 vop2_setup_alpha(vp, vop2_zpos);
9513 vop2_setup_dly_for_vp(vp);
9514 vop2_setup_dly_for_window(vp, vop2_zpos);
9515 }
9516
9517 if (vcstate->splice_mode) {/* Fixme for VOP3 8K */
9518 splice_vp->nr_layers = splice_nr_layers;
9519
9520 sort(vop2_zpos_splice, splice_nr_layers, sizeof(vop2_zpos_splice[0]),
9521 vop2_zpos_cmp, NULL);
9522
9523 vop2_setup_port_mux(splice_vp);
9524 if (!vp->hdr10_at_splice_mode)
9525 vop2_setup_layer_mixer_for_vp(splice_vp, vop2_zpos_splice);
9526 vop2_setup_hdr10(splice_vp, vop2_zpos_splice[0].win_phys_id);
9527 vop2_setup_alpha(splice_vp, vop2_zpos_splice);
9528 vop2_setup_dly_for_vp(splice_vp);
9529 vop2_setup_dly_for_window(splice_vp, vop2_zpos_splice);
9530
9531 if (vop2->version == VOP_VERSION_RK3588 &&
9532 vp->hdr10_at_splice_mode)
9533 rk3588_vop2_setup_hdr10_splice_layer_mixer(crtc, vop2_zpos, vop2_zpos_splice);
9534 }
9535 } else {
9536 if (!is_vop3(vop2)) {
9537 vop2_calc_bg_ovl_and_port_mux(vp);
9538 vop2_setup_dly_for_vp(vp);
9539 if (vcstate->splice_mode)
9540 vop2_setup_dly_for_vp(splice_vp);
9541 } else {
9542 vop3_setup_pipe_dly(vp, NULL);
9543 }
9544 }
9545
9546 /* The pre alpha overlay of Cluster still need process in one win mode. */
9547 drm_atomic_crtc_for_each_plane(plane, crtc) {
9548 struct vop2_win *win = to_vop2_win(plane);
9549 struct vop2_win *splice_win;
9550
9551 if (!(win->feature & WIN_FEATURE_CLUSTER_MAIN))
9552 continue;
9553 if (win->two_win_mode)
9554 continue;
9555 cluster.main = win;
9556 cluster.sub = NULL;
9557 cluster.splice_mode = false;
9558 vop2_setup_cluster_alpha(vop2, &cluster);
9559 if (vcstate->splice_mode) {
9560 splice_win = win->splice_win;
9561 cluster.main = splice_win;
9562 cluster.splice_mode = true;
9563 vop2_setup_cluster_alpha(vop2, &cluster);
9564 }
9565 }
9566
9567 if (vcstate->splice_mode)
9568 kfree(vop2_zpos_splice);
9569 out:
9570 kfree(vop2_zpos);
9571 }
9572
vop2_bcsh_reg_update(struct rockchip_crtc_state * vcstate,struct vop2_video_port * vp,struct rockchip_bcsh_state * bcsh_state)9573 static void vop2_bcsh_reg_update(struct rockchip_crtc_state *vcstate,
9574 struct vop2_video_port *vp,
9575 struct rockchip_bcsh_state *bcsh_state)
9576 {
9577 struct vop2 *vop2 = vp->vop2;
9578
9579 VOP_MODULE_SET(vop2, vp, bcsh_r2y_en, vcstate->post_r2y_en);
9580 VOP_MODULE_SET(vop2, vp, bcsh_y2r_en, vcstate->post_y2r_en);
9581 VOP_MODULE_SET(vop2, vp, bcsh_r2y_csc_mode, vcstate->post_csc_mode);
9582 VOP_MODULE_SET(vop2, vp, bcsh_y2r_csc_mode, vcstate->post_csc_mode);
9583 if (!vcstate->bcsh_en) {
9584 VOP_MODULE_SET(vop2, vp, bcsh_en, vcstate->bcsh_en);
9585 return;
9586 }
9587
9588 VOP_MODULE_SET(vop2, vp, bcsh_brightness, bcsh_state->brightness);
9589 VOP_MODULE_SET(vop2, vp, bcsh_contrast, bcsh_state->contrast);
9590 VOP_MODULE_SET(vop2, vp, bcsh_sat_con,
9591 bcsh_state->saturation * bcsh_state->contrast / 0x100);
9592 VOP_MODULE_SET(vop2, vp, bcsh_sin_hue, bcsh_state->sin_hue);
9593 VOP_MODULE_SET(vop2, vp, bcsh_cos_hue, bcsh_state->cos_hue);
9594 VOP_MODULE_SET(vop2, vp, bcsh_out_mode, BCSH_OUT_MODE_NORMAL_VIDEO);
9595 VOP_MODULE_SET(vop2, vp, bcsh_en, vcstate->bcsh_en);
9596 }
9597
vop2_tv_config_update(struct drm_crtc * crtc,struct drm_crtc_state * old_crtc_state)9598 static void vop2_tv_config_update(struct drm_crtc *crtc,
9599 struct drm_crtc_state *old_crtc_state)
9600 {
9601 struct rockchip_crtc_state *vcstate =
9602 to_rockchip_crtc_state(crtc->state);
9603 struct rockchip_crtc_state *old_vcstate =
9604 to_rockchip_crtc_state(old_crtc_state);
9605 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9606 struct vop2 *vop2 = vp->vop2;
9607 const struct vop2_data *vop2_data = vop2->data;
9608 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
9609 int brightness, contrast, saturation, hue, sin_hue, cos_hue;
9610 struct rockchip_bcsh_state bcsh_state;
9611
9612 if (!vcstate->tv_state)
9613 return;
9614
9615 /* post BCSH CSC */
9616 vcstate->post_r2y_en = 0;
9617 vcstate->post_y2r_en = 0;
9618 vcstate->bcsh_en = 0;
9619 if (vcstate->tv_state->brightness != 50 ||
9620 vcstate->tv_state->contrast != 50 ||
9621 vcstate->tv_state->saturation != 50 || vcstate->tv_state->hue != 50)
9622 vcstate->bcsh_en = 1;
9623 /*
9624 * The BCSH only need to config once except one of the following
9625 * condition changed:
9626 * 1. tv_state: include brightness,contrast,saturation and hue;
9627 * 2. yuv_overlay: it is related to BCSH r2y module;
9628 * 4. bcsh_en: control the BCSH module enable or disable state;
9629 * 5. bus_format: it is related to BCSH y2r module;
9630 */
9631 if (!memcmp(vcstate->tv_state, &vp->active_tv_state, sizeof(*vcstate->tv_state)) &&
9632 vcstate->yuv_overlay == old_vcstate->yuv_overlay &&
9633 vcstate->bcsh_en == old_vcstate->bcsh_en &&
9634 vcstate->bus_format == old_vcstate->bus_format)
9635 return;
9636
9637 memcpy(&vp->active_tv_state, vcstate->tv_state, sizeof(*vcstate->tv_state));
9638 if (vcstate->bcsh_en) {
9639 if (!vcstate->yuv_overlay)
9640 vcstate->post_r2y_en = 1;
9641 if (!is_yuv_output(vcstate->bus_format))
9642 vcstate->post_y2r_en = 1;
9643 } else {
9644 if (!vcstate->yuv_overlay && is_yuv_output(vcstate->bus_format))
9645 vcstate->post_r2y_en = 1;
9646 if (vcstate->yuv_overlay && !is_yuv_output(vcstate->bus_format))
9647 vcstate->post_y2r_en = 1;
9648 }
9649
9650 vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_space, CSC_10BIT_DEPTH);
9651
9652 if (vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)
9653 brightness = interpolate(0, -128, 100, 127,
9654 vcstate->tv_state->brightness);
9655 else
9656 brightness = interpolate(0, -32, 100, 31,
9657 vcstate->tv_state->brightness);
9658 contrast = interpolate(0, 0, 100, 511, vcstate->tv_state->contrast);
9659 saturation = interpolate(0, 0, 100, 511, vcstate->tv_state->saturation);
9660 hue = interpolate(0, -30, 100, 30, vcstate->tv_state->hue);
9661
9662 /*
9663 * a:[-30~0]:
9664 * sin_hue = 0x100 - sin(a)*256;
9665 * cos_hue = cos(a)*256;
9666 * a:[0~30]
9667 * sin_hue = sin(a)*256;
9668 * cos_hue = cos(a)*256;
9669 */
9670 sin_hue = fixp_sin32(hue) >> 23;
9671 cos_hue = fixp_cos32(hue) >> 23;
9672
9673 bcsh_state.brightness = brightness;
9674 bcsh_state.contrast = contrast;
9675 bcsh_state.saturation = saturation;
9676 bcsh_state.sin_hue = sin_hue;
9677 bcsh_state.cos_hue = cos_hue;
9678
9679 vop2_bcsh_reg_update(vcstate, vp, &bcsh_state);
9680 if (vcstate->splice_mode) {
9681 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
9682 struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
9683
9684 vop2_bcsh_reg_update(vcstate, splice_vp, &bcsh_state);
9685 }
9686 }
9687
vop3_post_csc_config(struct drm_crtc * crtc,struct post_acm * acm,struct post_csc * csc)9688 static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, struct post_csc *csc)
9689 {
9690 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9691 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
9692 struct vop2 *vop2 = vp->vop2;
9693 struct post_csc_coef csc_coef;
9694 bool acm_enable;
9695 bool is_input_yuv = false;
9696 bool is_output_yuv = false;
9697 bool post_r2y_en = false;
9698 bool post_csc_en = false;
9699 int range_type;
9700
9701 if (!acm)
9702 acm_enable = false;
9703 else
9704 acm_enable = acm->acm_enable;
9705
9706 if (acm_enable) {
9707 if (!vcstate->yuv_overlay)
9708 post_r2y_en = true;
9709
9710 /* do y2r in csc module */
9711 if (!is_yuv_output(vcstate->bus_format))
9712 post_csc_en = true;
9713 } else {
9714 if (!vcstate->yuv_overlay && is_yuv_output(vcstate->bus_format))
9715 post_r2y_en = true;
9716
9717 /* do y2r in csc module */
9718 if (vcstate->yuv_overlay && !is_yuv_output(vcstate->bus_format))
9719 post_csc_en = true;
9720 }
9721
9722 if (csc && csc->csc_enable)
9723 post_csc_en = true;
9724
9725 if (vcstate->yuv_overlay || post_r2y_en)
9726 is_input_yuv = true;
9727
9728 if (is_yuv_output(vcstate->bus_format))
9729 is_output_yuv = true;
9730
9731 vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_space, CSC_13BIT_DEPTH);
9732
9733 if (post_csc_en) {
9734 rockchip_calc_post_csc(csc, &csc_coef, vcstate->post_csc_mode, is_input_yuv,
9735 is_output_yuv);
9736
9737 VOP_MODULE_SET(vop2, vp, csc_coe00, csc_coef.csc_coef00);
9738 VOP_MODULE_SET(vop2, vp, csc_coe01, csc_coef.csc_coef01);
9739 VOP_MODULE_SET(vop2, vp, csc_coe02, csc_coef.csc_coef02);
9740 VOP_MODULE_SET(vop2, vp, csc_coe10, csc_coef.csc_coef10);
9741 VOP_MODULE_SET(vop2, vp, csc_coe11, csc_coef.csc_coef11);
9742 VOP_MODULE_SET(vop2, vp, csc_coe12, csc_coef.csc_coef12);
9743 VOP_MODULE_SET(vop2, vp, csc_coe20, csc_coef.csc_coef20);
9744 VOP_MODULE_SET(vop2, vp, csc_coe21, csc_coef.csc_coef21);
9745 VOP_MODULE_SET(vop2, vp, csc_coe22, csc_coef.csc_coef22);
9746 VOP_MODULE_SET(vop2, vp, csc_offset0, csc_coef.csc_dc0);
9747 VOP_MODULE_SET(vop2, vp, csc_offset1, csc_coef.csc_dc1);
9748 VOP_MODULE_SET(vop2, vp, csc_offset2, csc_coef.csc_dc2);
9749
9750 range_type = csc_coef.range_type ? 0 : 1;
9751 range_type <<= is_input_yuv ? 0 : 1;
9752 VOP_MODULE_SET(vop2, vp, csc_mode, range_type);
9753 }
9754
9755 VOP_MODULE_SET(vop2, vp, acm_r2y_en, post_r2y_en ? 1 : 0);
9756 VOP_MODULE_SET(vop2, vp, csc_en, post_csc_en ? 1 : 0);
9757 VOP_MODULE_SET(vop2, vp, acm_r2y_mode, vcstate->post_csc_mode);
9758 }
9759
vop3_post_acm_config(struct drm_crtc * crtc,struct post_acm * acm)9760 static void vop3_post_acm_config(struct drm_crtc *crtc, struct post_acm *acm)
9761 {
9762 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9763 struct vop2 *vop2 = vp->vop2;
9764 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
9765 s16 *lut_y;
9766 s16 *lut_h;
9767 s16 *lut_s;
9768 u32 value;
9769 int i;
9770
9771 writel(0, vop2->acm_regs + RK3528_ACM_CTRL);
9772 VOP_MODULE_SET(vop2, vp, acm_bypass_en, 0);
9773
9774 if (!acm || !acm->acm_enable)
9775 return;
9776
9777 /*
9778 * If acm update parameters, it need disable acm in the first frame,
9779 * then update parameters and enable acm in second frame.
9780 */
9781 vop2_cfg_done(crtc);
9782 readx_poll_timeout(readl, vop2->acm_regs + RK3528_ACM_CTRL, value, !value, 200, 50000);
9783
9784 value = RK3528_ACM_ENABLE + ((adjusted_mode->hdisplay & 0xfff) << 8) +
9785 ((adjusted_mode->vdisplay & 0xfff) << 20);
9786 writel(value, vop2->acm_regs + RK3528_ACM_CTRL);
9787
9788
9789 writel(1, vop2->acm_regs + RK3528_ACM_FETCH_START);
9790
9791 value = (acm->y_gain & 0x3ff) + ((acm->h_gain << 10) & 0xffc00) +
9792 ((acm->s_gain << 20) & 0x3ff00000);
9793 writel(value, vop2->acm_regs + RK3528_ACM_DELTA_RANGE);
9794
9795 lut_y = &acm->gain_lut_hy[0];
9796 lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH];
9797 lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2];
9798 for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) {
9799 value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
9800 ((lut_s[i] << 16) & 0xff0000);
9801 writel(value, vop2->acm_regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2));
9802 }
9803
9804 lut_y = &acm->gain_lut_hs[0];
9805 lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH];
9806 lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2];
9807 for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) {
9808 value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
9809 ((lut_s[i] << 16) & 0xff0000);
9810 writel(value, vop2->acm_regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2));
9811 }
9812
9813 lut_y = &acm->delta_lut_h[0];
9814 lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH];
9815 lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2];
9816 for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) {
9817 value = (lut_y[i] & 0x3ff) + ((lut_h[i] << 12) & 0xff000) +
9818 ((lut_s[i] << 20) & 0x3ff00000);
9819 writel(value, vop2->acm_regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2));
9820 }
9821
9822 writel(1, vop2->acm_regs + RK3528_ACM_FETCH_DONE);
9823 }
9824
vop3_post_config(struct drm_crtc * crtc)9825 static void vop3_post_config(struct drm_crtc *crtc)
9826 {
9827 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
9828 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9829 struct post_acm *acm;
9830 struct post_csc *csc;
9831
9832 csc = vcstate->post_csc_data ? (struct post_csc *)vcstate->post_csc_data->data : NULL;
9833 if (csc && memcmp(&vp->csc_info, csc, sizeof(struct post_csc)))
9834 memcpy(&vp->csc_info, csc, sizeof(struct post_csc));
9835 vop3_post_csc_config(crtc, &vp->acm_info, &vp->csc_info);
9836
9837 acm = vcstate->acm_lut_data ? (struct post_acm *)vcstate->acm_lut_data->data : NULL;
9838
9839 if (acm && memcmp(&vp->acm_info, acm, sizeof(struct post_acm))) {
9840 memcpy(&vp->acm_info, acm, sizeof(struct post_acm));
9841 vop3_post_acm_config(crtc, &vp->acm_info);
9842 } else if (crtc->state->active_changed) {
9843 vop3_post_acm_config(crtc, &vp->acm_info);
9844 }
9845 }
9846
vop2_cfg_update(struct drm_crtc * crtc,struct drm_crtc_state * old_crtc_state)9847 static void vop2_cfg_update(struct drm_crtc *crtc,
9848 struct drm_crtc_state *old_crtc_state)
9849 {
9850 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9851 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
9852 struct vop2 *vop2 = vp->vop2;
9853 const struct vop2_data *vop2_data = vop2->data;
9854 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
9855 struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
9856 uint32_t val;
9857 uint32_t r, g, b;
9858 uint8_t out_mode;
9859
9860 spin_lock(&vop2->reg_lock);
9861
9862 if ((vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
9863 !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) ||
9864 vcstate->output_if & VOP_OUTPUT_IF_BT656)
9865 out_mode = ROCKCHIP_OUT_MODE_P888;
9866 else
9867 out_mode = vcstate->output_mode;
9868 VOP_MODULE_SET(vop2, vp, out_mode, out_mode);
9869
9870 vop2_post_color_swap(crtc);
9871
9872 vop2_dither_setup(vcstate, crtc);
9873 if (vcstate->splice_mode)
9874 vop2_dither_setup(vcstate, &splice_vp->rockchip_crtc.crtc);
9875
9876 VOP_MODULE_SET(vop2, vp, overlay_mode, vcstate->yuv_overlay);
9877
9878 /*
9879 * userspace specified background.
9880 */
9881 if (vcstate->background) {
9882 r = (vcstate->background & 0xff0000) >> 16;
9883 g = (vcstate->background & 0xff00) >> 8;
9884 b = (vcstate->background & 0xff);
9885 r <<= 2;
9886 g <<= 2;
9887 b <<= 2;
9888 val = (r << 20) | (g << 10) | b;
9889 } else {
9890 if (vcstate->yuv_overlay)
9891 val = 0x20010200;
9892 else
9893 val = 0;
9894 }
9895
9896 VOP_MODULE_SET(vop2, vp, dsp_background, val);
9897 if (vcstate->splice_mode) {
9898 VOP_MODULE_SET(vop2, splice_vp, overlay_mode, vcstate->yuv_overlay);
9899 VOP_MODULE_SET(vop2, splice_vp, dsp_background, val);
9900 }
9901
9902 vop2_tv_config_update(crtc, old_crtc_state);
9903
9904 if (vp_data->feature & VOP_FEATURE_OVERSCAN)
9905 vop2_post_config(crtc);
9906
9907 spin_unlock(&vop2->reg_lock);
9908
9909 if (vp_data->feature & (VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC))
9910 vop3_post_config(crtc);
9911 }
9912
vop2_sleep_scan_line_time(struct vop2_video_port * vp,int scan_line)9913 static void vop2_sleep_scan_line_time(struct vop2_video_port *vp, int scan_line)
9914 {
9915 struct vop2 *vop2 = vp->vop2;
9916 struct drm_display_mode *mode = &vp->rockchip_crtc.crtc.state->adjusted_mode;
9917
9918 if (scan_line <= 0)
9919 return;
9920
9921 if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS) &&
9922 (!IS_ENABLED(CONFIG_NO_GKI) || (hrtimer_resolution != LOW_RES_NSEC))) {
9923 u16 htotal = VOP_MODULE_GET(vop2, vp, htotal_pw) >> 16;
9924 u32 linedur_ns = div_u64((u64) htotal * 1000000, mode->crtc_clock);
9925 u64 sleep_time = linedur_ns * scan_line;
9926
9927 sleep_time = div_u64((sleep_time + 1000), 1000);
9928 if (sleep_time > 200)
9929 usleep_range(sleep_time, sleep_time);
9930 }
9931 }
9932
9933 /*
9934 * return scan timing from FS to the assigned wait line
9935 */
vop2_wait_for_scan_timing_max_to_assigned_line(struct vop2_video_port * vp,u32 current_line,u32 wait_line)9936 static void vop2_wait_for_scan_timing_max_to_assigned_line(struct vop2_video_port *vp,
9937 u32 current_line,
9938 u32 wait_line)
9939
9940 {
9941 struct vop2 *vop2 = vp->vop2;
9942 u32 vcnt;
9943 int ret;
9944 u16 vtotal = VOP_MODULE_GET(vop2, vp, dsp_vtotal);
9945 int delta_line = vtotal - current_line;
9946
9947 vop2_sleep_scan_line_time(vp, delta_line);
9948 if (vop2_read_vcnt(vp) < wait_line)
9949 return;
9950
9951 ret = readx_poll_timeout_atomic(vop2_read_vcnt, vp, vcnt, vcnt < wait_line, 0, 50 * 1000);
9952 if (ret)
9953 DRM_DEV_ERROR(vop2->dev, "wait scan timing from FS to the assigned wait line: %d, vcnt:%d, ret:%d\n",
9954 wait_line, vcnt, ret);
9955 }
9956
9957 /*
9958 * return scan timing from the assigned wait line
9959 */
vop2_wait_for_scan_timing_from_the_assigned_line(struct vop2_video_port * vp,u32 current_line,u32 wait_line)9960 static void vop2_wait_for_scan_timing_from_the_assigned_line(struct vop2_video_port *vp,
9961 u32 current_line,
9962 u32 wait_line)
9963 {
9964 struct vop2 *vop2 = vp->vop2;
9965 u32 vcnt;
9966 int ret;
9967 int delta_line = wait_line - current_line;
9968
9969 vop2_sleep_scan_line_time(vp, delta_line);
9970 if (vop2_read_vcnt(vp) > wait_line)
9971 return;
9972
9973 ret = readx_poll_timeout_atomic(vop2_read_vcnt, vp, vcnt, vcnt > wait_line, 0, 50 * 1000);
9974 if (ret)
9975 DRM_DEV_ERROR(vop2->dev, "wait scan timing from the assigned wait line: %d, vcnt:%d, ret:%d\n",
9976 wait_line, vcnt, ret);
9977 }
9978
vop2_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_crtc_state * old_cstate)9979 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_cstate)
9980 {
9981 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
9982 struct drm_atomic_state *old_state = old_cstate->state;
9983 struct vop2_video_port *vp = to_vop2_video_port(crtc);
9984 struct vop2 *vop2 = vp->vop2;
9985 struct drm_plane_state *old_pstate;
9986 struct drm_plane *plane;
9987 unsigned long flags;
9988 int i, ret;
9989 struct vop2_wb *wb = &vop2->wb;
9990 struct drm_writeback_connector *wb_conn = &wb->conn;
9991 struct drm_connector_state *conn_state = wb_conn->base.state;
9992
9993 if (conn_state && conn_state->writeback_job && conn_state->writeback_job->fb) {
9994 u16 vtotal = VOP_MODULE_GET(vop2, vp, dsp_vtotal);
9995 u32 current_line = vop2_read_vcnt(vp);
9996
9997 if (current_line > vtotal * 7 >> 3)
9998 vop2_wait_for_scan_timing_max_to_assigned_line(vp, current_line, vtotal * 7 >> 3);
9999
10000 current_line = vop2_read_vcnt(vp);
10001 if (current_line < vtotal >> 3)
10002 vop2_wait_for_scan_timing_from_the_assigned_line(vp, current_line, vtotal >> 3);
10003 }
10004
10005 vop2_cfg_update(crtc, old_cstate);
10006
10007 if (!vop2->is_iommu_enabled && vop2->is_iommu_needed) {
10008 if (vcstate->mode_update)
10009 VOP_CTRL_SET(vop2, dma_stop, 1);
10010
10011 ret = rockchip_drm_dma_attach_device(vop2->drm_dev, vop2->dev);
10012 if (ret) {
10013 vop2->is_iommu_enabled = false;
10014 vop2_disable_all_planes_for_crtc(crtc);
10015 DRM_DEV_ERROR(vop2->dev, "vp%d failed to attach dma mapping, %d\n", vp->id, ret);
10016 } else {
10017 vop2->is_iommu_enabled = true;
10018 VOP_CTRL_SET(vop2, dma_stop, 0);
10019 }
10020 }
10021
10022
10023 if (crtc->state->color_mgmt_changed || crtc->state->active_changed) {
10024 if (crtc->state->gamma_lut || vp->gamma_lut) {
10025 if (crtc->state->gamma_lut)
10026 vp->gamma_lut = crtc->state->gamma_lut->data;
10027 vop2_crtc_atomic_gamma_set(crtc, crtc->state);
10028 }
10029 if (vcstate->cubic_lut_data || vp->cubic_lut) {
10030 if (vcstate->cubic_lut_data)
10031 vp->cubic_lut = vcstate->cubic_lut_data->data;
10032 vop2_crtc_atomic_cubic_lut_set(crtc, crtc->state);
10033 }
10034 } else {
10035 VOP_MODULE_SET(vop2, vp, cubic_lut_update_en, 0);
10036 }
10037
10038 if (vcstate->line_flag)
10039 vop2_crtc_enable_line_flag_event(crtc, vcstate->line_flag);
10040 else
10041 vop2_crtc_disable_line_flag_event(crtc);
10042
10043 spin_lock_irqsave(&vop2->irq_lock, flags);
10044 vop2_wb_commit(crtc);
10045 vop2_cfg_done(crtc);
10046
10047 if (vp->mcu_timing.mcu_pix_total)
10048 VOP_MODULE_SET(vop2, vp, mcu_hold_mode, 0);
10049
10050 spin_unlock_irqrestore(&vop2->irq_lock, flags);
10051
10052 /*
10053 * There is a (rather unlikely) possibility that a vblank interrupt
10054 * fired before we set the cfg_done bit. To avoid spuriously
10055 * signalling flip completion we need to wait for it to finish.
10056 */
10057 vop2_wait_for_irq_handler(crtc);
10058
10059 /**
10060 * move here is to make sure current fs call function is complete,
10061 * so when layer_sel_update is true, we can skip current vblank correctly.
10062 */
10063 vp->layer_sel_update = false;
10064
10065 spin_lock_irq(&crtc->dev->event_lock);
10066 if (crtc->state->event) {
10067 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
10068 WARN_ON(vp->event);
10069
10070 vp->event = crtc->state->event;
10071 crtc->state->event = NULL;
10072 }
10073 spin_unlock_irq(&crtc->dev->event_lock);
10074
10075 for_each_old_plane_in_state(old_state, plane, old_pstate, i) {
10076 if (!old_pstate->fb)
10077 continue;
10078
10079 if (old_pstate->fb == plane->state->fb)
10080 continue;
10081 if (!vop2->skip_ref_fb)
10082 drm_framebuffer_get(old_pstate->fb);
10083 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
10084 drm_flip_work_queue(&vp->fb_unref_work, old_pstate->fb);
10085 set_bit(VOP_PENDING_FB_UNREF, &vp->pending);
10086 }
10087 }
10088
10089 static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
10090 .mode_valid = vop2_crtc_mode_valid,
10091 .mode_fixup = vop2_crtc_mode_fixup,
10092 .atomic_check = vop2_crtc_atomic_check,
10093 .atomic_begin = vop2_crtc_atomic_begin,
10094 .atomic_flush = vop2_crtc_atomic_flush,
10095 .atomic_enable = vop2_crtc_atomic_enable,
10096 .atomic_disable = vop2_crtc_atomic_disable,
10097 };
10098
vop2_crtc_destroy(struct drm_crtc * crtc)10099 static void vop2_crtc_destroy(struct drm_crtc *crtc)
10100 {
10101 drm_crtc_cleanup(crtc);
10102 }
10103
vop2_crtc_reset(struct drm_crtc * crtc)10104 static void vop2_crtc_reset(struct drm_crtc *crtc)
10105 {
10106 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
10107
10108 if (crtc->state) {
10109 __drm_atomic_helper_crtc_destroy_state(crtc->state);
10110 kfree(vcstate);
10111 }
10112
10113 vcstate = kzalloc(sizeof(*vcstate), GFP_KERNEL);
10114 if (!vcstate)
10115 return;
10116 crtc->state = &vcstate->base;
10117 crtc->state->crtc = crtc;
10118
10119 vcstate->left_margin = 100;
10120 vcstate->right_margin = 100;
10121 vcstate->top_margin = 100;
10122 vcstate->bottom_margin = 100;
10123 vcstate->background = 0;
10124 }
10125
vop2_crtc_duplicate_state(struct drm_crtc * crtc)10126 static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
10127 {
10128 struct rockchip_crtc_state *vcstate, *old_vcstate;
10129 struct vop2_video_port *vp = to_vop2_video_port(crtc);
10130
10131 if (WARN_ON(!crtc->state))
10132 return NULL;
10133
10134 old_vcstate = to_rockchip_crtc_state(crtc->state);
10135 vcstate = kmemdup(old_vcstate, sizeof(*old_vcstate), GFP_KERNEL);
10136 if (!vcstate)
10137 return NULL;
10138
10139 vcstate->vp_id = vp->id;
10140 if (vcstate->hdr_ext_data)
10141 drm_property_blob_get(vcstate->hdr_ext_data);
10142 if (vcstate->acm_lut_data)
10143 drm_property_blob_get(vcstate->acm_lut_data);
10144 if (vcstate->post_csc_data)
10145 drm_property_blob_get(vcstate->post_csc_data);
10146 if (vcstate->cubic_lut_data)
10147 drm_property_blob_get(vcstate->cubic_lut_data);
10148
10149 __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base);
10150 return &vcstate->base;
10151 }
10152
vop2_crtc_destroy_state(struct drm_crtc * crtc,struct drm_crtc_state * state)10153 static void vop2_crtc_destroy_state(struct drm_crtc *crtc,
10154 struct drm_crtc_state *state)
10155 {
10156 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state);
10157
10158 __drm_atomic_helper_crtc_destroy_state(&vcstate->base);
10159 drm_property_blob_put(vcstate->hdr_ext_data);
10160 drm_property_blob_put(vcstate->acm_lut_data);
10161 drm_property_blob_put(vcstate->post_csc_data);
10162 drm_property_blob_put(vcstate->cubic_lut_data);
10163 kfree(vcstate);
10164 }
10165
10166 #ifdef CONFIG_DRM_ANALOGIX_DP
vop2_get_edp_connector(struct vop2 * vop2)10167 static struct drm_connector *vop2_get_edp_connector(struct vop2 *vop2)
10168 {
10169 struct drm_connector *connector;
10170 struct drm_connector_list_iter conn_iter;
10171
10172 drm_connector_list_iter_begin(vop2->drm_dev, &conn_iter);
10173 drm_for_each_connector_iter(connector, &conn_iter) {
10174 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
10175 drm_connector_list_iter_end(&conn_iter);
10176 return connector;
10177 }
10178 }
10179 drm_connector_list_iter_end(&conn_iter);
10180
10181 return NULL;
10182 }
10183
vop2_crtc_set_crc_source(struct drm_crtc * crtc,const char * source_name)10184 static int vop2_crtc_set_crc_source(struct drm_crtc *crtc,
10185 const char *source_name)
10186 {
10187 struct vop2_video_port *vp = to_vop2_video_port(crtc);
10188 struct vop2 *vop2 = vp->vop2;
10189 struct drm_connector *connector;
10190 int ret;
10191
10192 connector = vop2_get_edp_connector(vop2);
10193 if (!connector)
10194 return -EINVAL;
10195
10196 if (source_name && strcmp(source_name, "auto") == 0)
10197 ret = analogix_dp_start_crc(connector);
10198 else if (!source_name)
10199 ret = analogix_dp_stop_crc(connector);
10200 else
10201 ret = -EINVAL;
10202
10203 return ret;
10204 }
10205
vop2_crtc_verify_crc_source(struct drm_crtc * crtc,const char * source_name,size_t * values_cnt)10206 static int vop2_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
10207 size_t *values_cnt)
10208 {
10209 if (source_name && strcmp(source_name, "auto") != 0)
10210 return -EINVAL;
10211
10212 *values_cnt = 3;
10213 return 0;
10214 }
10215
10216 #else
vop2_crtc_set_crc_source(struct drm_crtc * crtc,const char * source_name)10217 static int vop2_crtc_set_crc_source(struct drm_crtc *crtc,
10218 const char *source_name)
10219 {
10220 return -ENODEV;
10221 }
10222
10223 static int
vop2_crtc_verify_crc_source(struct drm_crtc * crtc,const char * source_name,size_t * values_cnt)10224 vop2_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
10225 size_t *values_cnt)
10226 {
10227 return -ENODEV;
10228 }
10229 #endif
10230
vop2_crtc_atomic_get_property(struct drm_crtc * crtc,const struct drm_crtc_state * state,struct drm_property * property,uint64_t * val)10231 static int vop2_crtc_atomic_get_property(struct drm_crtc *crtc,
10232 const struct drm_crtc_state *state,
10233 struct drm_property *property,
10234 uint64_t *val)
10235 {
10236 struct drm_device *drm_dev = crtc->dev;
10237 struct rockchip_drm_private *private = drm_dev->dev_private;
10238 struct drm_mode_config *mode_config = &drm_dev->mode_config;
10239 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state);
10240 struct vop2_video_port *vp = to_vop2_video_port(crtc);
10241 struct vop2 *vop2 = vp->vop2;
10242
10243 if (property == mode_config->tv_left_margin_property) {
10244 *val = vcstate->left_margin;
10245 return 0;
10246 }
10247
10248 if (property == mode_config->tv_right_margin_property) {
10249 *val = vcstate->right_margin;
10250 return 0;
10251 }
10252
10253 if (property == mode_config->tv_top_margin_property) {
10254 *val = vcstate->top_margin;
10255 return 0;
10256 }
10257
10258 if (property == mode_config->tv_bottom_margin_property) {
10259 *val = vcstate->bottom_margin;
10260 return 0;
10261 }
10262
10263 if (property == private->aclk_prop) {
10264 /* KHZ, keep align with mode->clock */
10265 *val = clk_get_rate(vop2->aclk) / 1000;
10266 return 0;
10267 }
10268
10269 if (property == private->bg_prop) {
10270 *val = vcstate->background;
10271 return 0;
10272 }
10273
10274 if (property == private->line_flag_prop) {
10275 *val = vcstate->line_flag;
10276 return 0;
10277 }
10278
10279 if (property == vp->variable_refresh_rate_prop) {
10280 *val = vcstate->request_refresh_rate;
10281 return 0;
10282 }
10283
10284 if (property == vp->max_refresh_rate_prop) {
10285 *val = vcstate->max_refresh_rate;
10286 return 0;
10287 }
10288
10289 if (property == vp->min_refresh_rate_prop) {
10290 *val = vcstate->min_refresh_rate;
10291 return 0;
10292 }
10293
10294 if (property == vp->hdr_ext_data_prop) {
10295 *val = vcstate->hdr_ext_data ? vcstate->hdr_ext_data->base.id : 0;
10296 return 0;
10297 }
10298
10299 if (property == vp->acm_lut_data_prop) {
10300 *val = vcstate->acm_lut_data ? vcstate->acm_lut_data->base.id : 0;
10301 return 0;
10302 }
10303
10304 if (property == vp->post_csc_data_prop) {
10305 *val = vcstate->post_csc_data ? vcstate->post_csc_data->base.id : 0;
10306 return 0;
10307 }
10308
10309 if (property == private->cubic_lut_prop) {
10310 *val = (vcstate->cubic_lut_data) ? vcstate->cubic_lut_data->base.id : 0;
10311 return 0;
10312 }
10313
10314 DRM_ERROR("failed to get vop2 crtc property: %s\n", property->name);
10315
10316 return -EINVAL;
10317 }
10318
10319 /* copied from drm_atomic.c */
10320 static int
vop2_atomic_replace_property_blob_from_id(struct drm_device * dev,struct drm_property_blob ** blob,uint64_t blob_id,ssize_t expected_size,ssize_t expected_elem_size,bool * replaced)10321 vop2_atomic_replace_property_blob_from_id(struct drm_device *dev,
10322 struct drm_property_blob **blob,
10323 uint64_t blob_id,
10324 ssize_t expected_size,
10325 ssize_t expected_elem_size,
10326 bool *replaced)
10327 {
10328 struct drm_property_blob *new_blob = NULL;
10329
10330 if (blob_id != 0) {
10331 new_blob = drm_property_lookup_blob(dev, blob_id);
10332 if (new_blob == NULL)
10333 return -EINVAL;
10334
10335 if (expected_size > 0 &&
10336 new_blob->length != expected_size) {
10337 drm_property_blob_put(new_blob);
10338 return -EINVAL;
10339 }
10340 if (expected_elem_size > 0 &&
10341 new_blob->length % expected_elem_size != 0) {
10342 drm_property_blob_put(new_blob);
10343 return -EINVAL;
10344 }
10345 }
10346
10347 *replaced |= drm_property_replace_blob(blob, new_blob);
10348 drm_property_blob_put(new_blob);
10349
10350 return 0;
10351 }
10352
vop2_crtc_atomic_set_property(struct drm_crtc * crtc,struct drm_crtc_state * state,struct drm_property * property,uint64_t val)10353 static int vop2_crtc_atomic_set_property(struct drm_crtc *crtc,
10354 struct drm_crtc_state *state,
10355 struct drm_property *property,
10356 uint64_t val)
10357 {
10358 struct drm_device *drm_dev = crtc->dev;
10359 struct rockchip_drm_private *private = drm_dev->dev_private;
10360 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state);
10361 struct drm_mode_config *mode_config = &drm_dev->mode_config;
10362 struct vop2_video_port *vp = to_vop2_video_port(crtc);
10363 bool replaced = false;
10364 int ret;
10365
10366 if (property == mode_config->tv_left_margin_property) {
10367 vcstate->left_margin = val;
10368 return 0;
10369 }
10370
10371 if (property == mode_config->tv_right_margin_property) {
10372 vcstate->right_margin = val;
10373 return 0;
10374 }
10375
10376 if (property == mode_config->tv_top_margin_property) {
10377 vcstate->top_margin = val;
10378 return 0;
10379 }
10380
10381 if (property == mode_config->tv_bottom_margin_property) {
10382 vcstate->bottom_margin = val;
10383 return 0;
10384 }
10385
10386
10387 if (property == private->bg_prop) {
10388 vcstate->background = val;
10389 return 0;
10390 }
10391
10392 if (property == private->line_flag_prop) {
10393 vcstate->line_flag = val;
10394 return 0;
10395 }
10396
10397 if (property == vp->variable_refresh_rate_prop) {
10398 vcstate->request_refresh_rate = val;
10399 return 0;
10400 }
10401
10402 if (property == vp->max_refresh_rate_prop) {
10403 vcstate->max_refresh_rate = val;
10404 return 0;
10405 }
10406
10407 if (property == vp->min_refresh_rate_prop) {
10408 vcstate->min_refresh_rate = val;
10409 return 0;
10410 }
10411
10412 if (property == vp->hdr_ext_data_prop) {
10413 ret = vop2_atomic_replace_property_blob_from_id(drm_dev,
10414 &vcstate->hdr_ext_data,
10415 val,
10416 -1, -1,
10417 &replaced);
10418 return ret;
10419 }
10420
10421 if (property == vp->acm_lut_data_prop) {
10422 ret = vop2_atomic_replace_property_blob_from_id(drm_dev,
10423 &vcstate->acm_lut_data,
10424 val,
10425 sizeof(struct post_acm), -1,
10426 &replaced);
10427 return ret;
10428 }
10429
10430 if (property == vp->post_csc_data_prop) {
10431 ret = vop2_atomic_replace_property_blob_from_id(drm_dev,
10432 &vcstate->post_csc_data,
10433 val,
10434 sizeof(struct post_csc), -1,
10435 &replaced);
10436 return ret;
10437 }
10438
10439 if (property == private->cubic_lut_prop) {
10440 ret = vop2_atomic_replace_property_blob_from_id(drm_dev,
10441 &vcstate->cubic_lut_data,
10442 val,
10443 -1, sizeof(struct drm_color_lut),
10444 &replaced);
10445 state->color_mgmt_changed |= replaced;
10446 return ret;
10447 }
10448
10449 DRM_ERROR("failed to set vop2 crtc property %s\n", property->name);
10450
10451 return -EINVAL;
10452 }
10453
10454 static const struct drm_crtc_funcs vop2_crtc_funcs = {
10455 .gamma_set = vop2_crtc_legacy_gamma_set,
10456 .set_config = drm_atomic_helper_set_config,
10457 .page_flip = drm_atomic_helper_page_flip,
10458 .destroy = vop2_crtc_destroy,
10459 .reset = vop2_crtc_reset,
10460 .atomic_get_property = vop2_crtc_atomic_get_property,
10461 .atomic_set_property = vop2_crtc_atomic_set_property,
10462 .atomic_duplicate_state = vop2_crtc_duplicate_state,
10463 .atomic_destroy_state = vop2_crtc_destroy_state,
10464 .enable_vblank = vop2_crtc_enable_vblank,
10465 .disable_vblank = vop2_crtc_disable_vblank,
10466 .set_crc_source = vop2_crtc_set_crc_source,
10467 .verify_crc_source = vop2_crtc_verify_crc_source,
10468 };
10469
vop2_fb_unref_worker(struct drm_flip_work * work,void * val)10470 static void vop2_fb_unref_worker(struct drm_flip_work *work, void *val)
10471 {
10472 struct vop2_video_port *vp = container_of(work, struct vop2_video_port, fb_unref_work);
10473 struct drm_framebuffer *fb = val;
10474
10475 drm_crtc_vblank_put(&vp->rockchip_crtc.crtc);
10476 if (!vp->vop2->skip_ref_fb)
10477 drm_framebuffer_put(fb);
10478 }
10479
vop2_handle_vblank(struct vop2 * vop2,struct drm_crtc * crtc)10480 static void vop2_handle_vblank(struct vop2 *vop2, struct drm_crtc *crtc)
10481 {
10482 struct drm_device *drm = vop2->drm_dev;
10483 struct vop2_video_port *vp = to_vop2_video_port(crtc);
10484 unsigned long flags;
10485
10486 spin_lock_irqsave(&drm->event_lock, flags);
10487 if (vp->event) {
10488 drm_crtc_send_vblank_event(crtc, vp->event);
10489 drm_crtc_vblank_put(crtc);
10490 vp->event = NULL;
10491 }
10492 spin_unlock_irqrestore(&drm->event_lock, flags);
10493
10494 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vp->pending))
10495 drm_flip_work_commit(&vp->fb_unref_work, system_unbound_wq);
10496 }
10497
vop2_handle_vcnt(struct drm_crtc * crtc)10498 static void vop2_handle_vcnt(struct drm_crtc *crtc)
10499 {
10500 struct drm_device *dev = crtc->dev;
10501 struct rockchip_drm_private *priv = dev->dev_private;
10502 struct rockchip_drm_vcnt *vcnt;
10503 struct drm_pending_vblank_event *e;
10504 struct timespec64 now;
10505 unsigned long irqflags;
10506 int pipe;
10507
10508 now = ktime_to_timespec64(ktime_get());
10509
10510 spin_lock_irqsave(&dev->event_lock, irqflags);
10511 pipe = drm_crtc_index(crtc);
10512 vcnt = &priv->vcnt[pipe];
10513 vcnt->sequence++;
10514 if (vcnt->event) {
10515 e = vcnt->event;
10516 e->event.vbl.tv_sec = now.tv_sec;
10517 e->event.vbl.tv_usec = now.tv_nsec / NSEC_PER_USEC;
10518 e->event.vbl.sequence = vcnt->sequence;
10519 drm_send_event_locked(dev, &e->base);
10520 vcnt->event = NULL;
10521 }
10522 spin_unlock_irqrestore(&dev->event_lock, irqflags);
10523 }
10524
vop2_read_and_clear_active_vp_irqs(struct vop2 * vop2,int vp_id)10525 static u32 vop2_read_and_clear_active_vp_irqs(struct vop2 *vop2, int vp_id)
10526 {
10527 const struct vop2_data *vop2_data = vop2->data;
10528 const struct vop2_video_port_data *vp_data;
10529 const struct vop_intr *intr;
10530 int val;
10531
10532 vp_data = &vop2_data->vp[vp_id];
10533 intr = vp_data->intr;
10534 val = VOP_INTR_GET_TYPE(vop2, intr, status, INTR_MASK);
10535 if (val)
10536 VOP_INTR_SET_TYPE(vop2, intr, clear, val, 1);
10537 return val;
10538 }
10539
vop2_wb_disable(struct vop2_video_port * vp)10540 static void vop2_wb_disable(struct vop2_video_port *vp)
10541 {
10542 struct vop2 *vop2 = vp->vop2;
10543 struct vop2_wb *wb = &vop2->wb;
10544
10545 VOP_MODULE_SET(vop2, wb, enable, 0);
10546 VOP_CTRL_SET(vop2, wb_dma_finish_and_en, 0);
10547 vop2_wb_cfg_done(vp);
10548 }
10549
vop2_wb_handler(struct vop2_video_port * vp)10550 static void vop2_wb_handler(struct vop2_video_port *vp)
10551 {
10552 struct vop2 *vop2 = vp->vop2;
10553 struct vop2_wb *wb = &vop2->wb;
10554 struct vop2_wb_job *job;
10555 unsigned long flags;
10556 uint8_t wb_en;
10557 uint8_t wb_vp_id;
10558 uint8_t i;
10559
10560 wb_en = vop2_readl(vop2, RK3568_WB_CTRL) & 0x01;
10561 wb_vp_id = (vop2_readl(vop2, RK3568_LUT_PORT_SEL) >> 8) & 0x3;
10562 if (wb_vp_id != vp->id)
10563 return;
10564 /*
10565 * The write back should work in one shot mode,
10566 * stop when write back complete in next vsync.
10567 */
10568 if (wb_en)
10569 vop2_wb_disable(vp);
10570
10571 spin_lock_irqsave(&wb->job_lock, flags);
10572 for (i = 0; i < VOP2_WB_JOB_MAX; i++) {
10573 job = &wb->jobs[i];
10574 if (job->pending) {
10575 job->fs_vsync_cnt++;
10576
10577 if (job->fs_vsync_cnt == 2) {
10578 job->pending = false;
10579 job->fs_vsync_cnt = 0;
10580 drm_writeback_signal_completion(&vop2->wb.conn, 0);
10581 }
10582 }
10583 }
10584 spin_unlock_irqrestore(&wb->job_lock, flags);
10585 }
10586
vop2_dsc_isr(struct vop2 * vop2)10587 static void vop2_dsc_isr(struct vop2 *vop2)
10588 {
10589 const struct vop2_data *vop2_data = vop2->data;
10590 struct vop2_dsc *dsc;
10591 const struct dsc_error_info *dsc_error_ecw = vop2_data->dsc_error_ecw;
10592 const struct dsc_error_info *dsc_error_buffer_flow = vop2_data->dsc_error_buffer_flow;
10593 u32 dsc_error_status = 0, dsc_ecw = 0;
10594 int i = 0, j = 0;
10595
10596 for (i = 0; i < vop2_data->nr_dscs; i++) {
10597 dsc = &vop2->dscs[i];
10598
10599 if (!dsc->enabled)
10600 continue;
10601
10602 dsc_error_status = VOP_MODULE_GET(vop2, dsc, dsc_error_status);
10603 if (!dsc_error_status)
10604 continue;
10605 dsc_ecw = VOP_MODULE_GET(vop2, dsc, dsc_ecw);
10606
10607 for (j = 0; j < vop2_data->nr_dsc_ecw; j++) {
10608 if (dsc_ecw == dsc_error_ecw[j].dsc_error_val) {
10609 DRM_ERROR("dsc%d %s\n", dsc->id, dsc_error_ecw[j].dsc_error_info);
10610 break;
10611 }
10612 }
10613
10614 if (dsc_ecw == 0x0120ffff) {
10615 u32 offset = dsc->regs->dsc_status.offset;
10616
10617 for (j = 0; j < vop2_data->nr_dsc_buffer_flow; j++)
10618 DRM_ERROR("dsc%d %s:0x%x\n", dsc->id, dsc_error_buffer_flow[j].dsc_error_info,
10619 vop2_readl(vop2, offset + (j << 2)));
10620 }
10621 }
10622 }
10623
vop2_isr(int irq,void * data)10624 static irqreturn_t vop2_isr(int irq, void *data)
10625 {
10626 struct vop2 *vop2 = data;
10627 struct drm_crtc *crtc;
10628 struct vop2_video_port *vp;
10629 const struct vop2_data *vop2_data = vop2->data;
10630 size_t vp_max = min_t(size_t, vop2_data->nr_vps, ROCKCHIP_MAX_CRTC);
10631 size_t axi_max = min_t(size_t, vop2_data->nr_axi_intr, VOP2_SYS_AXI_BUS_NUM);
10632 uint32_t vp_irqs[ROCKCHIP_MAX_CRTC];
10633 uint32_t axi_irqs[VOP2_SYS_AXI_BUS_NUM];
10634 uint32_t active_irqs;
10635 uint32_t wb_irqs;
10636 unsigned long flags;
10637 int ret = IRQ_NONE;
10638 int i;
10639
10640 #define ERROR_HANDLER(x) \
10641 do { \
10642 if (active_irqs & x##_INTR) {\
10643 if (x##_INTR == POST_BUF_EMPTY_INTR) \
10644 DRM_DEV_ERROR_RATELIMITED(vop2->dev, #x " irq err at vp%d\n", vp->id); \
10645 else \
10646 DRM_DEV_ERROR_RATELIMITED(vop2->dev, #x " irq err\n"); \
10647 active_irqs &= ~x##_INTR; \
10648 ret = IRQ_HANDLED; \
10649 } \
10650 } while (0)
10651
10652 /*
10653 * The irq is shared with the iommu. If the runtime-pm state of the
10654 * vop2-device is disabled the irq has to be targeted at the iommu.
10655 */
10656 if (!pm_runtime_get_if_in_use(vop2->dev))
10657 return IRQ_NONE;
10658
10659 if (vop2_core_clks_enable(vop2)) {
10660 DRM_DEV_ERROR(vop2->dev, "couldn't enable clocks\n");
10661 goto out;
10662 }
10663
10664 /*
10665 * interrupt register has interrupt status, enable and clear bits, we
10666 * must hold irq_lock to avoid a race with enable/disable_vblank().
10667 */
10668 spin_lock_irqsave(&vop2->irq_lock, flags);
10669 for (i = 0; i < vp_max; i++)
10670 vp_irqs[i] = vop2_read_and_clear_active_vp_irqs(vop2, i);
10671 for (i = 0; i < axi_max; i++)
10672 axi_irqs[i] = vop2_read_and_clear_axi_irqs(vop2, i);
10673 wb_irqs = vop2_read_and_clear_wb_irqs(vop2);
10674 spin_unlock_irqrestore(&vop2->irq_lock, flags);
10675
10676 for (i = 0; i < vp_max; i++) {
10677 vp = &vop2->vps[i];
10678 crtc = &vp->rockchip_crtc.crtc;
10679 active_irqs = vp_irqs[i];
10680 if (active_irqs & DSP_HOLD_VALID_INTR) {
10681 complete(&vp->dsp_hold_completion);
10682 active_irqs &= ~DSP_HOLD_VALID_INTR;
10683 ret = IRQ_HANDLED;
10684 }
10685
10686 if (active_irqs & LINE_FLAG_INTR) {
10687 complete(&vp->line_flag_completion);
10688 active_irqs &= ~LINE_FLAG_INTR;
10689 ret = IRQ_HANDLED;
10690 }
10691
10692 if (active_irqs & LINE_FLAG1_INTR) {
10693 vop2_handle_vcnt(crtc);
10694 active_irqs &= ~LINE_FLAG1_INTR;
10695 ret = IRQ_HANDLED;
10696 }
10697
10698 if (vop2->version == VOP_VERSION_RK3528 && vp->id == 1) {
10699 if (active_irqs & POST_BUF_EMPTY_INTR)
10700 atomic_inc(&vp->post_buf_empty_flag);
10701
10702 if (active_irqs & FS_FIELD_INTR &&
10703 (atomic_read(&vp->post_buf_empty_flag) > 0 ||
10704 vp->need_reset_p2i_flag == true))
10705 queue_work(vop2->workqueue, &vop2->post_buf_empty_work);
10706 }
10707
10708 if (active_irqs & FS_FIELD_INTR) {
10709 rockchip_drm_dbg(vop2->dev, VOP_DEBUG_VSYNC, "vsync_vp%d\n", vp->id);
10710 vop2_wb_handler(vp);
10711 if (likely(!vp->skip_vsync) || (vp->layer_sel_update == false)) {
10712 drm_crtc_handle_vblank(crtc);
10713 vop2_handle_vblank(vop2, crtc);
10714 }
10715 active_irqs &= ~FS_FIELD_INTR;
10716 ret = IRQ_HANDLED;
10717 }
10718
10719 ERROR_HANDLER(POST_BUF_EMPTY);
10720
10721 /* Unhandled irqs are spurious. */
10722 if (active_irqs)
10723 DRM_ERROR("Unknown video_port%d IRQs: %02x\n", i, active_irqs);
10724 }
10725
10726 if (wb_irqs) {
10727 active_irqs = wb_irqs;
10728 ERROR_HANDLER(WB_UV_FIFO_FULL);
10729 ERROR_HANDLER(WB_YRGB_FIFO_FULL);
10730 }
10731
10732 for (i = 0; i < axi_max; i++) {
10733 active_irqs = axi_irqs[i];
10734
10735 ERROR_HANDLER(BUS_ERROR);
10736
10737 /* Unhandled irqs are spurious. */
10738 if (active_irqs)
10739 DRM_ERROR("Unknown axi_bus%d IRQs: %02x\n", i, active_irqs);
10740 }
10741
10742 if (vop2->data->nr_dscs)
10743 vop2_dsc_isr(vop2);
10744
10745 vop2_core_clks_disable(vop2);
10746 out:
10747 pm_runtime_put(vop2->dev);
10748 return ret;
10749 }
10750
vop2_plane_create_name_property(struct vop2 * vop2,struct vop2_win * win)10751 static int vop2_plane_create_name_property(struct vop2 *vop2, struct vop2_win *win)
10752 {
10753 struct drm_prop_enum_list *props = vop2->plane_name_list;
10754 struct drm_property *prop;
10755 uint64_t bits = BIT_ULL(win->plane_id);
10756
10757 prop = drm_property_create_bitmask(vop2->drm_dev,
10758 DRM_MODE_PROP_IMMUTABLE, "NAME",
10759 props, vop2->registered_num_wins,
10760 bits);
10761 if (!prop) {
10762 DRM_DEV_ERROR(vop2->dev, "create Name prop for %s failed\n", win->name);
10763 return -ENOMEM;
10764 }
10765 win->name_prop = prop;
10766 drm_object_attach_property(&win->base.base, win->name_prop, bits);
10767
10768 return 0;
10769 }
10770
vop2_plane_create_feature_property(struct vop2 * vop2,struct vop2_win * win)10771 static int vop2_plane_create_feature_property(struct vop2 *vop2, struct vop2_win *win)
10772 {
10773 uint64_t feature = 0;
10774 struct drm_property *prop;
10775
10776 static const struct drm_prop_enum_list props[] = {
10777 { ROCKCHIP_DRM_PLANE_FEATURE_SCALE, "scale" },
10778 { ROCKCHIP_DRM_PLANE_FEATURE_AFBDC, "afbdc" },
10779 };
10780
10781 if ((win->max_upscale_factor != 1) || (win->max_downscale_factor != 1))
10782 feature |= BIT(ROCKCHIP_DRM_PLANE_FEATURE_SCALE);
10783 if (win->feature & WIN_FEATURE_AFBDC)
10784 feature |= BIT(ROCKCHIP_DRM_PLANE_FEATURE_AFBDC);
10785
10786 prop = drm_property_create_bitmask(vop2->drm_dev,
10787 DRM_MODE_PROP_IMMUTABLE, "FEATURE",
10788 props, ARRAY_SIZE(props),
10789 feature);
10790 if (!prop) {
10791 DRM_DEV_ERROR(vop2->dev, "create feature prop for %s failed\n", win->name);
10792 return -ENOMEM;
10793 }
10794
10795 win->feature_prop = prop;
10796
10797 drm_object_attach_property(&win->base.base, win->feature_prop, feature);
10798
10799 return 0;
10800 }
10801
vop3_ignore_plane(struct vop2 * vop2,struct vop2_win * win)10802 static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win *win)
10803 {
10804 if (!is_vop3(vop2))
10805 return false;
10806
10807 if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE &&
10808 win->phys_id != ROCKCHIP_VOP2_ESMART0)
10809 return true;
10810 else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE &&
10811 (win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3))
10812 return true;
10813 else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE &&
10814 win->phys_id == ROCKCHIP_VOP2_ESMART1)
10815 return true;
10816 else
10817 return false;
10818 }
10819
vop3_esmart_linebuffer_size(struct vop2 * vop2,struct vop2_win * win)10820 static u32 vop3_esmart_linebuffer_size(struct vop2 *vop2, struct vop2_win *win)
10821 {
10822 if (!is_vop3(vop2) || vop2_cluster_window(win))
10823 return vop2->data->max_output.width;
10824
10825 if (vop2->esmart_lb_mode == VOP3_ESMART_2K_2K_2K_2K_MODE ||
10826 (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE && win->phys_id != ROCKCHIP_VOP2_ESMART0))
10827 return vop2->data->max_output.width / 2;
10828 else
10829 return vop2->data->max_output.width;
10830 }
10831
vop3_init_esmart_scale_engine(struct vop2 * vop2)10832 static void vop3_init_esmart_scale_engine(struct vop2 *vop2)
10833 {
10834 u8 scale_engine_num = 0;
10835 struct drm_plane *plane = NULL;
10836
10837 drm_for_each_plane(plane, vop2->drm_dev) {
10838 struct vop2_win *win = to_vop2_win(plane);
10839
10840 if (win->parent || vop2_cluster_window(win))
10841 continue;
10842
10843 win->scale_engine_num = scale_engine_num++;
10844 }
10845 }
10846
vop2_plane_init(struct vop2 * vop2,struct vop2_win * win,unsigned long possible_crtcs)10847 static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, unsigned long possible_crtcs)
10848 {
10849 struct rockchip_drm_private *private = vop2->drm_dev->dev_private;
10850 unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | BIT(DRM_MODE_BLEND_PREMULTI) |
10851 BIT(DRM_MODE_BLEND_COVERAGE);
10852 unsigned int max_width, max_height;
10853 int ret;
10854
10855 /*
10856 * Some userspace software don't want use afbc plane
10857 */
10858 if (win->feature & WIN_FEATURE_AFBDC) {
10859 if (vop2->disable_afbc_win)
10860 return -EACCES;
10861 }
10862
10863 /*
10864 * Some userspace software don't want cluster sub plane
10865 */
10866 if (!vop2->support_multi_area) {
10867 if (win->feature & WIN_FEATURE_CLUSTER_SUB)
10868 return -EACCES;
10869 }
10870
10871 /* ignore some plane register according vop3 esmart lb mode */
10872 if (vop3_ignore_plane(vop2, win))
10873 return -EACCES;
10874
10875 ret = drm_universal_plane_init(vop2->drm_dev, &win->base, possible_crtcs,
10876 &vop2_plane_funcs, win->formats, win->nformats,
10877 win->format_modifiers, win->type, win->name);
10878 if (ret) {
10879 DRM_DEV_ERROR(vop2->dev, "failed to initialize plane %d\n", ret);
10880 return ret;
10881 }
10882
10883 drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs);
10884
10885 drm_object_attach_property(&win->base.base, private->eotf_prop, 0);
10886 drm_object_attach_property(&win->base.base, private->color_space_prop, 0);
10887 drm_object_attach_property(&win->base.base, private->async_commit_prop, 0);
10888
10889 if (win->feature & (WIN_FEATURE_CLUSTER_SUB | WIN_FEATURE_CLUSTER_MAIN))
10890 drm_object_attach_property(&win->base.base, private->share_id_prop, win->plane_id);
10891
10892 if (win->parent)
10893 drm_object_attach_property(&win->base.base, private->share_id_prop,
10894 win->parent->base.base.id);
10895 else
10896 drm_object_attach_property(&win->base.base, private->share_id_prop,
10897 win->base.base.id);
10898 if (win->supported_rotations)
10899 drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0,
10900 DRM_MODE_ROTATE_0 | win->supported_rotations);
10901 drm_plane_create_alpha_property(&win->base);
10902 drm_plane_create_blend_mode_property(&win->base, blend_caps);
10903 drm_plane_create_zpos_property(&win->base, win->win_id, 0, vop2->registered_num_wins - 1);
10904 vop2_plane_create_name_property(vop2, win);
10905 vop2_plane_create_feature_property(vop2, win);
10906 max_width = vop2->data->max_input.width;
10907 max_height = vop2->data->max_input.height;
10908 if (win->feature & WIN_FEATURE_CLUSTER_SUB)
10909 max_width >>= 1;
10910 win->input_width_prop = drm_property_create_range(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE,
10911 "INPUT_WIDTH", 0, max_width);
10912 win->input_height_prop = drm_property_create_range(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE,
10913 "INPUT_HEIGHT", 0, max_height);
10914 max_width = vop3_esmart_linebuffer_size(vop2, win);
10915 max_height = vop2->data->max_output.height;
10916 if (win->feature & WIN_FEATURE_CLUSTER_SUB)
10917 max_width >>= 1;
10918 win->output_width_prop = drm_property_create_range(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE,
10919 "OUTPUT_WIDTH", 0, max_width);
10920 win->output_height_prop = drm_property_create_range(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE,
10921 "OUTPUT_HEIGHT", 0, max_height);
10922 win->scale_prop = drm_property_create_range(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE,
10923 "SCALE_RATE", win->max_downscale_factor,
10924 win->max_upscale_factor);
10925 /*
10926 * Support 24 bit(RGB888) or 16 bit(rgb565) color key.
10927 * Bit 31 is used as a flag to disable (0) or enable
10928 * color keying (1).
10929 */
10930 win->color_key_prop = drm_property_create_range(vop2->drm_dev, 0, "colorkey", 0,
10931 0x80ffffff);
10932
10933 if (!win->input_width_prop || !win->input_height_prop ||
10934 !win->output_width_prop || !win->output_height_prop ||
10935 !win->scale_prop || !win->color_key_prop) {
10936 DRM_ERROR("failed to create property\n");
10937 return -ENOMEM;
10938 }
10939
10940 drm_object_attach_property(&win->base.base, win->input_width_prop, 0);
10941 drm_object_attach_property(&win->base.base, win->input_height_prop, 0);
10942 drm_object_attach_property(&win->base.base, win->output_width_prop, 0);
10943 drm_object_attach_property(&win->base.base, win->output_height_prop, 0);
10944 drm_object_attach_property(&win->base.base, win->scale_prop, 0);
10945 drm_object_attach_property(&win->base.base, win->color_key_prop, 0);
10946
10947 return 0;
10948 }
10949
vop2_cursor_plane_init(struct vop2_video_port * vp)10950 static struct drm_plane *vop2_cursor_plane_init(struct vop2_video_port *vp)
10951 {
10952 struct vop2 *vop2 = vp->vop2;
10953 struct drm_plane *cursor = NULL;
10954 struct vop2_win *win;
10955 unsigned long possible_crtcs = 0;
10956
10957 win = vop2_find_win_by_phys_id(vop2, vp->cursor_win_id);
10958 if (win) {
10959 if (vop2->disable_win_move) {
10960 const struct vop2_data *vop2_data = vop2->data;
10961 struct drm_crtc *crtc = vop2_find_crtc_by_plane_mask(vop2, win->phys_id);
10962
10963 if (crtc)
10964 possible_crtcs = drm_crtc_mask(crtc);
10965 else
10966 possible_crtcs = (1 << vop2_data->nr_vps) - 1;
10967 }
10968
10969 if (win->possible_crtcs)
10970 possible_crtcs = win->possible_crtcs;
10971 win->type = DRM_PLANE_TYPE_CURSOR;
10972 win->zpos = vop2->registered_num_wins - 1;
10973 if (!vop2_plane_init(vop2, win, possible_crtcs))
10974 cursor = &win->base;
10975 }
10976
10977 return cursor;
10978 }
10979
vop2_gamma_init(struct vop2 * vop2)10980 static int vop2_gamma_init(struct vop2 *vop2)
10981 {
10982 const struct vop2_data *vop2_data = vop2->data;
10983 const struct vop2_video_port_data *vp_data;
10984 struct vop2_video_port *vp;
10985 struct device *dev = vop2->dev;
10986 u16 *r_base, *g_base, *b_base;
10987 struct drm_crtc *crtc;
10988 int i = 0, j = 0;
10989 u32 lut_len = 0;
10990
10991 if (!vop2->lut_regs)
10992 return 0;
10993
10994 for (i = 0; i < vop2_data->nr_vps; i++) {
10995 vp = &vop2->vps[i];
10996 crtc = &vp->rockchip_crtc.crtc;
10997 if (!crtc->dev)
10998 continue;
10999 vp_data = &vop2_data->vp[vp->id];
11000 lut_len = vp_data->gamma_lut_len;
11001 if (!lut_len)
11002 continue;
11003 vp->gamma_lut_len = vp_data->gamma_lut_len;
11004 vp->lut_dma_rid = vp_data->lut_dma_rid;
11005 vp->lut = devm_kmalloc_array(dev, lut_len, sizeof(*vp->lut),
11006 GFP_KERNEL);
11007 if (!vp->lut)
11008 return -ENOMEM;
11009
11010 for (j = 0; j < lut_len; j++) {
11011 u32 b = j * lut_len * lut_len;
11012 u32 g = j * lut_len;
11013 u32 r = j;
11014
11015 vp->lut[j] = r | g | b;
11016 }
11017
11018 drm_mode_crtc_set_gamma_size(crtc, lut_len);
11019 drm_crtc_enable_color_mgmt(crtc, 0, false, lut_len);
11020 r_base = crtc->gamma_store;
11021 g_base = r_base + crtc->gamma_size;
11022 b_base = g_base + crtc->gamma_size;
11023 for (j = 0; j < lut_len; j++) {
11024 rockchip_vop2_crtc_fb_gamma_get(crtc, &r_base[j],
11025 &g_base[j],
11026 &b_base[j], j);
11027 }
11028 }
11029
11030 return 0;
11031 }
11032
vop2_crtc_create_plane_mask_property(struct vop2 * vop2,struct drm_crtc * crtc,uint32_t plane_mask)11033 static int vop2_crtc_create_plane_mask_property(struct vop2 *vop2,
11034 struct drm_crtc *crtc,
11035 uint32_t plane_mask)
11036 {
11037 struct drm_property *prop;
11038 struct vop2_video_port *vp = to_vop2_video_port(crtc);
11039
11040 static const struct drm_prop_enum_list props[] = {
11041 { ROCKCHIP_VOP2_CLUSTER0, "Cluster0" },
11042 { ROCKCHIP_VOP2_CLUSTER1, "Cluster1" },
11043 { ROCKCHIP_VOP2_ESMART0, "Esmart0" },
11044 { ROCKCHIP_VOP2_ESMART1, "Esmart1" },
11045 { ROCKCHIP_VOP2_SMART0, "Smart0" },
11046 { ROCKCHIP_VOP2_SMART1, "Smart1" },
11047 { ROCKCHIP_VOP2_CLUSTER2, "Cluster2" },
11048 { ROCKCHIP_VOP2_CLUSTER3, "Cluster3" },
11049 { ROCKCHIP_VOP2_ESMART2, "Esmart2" },
11050 { ROCKCHIP_VOP2_ESMART3, "Esmart3" },
11051 };
11052
11053 prop = drm_property_create_bitmask(vop2->drm_dev,
11054 DRM_MODE_PROP_IMMUTABLE, "PLANE_MASK",
11055 props, ARRAY_SIZE(props),
11056 0xffffffff);
11057 if (!prop) {
11058 DRM_DEV_ERROR(vop2->dev, "create plane_mask prop for vp%d failed\n", vp->id);
11059 return -ENOMEM;
11060 }
11061
11062 vp->plane_mask_prop = prop;
11063 drm_object_attach_property(&crtc->base, vp->plane_mask_prop, plane_mask);
11064
11065 return 0;
11066 }
11067
vop2_crtc_create_feature_property(struct vop2 * vop2,struct drm_crtc * crtc)11068 static int vop2_crtc_create_feature_property(struct vop2 *vop2, struct drm_crtc *crtc)
11069 {
11070 const struct vop2_data *vop2_data = vop2->data;
11071 struct vop2_video_port *vp = to_vop2_video_port(crtc);
11072 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
11073 struct drm_property *prop;
11074 u64 feature = 0;
11075
11076 static const struct drm_prop_enum_list props[] = {
11077 { ROCKCHIP_DRM_CRTC_FEATURE_ALPHA_SCALE, "ALPHA_SCALE" },
11078 { ROCKCHIP_DRM_CRTC_FEATURE_HDR10, "HDR10" },
11079 { ROCKCHIP_DRM_CRTC_FEATURE_NEXT_HDR, "NEXT_HDR" },
11080 };
11081
11082 if (vp_data->feature & VOP_FEATURE_ALPHA_SCALE)
11083 feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_ALPHA_SCALE);
11084 if (vp_data->feature & VOP_FEATURE_HDR10)
11085 feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_HDR10);
11086 if (vp_data->feature & VOP_FEATURE_NEXT_HDR)
11087 feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_NEXT_HDR);
11088
11089 prop = drm_property_create_bitmask(vop2->drm_dev,
11090 DRM_MODE_PROP_IMMUTABLE, "FEATURE",
11091 props, ARRAY_SIZE(props),
11092 0xffffffff);
11093 if (!prop) {
11094 DRM_DEV_ERROR(vop2->dev, "create FEATURE prop for vp%d failed\n", vp->id);
11095 return -ENOMEM;
11096 }
11097
11098 vp->feature_prop = prop;
11099 drm_object_attach_property(&crtc->base, vp->feature_prop, feature);
11100
11101 prop = drm_property_create_range(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE, "OUTPUT_WIDTH",
11102 0, vop2->data->vp[vp->id].max_output.width);
11103 if (!prop) {
11104 DRM_DEV_ERROR(vop2->dev, "create OUTPUT_WIDTH prop for vp%d failed\n", vp->id);
11105 return -ENOMEM;
11106 }
11107 vp->output_width_prop = prop;
11108 drm_object_attach_property(&crtc->base, vp->output_width_prop, 0);
11109
11110 prop = drm_property_create_range(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE, "OUTPUT_DCLK",
11111 0, rockchip_drm_get_dclk_by_width(vop2->data->vp[vp->id].max_output.width) * 1000);
11112 if (!prop) {
11113 DRM_DEV_ERROR(vop2->dev, "create OUTPUT_DCLK prop for vp%d failed\n", vp->id);
11114 return -ENOMEM;
11115 }
11116 vp->output_dclk_prop = prop;
11117 drm_object_attach_property(&crtc->base, vp->output_dclk_prop, 0);
11118
11119 return 0;
11120 }
11121
vop2_crtc_create_vrr_property(struct vop2 * vop2,struct drm_crtc * crtc)11122 static int vop2_crtc_create_vrr_property(struct vop2 *vop2, struct drm_crtc *crtc)
11123 {
11124 struct vop2_video_port *vp = to_vop2_video_port(crtc);
11125 struct drm_property *prop;
11126
11127 prop = drm_property_create_range(vop2->drm_dev, 0, "variable refresh rate", 0, 144);
11128 if (!prop) {
11129 DRM_DEV_ERROR(vop2->dev, "create vrr prop for vp%d failed\n", vp->id);
11130 return -ENOMEM;
11131 }
11132 vp->variable_refresh_rate_prop = prop;
11133 drm_object_attach_property(&crtc->base, vp->variable_refresh_rate_prop, 0);
11134
11135 prop = drm_property_create_range(vop2->drm_dev, 0, "max refresh rate", 0, 144);
11136 if (!prop) {
11137 DRM_DEV_ERROR(vop2->dev, "create vrr prop for vp%d failed\n", vp->id);
11138 return -ENOMEM;
11139 }
11140 vp->max_refresh_rate_prop = prop;
11141 drm_object_attach_property(&crtc->base, vp->max_refresh_rate_prop, 0);
11142
11143 prop = drm_property_create_range(vop2->drm_dev, 0, "min refresh rate", 0, 144);
11144 if (!prop) {
11145 DRM_DEV_ERROR(vop2->dev, "create vrr prop for vp%d failed\n", vp->id);
11146 return -ENOMEM;
11147 }
11148 vp->min_refresh_rate_prop = prop;
11149 drm_object_attach_property(&crtc->base, vp->min_refresh_rate_prop, 0);
11150
11151 return 0;
11152 }
11153
vop2_crtc_create_hdr_property(struct vop2 * vop2,struct drm_crtc * crtc)11154 static int vop2_crtc_create_hdr_property(struct vop2 *vop2, struct drm_crtc *crtc)
11155 {
11156 struct vop2_video_port *vp = to_vop2_video_port(crtc);
11157 struct drm_property *prop;
11158
11159 prop = drm_property_create(vop2->drm_dev, DRM_MODE_PROP_BLOB, "HDR_EXT_DATA", 0);
11160 if (!prop) {
11161 DRM_DEV_ERROR(vop2->dev, "create hdr ext data prop for vp%d failed\n", vp->id);
11162 return -ENOMEM;
11163 }
11164 vp->hdr_ext_data_prop = prop;
11165 drm_object_attach_property(&crtc->base, vp->hdr_ext_data_prop, 0);
11166
11167 return 0;
11168 }
11169
vop2_crtc_create_post_acm_property(struct vop2 * vop2,struct drm_crtc * crtc)11170 static int vop2_crtc_create_post_acm_property(struct vop2 *vop2, struct drm_crtc *crtc)
11171 {
11172 struct vop2_video_port *vp = to_vop2_video_port(crtc);
11173 struct drm_property *prop;
11174
11175 prop = drm_property_create(vop2->drm_dev, DRM_MODE_PROP_BLOB, "ACM_LUT_DATA", 0);
11176 if (!prop) {
11177 DRM_DEV_ERROR(vop2->dev, "create acm lut data prop for vp%d failed\n", vp->id);
11178 return -ENOMEM;
11179 }
11180 vp->acm_lut_data_prop = prop;
11181 drm_object_attach_property(&crtc->base, vp->acm_lut_data_prop, 0);
11182
11183 return 0;
11184 }
11185
vop2_crtc_create_post_csc_property(struct vop2 * vop2,struct drm_crtc * crtc)11186 static int vop2_crtc_create_post_csc_property(struct vop2 *vop2, struct drm_crtc *crtc)
11187 {
11188 struct vop2_video_port *vp = to_vop2_video_port(crtc);
11189 struct drm_property *prop;
11190
11191 prop = drm_property_create(vop2->drm_dev, DRM_MODE_PROP_BLOB, "POST_CSC_DATA", 0);
11192 if (!prop) {
11193 DRM_DEV_ERROR(vop2->dev, "create post csc data prop for vp%d failed\n", vp->id);
11194 return -ENOMEM;
11195 }
11196 vp->post_csc_data_prop = prop;
11197 drm_object_attach_property(&crtc->base, vp->post_csc_data_prop, 0);
11198
11199 return 0;
11200 }
11201 #define RK3566_MIRROR_PLANE_MASK (BIT(ROCKCHIP_VOP2_CLUSTER1) | BIT(ROCKCHIP_VOP2_ESMART1) | \
11202 BIT(ROCKCHIP_VOP2_SMART1))
11203
11204 /*
11205 * Returns:
11206 * Registered crtc number on success, negative error code on failure.
11207 */
vop2_create_crtc(struct vop2 * vop2)11208 static int vop2_create_crtc(struct vop2 *vop2)
11209 {
11210 const struct vop2_data *vop2_data = vop2->data;
11211 struct drm_device *drm_dev = vop2->drm_dev;
11212 struct device *dev = vop2->dev;
11213 struct drm_plane *primary;
11214 struct drm_plane *cursor = NULL;
11215 struct drm_crtc *crtc;
11216 struct device_node *port;
11217 struct vop2_win *win = NULL;
11218 struct vop2_video_port *vp;
11219 const struct vop2_video_port_data *vp_data;
11220 uint32_t possible_crtcs;
11221 uint64_t soc_id;
11222 uint32_t registered_num_crtcs = 0;
11223 uint32_t plane_mask = 0;
11224 char clk_name[16];
11225 int i = 0, j = 0, k = 0;
11226 int ret = 0;
11227 bool be_used_for_primary_plane = false;
11228 bool find_primary_plane = false;
11229 bool bootloader_initialized = false;
11230 struct rockchip_drm_private *private = drm_dev->dev_private;
11231
11232 /* all planes can attach to any crtc */
11233 possible_crtcs = (1 << vop2_data->nr_vps) - 1;
11234
11235 /*
11236 * We set plane_mask from dts or bootloader
11237 * if all the plane_mask are zero, that means
11238 * the bootloader don't initialized the vop, or
11239 * something is wrong, the kernel will try to
11240 * initial all the vp.
11241 */
11242 for (i = 0; i < vop2_data->nr_vps; i++) {
11243 vp = &vop2->vps[i];
11244 if (vp->plane_mask) {
11245 bootloader_initialized = true;
11246 break;
11247 }
11248 }
11249
11250 /*
11251 * Create primary plane for eache crtc first, since we need
11252 * to pass them to drm_crtc_init_with_planes, which sets the
11253 * "possible_crtcs" to the newly initialized crtc.
11254 */
11255 for (i = 0; i < vop2_data->nr_vps; i++) {
11256 vp_data = &vop2_data->vp[i];
11257 vp = &vop2->vps[i];
11258 vp->vop2 = vop2;
11259 vp->id = vp_data->id;
11260 vp->regs = vp_data->regs;
11261 vp->cursor_win_id = -1;
11262 primary = NULL;
11263 cursor = NULL;
11264
11265 if (vop2->disable_win_move)
11266 possible_crtcs = BIT(registered_num_crtcs);
11267
11268 /*
11269 * we assume a vp with a zere plane_mask(set from dts or bootloader)
11270 * as unused.
11271 */
11272 if (!vp->plane_mask && bootloader_initialized)
11273 continue;
11274
11275 if (vop2_soc_is_rk3566())
11276 soc_id = vp_data->soc_id[1];
11277 else
11278 soc_id = vp_data->soc_id[0];
11279
11280 snprintf(clk_name, sizeof(clk_name), "dclk_vp%d", vp->id);
11281 vp->dclk_rst = devm_reset_control_get_optional(vop2->dev, clk_name);
11282 if (IS_ERR(vp->dclk_rst)) {
11283 DRM_DEV_ERROR(vop2->dev, "failed to get dclk reset\n");
11284 return PTR_ERR(vp->dclk_rst);
11285 }
11286
11287 vp->dclk = devm_clk_get(vop2->dev, clk_name);
11288 if (IS_ERR(vp->dclk)) {
11289 DRM_DEV_ERROR(vop2->dev, "failed to get %s\n", clk_name);
11290 return PTR_ERR(vp->dclk);
11291 }
11292
11293 snprintf(clk_name, sizeof(clk_name), "dclk_src_vp%d", vp->id);
11294 vp->dclk_parent = devm_clk_get_optional(vop2->dev, clk_name);
11295 if (IS_ERR(vp->dclk)) {
11296 DRM_DEV_ERROR(vop2->dev, "failed to get %s\n", clk_name);
11297 return PTR_ERR(vp->dclk);
11298 }
11299
11300 crtc = &vp->rockchip_crtc.crtc;
11301
11302 port = of_graph_get_port_by_id(dev->of_node, i);
11303 if (!port) {
11304 DRM_DEV_ERROR(vop2->dev, "no port node found for video_port%d\n", i);
11305 return -ENOENT;
11306 }
11307 crtc->port = port;
11308 of_property_read_u32(port, "cursor-win-id", &vp->cursor_win_id);
11309
11310 plane_mask = vp->plane_mask;
11311 if (vop2_soc_is_rk3566()) {
11312 if ((vp->plane_mask & RK3566_MIRROR_PLANE_MASK) &&
11313 (vp->plane_mask & ~RK3566_MIRROR_PLANE_MASK)) {
11314 plane_mask &= ~RK3566_MIRROR_PLANE_MASK;
11315 }
11316 }
11317
11318 if (vp->primary_plane_phy_id >= 0) {
11319 win = vop2_find_win_by_phys_id(vop2, vp->primary_plane_phy_id);
11320 if (win) {
11321 find_primary_plane = true;
11322 win->type = DRM_PLANE_TYPE_PRIMARY;
11323 }
11324 } else {
11325 j = 0;
11326 while (j < vop2->registered_num_wins) {
11327 be_used_for_primary_plane = false;
11328 win = &vop2->win[j];
11329 j++;
11330
11331 if (win->parent || (win->feature & WIN_FEATURE_CLUSTER_SUB))
11332 continue;
11333
11334 if (win->type != DRM_PLANE_TYPE_PRIMARY)
11335 continue;
11336
11337 for (k = 0; k < vop2_data->nr_vps; k++) {
11338 if (win->phys_id == vop2->vps[k].primary_plane_phy_id) {
11339 be_used_for_primary_plane = true;
11340 break;
11341 }
11342 }
11343
11344 if (be_used_for_primary_plane)
11345 continue;
11346
11347 find_primary_plane = true;
11348 break;
11349 }
11350
11351 if (find_primary_plane)
11352 vp->primary_plane_phy_id = win->phys_id;
11353 }
11354
11355 if (!find_primary_plane) {
11356 DRM_DEV_ERROR(vop2->dev, "No primary plane find for video_port%d\n", i);
11357 break;
11358 } else {
11359 /* give lowest zpos for primary plane */
11360 win->zpos = registered_num_crtcs;
11361 if (win->possible_crtcs)
11362 possible_crtcs = win->possible_crtcs;
11363 if (vop2_plane_init(vop2, win, possible_crtcs)) {
11364 DRM_DEV_ERROR(vop2->dev, "failed to init primary plane\n");
11365 break;
11366 }
11367 primary = &win->base;
11368 }
11369
11370 /* some times we want a cursor window for some vp */
11371 if (vp->cursor_win_id < 0) {
11372 bool be_used_for_cursor_plane = false;
11373
11374 j = 0;
11375 while (j < vop2->registered_num_wins) {
11376 win = &vop2->win[j++];
11377
11378 if (win->parent || (win->feature & WIN_FEATURE_CLUSTER_SUB))
11379 continue;
11380
11381 if (win->type != DRM_PLANE_TYPE_CURSOR)
11382 continue;
11383
11384 for (k = 0; k < vop2_data->nr_vps; k++) {
11385 if (vop2->vps[k].cursor_win_id == win->phys_id)
11386 be_used_for_cursor_plane = true;
11387 }
11388 if (be_used_for_cursor_plane)
11389 continue;
11390 vp->cursor_win_id = win->phys_id;
11391 }
11392 }
11393
11394 if (vp->cursor_win_id >= 0) {
11395 cursor = vop2_cursor_plane_init(vp);
11396 if (!cursor)
11397 DRM_WARN("failed to init cursor plane for vp%d\n", vp->id);
11398 else
11399 DRM_DEV_INFO(vop2->dev, "%s as cursor plane for vp%d\n",
11400 cursor->name, vp->id);
11401 }
11402
11403 ret = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor, &vop2_crtc_funcs,
11404 "video_port%d", vp->id);
11405 if (ret) {
11406 DRM_DEV_ERROR(vop2->dev, "crtc init for video_port%d failed\n", i);
11407 return ret;
11408 }
11409
11410 drm_crtc_helper_add(crtc, &vop2_crtc_helper_funcs);
11411
11412 drm_flip_work_init(&vp->fb_unref_work, "fb_unref", vop2_fb_unref_worker);
11413
11414 init_completion(&vp->dsp_hold_completion);
11415 init_completion(&vp->line_flag_completion);
11416 rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
11417 soc_id = vop2_soc_id_fixup(soc_id);
11418 drm_object_attach_property(&crtc->base, private->soc_id_prop, soc_id);
11419 drm_object_attach_property(&crtc->base, private->port_id_prop, vp->id);
11420 drm_object_attach_property(&crtc->base, private->aclk_prop, 0);
11421 drm_object_attach_property(&crtc->base, private->bg_prop, 0);
11422 drm_object_attach_property(&crtc->base, private->line_flag_prop, 0);
11423 if (vp_data->feature & VOP_FEATURE_OVERSCAN) {
11424 drm_object_attach_property(&crtc->base,
11425 drm_dev->mode_config.tv_left_margin_property, 100);
11426 drm_object_attach_property(&crtc->base,
11427 drm_dev->mode_config.tv_right_margin_property, 100);
11428 drm_object_attach_property(&crtc->base,
11429 drm_dev->mode_config.tv_top_margin_property, 100);
11430 drm_object_attach_property(&crtc->base,
11431 drm_dev->mode_config.tv_bottom_margin_property, 100);
11432 }
11433 if (plane_mask)
11434 vop2_crtc_create_plane_mask_property(vop2, crtc, plane_mask);
11435 vop2_crtc_create_feature_property(vop2, crtc);
11436 vop2_crtc_create_vrr_property(vop2, crtc);
11437
11438 ret = drm_self_refresh_helper_init(crtc);
11439 if (ret)
11440 DRM_DEV_DEBUG_KMS(vop2->dev,
11441 "Failed to init %s with SR helpers %d, ignoring\n",
11442 crtc->name, ret);
11443
11444 if (vp_data->feature & VOP_FEATURE_VIVID_HDR)
11445 vop2_crtc_create_hdr_property(vop2, crtc);
11446 if (vp_data->feature & VOP_FEATURE_POST_ACM)
11447 vop2_crtc_create_post_acm_property(vop2, crtc);
11448 if (vp_data->feature & VOP_FEATURE_POST_CSC)
11449 vop2_crtc_create_post_csc_property(vop2, crtc);
11450
11451 registered_num_crtcs++;
11452 }
11453
11454 /*
11455 * change the unused primary window to overlay window
11456 */
11457 for (j = 0; j < vop2->registered_num_wins; j++) {
11458 win = &vop2->win[j];
11459 be_used_for_primary_plane = false;
11460
11461 for (k = 0; k < vop2_data->nr_vps; k++) {
11462 if (vop2->vps[k].primary_plane_phy_id == win->phys_id) {
11463 be_used_for_primary_plane = true;
11464 break;
11465 }
11466 }
11467
11468 if (win->type == DRM_PLANE_TYPE_PRIMARY &&
11469 !be_used_for_primary_plane)
11470 win->type = DRM_PLANE_TYPE_OVERLAY;
11471 }
11472
11473 /*
11474 * create overlay planes of the leftover overlay win
11475 * Create drm_planes for overlay windows with possible_crtcs restricted
11476 */
11477 for (j = 0; j < vop2->registered_num_wins; j++) {
11478 win = &vop2->win[j];
11479
11480 if (win->type != DRM_PLANE_TYPE_OVERLAY)
11481 continue;
11482 /*
11483 * Only dual display on rk3568(which need two crtcs) need mirror win
11484 */
11485 if (registered_num_crtcs < 2 && vop2_is_mirror_win(win))
11486 continue;
11487 /*
11488 * zpos of overlay plane is higher than primary
11489 * and lower than cursor
11490 */
11491 win->zpos = registered_num_crtcs + j;
11492
11493 if (vop2->disable_win_move) {
11494 crtc = vop2_find_crtc_by_plane_mask(vop2, win->phys_id);
11495 if (crtc)
11496 possible_crtcs = drm_crtc_mask(crtc);
11497 else
11498 possible_crtcs = (1 << vop2_data->nr_vps) - 1;
11499 }
11500 if (win->possible_crtcs)
11501 possible_crtcs = win->possible_crtcs;
11502
11503 ret = vop2_plane_init(vop2, win, possible_crtcs);
11504 if (ret)
11505 DRM_WARN("failed to init overlay plane %s\n", win->name);
11506 }
11507
11508 if (is_vop3(vop2))
11509 vop3_init_esmart_scale_engine(vop2);
11510
11511 return registered_num_crtcs;
11512 }
11513
vop2_destroy_crtc(struct drm_crtc * crtc)11514 static void vop2_destroy_crtc(struct drm_crtc *crtc)
11515 {
11516 struct vop2_video_port *vp = to_vop2_video_port(crtc);
11517
11518 drm_self_refresh_helper_cleanup(crtc);
11519 if (vp->hdr_lut_gem_obj)
11520 rockchip_gem_free_object(&vp->hdr_lut_gem_obj->base);
11521
11522 of_node_put(crtc->port);
11523
11524 /*
11525 * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane()
11526 * references the CRTC.
11527 */
11528 drm_crtc_cleanup(crtc);
11529 drm_flip_work_cleanup(&vp->fb_unref_work);
11530 }
11531
vop2_pd_data_init(struct vop2 * vop2)11532 static int vop2_pd_data_init(struct vop2 *vop2)
11533 {
11534 const struct vop2_data *vop2_data = vop2->data;
11535 const struct vop2_power_domain_data *pd_data;
11536 struct vop2_power_domain *pd;
11537 int i;
11538
11539 INIT_LIST_HEAD(&vop2->pd_list_head);
11540
11541 for (i = 0; i < vop2_data->nr_pds; i++) {
11542 pd_data = &vop2_data->pd[i];
11543 pd = devm_kzalloc(vop2->dev, sizeof(*pd), GFP_KERNEL);
11544 if (!pd)
11545 return -ENOMEM;
11546 pd->vop2 = vop2;
11547 pd->data = pd_data;
11548 pd->vp_mask = 0;
11549 spin_lock_init(&pd->lock);
11550 list_add_tail(&pd->list, &vop2->pd_list_head);
11551 INIT_DELAYED_WORK(&pd->power_off_work, vop2_power_domain_off_work);
11552 if (pd_data->parent_id) {
11553 pd->parent = vop2_find_pd_by_id(vop2, pd_data->parent_id);
11554 if (!pd->parent) {
11555 DRM_DEV_ERROR(vop2->dev, "no parent pd find for pd%d\n", pd->data->id);
11556 return -EINVAL;
11557 }
11558 }
11559 }
11560
11561 return 0;
11562 }
11563
vop2_dsc_data_init(struct vop2 * vop2)11564 static void vop2_dsc_data_init(struct vop2 *vop2)
11565 {
11566 const struct vop2_data *vop2_data = vop2->data;
11567 const struct vop2_dsc_data *dsc_data;
11568 struct vop2_dsc *dsc;
11569 int i;
11570
11571 for (i = 0; i < vop2_data->nr_dscs; i++) {
11572 dsc = &vop2->dscs[i];
11573 dsc_data = &vop2_data->dsc[i];
11574 dsc->id = dsc_data->id;
11575 dsc->max_slice_num = dsc_data->max_slice_num;
11576 dsc->max_linebuf_depth = dsc_data->max_linebuf_depth;
11577 dsc->min_bits_per_pixel = dsc_data->min_bits_per_pixel;
11578 dsc->regs = dsc_data->regs;
11579 dsc->attach_vp_id = -1;
11580 if (dsc_data->pd_id)
11581 dsc->pd = vop2_find_pd_by_id(vop2, dsc_data->pd_id);
11582 }
11583 }
11584
vop2_win_init(struct vop2 * vop2)11585 static int vop2_win_init(struct vop2 *vop2)
11586 {
11587 const struct vop2_data *vop2_data = vop2->data;
11588 const struct vop2_layer_data *layer_data;
11589 struct drm_prop_enum_list *plane_name_list;
11590 struct vop2_win *win;
11591 struct vop2_layer *layer;
11592 char name[DRM_PROP_NAME_LEN];
11593 unsigned int num_wins = 0;
11594 uint8_t plane_id = 0;
11595 unsigned int i, j;
11596
11597 for (i = 0; i < vop2_data->win_size; i++) {
11598 const struct vop2_win_data *win_data = &vop2_data->win[i];
11599
11600 win = &vop2->win[num_wins];
11601 win->name = win_data->name;
11602 win->regs = win_data->regs;
11603 win->offset = win_data->base;
11604 win->type = win_data->type;
11605 win->formats = win_data->formats;
11606 win->nformats = win_data->nformats;
11607 win->format_modifiers = win_data->format_modifiers;
11608 win->supported_rotations = win_data->supported_rotations;
11609 win->max_upscale_factor = win_data->max_upscale_factor;
11610 win->max_downscale_factor = win_data->max_downscale_factor;
11611 win->hsu_filter_mode = win_data->hsu_filter_mode;
11612 win->hsd_filter_mode = win_data->hsd_filter_mode;
11613 win->vsu_filter_mode = win_data->vsu_filter_mode;
11614 win->vsd_filter_mode = win_data->vsd_filter_mode;
11615 win->hsd_pre_filter_mode = win_data->hsd_pre_filter_mode;
11616 win->vsd_pre_filter_mode = win_data->vsd_pre_filter_mode;
11617 win->dly = win_data->dly;
11618 win->feature = win_data->feature;
11619 win->phys_id = win_data->phys_id;
11620 win->splice_win_id = win_data->splice_win_id;
11621 win->layer_sel_id = win_data->layer_sel_id;
11622 win->win_id = i;
11623 win->plane_id = plane_id++;
11624 win->area_id = 0;
11625 win->zpos = i;
11626 win->vop2 = vop2;
11627 win->axi_id = win_data->axi_id;
11628 win->axi_yrgb_id = win_data->axi_yrgb_id;
11629 win->axi_uv_id = win_data->axi_uv_id;
11630 win->possible_crtcs = win_data->possible_crtcs;
11631
11632 if (win_data->pd_id)
11633 win->pd = vop2_find_pd_by_id(vop2, win_data->pd_id);
11634
11635 num_wins++;
11636
11637 if (!vop2->support_multi_area)
11638 continue;
11639
11640 for (j = 0; j < win_data->area_size; j++) {
11641 struct vop2_win *area = &vop2->win[num_wins];
11642 const struct vop2_win_regs *regs = win_data->area[j];
11643
11644 area->parent = win;
11645 area->offset = win->offset;
11646 area->regs = regs;
11647 area->type = DRM_PLANE_TYPE_OVERLAY;
11648 area->formats = win->formats;
11649 area->feature = win->feature;
11650 area->nformats = win->nformats;
11651 area->format_modifiers = win->format_modifiers;
11652 area->max_upscale_factor = win_data->max_upscale_factor;
11653 area->max_downscale_factor = win_data->max_downscale_factor;
11654 area->supported_rotations = win_data->supported_rotations;
11655 area->hsu_filter_mode = win_data->hsu_filter_mode;
11656 area->hsd_filter_mode = win_data->hsd_filter_mode;
11657 area->vsu_filter_mode = win_data->vsu_filter_mode;
11658 area->vsd_filter_mode = win_data->vsd_filter_mode;
11659 area->hsd_pre_filter_mode = win_data->hsd_pre_filter_mode;
11660 area->vsd_pre_filter_mode = win_data->vsd_pre_filter_mode;
11661 area->possible_crtcs = win->possible_crtcs;
11662
11663 area->vop2 = vop2;
11664 area->win_id = i;
11665 area->phys_id = win->phys_id;
11666 area->area_id = j + 1;
11667 area->plane_id = plane_id++;
11668 snprintf(name, min(sizeof(name), strlen(win->name)), "%s", win->name);
11669 snprintf(name, sizeof(name), "%s%d", name, area->area_id);
11670 area->name = devm_kstrdup(vop2->dev, name, GFP_KERNEL);
11671 num_wins++;
11672 }
11673 }
11674
11675 vop2->registered_num_wins = num_wins;
11676
11677 if (!is_vop3(vop2)) {
11678 for (i = 0; i < vop2_data->nr_layers; i++) {
11679 layer = &vop2->layers[i];
11680 layer_data = &vop2_data->layer[i];
11681 layer->id = layer_data->id;
11682 layer->regs = layer_data->regs;
11683 }
11684 }
11685
11686 plane_name_list = devm_kzalloc(vop2->dev,
11687 vop2->registered_num_wins * sizeof(*plane_name_list),
11688 GFP_KERNEL);
11689 if (!plane_name_list) {
11690 DRM_DEV_ERROR(vop2->dev, "failed to alloc memory for plane_name_list\n");
11691 return -ENOMEM;
11692 }
11693
11694 for (i = 0; i < vop2->registered_num_wins; i++) {
11695 win = &vop2->win[i];
11696 plane_name_list[i].type = win->plane_id;
11697 plane_name_list[i].name = win->name;
11698 }
11699
11700 vop2->plane_name_list = plane_name_list;
11701
11702 return 0;
11703 }
11704
11705 #include "rockchip_vop2_clk.c"
post_buf_empty_work_event(struct work_struct * work)11706 static void post_buf_empty_work_event(struct work_struct *work)
11707 {
11708 struct vop2 *vop2 = container_of(work, struct vop2, post_buf_empty_work);
11709 struct rockchip_drm_private *private = vop2->drm_dev->dev_private;
11710 struct vop2_video_port *vp = &vop2->vps[1];
11711
11712 /*
11713 * For RK3528, VP1 only supports NTSC and PAL mode(both interlace). If
11714 * POST_BUF_EMPTY_INTR comes, it is needed to reset the p2i_en bit, in
11715 * order to update the line parity flag, which ensures the correct order
11716 * of odd and even lines.
11717 */
11718 if (vop2->version == VOP_VERSION_RK3528) {
11719 if (atomic_read(&vp->post_buf_empty_flag) > 0) {
11720 atomic_set(&vp->post_buf_empty_flag, 0);
11721
11722 mutex_lock(&private->ovl_lock);
11723 vop2_wait_for_fs_by_done_bit_status(vp);
11724 VOP_MODULE_SET(vop2, vp, p2i_en, 0);
11725 vop2_cfg_done(&vp->rockchip_crtc.crtc);
11726 vop2_wait_for_fs_by_done_bit_status(vp);
11727 mutex_unlock(&private->ovl_lock);
11728
11729 vp->need_reset_p2i_flag = true;
11730 } else if (vp->need_reset_p2i_flag == true) {
11731 mutex_lock(&private->ovl_lock);
11732 vop2_wait_for_fs_by_done_bit_status(vp);
11733 VOP_MODULE_SET(vop2, vp, p2i_en, 1);
11734 vop2_cfg_done(&vp->rockchip_crtc.crtc);
11735 vop2_wait_for_fs_by_done_bit_status(vp);
11736 mutex_unlock(&private->ovl_lock);
11737
11738 vp->need_reset_p2i_flag = false;
11739 }
11740 }
11741 }
11742
vop2_plane_mask_check(struct vop2 * vop2)11743 static bool vop2_plane_mask_check(struct vop2 *vop2)
11744 {
11745 const struct vop2_data *vop2_data = vop2->data;
11746 u32 plane_mask = 0;
11747 int i;
11748
11749 /*
11750 * For RK3568 and RK3588, all windows need to be assigned to
11751 * one of all vps, and two of vps can not share the same window.
11752 */
11753 if (vop2->version != VOP_VERSION_RK3568 && vop2->version != VOP_VERSION_RK3588)
11754 return true;
11755
11756 for (i = 0; i < vop2_data->nr_vps; i++) {
11757 if (plane_mask & vop2->vps[i].plane_mask) {
11758 DRM_WARN("the same window can't be assigned to two vp\n");
11759 return false;
11760 }
11761 plane_mask |= vop2->vps[i].plane_mask;
11762 }
11763
11764 if (hweight32(plane_mask) != vop2_data->nr_layers ||
11765 plane_mask != vop2_data->plane_mask_base) {
11766 DRM_WARN("all windows should be assigned, full plane mask: 0x%x, current plane mask: 0x%x\n",
11767 vop2_data->plane_mask_base, plane_mask);
11768 return false;
11769 }
11770
11771 return true;
11772 }
11773
vop2_vp_plane_mask_to_bitmap(const struct vop2_vp_plane_mask * vp_plane_mask)11774 static uint32_t vop2_vp_plane_mask_to_bitmap(const struct vop2_vp_plane_mask *vp_plane_mask)
11775 {
11776 int layer_phy_id = 0;
11777 int plane_mask = 0;
11778 int i;
11779
11780 for (i = 0; i < vp_plane_mask->attached_layers_nr; i++) {
11781 layer_phy_id = vp_plane_mask->attached_layers[i];
11782 plane_mask |= BIT(layer_phy_id);
11783 }
11784
11785 return plane_mask;
11786 }
11787
vop2_get_vp_of_status(struct device_node * vp_node)11788 static bool vop2_get_vp_of_status(struct device_node *vp_node)
11789 {
11790 struct device_node *vp_sub_node;
11791 struct device_node *remote_node;
11792 bool vp_enable = false;
11793
11794 for_each_child_of_node(vp_node, vp_sub_node) {
11795 remote_node = of_graph_get_remote_endpoint(vp_sub_node);
11796 vp_enable |= of_device_is_available(remote_node);
11797 }
11798
11799 return vp_enable;
11800 }
11801
vop2_plane_mask_assign(struct vop2 * vop2,struct device_node * vop_out_node)11802 static void vop2_plane_mask_assign(struct vop2 *vop2, struct device_node *vop_out_node)
11803 {
11804 const struct vop2_data *vop2_data = vop2->data;
11805 const struct vop2_vp_plane_mask *plane_mask;
11806 struct device_node *child;
11807 int active_vp_num = 0;
11808 int vp_id;
11809 int i = 0;
11810
11811 for_each_child_of_node(vop_out_node, child) {
11812 if (vop2_get_vp_of_status(child))
11813 active_vp_num++;
11814 }
11815
11816 if (vop2_soc_is_rk3566() && active_vp_num > 2)
11817 DRM_WARN("RK3566 only support 2 vps\n");
11818 plane_mask = vop2_data->plane_mask;
11819 plane_mask += (active_vp_num - 1) * ROCKCHIP_MAX_CRTC;
11820
11821 for_each_child_of_node(vop_out_node, child) {
11822 of_property_read_u32(child, "reg", &vp_id);
11823 if (vop2_get_vp_of_status(child)) {
11824 vop2->vps[vp_id].plane_mask = vop2_vp_plane_mask_to_bitmap(&plane_mask[i]);
11825 vop2->vps[vp_id].primary_plane_phy_id = plane_mask[i].primary_plane_id;
11826 i++;
11827 } else {
11828 vop2->vps[vp_id].plane_mask = 0;
11829 vop2->vps[vp_id].primary_plane_phy_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
11830 }
11831 }
11832 }
11833
vop2_bind(struct device * dev,struct device * master,void * data)11834 static int vop2_bind(struct device *dev, struct device *master, void *data)
11835 {
11836 struct platform_device *pdev = to_platform_device(dev);
11837 const struct vop2_data *vop2_data;
11838 struct drm_device *drm_dev = data;
11839 struct vop2 *vop2;
11840 struct resource *res;
11841 size_t alloc_size;
11842 int ret, i;
11843 int num_wins = 0;
11844 int registered_num_crtcs;
11845 struct device_node *vop_out_node;
11846 struct device_node *mcu_timing_node;
11847
11848 vop2_data = of_device_get_match_data(dev);
11849 if (!vop2_data)
11850 return -ENODEV;
11851
11852 for (i = 0; i < vop2_data->win_size; i++) {
11853 const struct vop2_win_data *win_data = &vop2_data->win[i];
11854
11855 num_wins += win_data->area_size + 1;
11856 }
11857
11858 /* Allocate vop2 struct and its vop2_win array */
11859 alloc_size = sizeof(*vop2) + sizeof(*vop2->win) * num_wins;
11860 vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
11861 if (!vop2)
11862 return -ENOMEM;
11863
11864 vop2->dev = dev;
11865 vop2->data = vop2_data;
11866 vop2->drm_dev = drm_dev;
11867 vop2->version = vop2_data->version;
11868
11869 dev_set_drvdata(dev, vop2);
11870
11871 vop2->support_multi_area = of_property_read_bool(dev->of_node, "support-multi-area");
11872 vop2->disable_afbc_win = of_property_read_bool(dev->of_node, "disable-afbc-win");
11873 vop2->disable_win_move = of_property_read_bool(dev->of_node, "disable-win-move");
11874 vop2->skip_ref_fb = of_property_read_bool(dev->of_node, "skip-ref-fb");
11875
11876 ret = vop2_pd_data_init(vop2);
11877 if (ret)
11878 return ret;
11879 /*
11880 * esmart lb mode default config at vop2_reg.c vop2_data.esmart_lb_mode,
11881 * you can rewrite at dts vop node:
11882 *
11883 * VOP3_ESMART_8K_MODE = 0,
11884 * VOP3_ESMART_4K_4K_MODE = 1,
11885 * VOP3_ESMART_4K_2K_2K_MODE = 2,
11886 * VOP3_ESMART_2K_2K_2K_2K_MODE = 3,
11887 *
11888 * &vop {
11889 * esmart_lb_mode = /bits/ 8 <2>;
11890 * };
11891 */
11892 ret = of_property_read_u8(dev->of_node, "esmart_lb_mode", &vop2->esmart_lb_mode);
11893 if (ret < 0)
11894 vop2->esmart_lb_mode = vop2->data->esmart_lb_mode;
11895
11896 ret = vop2_win_init(vop2);
11897 if (ret)
11898 return ret;
11899
11900 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
11901 if (!res) {
11902 DRM_DEV_ERROR(vop2->dev, "failed to get vop2 register byname\n");
11903 return -EINVAL;
11904 }
11905 vop2->res = res;
11906 vop2->regs = devm_ioremap_resource(dev, res);
11907 if (IS_ERR(vop2->regs))
11908 return PTR_ERR(vop2->regs);
11909 vop2->len = resource_size(res);
11910
11911 vop2->regsbak = devm_kzalloc(dev, vop2->len, GFP_KERNEL);
11912 if (!vop2->regsbak)
11913 return -ENOMEM;
11914
11915 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma_lut");
11916 if (res) {
11917 vop2->lut_regs = devm_ioremap_resource(dev, res);
11918 if (IS_ERR(vop2->lut_regs))
11919 return PTR_ERR(vop2->lut_regs);
11920 }
11921
11922 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acm_regs");
11923 if (res) {
11924 vop2->acm_regs = devm_ioremap_resource(dev, res);
11925 if (IS_ERR(vop2->acm_regs))
11926 return PTR_ERR(vop2->acm_regs);
11927 }
11928
11929 vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
11930 vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf");
11931 vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf");
11932 vop2->sys_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu");
11933
11934 vop2->hclk = devm_clk_get(vop2->dev, "hclk_vop");
11935 if (IS_ERR(vop2->hclk)) {
11936 DRM_DEV_ERROR(vop2->dev, "failed to get hclk source\n");
11937 return PTR_ERR(vop2->hclk);
11938 }
11939 vop2->aclk = devm_clk_get(vop2->dev, "aclk_vop");
11940 if (IS_ERR(vop2->aclk)) {
11941 DRM_DEV_ERROR(vop2->dev, "failed to get aclk source\n");
11942 return PTR_ERR(vop2->aclk);
11943 }
11944
11945 vop2->pclk = devm_clk_get_optional(vop2->dev, "pclk_vop");
11946 if (IS_ERR(vop2->pclk)) {
11947 DRM_DEV_ERROR(vop2->dev, "failed to get pclk source\n");
11948 return PTR_ERR(vop2->pclk);
11949 }
11950
11951 vop2->ahb_rst = devm_reset_control_get_optional(vop2->dev, "ahb");
11952 if (IS_ERR(vop2->ahb_rst)) {
11953 DRM_DEV_ERROR(vop2->dev, "failed to get ahb reset\n");
11954 return PTR_ERR(vop2->ahb_rst);
11955 }
11956
11957 vop2->axi_rst = devm_reset_control_get_optional(vop2->dev, "axi");
11958 if (IS_ERR(vop2->axi_rst)) {
11959 DRM_DEV_ERROR(vop2->dev, "failed to get axi reset\n");
11960 return PTR_ERR(vop2->axi_rst);
11961 }
11962
11963 vop2->irq = platform_get_irq(pdev, 0);
11964 if (vop2->irq < 0) {
11965 DRM_DEV_ERROR(dev, "cannot find irq for vop2\n");
11966 return vop2->irq;
11967 }
11968
11969 vop_out_node = of_get_child_by_name(dev->of_node, "ports");
11970 if (vop_out_node) {
11971 struct device_node *child;
11972
11973 for_each_child_of_node(vop_out_node, child) {
11974 u32 plane_mask = 0;
11975 u32 primary_plane_phy_id = 0;
11976 u32 vp_id = 0;
11977 u32 val = 0;
11978
11979 of_property_read_u32(child, "rockchip,plane-mask", &plane_mask);
11980 of_property_read_u32(child, "rockchip,primary-plane", &primary_plane_phy_id);
11981 of_property_read_u32(child, "reg", &vp_id);
11982
11983 vop2->vps[vp_id].plane_mask = plane_mask;
11984 if (plane_mask)
11985 vop2->vps[vp_id].primary_plane_phy_id = primary_plane_phy_id;
11986 else
11987 vop2->vps[vp_id].primary_plane_phy_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
11988
11989 vop2->vps[vp_id].xmirror_en = of_property_read_bool(child, "xmirror-enable");
11990
11991 ret = of_clk_set_defaults(child, false);
11992 if (ret) {
11993 DRM_DEV_ERROR(dev, "Failed to set clock defaults %d\n", ret);
11994 return ret;
11995 }
11996
11997 mcu_timing_node = of_get_child_by_name(child, "mcu-timing");
11998 if (mcu_timing_node) {
11999 if (!of_property_read_u32(mcu_timing_node, "mcu-pix-total", &val))
12000 vop2->vps[vp_id].mcu_timing.mcu_pix_total = val;
12001 if (!of_property_read_u32(mcu_timing_node, "mcu-cs-pst", &val))
12002 vop2->vps[vp_id].mcu_timing.mcu_cs_pst = val;
12003 if (!of_property_read_u32(mcu_timing_node, "mcu-cs-pend", &val))
12004 vop2->vps[vp_id].mcu_timing.mcu_cs_pend = val;
12005 if (!of_property_read_u32(mcu_timing_node, "mcu-rw-pst", &val))
12006 vop2->vps[vp_id].mcu_timing.mcu_rw_pst = val;
12007 if (!of_property_read_u32(mcu_timing_node, "mcu-rw-pend", &val))
12008 vop2->vps[vp_id].mcu_timing.mcu_rw_pend = val;
12009 if (!of_property_read_u32(mcu_timing_node, "mcu-hold-mode", &val))
12010 vop2->vps[vp_id].mcu_timing.mcu_hold_mode = val;
12011 }
12012 }
12013
12014 if (!vop2_plane_mask_check(vop2)) {
12015 DRM_WARN("use default plane mask\n");
12016 vop2_plane_mask_assign(vop2, vop_out_node);
12017 }
12018
12019 for (i = 0; i < vop2->data->nr_vps; i++) {
12020 DRM_DEV_INFO(dev, "vp%d assign plane mask: 0x%x, primary plane phy id: %d\n",
12021 i, vop2->vps[i].plane_mask,
12022 vop2->vps[i].primary_plane_phy_id);
12023 }
12024 }
12025
12026 vop2_extend_clk_init(vop2);
12027 spin_lock_init(&vop2->reg_lock);
12028 spin_lock_init(&vop2->irq_lock);
12029 mutex_init(&vop2->vop2_lock);
12030
12031 if (vop2->version == VOP_VERSION_RK3528) {
12032 atomic_set(&vop2->vps[1].post_buf_empty_flag, 0);
12033 vop2->workqueue = create_workqueue("post_buf_empty_wq");
12034 INIT_WORK(&vop2->post_buf_empty_work, post_buf_empty_work_event);
12035 }
12036
12037 ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2);
12038 if (ret)
12039 return ret;
12040
12041 vop2_dsc_data_init(vop2);
12042
12043 registered_num_crtcs = vop2_create_crtc(vop2);
12044 if (registered_num_crtcs <= 0)
12045 return -ENODEV;
12046
12047 ret = vop2_gamma_init(vop2);
12048 if (ret)
12049 return ret;
12050 vop2_clk_init(vop2);
12051 vop2_cubic_lut_init(vop2);
12052 vop2_wb_connector_init(vop2, registered_num_crtcs);
12053 pm_runtime_enable(&pdev->dev);
12054
12055 return 0;
12056 }
12057
vop2_unbind(struct device * dev,struct device * master,void * data)12058 static void vop2_unbind(struct device *dev, struct device *master, void *data)
12059 {
12060 struct vop2 *vop2 = dev_get_drvdata(dev);
12061 struct drm_device *drm_dev = vop2->drm_dev;
12062 struct list_head *plane_list = &drm_dev->mode_config.plane_list;
12063 struct list_head *crtc_list = &drm_dev->mode_config.crtc_list;
12064 struct drm_crtc *crtc, *tmpc;
12065 struct drm_plane *plane, *tmpp;
12066
12067 pm_runtime_disable(dev);
12068
12069 list_for_each_entry_safe(plane, tmpp, plane_list, head)
12070 drm_plane_cleanup(plane);
12071
12072 list_for_each_entry_safe(crtc, tmpc, crtc_list, head)
12073 vop2_destroy_crtc(crtc);
12074
12075 vop2_wb_connector_destory(vop2);
12076 }
12077
12078 const struct component_ops vop2_component_ops = {
12079 .bind = vop2_bind,
12080 .unbind = vop2_unbind,
12081 };
12082 EXPORT_SYMBOL_GPL(vop2_component_ops);
12083