Skip to content

Commit 944757a

Browse files
Andy Yanmmind
authored andcommitted
drm/rockchip: vop2: Add support for rk3576
VOP2 on rk3576: Three video ports: VP0 Max 4096x2160 VP1 Max 2560x1600 VP2 Max 1920x1080 2 4K Cluster windows with AFBC/RFBC, line RGB and YUV 4 Esmart windows with line RGB/YUV support: Esmart0/1: 4K Esmart2/3: 2k, or worked together as a single 4K plane at shared line buffer mode. Compared to the previous VOP, another difference is that each VP has its own independent vsync interrupt number. Signed-off-by: Andy Yan <[email protected]> Tested-by: Michael Riesch <[email protected]> # on RK3568 Tested-by: Detlev Casanova <[email protected]> Signed-off-by: Heiko Stuebner <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent c3b7c5a commit 944757a

File tree

3 files changed

+1050
-125
lines changed

3 files changed

+1050
-125
lines changed

drivers/gpu/drm/rockchip/rockchip_drm_vop2.c

Lines changed: 109 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
12801280
vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
12811281
}
12821282

1283+
if (vop2->version >= VOP_VERSION_RK3576)
1284+
vop2_win_write(win, VOP2_WIN_VP_SEL, vp->id);
1285+
12831286
if (vop2_cluster_window(win))
12841287
vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
12851288

@@ -1344,6 +1347,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
13441347
else
13451348
vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
13461349

1350+
if (vop2->version >= VOP_VERSION_RK3576) {
1351+
vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET_EN, 1);
1352+
vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET, yrgb_mst);
1353+
}
1354+
13471355
transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
13481356
vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
13491357
vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
@@ -2159,6 +2167,52 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
21592167
.late_register = vop2_crtc_late_register,
21602168
};
21612169

2170+
static irqreturn_t rk3576_vp_isr(int irq, void *data)
2171+
{
2172+
struct vop2_video_port *vp = data;
2173+
struct vop2 *vop2 = vp->vop2;
2174+
struct drm_crtc *crtc = &vp->crtc;
2175+
uint32_t irqs;
2176+
int ret = IRQ_NONE;
2177+
2178+
if (!pm_runtime_get_if_in_use(vop2->dev))
2179+
return IRQ_NONE;
2180+
2181+
irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
2182+
vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
2183+
2184+
if (irqs & VP_INT_DSP_HOLD_VALID) {
2185+
complete(&vp->dsp_hold_completion);
2186+
ret = IRQ_HANDLED;
2187+
}
2188+
2189+
if (irqs & VP_INT_FS_FIELD) {
2190+
drm_crtc_handle_vblank(crtc);
2191+
spin_lock(&crtc->dev->event_lock);
2192+
if (vp->event) {
2193+
u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
2194+
2195+
if (!(val & BIT(vp->id))) {
2196+
drm_crtc_send_vblank_event(crtc, vp->event);
2197+
vp->event = NULL;
2198+
drm_crtc_vblank_put(crtc);
2199+
}
2200+
}
2201+
spin_unlock(&crtc->dev->event_lock);
2202+
2203+
ret = IRQ_HANDLED;
2204+
}
2205+
2206+
if (irqs & VP_INT_POST_BUF_EMPTY) {
2207+
drm_err_ratelimited(vop2->drm, "POST_BUF_EMPTY irq err at vp%d\n", vp->id);
2208+
ret = IRQ_HANDLED;
2209+
}
2210+
2211+
pm_runtime_put(vop2->dev);
2212+
2213+
return ret;
2214+
}
2215+
21622216
static irqreturn_t vop2_isr(int irq, void *data)
21632217
{
21642218
struct vop2 *vop2 = data;
@@ -2174,41 +2228,43 @@ static irqreturn_t vop2_isr(int irq, void *data)
21742228
if (!pm_runtime_get_if_in_use(vop2->dev))
21752229
return IRQ_NONE;
21762230

2177-
for (i = 0; i < vop2_data->nr_vps; i++) {
2178-
struct vop2_video_port *vp = &vop2->vps[i];
2179-
struct drm_crtc *crtc = &vp->crtc;
2180-
u32 irqs;
2231+
if (vop2->version < VOP_VERSION_RK3576) {
2232+
for (i = 0; i < vop2_data->nr_vps; i++) {
2233+
struct vop2_video_port *vp = &vop2->vps[i];
2234+
struct drm_crtc *crtc = &vp->crtc;
2235+
u32 irqs;
21812236

2182-
irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
2183-
vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
2237+
irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
2238+
vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
21842239

2185-
if (irqs & VP_INT_DSP_HOLD_VALID) {
2186-
complete(&vp->dsp_hold_completion);
2187-
ret = IRQ_HANDLED;
2188-
}
2189-
2190-
if (irqs & VP_INT_FS_FIELD) {
2191-
drm_crtc_handle_vblank(crtc);
2192-
spin_lock(&crtc->dev->event_lock);
2193-
if (vp->event) {
2194-
u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
2240+
if (irqs & VP_INT_DSP_HOLD_VALID) {
2241+
complete(&vp->dsp_hold_completion);
2242+
ret = IRQ_HANDLED;
2243+
}
21952244

2196-
if (!(val & BIT(vp->id))) {
2197-
drm_crtc_send_vblank_event(crtc, vp->event);
2198-
vp->event = NULL;
2199-
drm_crtc_vblank_put(crtc);
2245+
if (irqs & VP_INT_FS_FIELD) {
2246+
drm_crtc_handle_vblank(crtc);
2247+
spin_lock(&crtc->dev->event_lock);
2248+
if (vp->event) {
2249+
u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
2250+
2251+
if (!(val & BIT(vp->id))) {
2252+
drm_crtc_send_vblank_event(crtc, vp->event);
2253+
vp->event = NULL;
2254+
drm_crtc_vblank_put(crtc);
2255+
}
22002256
}
2201-
}
2202-
spin_unlock(&crtc->dev->event_lock);
2257+
spin_unlock(&crtc->dev->event_lock);
22032258

2204-
ret = IRQ_HANDLED;
2205-
}
2259+
ret = IRQ_HANDLED;
2260+
}
22062261

2207-
if (irqs & VP_INT_POST_BUF_EMPTY) {
2208-
drm_err_ratelimited(vop2->drm,
2209-
"POST_BUF_EMPTY irq err at vp%d\n",
2210-
vp->id);
2211-
ret = IRQ_HANDLED;
2262+
if (irqs & VP_INT_POST_BUF_EMPTY) {
2263+
drm_err_ratelimited(vop2->drm,
2264+
"POST_BUF_EMPTY irq err at vp%d\n",
2265+
vp->id);
2266+
ret = IRQ_HANDLED;
2267+
}
22122268
}
22132269
}
22142270

@@ -2677,6 +2733,30 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
26772733
if (ret)
26782734
return ret;
26792735

2736+
if (vop2->version >= VOP_VERSION_RK3576) {
2737+
struct drm_crtc *crtc;
2738+
2739+
drm_for_each_crtc(crtc, drm) {
2740+
struct vop2_video_port *vp = to_vop2_video_port(crtc);
2741+
int vp_irq;
2742+
const char *irq_name = devm_kasprintf(dev, GFP_KERNEL, "vp%d", vp->id);
2743+
2744+
if (!irq_name)
2745+
return -ENOMEM;
2746+
2747+
vp_irq = platform_get_irq_byname(pdev, irq_name);
2748+
if (vp_irq < 0)
2749+
return dev_err_probe(drm->dev, vp_irq,
2750+
"cannot find irq for vop2 vp%d\n", vp->id);
2751+
2752+
ret = devm_request_irq(dev, vp_irq, rk3576_vp_isr, IRQF_SHARED, irq_name,
2753+
vp);
2754+
if (ret)
2755+
dev_err_probe(drm->dev, ret,
2756+
"request irq for vop2 vp%d failed\n", vp->id);
2757+
}
2758+
}
2759+
26802760
ret = vop2_find_rgb_encoder(vop2);
26812761
if (ret >= 0) {
26822762
vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,

drivers/gpu/drm/rockchip/rockchip_drm_vop2.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ enum win_dly_mode {
4444
VOP2_DLY_MODE_MAX,
4545
};
4646

47+
enum vop2_dly_module {
48+
VOP2_DLY_WIN, /** Win delay cycle for this VP */
49+
VOP2_DLY_LAYER_MIX, /** Layer Mix delay cycle for this VP */
50+
VOP2_DLY_HDR_MIX, /** HDR delay cycle for this VP */
51+
VOP2_DLY_MAX,
52+
};
53+
4754
enum vop2_scale_up_mode {
4855
VOP2_SCALE_UP_NRST_NBOR,
4956
VOP2_SCALE_UP_BIL,
@@ -140,16 +147,22 @@ enum vop2_win_regs {
140147
VOP2_WIN_AFBC_UV_SWAP,
141148
VOP2_WIN_AFBC_AUTO_GATING_EN,
142149
VOP2_WIN_AFBC_BLOCK_SPLIT_EN,
150+
VOP2_WIN_AFBC_PLD_OFFSET_EN,
143151
VOP2_WIN_AFBC_PIC_VIR_WIDTH,
144152
VOP2_WIN_AFBC_TILE_NUM,
145153
VOP2_WIN_AFBC_PIC_OFFSET,
146154
VOP2_WIN_AFBC_PIC_SIZE,
147155
VOP2_WIN_AFBC_DSP_OFFSET,
156+
VOP2_WIN_AFBC_PLD_OFFSET,
148157
VOP2_WIN_TRANSFORM_OFFSET,
149158
VOP2_WIN_AFBC_HDR_PTR,
150159
VOP2_WIN_AFBC_HALF_BLOCK_EN,
151160
VOP2_WIN_AFBC_ROTATE_270,
152161
VOP2_WIN_AFBC_ROTATE_90,
162+
163+
VOP2_WIN_VP_SEL,
164+
VOP2_WIN_DLY_NUM,
165+
153166
VOP2_WIN_MAX_REG,
154167
};
155168

@@ -215,6 +228,10 @@ struct vop2_video_port_data {
215228
struct vop_rect max_output;
216229
const u8 pre_scan_max_dly[4];
217230
unsigned int offset;
231+
/**
232+
* @pixel_rate: pixel per cycle
233+
*/
234+
u8 pixel_rate;
218235
};
219236

220237
struct vop2_video_port {
@@ -375,10 +392,13 @@ enum dst_factor_mode {
375392
#define RK3568_REG_CFG_DONE 0x000
376393
#define RK3568_VERSION_INFO 0x004
377394
#define RK3568_SYS_AUTO_GATING_CTRL 0x008
395+
#define RK3576_SYS_MMU_CTRL_IMD 0x020
378396
#define RK3568_SYS_AXI_LUT_CTRL 0x024
379397
#define RK3568_DSP_IF_EN 0x028
398+
#define RK3576_SYS_PORT_CTRL_IMD 0x028
380399
#define RK3568_DSP_IF_CTRL 0x02c
381400
#define RK3568_DSP_IF_POL 0x030
401+
#define RK3576_SYS_CLUSTER_PD_CTRL_IMD 0x030
382402
#define RK3588_SYS_PD_CTRL 0x034
383403
#define RK3568_WB_CTRL 0x40
384404
#define RK3568_WB_XSCAL_FACTOR 0x44
@@ -398,6 +418,55 @@ enum dst_factor_mode {
398418
#define RK3568_VP_INT_CLR(vp) (0xA4 + (vp) * 0x10)
399419
#define RK3568_VP_INT_STATUS(vp) (0xA8 + (vp) * 0x10)
400420
#define RK3568_VP_INT_RAW_STATUS(vp) (0xAC + (vp) * 0x10)
421+
#define RK3576_WB_CTRL 0x100
422+
#define RK3576_WB_XSCAL_FACTOR 0x104
423+
#define RK3576_WB_YRGB_MST 0x108
424+
#define RK3576_WB_CBR_MST 0x10C
425+
#define RK3576_WB_VIR_STRIDE 0x110
426+
#define RK3576_WB_TIMEOUT_CTRL 0x114
427+
#define RK3576_MIPI0_IF_CTRL 0x180
428+
#define RK3576_HDMI0_IF_CTRL 0x184
429+
#define RK3576_EDP0_IF_CTRL 0x188
430+
#define RK3576_DP0_IF_CTRL 0x18C
431+
#define RK3576_RGB_IF_CTRL 0x194
432+
#define RK3576_DP1_IF_CTRL 0x1A4
433+
#define RK3576_DP2_IF_CTRL 0x1B0
434+
435+
/* Extra OVL register definition */
436+
#define RK3576_SYS_EXTRA_ALPHA_CTRL 0x500
437+
#define RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL 0x530
438+
#define RK3576_CLUSTER0_MIX_DST_COLOR_CTRL 0x534
439+
#define RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x538
440+
#define RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL 0x53c
441+
#define RK3576_CLUSTER1_MIX_SRC_COLOR_CTRL 0x540
442+
#define RK3576_CLUSTER1_MIX_DST_COLOR_CTRL 0x544
443+
#define RK3576_CLUSTER1_MIX_SRC_ALPHA_CTRL 0x548
444+
#define RK3576_CLUSTER1_MIX_DST_ALPHA_CTRL 0x54c
445+
446+
/* OVL registers for Video Port definition */
447+
#define RK3576_OVL_CTRL(vp) (0x600 + (vp) * 0x100)
448+
#define RK3576_OVL_LAYER_SEL(vp) (0x604 + (vp) * 0x100)
449+
#define RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp) (0x620 + (vp) * 0x100)
450+
#define RK3576_OVL_MIX0_DST_COLOR_CTRL(vp) (0x624 + (vp) * 0x100)
451+
#define RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp) (0x628 + (vp) * 0x100)
452+
#define RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp) (0x62C + (vp) * 0x100)
453+
#define RK3576_OVL_MIX1_SRC_COLOR_CTRL(vp) (0x630 + (vp) * 0x100)
454+
#define RK3576_OVL_MIX1_DST_COLOR_CTRL(vp) (0x634 + (vp) * 0x100)
455+
#define RK3576_OVL_MIX1_SRC_ALPHA_CTRL(vp) (0x638 + (vp) * 0x100)
456+
#define RK3576_OVL_MIX1_DST_ALPHA_CTRL(vp) (0x63C + (vp) * 0x100)
457+
#define RK3576_OVL_MIX2_SRC_COLOR_CTRL(vp) (0x640 + (vp) * 0x100)
458+
#define RK3576_OVL_MIX2_DST_COLOR_CTRL(vp) (0x644 + (vp) * 0x100)
459+
#define RK3576_OVL_MIX2_SRC_ALPHA_CTRL(vp) (0x648 + (vp) * 0x100)
460+
#define RK3576_OVL_MIX2_DST_ALPHA_CTRL(vp) (0x64C + (vp) * 0x100)
461+
#define RK3576_EXTRA_OVL_SRC_COLOR_CTRL(vp) (0x650 + (vp) * 0x100)
462+
#define RK3576_EXTRA_OVL_DST_COLOR_CTRL(vp) (0x654 + (vp) * 0x100)
463+
#define RK3576_EXTRA_OVL_SRC_ALPHA_CTRL(vp) (0x658 + (vp) * 0x100)
464+
#define RK3576_EXTRA_OVL_DST_ALPHA_CTRL(vp) (0x65C + (vp) * 0x100)
465+
#define RK3576_OVL_HDR_SRC_COLOR_CTRL(vp) (0x660 + (vp) * 0x100)
466+
#define RK3576_OVL_HDR_DST_COLOR_CTRL(vp) (0x664 + (vp) * 0x100)
467+
#define RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp) (0x668 + (vp) * 0x100)
468+
#define RK3576_OVL_HDR_DST_ALPHA_CTRL(vp) (0x66C + (vp) * 0x100)
469+
#define RK3576_OVL_BG_MIX_CTRL(vp) (0x670 + (vp) * 0x100)
401470

402471
/* Video Port registers definition */
403472
#define RK3568_VP0_CTRL_BASE 0x0C00
@@ -480,7 +549,11 @@ enum dst_factor_mode {
480549
#define RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET 0x68
481550
#define RK3568_CLUSTER_WIN_AFBCD_CTRL 0x6C
482551

552+
#define RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET 0x78
553+
483554
#define RK3568_CLUSTER_CTRL 0x100
555+
#define RK3576_CLUSTER_PORT_SEL_IMD 0x1F4
556+
#define RK3576_CLUSTER_DLY_NUM 0x1F8
484557

485558
/* (E)smart register definition, offset relative to window base */
486559
#define RK3568_SMART_CTRL0 0x00
@@ -531,6 +604,9 @@ enum dst_factor_mode {
531604
#define RK3568_SMART_REGION3_SCL_FACTOR_CBR 0xC8
532605
#define RK3568_SMART_REGION3_SCL_OFFSET 0xCC
533606
#define RK3568_SMART_COLOR_KEY_CTRL 0xD0
607+
#define RK3576_SMART_ALPHA_MAP 0xD8
608+
#define RK3576_SMART_PORT_SEL_IMD 0xF4
609+
#define RK3576_SMART_DLY_NUM 0xF8
534610

535611
/* HDR register definition */
536612
#define RK3568_HDR_LUT_CTRL 0x2000
@@ -679,6 +755,17 @@ enum dst_factor_mode {
679755

680756
#define POLFLAG_DCLK_INV BIT(3)
681757

758+
#define RK3576_OVL_CTRL__YUV_MODE BIT(0)
759+
#define RK3576_OVL_BG_MIX_CTRL__BG_DLY GENMASK(31, 24)
760+
761+
#define RK3576_DSP_IF_CFG_DONE_IMD BIT(31)
762+
#define RK3576_DSP_IF_DCLK_SEL_OUT BIT(21)
763+
#define RK3576_DSP_IF_PCLK_DIV BIT(20)
764+
#define RK3576_DSP_IF_PIN_POL GENMASK(5, 4)
765+
#define RK3576_DSP_IF_MUX GENMASK(3, 2)
766+
#define RK3576_DSP_IF_CLK_OUT_EN BIT(1)
767+
#define RK3576_DSP_IF_EN BIT(0)
768+
682769
enum vop2_layer_phy_id {
683770
ROCKCHIP_VOP2_CLUSTER0 = 0,
684771
ROCKCHIP_VOP2_CLUSTER1,

0 commit comments

Comments
 (0)