mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
drm/rockchip: vop2: Change port_mux must make sure previous configuration is done
port_mux register is shared by all the three(four on rk3588) video ports, and the config done vsync is controlled by layer_sel_regdone_sel bits. We must make sure the previous configuration is take effect, when change port_mux for another vp. Change-Id: Ic4bd58f52760080f2f264f37cc6f01a9cd58939f Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
This commit is contained in:
@@ -521,6 +521,7 @@ struct vop2 {
|
||||
* @active_vp_mask: Bitmask of active video ports;
|
||||
*/
|
||||
uint8_t active_vp_mask;
|
||||
uint16_t port_mux_cfg;
|
||||
|
||||
uint32_t *regsbak;
|
||||
void __iomem *regs;
|
||||
@@ -856,6 +857,27 @@ static void vop2_wait_for_fs_by_raw_status(struct vop2_video_port *vp)
|
||||
|
||||
}
|
||||
|
||||
static uint16_t vop2_read_port_mux(struct vop2 *vop2)
|
||||
{
|
||||
return vop2_readl(vop2, RK3568_OVL_PORT_SEL) & 0xffff;
|
||||
}
|
||||
|
||||
static void vop2_wait_for_port_mux_done(struct vop2 *vop2)
|
||||
{
|
||||
uint16_t port_mux_cfg;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Spin until the previous port_mux figuration
|
||||
* is done.
|
||||
*/
|
||||
ret = readx_poll_timeout_atomic(vop2_read_port_mux, vop2, port_mux_cfg,
|
||||
port_mux_cfg == vop2->port_mux_cfg, 0, 20 * 1000);
|
||||
if (ret)
|
||||
DRM_DEV_ERROR(vop2->dev, "wait port_mux done timeout: 0x%x--0x%x\n",
|
||||
port_mux_cfg, vop2->port_mux_cfg);
|
||||
}
|
||||
|
||||
static int32_t vop2_pending_done_bits(struct vop2_video_port *vp)
|
||||
{
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
@@ -2293,7 +2315,8 @@ static void vop2_layer_map_initial(struct vop2 *vop2, uint32_t current_vp_id)
|
||||
uint32_t used_layers = 0;
|
||||
uint32_t layer_map, sel;
|
||||
uint32_t win_map, vp_id;
|
||||
uint32_t port_mux;
|
||||
uint16_t port_mux_cfg = 0;
|
||||
uint16_t port_mux;
|
||||
uint32_t active_vp_mask = 0;
|
||||
uint32_t standby;
|
||||
uint32_t shift;
|
||||
@@ -2357,9 +2380,15 @@ static void vop2_layer_map_initial(struct vop2 *vop2, uint32_t current_vp_id)
|
||||
port_mux = 8;
|
||||
else
|
||||
port_mux = used_layers - 1;
|
||||
VOP_MODULE_SET(vop2, vp, port_mux, port_mux);
|
||||
port_mux_cfg |= port_mux << (vp->id * 4);
|
||||
}
|
||||
|
||||
/* the last VP is fixed */
|
||||
if (vop2->data->nr_vps >= 1)
|
||||
port_mux_cfg |= 7 << (4 * (vop2->data->nr_vps - 1));
|
||||
vop2->port_mux_cfg = port_mux_cfg;
|
||||
VOP_CTRL_SET(vop2, ovl_port_mux_cfg, port_mux_cfg);
|
||||
|
||||
for (i = 0; i < vop2->data->nr_layers; i++) {
|
||||
sel = (layer_map >> (4 * i)) & 0xf;
|
||||
layer = &vop2->layers[i];
|
||||
@@ -4570,13 +4599,12 @@ static void vop2_setup_layer_mixer_for_vp(struct vop2_video_port *vp,
|
||||
const struct vop2_zpos *zpos;
|
||||
struct vop2_win *win;
|
||||
struct vop2_layer *layer;
|
||||
u8 used_layers = 0;
|
||||
u16 port_mux_cfg = 0;
|
||||
u8 port_mux;
|
||||
u8 used_layers = 0;
|
||||
u8 layer_id, win_phys_id;
|
||||
int i;
|
||||
|
||||
VOP_CTRL_SET(vop2, ovl_cfg_done_port, port_id);
|
||||
VOP_CTRL_SET(vop2, ovl_port_mux_cfg_done_imd, 0);
|
||||
for (i = 0; i < vop2_data->nr_vps - 1; i++) {
|
||||
prev_vp = &vop2->vps[i];
|
||||
used_layers += hweight32(prev_vp->win_mask);
|
||||
@@ -4597,13 +4625,22 @@ static void vop2_setup_layer_mixer_for_vp(struct vop2_video_port *vp,
|
||||
else
|
||||
port_mux = used_layers - 1;
|
||||
|
||||
port_mux_cfg |= port_mux << (prev_vp->id * 4);
|
||||
|
||||
if (port_mux > vop2_data->nr_mixers)
|
||||
prev_vp->bg_ovl_dly = 0;
|
||||
else
|
||||
prev_vp->bg_ovl_dly = (vop2_data->nr_mixers - port_mux) << 1;
|
||||
VOP_MODULE_SET(vop2, prev_vp, port_mux, port_mux);
|
||||
}
|
||||
|
||||
port_mux_cfg |= 7 << (4 * (vop2->data->nr_vps - 1));
|
||||
|
||||
vop2_wait_for_port_mux_done(vop2);
|
||||
vop2->port_mux_cfg = port_mux_cfg;
|
||||
VOP_CTRL_SET(vop2, ovl_port_mux_cfg, port_mux_cfg);
|
||||
VOP_CTRL_SET(vop2, ovl_cfg_done_port, port_id);
|
||||
VOP_CTRL_SET(vop2, ovl_port_mux_cfg_done_imd, 0);
|
||||
|
||||
/*
|
||||
* Win and layer must map one by one, if a win is selected
|
||||
* by two layers, unexpected error may happen.
|
||||
|
||||
@@ -1182,6 +1182,7 @@ static const struct vop2_ctrl rk3568_vop_ctrl = {
|
||||
.auto_gating_en = VOP_REG(RK3568_SYS_AUTO_GATING_CTRL, 0x1, 31),
|
||||
.ovl_cfg_done_port = VOP_REG(RK3568_OVL_CTRL, 0x3, 30),
|
||||
.ovl_port_mux_cfg_done_imd = VOP_REG(RK3568_OVL_CTRL, 0x1, 28),
|
||||
.ovl_port_mux_cfg = VOP_REG(RK3568_OVL_PORT_SEL, 0xffff, 0),
|
||||
.if_ctrl_cfg_done_imd = VOP_REG(RK3568_DSP_IF_POL, 0x1, 28),
|
||||
.version = VOP_REG(RK3568_VERSION_INFO, 0xffff, 16),
|
||||
.lut_dma_en = VOP_REG(RK3568_SYS_AXI_LUT_CTRL, 0x1, 0),
|
||||
|
||||
Reference in New Issue
Block a user