mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
drm/rockchip: vop3: sync with kernel 4.19
Signed-off-by: Sandy Huang <hjc@rock-chips.com> Change-Id: I11c5491e51b0159ddfa8da778fe77cc9c617450b
This commit is contained in:
@@ -1125,7 +1125,47 @@ static int rockchip_drm_summary_show(struct seq_file *s, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_drm_regs_dump(struct seq_file *s, void *data)
|
||||
{
|
||||
struct drm_info_node *node = s->private;
|
||||
struct drm_minor *minor = node->minor;
|
||||
struct drm_device *drm_dev = minor->dev;
|
||||
struct rockchip_drm_private *priv = drm_dev->dev_private;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
drm_for_each_crtc(crtc, drm_dev) {
|
||||
int pipe = drm_crtc_index(crtc);
|
||||
|
||||
if (priv->crtc_funcs[pipe] &&
|
||||
priv->crtc_funcs[pipe]->regs_dump)
|
||||
priv->crtc_funcs[pipe]->regs_dump(crtc, s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_drm_active_regs_dump(struct seq_file *s, void *data)
|
||||
{
|
||||
struct drm_info_node *node = s->private;
|
||||
struct drm_minor *minor = node->minor;
|
||||
struct drm_device *drm_dev = minor->dev;
|
||||
struct rockchip_drm_private *priv = drm_dev->dev_private;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
drm_for_each_crtc(crtc, drm_dev) {
|
||||
int pipe = drm_crtc_index(crtc);
|
||||
|
||||
if (priv->crtc_funcs[pipe] &&
|
||||
priv->crtc_funcs[pipe]->active_regs_dump)
|
||||
priv->crtc_funcs[pipe]->active_regs_dump(crtc, s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_info_list rockchip_debugfs_files[] = {
|
||||
{ "active_regs", rockchip_drm_active_regs_dump, 0, NULL },
|
||||
{ "regs", rockchip_drm_regs_dump, 0, NULL },
|
||||
{ "summary", rockchip_drm_summary_show, 0, NULL },
|
||||
{ "mm_dump", rockchip_drm_mm_dump, 0, NULL },
|
||||
};
|
||||
|
||||
@@ -388,6 +388,7 @@ struct rockchip_crtc_funcs {
|
||||
int (*debugfs_init)(struct drm_minor *minor, struct drm_crtc *crtc);
|
||||
int (*debugfs_dump)(struct drm_crtc *crtc, struct seq_file *s);
|
||||
void (*regs_dump)(struct drm_crtc *crtc, struct seq_file *s);
|
||||
void (*active_regs_dump)(struct drm_crtc *crtc, struct seq_file *s);
|
||||
enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode,
|
||||
int output_type);
|
||||
|
||||
@@ -1072,16 +1072,14 @@ void rockchip_drm_show_logo(struct drm_device *drm_dev)
|
||||
private->loader_protect = true;
|
||||
drm_modeset_unlock_all(drm_dev);
|
||||
|
||||
drm_for_each_crtc(crtc, drm_dev) {
|
||||
struct drm_fb_helper *helper = private->fbdev_helper;
|
||||
struct rockchip_crtc_state *s = NULL;
|
||||
if (private->fbdev_helper && private->fbdev_helper->fb) {
|
||||
drm_for_each_crtc(crtc, drm_dev) {
|
||||
struct rockchip_crtc_state *s = NULL;
|
||||
|
||||
if (!helper)
|
||||
break;
|
||||
|
||||
s = to_rockchip_crtc_state(crtc->state);
|
||||
if (is_support_hotplug(s->output_type))
|
||||
drm_framebuffer_get(helper->fb);
|
||||
s = to_rockchip_crtc_state(crtc->state);
|
||||
if (is_support_hotplug(s->output_type))
|
||||
drm_framebuffer_get(private->fbdev_helper->fb);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -123,10 +123,10 @@ enum vop2_win_dly_mode {
|
||||
};
|
||||
|
||||
enum vop3_esmart_lb_mode {
|
||||
VOP3_ESMART_ONE_8K_MODE,
|
||||
VOP3_ESMART_TWO_4K_MODE,
|
||||
VOP3_ESMART_ONE_4K_AND_TWO_2K_MODE,
|
||||
VOP3_ESMART_FOUR_2K_MODE,
|
||||
VOP3_ESMART_8K_MODE,
|
||||
VOP3_ESMART_4K_4K_MODE,
|
||||
VOP3_ESMART_4K_2K_2K_MODE,
|
||||
VOP3_ESMART_2K_2K_2K_2K_MODE,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -559,7 +559,7 @@ struct hdr_extend {
|
||||
};
|
||||
|
||||
enum _vop_hdrvivid_mode {
|
||||
PQHDR2HDR_WITH_DYNAMIC,
|
||||
PQHDR2HDR_WITH_DYNAMIC = 0,
|
||||
PQHDR2SDR_WITH_DYNAMIC,
|
||||
HLG2PQHDR_WITH_DYNAMIC,
|
||||
HLG2SDR_WITH_DYNAMIC,
|
||||
@@ -567,14 +567,16 @@ enum _vop_hdrvivid_mode {
|
||||
HLG2SDR_WITHOUT_DYNAMIC,
|
||||
HDR_BYPASS,
|
||||
HDR102SDR,
|
||||
SDR2PQ,
|
||||
SDR2HDR10,
|
||||
SDR2HLG,
|
||||
SDR2HDR10_USERSPACE = 100,
|
||||
SDR2HLG_USERSPACE = 101,
|
||||
};
|
||||
|
||||
enum vop_hdr_format {
|
||||
HDR_NONE = 0,
|
||||
HDR_HDR10 = 1,
|
||||
HDR_HGGSTATIC = 2,
|
||||
HDR_HLGSTATIC = 2,
|
||||
RESERVED3 = 3, /* reserved for more future static hdr format */
|
||||
RESERVED4 = 4, /* reserved for more future static hdr format */
|
||||
HDR_HDRVIVID = 5,
|
||||
@@ -720,6 +722,7 @@ struct vop2_cluster_regs {
|
||||
struct vop_reg enable;
|
||||
struct vop_reg afbc_enable;
|
||||
struct vop_reg lb_mode;
|
||||
struct vop_reg scl_lb_mode;
|
||||
|
||||
struct vop_reg src_color_ctrl;
|
||||
struct vop_reg dst_color_ctrl;
|
||||
@@ -1039,7 +1042,6 @@ struct vop2_win_data {
|
||||
uint8_t axi_id;
|
||||
uint8_t axi_yrgb_id;
|
||||
uint8_t axi_uv_id;
|
||||
uint8_t scale_engine_num;
|
||||
uint8_t possible_crtcs;
|
||||
|
||||
uint32_t base;
|
||||
@@ -1211,6 +1213,7 @@ struct vop2_ctrl {
|
||||
struct vop_reg version;
|
||||
struct vop_reg standby;
|
||||
struct vop_reg dma_stop;
|
||||
struct vop_reg dsp_vs_t_sel;
|
||||
struct vop_reg lut_dma_en;
|
||||
struct vop_reg axi_outstanding_max_num;
|
||||
struct vop_reg axi_max_outstanding_en;
|
||||
@@ -1307,6 +1310,8 @@ struct vop2_ctrl {
|
||||
struct vop_dump_regs {
|
||||
uint32_t offset;
|
||||
const char *name;
|
||||
struct vop_reg state;
|
||||
bool enable_state;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <linux/swab.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/rockchip/cpu.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/types.h>
|
||||
#include <soc/rockchip/rockchip_dmc.h>
|
||||
#include <soc/rockchip/rockchip-system-status.h>
|
||||
#include <uapi/linux/videodev2.h>
|
||||
@@ -66,6 +68,8 @@
|
||||
#define REG_SET_MASK(x, name, off, reg, mask, v, relaxed) \
|
||||
_REG_SET(x, name, off, reg, reg.mask & mask, v, relaxed)
|
||||
|
||||
#define REG_GET(vop2, reg) ((vop2_readl(vop2, reg.offset) >> reg.shift) & reg.mask)
|
||||
|
||||
#define VOP_CLUSTER_SET(x, win, name, v) \
|
||||
do { \
|
||||
if (win->regs->cluster) \
|
||||
@@ -87,6 +91,8 @@
|
||||
#define VOP_CTRL_SET(x, name, v) \
|
||||
REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
|
||||
|
||||
#define VOP_CTRL_GET(x, name) vop2_read_reg(x, 0, &(x)->data->ctrl->name)
|
||||
|
||||
#define VOP_INTR_GET(vop2, name) \
|
||||
vop2_read_reg(vop2, 0, &vop2->data->ctrl->name)
|
||||
|
||||
@@ -563,6 +569,8 @@ struct vop2_video_port {
|
||||
uint8_t id;
|
||||
bool layer_sel_update;
|
||||
bool xmirror_en;
|
||||
bool need_reset_p2i_flag;
|
||||
atomic_t post_buf_empty_flag;
|
||||
const struct vop2_video_port_regs *regs;
|
||||
|
||||
struct completion dsp_hold_completion;
|
||||
@@ -736,10 +744,8 @@ struct vop2_video_port {
|
||||
*/
|
||||
struct drm_property *hdr_ext_data_prop;
|
||||
|
||||
bool hdr_ext_data_change;
|
||||
int hdrvivid_mode;
|
||||
|
||||
|
||||
/**
|
||||
* @acm_lut_data_prop: acm lut data interaction with userspace
|
||||
*/
|
||||
@@ -822,6 +828,7 @@ struct vop2 {
|
||||
*/
|
||||
uint32_t registered_num_wins;
|
||||
uint8_t used_mixers;
|
||||
uint8_t esmart_lb_mode;
|
||||
/**
|
||||
* @active_vp_mask: Bitmask of active video ports;
|
||||
*/
|
||||
@@ -867,6 +874,8 @@ struct vop2 {
|
||||
/* list_head of internal clk */
|
||||
struct list_head clk_list_head;
|
||||
struct list_head pd_list_head;
|
||||
struct work_struct post_buf_empty_work;
|
||||
struct workqueue_struct *workqueue;
|
||||
|
||||
struct vop2_layer layers[ROCKCHIP_MAX_LAYER];
|
||||
/* must put at the end of the struct */
|
||||
@@ -2414,7 +2423,7 @@ static int vop2_get_cluster_lb_mode(struct vop2_win *win, struct vop2_plane_stat
|
||||
#define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \
|
||||
(fac * (dst - 1) >> 16 < (src - 1))
|
||||
#define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \
|
||||
(fac * (dst - 1) >> 16 <= (src - 1))
|
||||
(fac * (dst - 1) >> 16 < (src - 1))
|
||||
|
||||
static uint16_t vop2_scale_factor(enum scale_mode mode,
|
||||
int32_t filter_mode,
|
||||
@@ -3238,7 +3247,7 @@ static void vop2_wb_commit(struct drm_crtc *crtc)
|
||||
fifo_throd = fb->pitches[0] >> 4;
|
||||
if (fifo_throd >= vop2->data->wb->fifo_depth)
|
||||
fifo_throd = vop2->data->wb->fifo_depth;
|
||||
r2y = fb->format->is_yuv && (!is_yuv_output(vcstate->bus_format));
|
||||
r2y = !vcstate->yuv_overlay && fb->format->is_yuv;
|
||||
|
||||
/*
|
||||
* the vp_id register config done immediately
|
||||
@@ -3610,25 +3619,15 @@ err:
|
||||
*/
|
||||
static void vop3_layer_map_initial(struct vop2 *vop2, uint32_t current_vp_id)
|
||||
{
|
||||
struct vop2_video_port *vp;
|
||||
struct vop2_win *win;
|
||||
unsigned long win_mask;
|
||||
uint16_t vp_id;
|
||||
int phys_id;
|
||||
int i;
|
||||
struct drm_plane *plane = NULL;
|
||||
|
||||
for (i = 0; i < vop2->data->nr_vps; i++) {
|
||||
vp_id = i;
|
||||
vp = &vop2->vps[vp_id];
|
||||
vp->win_mask = vp->plane_mask;
|
||||
win_mask = vp->win_mask;
|
||||
for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
|
||||
win = vop2_find_win_by_phys_id(vop2, phys_id);
|
||||
VOP_CTRL_SET(vop2, win_vp_id[phys_id], vp_id);
|
||||
win->vp_mask = BIT(vp_id);
|
||||
win->old_vp_mask = win->vp_mask;
|
||||
DRM_DEV_DEBUG(vop2->dev, "%s attach to vp%d\n", win->name, vp_id);
|
||||
}
|
||||
drm_for_each_plane(plane, vop2->drm_dev) {
|
||||
struct vop2_win *win = to_vop2_win(plane);
|
||||
|
||||
vp_id = VOP_CTRL_GET(vop2, win_vp_id[win->phys_id]);
|
||||
win->vp_mask = BIT(vp_id);
|
||||
win->old_vp_mask = win->vp_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3746,8 +3745,10 @@ static void vop2_initial(struct drm_crtc *crtc)
|
||||
VOP_MODULE_SET(vop2, wb, axi_uv_id, 0xe);
|
||||
vop2_wb_cfg_done(vp);
|
||||
|
||||
if (is_vop3(vop2))
|
||||
if (is_vop3(vop2)) {
|
||||
VOP_CTRL_SET(vop2, dsp_vs_t_sel, 0);
|
||||
VOP_CTRL_SET(vop2, esmart_lb_mode, vop2->data->esmart_lb_mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is unused and error init value for rk3528 vp1, if less of this config,
|
||||
@@ -3762,6 +3763,9 @@ static void vop2_initial(struct drm_crtc *crtc)
|
||||
* avoid display image shift when a window enabled.
|
||||
*/
|
||||
VOP_CTRL_SET(vop2, auto_gating_en, 0);
|
||||
|
||||
VOP_CTRL_SET(vop2, aclk_pre_auto_gating_en, 0);
|
||||
|
||||
/*
|
||||
* Register OVERLAY_LAYER_SEL and OVERLAY_PORT_SEL should take effect immediately,
|
||||
* than windows configuration(CLUSTER/ESMART/SMART) can take effect according the
|
||||
@@ -4249,6 +4253,8 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
VOP_MODULE_SET(vop2, vp, cubic_lut_en, 0);
|
||||
}
|
||||
|
||||
if (vp_data->feature & VOP_FEATURE_VIVID_HDR)
|
||||
VOP_MODULE_SET(vop2, vp, hdr_lut_update_en, 0);
|
||||
vop2_disable_all_planes_for_crtc(crtc);
|
||||
|
||||
/*
|
||||
@@ -4980,7 +4986,7 @@ static void vop2_win_atomic_update(struct vop2_win *win, struct drm_rect *src, s
|
||||
if (vop2->version != VOP_VERSION_RK3568)
|
||||
rk3588_vop2_win_cfg_axi(win);
|
||||
|
||||
if (is_vop3(vop2) && !vop2_cluster_window(win))
|
||||
if (!win->parent && !vop2_cluster_window(win) && is_vop3(vop2))
|
||||
VOP_WIN_SET(vop2, win, scale_engine_num, win->scale_engine_num);
|
||||
|
||||
if (vpstate->afbc_en) {
|
||||
@@ -5079,7 +5085,7 @@ static void vop2_win_atomic_update(struct vop2_win *win, struct drm_rect *src, s
|
||||
}
|
||||
|
||||
VOP_WIN_SET(vop2, win, uv_vir, uv_stride);
|
||||
VOP_WIN_SET(vop2, win, uv_mst, vpstate->uv_mst);
|
||||
VOP_WIN_SET(vop2, win, uv_mst, uv_mst);
|
||||
}
|
||||
|
||||
/* tile 4x4 m0 format, y and uv is packed together */
|
||||
@@ -5108,6 +5114,7 @@ static void vop2_win_atomic_update(struct vop2_win *win, struct drm_rect *src, s
|
||||
if (vop2_cluster_window(win)) {
|
||||
lb_mode = vop2_get_cluster_lb_mode(win, vpstate);
|
||||
VOP_CLUSTER_SET(vop2, win, lb_mode, lb_mode);
|
||||
VOP_CLUSTER_SET(vop2, win, scl_lb_mode, lb_mode == 1 ? 3 : 0);
|
||||
VOP_CLUSTER_SET(vop2, win, enable, 1);
|
||||
}
|
||||
spin_unlock(&vop2->reg_lock);
|
||||
@@ -5916,6 +5923,7 @@ static void vop2_crtc_regs_dump(struct drm_crtc *crtc, struct seq_file *s)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
struct drm_crtc_state *cstate = crtc->state;
|
||||
const struct vop_dump_regs *regs = vop2->data->dump_regs;
|
||||
uint32_t buf[68];
|
||||
@@ -5923,20 +5931,80 @@ static void vop2_crtc_regs_dump(struct drm_crtc *crtc, struct seq_file *s)
|
||||
unsigned int n, i, j;
|
||||
resource_size_t offset_addr;
|
||||
uint32_t base;
|
||||
struct drm_crtc *first_active_crtc = NULL;
|
||||
|
||||
if (!cstate->active)
|
||||
return;
|
||||
|
||||
n = vop2->data->dump_regs_size;
|
||||
/* only need to dump once at first active crtc for vop2 */
|
||||
for (i = 0; i < vop2_data->nr_vps; i++) {
|
||||
if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
|
||||
first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_active_crtc != crtc)
|
||||
return;
|
||||
|
||||
n = vop2->data->dump_regs_size;
|
||||
for (i = 0; i < n; i++) {
|
||||
base = regs[i].offset;
|
||||
offset_addr = vop2->res->start + base;
|
||||
pr_info("%s[%pa]:\n", regs[i].name, &offset_addr);
|
||||
for (j = 0; j < len; j++)
|
||||
buf[j] = vop2_readl(vop2, base + (4 * j));
|
||||
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4, buf,
|
||||
len << 2, 0);
|
||||
DEBUG_PRINT("\n%s:\n", regs[i].name);
|
||||
for (j = 0; j < len;) {
|
||||
DEBUG_PRINT("%08x: %08x %08x %08x %08x\n", (u32)offset_addr + j * 4,
|
||||
vop2_readl(vop2, base + (4 * j)),
|
||||
vop2_readl(vop2, base + (4 * (j + 1))),
|
||||
vop2_readl(vop2, base + (4 * (j + 2))),
|
||||
vop2_readl(vop2, base + (4 * (j + 3))));
|
||||
j += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vop2_crtc_active_regs_dump(struct drm_crtc *crtc, struct seq_file *s)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
struct drm_crtc_state *cstate = crtc->state;
|
||||
const struct vop_dump_regs *regs = vop2->data->dump_regs;
|
||||
uint32_t buf[68];
|
||||
uint32_t len = ARRAY_SIZE(buf);
|
||||
unsigned int n, i, j;
|
||||
resource_size_t offset_addr;
|
||||
uint32_t base;
|
||||
struct drm_crtc *first_active_crtc = NULL;
|
||||
|
||||
if (!cstate->active)
|
||||
return;
|
||||
|
||||
/* only need to dump once at first active crtc for vop2 */
|
||||
for (i = 0; i < vop2_data->nr_vps; i++) {
|
||||
if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
|
||||
first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_active_crtc != crtc)
|
||||
return;
|
||||
|
||||
n = vop2->data->dump_regs_size;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (regs[i].state.mask &&
|
||||
REG_GET(vop2, regs[i].state) != regs[i].enable_state)
|
||||
continue;
|
||||
base = regs[i].offset;
|
||||
offset_addr = vop2->res->start + base;
|
||||
DEBUG_PRINT("\n%s:\n", regs[i].name);
|
||||
for (j = 0; j < len;) {
|
||||
DEBUG_PRINT("%08x: %08x %08x %08x %08x\n", (u32)offset_addr + j * 4,
|
||||
vop2_readl(vop2, base + (4 * j)),
|
||||
vop2_readl(vop2, base + (4 * (j + 1))),
|
||||
vop2_readl(vop2, base + (4 * (j + 2))),
|
||||
vop2_readl(vop2, base + (4 * (j + 3))));
|
||||
j += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6284,6 +6352,7 @@ static const struct rockchip_crtc_funcs private_crtc_funcs = {
|
||||
.debugfs_init = vop2_crtc_debugfs_init,
|
||||
.debugfs_dump = vop2_crtc_debugfs_dump,
|
||||
.regs_dump = vop2_crtc_regs_dump,
|
||||
.active_regs_dump = vop2_crtc_active_regs_dump,
|
||||
.bandwidth = vop2_crtc_bandwidth,
|
||||
.crtc_close = vop2_crtc_close,
|
||||
.te_handler = vop2_crtc_te_handler,
|
||||
@@ -6375,6 +6444,8 @@ static void vop2_post_config(struct drm_crtc *crtc)
|
||||
to_rockchip_crtc_state(crtc->state);
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
|
||||
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
|
||||
u16 vtotal = mode->crtc_vtotal;
|
||||
u16 hdisplay = mode->crtc_hdisplay;
|
||||
@@ -6414,8 +6485,16 @@ static void vop2_post_config(struct drm_crtc *crtc)
|
||||
val = vact_st_f1 << 16 | vact_end_f1;
|
||||
VOP_MODULE_SET(vop2, vp, vpost_st_end_f1, val);
|
||||
}
|
||||
VOP_MODULE_SET(vop2, vp, post_dsp_out_r2y,
|
||||
is_yuv_output(vcstate->bus_format));
|
||||
|
||||
/*
|
||||
* BCSH[R2Y] -> POST Linebuffer[post scale] -> the background R2Y will be deal by post_dsp_out_r2y
|
||||
*
|
||||
* POST Linebuffer[post scale] -> ACM[R2Y] -> the background R2Y will be deal by ACM[R2Y]
|
||||
*/
|
||||
if (vp_data->feature & VOP_FEATURE_POST_ACM)
|
||||
VOP_MODULE_SET(vop2, vp, post_dsp_out_r2y, vcstate->yuv_overlay);
|
||||
else
|
||||
VOP_MODULE_SET(vop2, vp, post_dsp_out_r2y, is_yuv_output(vcstate->bus_format));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -7044,6 +7123,107 @@ static void vop2_post_color_swap(struct drm_crtc *crtc)
|
||||
VOP_MODULE_SET(vop2, vp, dsp_data_swap, data_swap);
|
||||
}
|
||||
|
||||
/*
|
||||
* For vop3 video port0, if hdr_vivid is not enable, the pipe delay time as follow:
|
||||
* win_dly + config_win_dly + layer_mix_dly + sdr2hdr_dly + * hdr_mix_dly = config_bg_dly
|
||||
*
|
||||
* if hdr_vivid is enable, the hdr layer's pipe delay time as follow:
|
||||
* win_dly + config_win_dly +hdrvivid_dly + hdr_mix_dly = config_bg_dly
|
||||
*
|
||||
* If hdrvivid and sdr2hdr bot enable, the time arrivr hdr_mix should be the same:
|
||||
* win_dly + config_win_dly0 + hdrvivid_dly = win_dly + config_win_dly1 + laer_mix_dly +
|
||||
* sdr2hdr_dly
|
||||
*
|
||||
* For vop3 video port1, the pipe delay time as follow:
|
||||
* win_dly + config_win_dly + layer_mix_dly = config_bg_dly
|
||||
*
|
||||
* Here, win_dly, layer_mix_dly, sdr2hdr_dly, hdr_mix_dly, hdrvivid_dly is the hardware
|
||||
* delay cycles. Config_win_dly and config_bg_dly is the register value that we can config.
|
||||
* Different hdr vivid mode have different hdrvivid_dly. For sdr2hdr_dly, only sde2hdr
|
||||
* enable, it will delay, otherwise, the sdr2hdr_dly is 0.
|
||||
*
|
||||
* For default, the config_win_dly will be 0, it just user to make the pipe to arrive
|
||||
* hdr_mix at the same time.
|
||||
*/
|
||||
static void vop3_setup_pipe_dly(struct vop2_video_port *vp, const struct vop2_zpos *vop2_zpos)
|
||||
{
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
struct drm_crtc *crtc = &vp->rockchip_crtc.crtc;
|
||||
const struct vop2_zpos *zpos;
|
||||
struct drm_plane *plane;
|
||||
struct vop2_plane_state *vpstate;
|
||||
struct vop2_win *win;
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
|
||||
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
|
||||
u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
|
||||
u16 hdisplay = adjusted_mode->crtc_hdisplay;
|
||||
int bg_dly = 0x0;
|
||||
int dly = 0x0;
|
||||
int hdr_win_dly;
|
||||
int sdr_win_dly;
|
||||
int sdr2hdr_dly;
|
||||
int pre_scan_dly;
|
||||
int i;
|
||||
|
||||
/**
|
||||
* config bg dly, select the max delay num of hdrvivid and sdr2hdr module
|
||||
* as the increase value of bg delay num. If hdrvivid and sdr2hdr is not
|
||||
* work, the default bg_dly is 0x10. and the default win delay num is 0.
|
||||
*/
|
||||
if ((vp->hdr_en || vp->sdr2hdr_en) &&
|
||||
(vp->hdrvivid_mode >= 0 && vp->hdrvivid_mode <= SDR2HLG)) {
|
||||
/* set sdr2hdr_dly to 0 if sdr2hdr is disable */
|
||||
sdr2hdr_dly = vp->sdr2hdr_en ? vp_data->sdr2hdr_dly : 0;
|
||||
|
||||
/* set the max delay pipe's config_win_dly as 0 */
|
||||
if (vp_data->hdrvivid_dly[vp->hdrvivid_mode] >=
|
||||
sdr2hdr_dly + vp_data->layer_mix_dly) {
|
||||
bg_dly = vp_data->win_dly + vp_data->hdrvivid_dly[vp->hdrvivid_mode] +
|
||||
vp_data->hdr_mix_dly;
|
||||
hdr_win_dly = 0;
|
||||
sdr_win_dly = vp_data->hdrvivid_dly[vp->hdrvivid_mode] -
|
||||
vp_data->layer_mix_dly - sdr2hdr_dly;
|
||||
} else {
|
||||
bg_dly = vp_data->win_dly + vp_data->layer_mix_dly + sdr2hdr_dly +
|
||||
vp_data->hdr_mix_dly;
|
||||
hdr_win_dly = sdr2hdr_dly + vp_data->layer_mix_dly -
|
||||
vp_data->hdrvivid_dly[vp->hdrvivid_mode];
|
||||
sdr_win_dly = 0;
|
||||
}
|
||||
} else {
|
||||
bg_dly = vp_data->win_dly + vp_data->layer_mix_dly + vp_data->hdr_mix_dly;
|
||||
sdr_win_dly = 0;
|
||||
}
|
||||
|
||||
pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
|
||||
pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
|
||||
VOP_MODULE_SET(vop2, vp, bg_dly, bg_dly);
|
||||
VOP_MODULE_SET(vop2, vp, pre_scan_htiming, pre_scan_dly);
|
||||
|
||||
/**
|
||||
* config win dly
|
||||
*/
|
||||
if (!vop2_zpos)
|
||||
return;
|
||||
|
||||
for (i = 0; i < vp->nr_layers; i++) {
|
||||
zpos = &vop2_zpos[i];
|
||||
win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
|
||||
plane = &win->base;
|
||||
vpstate = to_vop2_plane_state(plane->state);
|
||||
|
||||
if ((vp->hdr_en || vp->sdr2hdr_en) &&
|
||||
(vp->hdrvivid_mode >= 0 && vp->hdrvivid_mode <= SDR2HLG)) {
|
||||
dly = vpstate->hdr_in ? hdr_win_dly : sdr_win_dly;
|
||||
}
|
||||
if (vop2_cluster_window(win))
|
||||
dly |= dly << 8;
|
||||
|
||||
VOP_CTRL_SET(vop2, win_dly[win->phys_id], dly);
|
||||
}
|
||||
}
|
||||
|
||||
static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
@@ -7435,6 +7615,15 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
|
||||
|
||||
if (vp_data->feature & VOP_FEATURE_OVERSCAN)
|
||||
vop2_post_config(crtc);
|
||||
/*
|
||||
* For RK3528, the path of CVBS output is like:
|
||||
* VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
|
||||
* The vop2 dclk should be four times crtc_clock for CVBS sampling clock needs.
|
||||
*/
|
||||
if (vop2->version == VOP_VERSION_RK3528 && vcstate->output_if & VOP_OUTPUT_IF_BT656)
|
||||
clk_set_rate(vp->dclk, 4 * adjusted_mode->crtc_clock * 1000);
|
||||
else
|
||||
clk_set_rate(vp->dclk, adjusted_mode->crtc_clock * 1000);
|
||||
|
||||
if (vcstate->dsc_enable) {
|
||||
if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
|
||||
@@ -7454,6 +7643,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
|
||||
*/
|
||||
if (vop2->version == VOP_VERSION_RK3588)
|
||||
VOP_MODULE_SET(vop2, vp, dsp_background, 0x80000000);
|
||||
if (is_vop3(vop2))
|
||||
vop3_setup_pipe_dly(vp, NULL);
|
||||
|
||||
vop2_cfg_done(crtc);
|
||||
|
||||
/*
|
||||
@@ -7498,53 +7690,9 @@ static int vop2_zpos_cmp(const void *a, const void *b)
|
||||
return pa->plane->base.id - pb->plane->base.id;
|
||||
}
|
||||
|
||||
static bool vop3_hdr_ext_data_equal(struct drm_crtc_state *old_state,
|
||||
struct drm_crtc_state *new_state)
|
||||
{
|
||||
struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_state);
|
||||
struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_state);
|
||||
struct drm_property_blob *new_blob = new_vcstate->hdr_ext_data;
|
||||
struct drm_property_blob *old_blob = old_vcstate->hdr_ext_data;
|
||||
|
||||
if (!old_blob || !new_blob)
|
||||
return old_blob == new_blob;
|
||||
|
||||
if (old_blob->length != new_blob->length)
|
||||
return false;
|
||||
|
||||
return !memcmp(old_blob->data, new_blob->data, old_blob->length);
|
||||
}
|
||||
|
||||
static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2_video_port *splice_vp;
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
|
||||
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
|
||||
struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(crtc_state);
|
||||
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
|
||||
|
||||
if (vop2_has_feature(vop2, VOP_FEATURE_SPLICE)) {
|
||||
if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
|
||||
vcstate->splice_mode = true;
|
||||
splice_vp = &vop2->vps[vp_data->splice_vp_id];
|
||||
splice_vp->splice_mode_right = true;
|
||||
splice_vp->left_vp = vp;
|
||||
}
|
||||
}
|
||||
|
||||
if ((vcstate->request_refresh_rate != new_vcstate->request_refresh_rate) ||
|
||||
crtc_state->active_changed || crtc_state->mode_changed)
|
||||
vp->refresh_rate_change = true;
|
||||
else
|
||||
vp->refresh_rate_change = false;
|
||||
|
||||
vp->hdr_ext_data_change = !vop3_hdr_ext_data_equal(crtc->state, crtc_state) |
|
||||
crtc_state->active_changed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7559,8 +7707,10 @@ static void vop3_disable_dynamic_hdr(struct vop2_video_port *vp, uint8_t win_phy
|
||||
VOP_MODULE_SET(vop2, vp, hdr10_en, 0);
|
||||
VOP_MODULE_SET(vop2, vp, hdr_vivid_en, 0);
|
||||
VOP_MODULE_SET(vop2, vp, hdr_vivid_bypass_en, 0);
|
||||
VOP_MODULE_SET(vop2, vp, hdr_lut_update_en, 0);
|
||||
VOP_MODULE_SET(vop2, vp, sdr2hdr_en, 0);
|
||||
VOP_MODULE_SET(vop2, vp, sdr2hdr_path_en, 0);
|
||||
VOP_MODULE_SET(vop2, vp, sdr2hdr_auto_gating_en, 1);
|
||||
|
||||
vp->hdr_en = false;
|
||||
vp->hdr_in = false;
|
||||
@@ -7601,13 +7751,19 @@ static void vop3_setup_hdrvivid(struct vop2_video_port *vp, uint8_t win_phys_id)
|
||||
|
||||
hdr_mode = hdrvivid_data->hdr_mode;
|
||||
|
||||
if (hdr_mode > SDR2HLG) {
|
||||
if (hdr_mode > SDR2HLG && hdr_mode != SDR2HDR10_USERSPACE &&
|
||||
hdr_mode != SDR2HLG_USERSPACE) {
|
||||
DRM_ERROR("Invalid HDR mode:%d, beyond the mode range\n", hdr_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr_mode <= HDR102SDR && vpstate->eotf != HDMI_EOTF_SMPTE_ST2084 &&
|
||||
vpstate->eotf != HDMI_EOTF_BT_2100_HLG) {
|
||||
/* adjust userspace hdr mode value to kernel value */
|
||||
if (hdr_mode == SDR2HDR10_USERSPACE)
|
||||
hdr_mode = SDR2HDR10;
|
||||
if (hdr_mode == SDR2HLG_USERSPACE)
|
||||
hdr_mode = SDR2HLG;
|
||||
|
||||
if (hdr_mode <= HDR102SDR && vpstate->eotf != HDMI_EOTF_SMPTE_ST2084 && vpstate->eotf != HDMI_EOTF_BT_2100_HLG) {
|
||||
DRM_ERROR("Invalid HDR mode:%d, mismatch plane eotf:%d\n", hdr_mode,
|
||||
vpstate->eotf);
|
||||
return;
|
||||
@@ -7670,6 +7826,7 @@ static void vop3_setup_hdrvivid(struct vop2_video_port *vp, uint8_t win_phys_id)
|
||||
}
|
||||
VOP_MODULE_SET(vop2, vp, sdr2hdr_en, vp->sdr2hdr_en);
|
||||
VOP_MODULE_SET(vop2, vp, sdr2hdr_path_en, vp->sdr2hdr_en);
|
||||
VOP_MODULE_SET(vop2, vp, sdr2hdr_auto_gating_en, vp->sdr2hdr_en ? 0 : 1);
|
||||
|
||||
vop2_writel(vop2, RK3528_SDR_CFG_COE0, hdrvivid_data->sdr2hdr_coe0);
|
||||
vop2_writel(vop2, RK3528_SDR_CFG_COE1, hdrvivid_data->sdr2hdr_coe1);
|
||||
@@ -7738,15 +7895,18 @@ static void vop3_setup_dynamic_hdr(struct vop2_video_port *vp, uint8_t win_phys_
|
||||
return;
|
||||
}
|
||||
|
||||
/* If hdr ext data is not change, do nothing here */
|
||||
if (!vp->hdr_ext_data_change)
|
||||
return;
|
||||
|
||||
hdr_data = (struct hdr_extend *)vcstate->hdr_ext_data->data;
|
||||
hdr_format = hdr_data->hdr_type;
|
||||
|
||||
switch (hdr_format) {
|
||||
case HDR_NONE:
|
||||
case HDR_HDR10:
|
||||
case HDR_HLGSTATIC:
|
||||
case HDR_HDRVIVID:
|
||||
/*
|
||||
* hdr module support hdr10, hlg, vividhdr
|
||||
* sdr2hdr module support hdrnone for sdr2hdr
|
||||
*/
|
||||
vop3_setup_hdrvivid(vp, win_phys_id);
|
||||
break;
|
||||
default:
|
||||
@@ -8689,107 +8849,6 @@ static void vop2_crtc_update_vrr(struct drm_crtc *crtc)
|
||||
rockchip_connector_update_vfp_for_vrr(crtc, adjust_mode, new_vfp);
|
||||
}
|
||||
|
||||
/*
|
||||
* For vop3 video port0, if hdr_vivid is not enable, the pipe delay time as follow:
|
||||
* win_dly + config_win_dly + layer_mix_dly + sdr2hdr_dly + * hdr_mix_dly = config_bg_dly
|
||||
*
|
||||
* if hdr_vivid is enable, the hdr layer's pipe delay time as follow:
|
||||
* win_dly + config_win_dly +hdrvivid_dly + hdr_mix_dly = config_bg_dly
|
||||
*
|
||||
* If hdrvivid and sdr2hdr bot enable, the time arrivr hdr_mix should be the same:
|
||||
* win_dly + config_win_dly0 + hdrvivid_dly = win_dly + config_win_dly1 + laer_mix_dly +
|
||||
* sdr2hdr_dly
|
||||
*
|
||||
* For vop3 video port1, the pipe delay time as follow:
|
||||
* win_dly + config_win_dly + layer_mix_dly = config_bg_dly
|
||||
*
|
||||
* Here, win_dly, layer_mix_dly, sdr2hdr_dly, hdr_mix_dly, hdrvivid_dly is the hardware
|
||||
* delay cycles. Config_win_dly and config_bg_dly is the register value that we can config.
|
||||
* Different hdr vivid mode have different hdrvivid_dly. For sdr2hdr_dly, only sde2hdr
|
||||
* enable, it will delay, otherwise, the sdr2hdr_dly is 0.
|
||||
*
|
||||
* For default, the config_win_dly will be 0, it just user to make the pipe to arrive
|
||||
* hdr_mix at the same time.
|
||||
*/
|
||||
static void vop3_setup_pipe_dly(struct vop2_video_port *vp, const struct vop2_zpos *vop2_zpos)
|
||||
{
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
struct drm_crtc *crtc = &vp->rockchip_crtc.crtc;
|
||||
const struct vop2_zpos *zpos;
|
||||
struct drm_plane *plane;
|
||||
struct vop2_plane_state *vpstate;
|
||||
struct vop2_win *win;
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
|
||||
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
|
||||
u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
|
||||
u16 hdisplay = adjusted_mode->crtc_hdisplay;
|
||||
int bg_dly = 0x0;
|
||||
int dly = 0x0;
|
||||
int hdr_win_dly;
|
||||
int sdr_win_dly;
|
||||
int sdr2hdr_dly;
|
||||
int pre_scan_dly;
|
||||
int i;
|
||||
|
||||
/**
|
||||
* config bg dly, select the max delay num of hdrvivid and sdr2hdr module
|
||||
* as the increase value of bg delay num. If hdrvivid and sdr2hdr is not
|
||||
* work, the default bg_dly is 0x10. and the default win delay num is 0.
|
||||
*/
|
||||
if ((vp->hdr_en || vp->sdr2hdr_en) &&
|
||||
(vp->hdrvivid_mode >= 0 && vp->hdrvivid_mode <= SDR2HLG)) {
|
||||
/* set sdr2hdr_dly to 0 if sdr2hdr is disable */
|
||||
sdr2hdr_dly = vp->sdr2hdr_en ? vp_data->sdr2hdr_dly : 0;
|
||||
|
||||
/* set the max delay pipe's config_win_dly as 0 */
|
||||
if (vp_data->hdrvivid_dly[vp->hdrvivid_mode] >=
|
||||
sdr2hdr_dly + vp_data->layer_mix_dly) {
|
||||
bg_dly = vp_data->win_dly + vp_data->hdrvivid_dly[vp->hdrvivid_mode] +
|
||||
vp_data->hdr_mix_dly;
|
||||
hdr_win_dly = 0;
|
||||
sdr_win_dly = vp_data->hdrvivid_dly[vp->hdrvivid_mode] -
|
||||
vp_data->layer_mix_dly - sdr2hdr_dly;
|
||||
} else {
|
||||
bg_dly = vp_data->win_dly + vp_data->layer_mix_dly + sdr2hdr_dly +
|
||||
vp_data->hdr_mix_dly;
|
||||
hdr_win_dly = sdr2hdr_dly + vp_data->layer_mix_dly -
|
||||
vp_data->hdrvivid_dly[vp->hdrvivid_mode];
|
||||
sdr_win_dly = 0;
|
||||
}
|
||||
} else {
|
||||
bg_dly = vp_data->win_dly + vp_data->layer_mix_dly + vp_data->hdr_mix_dly;
|
||||
sdr_win_dly = 0;
|
||||
}
|
||||
|
||||
pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
|
||||
pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
|
||||
VOP_MODULE_SET(vop2, vp, bg_dly, bg_dly);
|
||||
VOP_MODULE_SET(vop2, vp, pre_scan_htiming, pre_scan_dly);
|
||||
|
||||
/**
|
||||
* config win dly
|
||||
*/
|
||||
if (!vop2_zpos)
|
||||
return;
|
||||
|
||||
for (i = 0; i < vp->nr_layers; i++) {
|
||||
zpos = &vop2_zpos[i];
|
||||
win = vop2_find_win_by_phys_id(vop2, zpos->win_phys_id);
|
||||
plane = &win->base;
|
||||
vpstate = to_vop2_plane_state(plane->state);
|
||||
|
||||
if ((vp->hdr_en || vp->sdr2hdr_en) &&
|
||||
(vp->hdrvivid_mode >= 0 && vp->hdrvivid_mode <= SDR2HLG)) {
|
||||
dly = vpstate->hdr_in ? hdr_win_dly : sdr_win_dly;
|
||||
}
|
||||
if (vop2_cluster_window(win))
|
||||
dly |= dly << 8;
|
||||
|
||||
VOP_CTRL_SET(vop2, win_dly[win->phys_id], dly);
|
||||
}
|
||||
}
|
||||
|
||||
static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
@@ -8919,7 +8978,8 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state
|
||||
}
|
||||
|
||||
if (is_vop3(vop2)) {
|
||||
vop3_setup_dynamic_hdr(vp, vop2_zpos[0].win_phys_id);
|
||||
if (vp_data->feature & VOP_FEATURE_VIVID_HDR)
|
||||
vop3_setup_dynamic_hdr(vp, vop2_zpos[0].win_phys_id);
|
||||
vop3_setup_alpha(vp, vop2_zpos);
|
||||
vop3_setup_pipe_dly(vp, vop2_zpos);
|
||||
} else {
|
||||
@@ -9143,7 +9203,7 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
||||
if (is_yuv_output(vcstate->bus_format))
|
||||
is_output_yuv = true;
|
||||
|
||||
vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_space, CSC_10BIT_DEPTH);
|
||||
vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_space, CSC_13BIT_DEPTH);
|
||||
|
||||
if (post_csc_en) {
|
||||
rockchip_calc_post_csc(csc, &csc_coef, vcstate->post_csc_mode, is_input_yuv,
|
||||
@@ -9165,23 +9225,6 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
||||
range_type = csc_coef.range_type ? 0 : 1;
|
||||
range_type <<= is_input_yuv ? 0 : 1;
|
||||
VOP_MODULE_SET(vop2, vp, csc_mode, range_type);
|
||||
|
||||
/* rgb input rgb output for csc need rg swap and bg swap */
|
||||
if (!is_input_yuv && !is_output_yuv)
|
||||
VOP_MODULE_SET(vop2, vp, dsp_data_swap, DSP_RG_SWAP | DSP_BG_SWAP);
|
||||
|
||||
/* rgb input yuv output for csc need rg swap */
|
||||
if (!is_input_yuv && is_output_yuv)
|
||||
VOP_MODULE_SET(vop2, vp, dsp_data_swap, DSP_RG_SWAP);
|
||||
|
||||
/* yuv input yuv output for csc need rg swap */
|
||||
if (is_input_yuv && is_output_yuv)
|
||||
VOP_MODULE_SET(vop2, vp, dsp_data_swap, DSP_RG_SWAP);
|
||||
} else {
|
||||
if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode))
|
||||
VOP_MODULE_SET(vop2, vp, dsp_data_swap, DSP_RB_SWAP);
|
||||
else
|
||||
VOP_MODULE_SET(vop2, vp, dsp_data_swap, 0);
|
||||
}
|
||||
|
||||
VOP_MODULE_SET(vop2, vp, acm_r2y_en, post_r2y_en ? 1 : 0);
|
||||
@@ -9989,6 +10032,16 @@ static irqreturn_t vop2_isr(int irq, void *data)
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (vop2->version == VOP_VERSION_RK3528 && vp->id == 1) {
|
||||
if (active_irqs & POST_BUF_EMPTY_INTR)
|
||||
atomic_inc(&vp->post_buf_empty_flag);
|
||||
|
||||
if (active_irqs & FS_FIELD_INTR &&
|
||||
(atomic_read(&vp->post_buf_empty_flag) > 0 ||
|
||||
vp->need_reset_p2i_flag == true))
|
||||
queue_work(vop2->workqueue, &vop2->post_buf_empty_work);
|
||||
}
|
||||
|
||||
if (active_irqs & FS_FIELD_INTR) {
|
||||
rockchip_drm_dbg(vop2->dev, VOP_DEBUG_VSYNC, "vsync_vp%d\n", vp->id);
|
||||
vop2_wb_handler(vp);
|
||||
@@ -10083,6 +10136,39 @@ static int vop2_plane_create_feature_property(struct vop2 *vop2, struct vop2_win
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win *win)
|
||||
{
|
||||
if (!is_vop3(vop2))
|
||||
return false;
|
||||
|
||||
if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE &&
|
||||
win->phys_id != ROCKCHIP_VOP2_ESMART0)
|
||||
return true;
|
||||
else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE &&
|
||||
(win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3))
|
||||
return true;
|
||||
else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE &&
|
||||
win->phys_id == ROCKCHIP_VOP2_ESMART1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void vop3_init_esmart_scale_engine(struct vop2 *vop2)
|
||||
{
|
||||
u8 scale_engine_num = 0;
|
||||
struct drm_plane *plane = NULL;
|
||||
|
||||
drm_for_each_plane(plane, vop2->drm_dev) {
|
||||
struct vop2_win *win = to_vop2_win(plane);
|
||||
|
||||
if (win->parent || vop2_cluster_window(win))
|
||||
continue;
|
||||
|
||||
win->scale_engine_num = scale_engine_num++;
|
||||
}
|
||||
}
|
||||
|
||||
static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, unsigned long possible_crtcs)
|
||||
{
|
||||
struct rockchip_drm_private *private = vop2->drm_dev->dev_private;
|
||||
@@ -10107,6 +10193,10 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, unsigned lon
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* ignore some plane register according vop3 esmart lb mode */
|
||||
if (vop3_ignore_plane(vop2, win))
|
||||
return -EACCES;
|
||||
|
||||
ret = drm_universal_plane_init(vop2->drm_dev, &win->base, possible_crtcs,
|
||||
&vop2_plane_funcs, win->formats, win->nformats,
|
||||
win->format_modifiers, win->type, win->name);
|
||||
@@ -10182,15 +10272,27 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, unsigned lon
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_plane *vop2_cursor_plane_init(struct vop2_video_port *vp,
|
||||
unsigned long possible_crtcs)
|
||||
static struct drm_plane *vop2_cursor_plane_init(struct vop2_video_port *vp)
|
||||
{
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
struct drm_plane *cursor = NULL;
|
||||
struct vop2_win *win;
|
||||
unsigned long possible_crtcs = 0;
|
||||
|
||||
win = vop2_find_win_by_phys_id(vop2, vp->cursor_win_id);
|
||||
if (win) {
|
||||
if (vop2->disable_win_move) {
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
struct drm_crtc *crtc = vop2_find_crtc_by_plane_mask(vop2, win->phys_id);
|
||||
|
||||
if (crtc)
|
||||
possible_crtcs = drm_crtc_mask(crtc);
|
||||
else
|
||||
possible_crtcs = (1 << vop2_data->nr_vps) - 1;
|
||||
}
|
||||
|
||||
if (win->possible_crtcs)
|
||||
possible_crtcs = win->possible_crtcs;
|
||||
win->type = DRM_PLANE_TYPE_CURSOR;
|
||||
win->zpos = vop2->registered_num_wins - 1;
|
||||
if (!vop2_plane_init(vop2, win, possible_crtcs))
|
||||
@@ -10415,7 +10517,7 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
struct drm_device *drm_dev = vop2->drm_dev;
|
||||
struct device *dev = vop2->dev;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane *primary;
|
||||
struct drm_plane *cursor = NULL;
|
||||
struct drm_crtc *crtc;
|
||||
struct device_node *port;
|
||||
@@ -10464,6 +10566,9 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
vp->id = vp_data->id;
|
||||
vp->regs = vp_data->regs;
|
||||
vp->cursor_win_id = -1;
|
||||
primary = NULL;
|
||||
cursor = NULL;
|
||||
|
||||
if (vop2->disable_win_move)
|
||||
possible_crtcs = BIT(registered_num_crtcs);
|
||||
|
||||
@@ -10524,6 +10629,7 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
win->type = DRM_PLANE_TYPE_PRIMARY;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
while (j < vop2->registered_num_wins) {
|
||||
be_used_for_primary_plane = false;
|
||||
win = &vop2->win[j];
|
||||
@@ -10565,24 +10671,43 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
DRM_DEV_ERROR(vop2->dev, "failed to init primary plane\n");
|
||||
break;
|
||||
}
|
||||
plane = &win->base;
|
||||
primary = &win->base;
|
||||
}
|
||||
|
||||
/* some times we want a cursor window for some vp */
|
||||
if (vp->cursor_win_id < 0) {
|
||||
bool be_used_for_cursor_plane = false;
|
||||
|
||||
j = 0;
|
||||
while (j < vop2->registered_num_wins) {
|
||||
win = &vop2->win[j++];
|
||||
|
||||
if (win->parent || (win->feature & WIN_FEATURE_CLUSTER_SUB))
|
||||
continue;
|
||||
|
||||
if (win->type != DRM_PLANE_TYPE_CURSOR)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < vop2_data->nr_vps; k++) {
|
||||
if (vop2->vps[k].cursor_win_id == win->phys_id)
|
||||
be_used_for_cursor_plane = true;
|
||||
}
|
||||
if (be_used_for_cursor_plane)
|
||||
continue;
|
||||
vp->cursor_win_id = win->phys_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (vp->cursor_win_id >= 0) {
|
||||
if (win->possible_crtcs)
|
||||
possible_crtcs = win->possible_crtcs;
|
||||
cursor = vop2_cursor_plane_init(vp, possible_crtcs);
|
||||
cursor = vop2_cursor_plane_init(vp);
|
||||
if (!cursor)
|
||||
DRM_WARN("failed to init cursor plane for vp%d\n", vp->id);
|
||||
else
|
||||
DRM_DEV_INFO(vop2->dev, "%s as cursor plane for vp%d\n",
|
||||
cursor->name, vp->id);
|
||||
} else {
|
||||
cursor = NULL;
|
||||
}
|
||||
|
||||
ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, cursor, &vop2_crtc_funcs,
|
||||
ret = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor, &vop2_crtc_funcs,
|
||||
"video_port%d", vp->id);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(vop2->dev, "crtc init for video_port%d failed\n", i);
|
||||
@@ -10612,7 +10737,8 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
drm_object_attach_property(&crtc->base,
|
||||
drm_dev->mode_config.tv_bottom_margin_property, 100);
|
||||
}
|
||||
vop2_crtc_create_plane_mask_property(vop2, crtc, plane_mask);
|
||||
if (plane_mask)
|
||||
vop2_crtc_create_plane_mask_property(vop2, crtc, plane_mask);
|
||||
vop2_crtc_create_feature_property(vop2, crtc);
|
||||
vop2_crtc_create_vrr_property(vop2, crtc);
|
||||
|
||||
@@ -10693,6 +10819,9 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
DRM_WARN("failed to init overlay plane %s\n", win->name);
|
||||
}
|
||||
|
||||
if (is_vop3(vop2))
|
||||
vop3_init_esmart_scale_engine(vop2);
|
||||
|
||||
return registered_num_crtcs;
|
||||
}
|
||||
|
||||
@@ -10812,7 +10941,6 @@ static int vop2_win_init(struct vop2 *vop2)
|
||||
win->axi_id = win_data->axi_id;
|
||||
win->axi_yrgb_id = win_data->axi_yrgb_id;
|
||||
win->axi_uv_id = win_data->axi_uv_id;
|
||||
win->scale_engine_num = win_data->scale_engine_num;
|
||||
win->possible_crtcs = win_data->possible_crtcs;
|
||||
|
||||
if (win_data->pd_id)
|
||||
@@ -10844,6 +10972,7 @@ static int vop2_win_init(struct vop2 *vop2)
|
||||
area->vsd_filter_mode = win_data->vsd_filter_mode;
|
||||
area->hsd_pre_filter_mode = win_data->hsd_pre_filter_mode;
|
||||
area->vsd_pre_filter_mode = win_data->vsd_pre_filter_mode;
|
||||
area->possible_crtcs = win->possible_crtcs;
|
||||
|
||||
area->vop2 = vop2;
|
||||
area->win_id = i;
|
||||
@@ -10888,6 +11017,42 @@ static int vop2_win_init(struct vop2 *vop2)
|
||||
}
|
||||
|
||||
#include "rockchip_vop2_clk.c"
|
||||
static void post_buf_empty_work_event(struct work_struct *work)
|
||||
{
|
||||
struct vop2 *vop2 = container_of(work, struct vop2, post_buf_empty_work);
|
||||
struct rockchip_drm_private *private = vop2->drm_dev->dev_private;
|
||||
struct vop2_video_port *vp = &vop2->vps[1];
|
||||
|
||||
/*
|
||||
* For RK3528, VP1 only supports NTSC and PAL mode(both interlace). If
|
||||
* POST_BUF_EMPTY_INTR comes, it is needed to reset the p2i_en bit, in
|
||||
* order to update the line parity flag, which ensures the correct order
|
||||
* of odd and even lines.
|
||||
*/
|
||||
if (vop2->version == VOP_VERSION_RK3528) {
|
||||
if (atomic_read(&vp->post_buf_empty_flag) > 0) {
|
||||
atomic_set(&vp->post_buf_empty_flag, 0);
|
||||
|
||||
mutex_lock(&private->ovl_lock);
|
||||
vop2_wait_for_fs_by_done_bit_status(vp);
|
||||
VOP_MODULE_SET(vop2, vp, p2i_en, 0);
|
||||
vop2_cfg_done(&vp->rockchip_crtc.crtc);
|
||||
vop2_wait_for_fs_by_done_bit_status(vp);
|
||||
mutex_unlock(&private->ovl_lock);
|
||||
|
||||
vp->need_reset_p2i_flag = true;
|
||||
} else if (vp->need_reset_p2i_flag == true) {
|
||||
mutex_lock(&private->ovl_lock);
|
||||
vop2_wait_for_fs_by_done_bit_status(vp);
|
||||
VOP_MODULE_SET(vop2, vp, p2i_en, 1);
|
||||
vop2_cfg_done(&vp->rockchip_crtc.crtc);
|
||||
vop2_wait_for_fs_by_done_bit_status(vp);
|
||||
mutex_unlock(&private->ovl_lock);
|
||||
|
||||
vp->need_reset_p2i_flag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
@@ -10933,6 +11098,22 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
ret = vop2_pd_data_init(vop2);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* esmart lb mode default config at vop2_reg.c vop2_data.esmart_lb_mode,
|
||||
* you can rewrite at dts vop node:
|
||||
*
|
||||
* VOP3_ESMART_8K_MODE = 0,
|
||||
* VOP3_ESMART_4K_4K_MODE = 1,
|
||||
* VOP3_ESMART_4K_2K_2K_MODE = 2,
|
||||
* VOP3_ESMART_2K_2K_2K_2K_MODE = 3,
|
||||
*
|
||||
* &vop {
|
||||
* esmart_lb_mode = /bits/ 8 <2>;
|
||||
* };
|
||||
*/
|
||||
ret = of_property_read_u8(dev->of_node, "esmart_lb_mode", &vop2->esmart_lb_mode);
|
||||
if (ret < 0)
|
||||
vop2->esmart_lb_mode = vop2->data->esmart_lb_mode;
|
||||
|
||||
ret = vop2_win_init(vop2);
|
||||
if (ret)
|
||||
@@ -11045,6 +11226,12 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
spin_lock_init(&vop2->irq_lock);
|
||||
mutex_init(&vop2->vop2_lock);
|
||||
|
||||
if (vop2->version == VOP_VERSION_RK3528) {
|
||||
atomic_set(&vop2->vps[1].post_buf_empty_flag, 0);
|
||||
vop2->workqueue = create_workqueue("post_buf_empty_wq");
|
||||
INIT_WORK(&vop2->post_buf_empty_work, post_buf_empty_work_event);
|
||||
}
|
||||
|
||||
ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -670,7 +670,7 @@ static const struct rk_csc_mode_coef g_mode_csc_coef[] = {
|
||||
&rk_csc_table_rgb_to_xv_yccsdy_cb_cr_full,
|
||||
&rk_dc_csc_table_rgb_to_xv_yccsdy_cb_cr_full,
|
||||
{
|
||||
OPTM_CS_E_XV_YCC_601, OPTM_CS_E_RGB, true, true
|
||||
OPTM_CS_E_RGB, OPTM_CS_E_XV_YCC_601, true, true
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -782,7 +782,7 @@ static const struct rk_csc_mode_coef g_mode_csc_coef[] = {
|
||||
&rk_csc_table_rgb_limit_to_hdy_cb_cr,
|
||||
&rk_dc_csc_table_rgb_limit_to_hdy_cb_cr,
|
||||
{
|
||||
OPTM_CS_E_RGB, OPTM_CS_E_XV_YCC_601, false, false
|
||||
OPTM_CS_E_RGB, OPTM_CS_E_ITU_R_BT_709, false, false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -991,8 +991,8 @@ struct csc_mapping {
|
||||
enum vop_csc_format csc_format;
|
||||
enum color_space_type rgb_color_space;
|
||||
enum color_space_type yuv_color_space;
|
||||
bool yuv_full_range;
|
||||
bool rgb_full_range;
|
||||
bool yuv_full_range;
|
||||
};
|
||||
|
||||
static const struct csc_mapping csc_mapping_table[] = {
|
||||
@@ -1000,14 +1000,14 @@ static const struct csc_mapping csc_mapping_table[] = {
|
||||
CSC_BT601L,
|
||||
OPTM_CS_E_RGB,
|
||||
OPTM_CS_E_XV_YCC_601,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
CSC_BT709L,
|
||||
OPTM_CS_E_RGB,
|
||||
OPTM_CS_E_XV_YCC_709,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
@@ -1028,7 +1028,7 @@ static const struct csc_mapping csc_mapping_table[] = {
|
||||
CSC_BT709L_13BIT,
|
||||
OPTM_CS_E_RGB,
|
||||
OPTM_CS_E_XV_YCC_709,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
@@ -1042,7 +1042,7 @@ static const struct csc_mapping csc_mapping_table[] = {
|
||||
CSC_BT2020L_13BIT,
|
||||
OPTM_CS_E_RGB_2020,
|
||||
OPTM_CS_E_XV_YCC_2020,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
@@ -1054,6 +1054,30 @@ static const struct csc_mapping csc_mapping_table[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef r2y_for_y2y = {
|
||||
306, 601, 117,
|
||||
-151, -296, 446,
|
||||
630, -527, -102,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef y2r_for_y2y = {
|
||||
1024, -0, 1167,
|
||||
1024, -404, -594,
|
||||
1024, 2081, -1,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef rgb_input_swap_matrix = {
|
||||
0, 0, 1,
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef yuv_output_swap_matrix = {
|
||||
0, 0, 1,
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
};
|
||||
|
||||
static int csc_get_mode_index(int post_csc_mode, bool is_input_yuv, bool is_output_yuv)
|
||||
{
|
||||
const struct rk_csc_colorspace_info *colorspace_info;
|
||||
@@ -1244,35 +1268,17 @@ static struct rk_pq_csc_coef create_saturation_matrix(s32 saturation)
|
||||
return m;
|
||||
}
|
||||
|
||||
static const struct rk_pq_csc_coef r2y_for_y2y = {
|
||||
306, 601, 117,
|
||||
-151, -296, 446,
|
||||
630, -527, -102,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef y2r_for_y2y = {
|
||||
1024, -0, 1167,
|
||||
1024, -404, -594,
|
||||
1024, 2081, -1,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef rgb_swap_matrix = {
|
||||
0, 0, 1,
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
};
|
||||
|
||||
static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
struct post_csc *csc_input_cfg,
|
||||
const struct rk_csc_mode_coef *csc_mode_cfg,
|
||||
struct post_csc_coef *csc_output)
|
||||
struct rk_pq_csc_coef *out_matrix,
|
||||
struct rk_pq_csc_ventor *out_dc)
|
||||
{
|
||||
struct rk_pq_csc_coef gain_matrix;
|
||||
struct rk_pq_csc_coef contrast_matrix;
|
||||
struct rk_pq_csc_coef hue_matrix;
|
||||
struct rk_pq_csc_coef saturation_matrix;
|
||||
struct rk_pq_csc_coef temp0, temp1;
|
||||
struct rk_pq_csc_coef output;
|
||||
const struct rk_pq_csc_coef *r2y_matrix;
|
||||
const struct rk_pq_csc_coef *y2r_matrix;
|
||||
struct rk_pq_csc_ventor dc_in_ventor;
|
||||
@@ -1336,8 +1342,8 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &temp1, &contrast_matrix);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&output, &temp0, y2r_matrix);
|
||||
csc_matrix_element_left_shift(&output, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
csc_matrix_multiply(out_matrix, &temp0, y2r_matrix);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
@@ -1359,8 +1365,8 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &contrast_matrix, &temp1);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&output, &gain_matrix, &temp0);
|
||||
csc_matrix_element_left_shift(&output, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH +
|
||||
csc_matrix_multiply(out_matrix, &gain_matrix, &temp0);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
@@ -1382,14 +1388,9 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &saturation_matrix, &temp1);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp1, &hue_matrix, &temp0);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
csc_matrix_multiply(out_matrix, &hue_matrix, &temp0);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
/*
|
||||
* In rgb2yuv case, the rgb channel need swap, but vop post rgb swap
|
||||
* function can't config the correct swap, do this work in csc.
|
||||
*/
|
||||
csc_matrix_multiply(&output, &temp1, &rgb_swap_matrix);
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
dc_in_ventor.csc_offset1 = dc_in_offset;
|
||||
@@ -1426,12 +1427,12 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp1, &temp0, &saturation_matrix);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&output, &temp1, r2y_matrix);
|
||||
csc_matrix_element_left_shift(&output, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
csc_matrix_multiply(out_matrix, &temp1, r2y_matrix);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
if (color_info->in_full_range && color_info->out_full_range)
|
||||
output.csc_coef00 += 1;
|
||||
out_matrix->csc_coef00 += 1;
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
dc_in_ventor.csc_offset1 = dc_in_offset;
|
||||
@@ -1441,29 +1442,20 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
dc_out_ventor.csc_offset2 = brightness + dc_out_offset + b_offset;
|
||||
}
|
||||
|
||||
csc_output->csc_coef00 = output.csc_coef00;
|
||||
csc_output->csc_coef01 = output.csc_coef01;
|
||||
csc_output->csc_coef02 = output.csc_coef02;
|
||||
csc_output->csc_coef10 = output.csc_coef10;
|
||||
csc_output->csc_coef11 = output.csc_coef11;
|
||||
csc_output->csc_coef12 = output.csc_coef12;
|
||||
csc_output->csc_coef20 = output.csc_coef20;
|
||||
csc_output->csc_coef21 = output.csc_coef21;
|
||||
csc_output->csc_coef22 = output.csc_coef22;
|
||||
|
||||
csc_matrix_ventor_multiply(&v, &output, &dc_in_ventor);
|
||||
csc_output->csc_dc0 = v.csc_offset0 + dc_out_ventor.csc_offset0 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
csc_output->csc_dc1 = v.csc_offset1 + dc_out_ventor.csc_offset1 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
csc_output->csc_dc2 = v.csc_offset2 + dc_out_ventor.csc_offset2 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
csc_matrix_ventor_multiply(&v, out_matrix, &dc_in_ventor);
|
||||
out_dc->csc_offset0 = v.csc_offset0 + dc_out_ventor.csc_offset0 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
out_dc->csc_offset1 = v.csc_offset1 + dc_out_ventor.csc_offset1 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
out_dc->csc_offset2 = v.csc_offset2 + dc_out_ventor.csc_offset2 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int csc_calc_default_output_coef(const struct rk_csc_mode_coef *csc_mode_cfg,
|
||||
struct post_csc_coef *csc_output)
|
||||
struct rk_pq_csc_coef *out_matrix,
|
||||
struct rk_pq_csc_ventor *out_dc)
|
||||
{
|
||||
const struct rk_pq_csc_coef *csc_coef;
|
||||
const struct rk_pq_csc_dc_coef *csc_dc_coef;
|
||||
@@ -1474,15 +1466,15 @@ static int csc_calc_default_output_coef(const struct rk_csc_mode_coef *csc_mode_
|
||||
csc_coef = csc_mode_cfg->pst_csc_coef;
|
||||
csc_dc_coef = csc_mode_cfg->pst_csc_dc_coef;
|
||||
|
||||
csc_output->csc_coef00 = csc_coef->csc_coef00;
|
||||
csc_output->csc_coef01 = csc_coef->csc_coef01;
|
||||
csc_output->csc_coef02 = csc_coef->csc_coef02;
|
||||
csc_output->csc_coef10 = csc_coef->csc_coef10;
|
||||
csc_output->csc_coef11 = csc_coef->csc_coef11;
|
||||
csc_output->csc_coef12 = csc_coef->csc_coef12;
|
||||
csc_output->csc_coef20 = csc_coef->csc_coef20;
|
||||
csc_output->csc_coef21 = csc_coef->csc_coef21;
|
||||
csc_output->csc_coef22 = csc_coef->csc_coef22;
|
||||
out_matrix->csc_coef00 = csc_coef->csc_coef00;
|
||||
out_matrix->csc_coef01 = csc_coef->csc_coef01;
|
||||
out_matrix->csc_coef02 = csc_coef->csc_coef02;
|
||||
out_matrix->csc_coef10 = csc_coef->csc_coef10;
|
||||
out_matrix->csc_coef11 = csc_coef->csc_coef11;
|
||||
out_matrix->csc_coef12 = csc_coef->csc_coef12;
|
||||
out_matrix->csc_coef20 = csc_coef->csc_coef20;
|
||||
out_matrix->csc_coef21 = csc_coef->csc_coef21;
|
||||
out_matrix->csc_coef22 = csc_coef->csc_coef22;
|
||||
|
||||
dc_in_ventor.csc_offset0 = csc_dc_coef->csc_in_dc0;
|
||||
dc_in_ventor.csc_offset1 = csc_dc_coef->csc_in_dc1;
|
||||
@@ -1492,11 +1484,11 @@ static int csc_calc_default_output_coef(const struct rk_csc_mode_coef *csc_mode_
|
||||
dc_out_ventor.csc_offset2 = csc_dc_coef->csc_out_dc2;
|
||||
|
||||
csc_matrix_ventor_multiply(&v, csc_coef, &dc_in_ventor);
|
||||
csc_output->csc_dc0 = v.csc_offset0 + dc_out_ventor.csc_offset0 *
|
||||
out_dc->csc_offset0 = v.csc_offset0 + dc_out_ventor.csc_offset0 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
csc_output->csc_dc1 = v.csc_offset1 + dc_out_ventor.csc_offset1 *
|
||||
out_dc->csc_offset1 = v.csc_offset1 + dc_out_ventor.csc_offset1 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
csc_output->csc_dc2 = v.csc_offset2 + dc_out_ventor.csc_offset2 *
|
||||
out_dc->csc_offset2 = v.csc_offset2 + dc_out_ventor.csc_offset2 *
|
||||
PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM;
|
||||
|
||||
return 0;
|
||||
@@ -1513,10 +1505,46 @@ static inline s32 pq_csc_simple_round(s32 x, s32 n)
|
||||
return (((x) >= 0) ? value : -value);
|
||||
}
|
||||
|
||||
static void rockchip_swap_color_channel(bool is_input_yuv, bool is_output_yuv,
|
||||
struct post_csc_coef *csc_simple_coef,
|
||||
struct rk_pq_csc_coef *out_matrix,
|
||||
struct rk_pq_csc_ventor *out_dc)
|
||||
{
|
||||
struct rk_pq_csc_coef tmp_matrix;
|
||||
struct rk_pq_csc_ventor tmp_v;
|
||||
|
||||
if (!is_input_yuv) {
|
||||
memcpy(&tmp_matrix, out_matrix, sizeof(struct rk_pq_csc_coef));
|
||||
csc_matrix_multiply(out_matrix, &tmp_matrix, &rgb_input_swap_matrix);
|
||||
}
|
||||
|
||||
if (is_output_yuv) {
|
||||
memcpy(&tmp_matrix, out_matrix, sizeof(struct rk_pq_csc_coef));
|
||||
memcpy(&tmp_v, out_dc, sizeof(struct rk_pq_csc_ventor));
|
||||
csc_matrix_multiply(out_matrix, &yuv_output_swap_matrix, &tmp_matrix);
|
||||
csc_matrix_ventor_multiply(out_dc, &yuv_output_swap_matrix, &tmp_v);
|
||||
}
|
||||
|
||||
csc_simple_coef->csc_coef00 = out_matrix->csc_coef00;
|
||||
csc_simple_coef->csc_coef01 = out_matrix->csc_coef01;
|
||||
csc_simple_coef->csc_coef02 = out_matrix->csc_coef02;
|
||||
csc_simple_coef->csc_coef10 = out_matrix->csc_coef10;
|
||||
csc_simple_coef->csc_coef11 = out_matrix->csc_coef11;
|
||||
csc_simple_coef->csc_coef12 = out_matrix->csc_coef12;
|
||||
csc_simple_coef->csc_coef20 = out_matrix->csc_coef20;
|
||||
csc_simple_coef->csc_coef21 = out_matrix->csc_coef21;
|
||||
csc_simple_coef->csc_coef22 = out_matrix->csc_coef22;
|
||||
csc_simple_coef->csc_dc0 = out_dc->csc_offset0;
|
||||
csc_simple_coef->csc_dc1 = out_dc->csc_offset1;
|
||||
csc_simple_coef->csc_dc2 = out_dc->csc_offset2;
|
||||
}
|
||||
|
||||
int rockchip_calc_post_csc(struct post_csc *csc_cfg, struct post_csc_coef *csc_simple_coef,
|
||||
int csc_mode, bool is_input_yuv, bool is_output_yuv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct rk_pq_csc_coef out_matrix;
|
||||
struct rk_pq_csc_ventor out_dc;
|
||||
const struct rk_csc_mode_coef *csc_mode_cfg;
|
||||
int bit_num = PQ_CSC_SIMPLE_MAT_PARAM_FIX_BIT_WIDTH;
|
||||
|
||||
@@ -1530,9 +1558,12 @@ int rockchip_calc_post_csc(struct post_csc *csc_cfg, struct post_csc_coef *csc_s
|
||||
|
||||
if (csc_cfg)
|
||||
ret = csc_calc_adjust_output_coef(is_input_yuv, is_output_yuv, csc_cfg,
|
||||
csc_mode_cfg, csc_simple_coef);
|
||||
csc_mode_cfg, &out_matrix, &out_dc);
|
||||
else
|
||||
ret = csc_calc_default_output_coef(csc_mode_cfg, csc_simple_coef);
|
||||
ret = csc_calc_default_output_coef(csc_mode_cfg, &out_matrix, &out_dc);
|
||||
|
||||
rockchip_swap_color_channel(is_input_yuv, is_output_yuv, csc_simple_coef, &out_matrix,
|
||||
&out_dc);
|
||||
|
||||
csc_simple_coef->csc_dc0 = pq_csc_simple_round(csc_simple_coef->csc_dc0, bit_num);
|
||||
csc_simple_coef->csc_dc1 = pq_csc_simple_round(csc_simple_coef->csc_dc1, bit_num);
|
||||
|
||||
@@ -776,7 +776,9 @@ static const struct vop2_video_port_regs rk3528_vop_vp0_regs = {
|
||||
.overlay_mode = VOP_REG(RK3528_OVL_PORT0_CTRL, 0x1, 0),
|
||||
.dsp_background = VOP_REG(RK3568_VP0_DSP_BG, 0xffffffff, 0),
|
||||
.out_mode = VOP_REG(RK3568_VP0_DSP_CTRL, 0xf, 0),
|
||||
.core_dclk_div = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 4),
|
||||
.dclk_div2 = VOP_REG(RK3568_VP0_CLK_CTRL, 0x1, 4),
|
||||
.dclk_div2_phase_lock = VOP_REG(RK3568_VP0_DUAL_CHANNEL_CTRL, 0x1, 4),
|
||||
.p2i_en = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 5),
|
||||
.dsp_filed_pol = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 6),
|
||||
.dsp_interlace = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 7),
|
||||
@@ -818,6 +820,7 @@ static const struct vop2_video_port_regs rk3528_vop_vp0_regs = {
|
||||
.hdr10_en = VOP_REG(RK3568_OVL_CTRL, 0x1, 4),
|
||||
.sdr2hdr_path_en = VOP_REG(RK3568_OVL_CTRL, 0x1, 5),
|
||||
.sdr2hdr_en = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 0),
|
||||
.sdr2hdr_auto_gating_en = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 1),
|
||||
.sdr2hdr_bypass_en = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 2),
|
||||
.sdr2hdr_dstmode = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 3),
|
||||
.hdr_vivid_en = VOP_REG(RK3528_HDRVIVID_CTRL, 0x1, 0),
|
||||
@@ -928,7 +931,7 @@ static const struct vop2_video_port_data rk3528_vop_video_ports[] = {
|
||||
.soc_id = { 0x3528, 0x3528 },
|
||||
.lut_dma_rid = 14,
|
||||
.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_VIVID_HDR |
|
||||
VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC,
|
||||
VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC | VOP_FEATURE_OUTPUT_10BIT,
|
||||
.gamma_lut_len = 1024,
|
||||
.max_output = { 4096, 4096 },
|
||||
.hdrvivid_dly = {17, 29, 32, 44, 15, 38, 1, 29, 0, 0},
|
||||
@@ -1738,6 +1741,7 @@ static const struct vop2_cluster_regs rk3528_vop_cluster0 = {
|
||||
.afbc_enable = VOP_REG(RK3568_CLUSTER0_CTRL, 0x1, 1),
|
||||
.enable = VOP_REG(RK3568_CLUSTER0_CTRL, 1, 0),
|
||||
.lb_mode = VOP_REG(RK3568_CLUSTER0_CTRL, 0xf, 4),
|
||||
.scl_lb_mode = VOP_REG(RK3568_CLUSTER0_CTRL, 0x3, 9),
|
||||
.src_color_ctrl = VOP_REG(RK3528_CLUSTER0_MIX_SRC_COLOR_CTRL, 0xffffffff, 0),
|
||||
.dst_color_ctrl = VOP_REG(RK3528_CLUSTER0_MIX_DST_COLOR_CTRL, 0xffffffff, 0),
|
||||
.src_alpha_ctrl = VOP_REG(RK3528_CLUSTER0_MIX_SRC_ALPHA_CTRL, 0xffffffff, 0),
|
||||
@@ -1810,6 +1814,9 @@ static const struct vop2_scl_regs rk3528_cluster0_win_scl = {
|
||||
.yrgb_ver_scl_mode = VOP_REG(RK3528_CLUSTER0_WIN0_CTRL1, 0x3, 14),
|
||||
.yrgb_hor_scl_mode = VOP_REG(RK3528_CLUSTER0_WIN0_CTRL1, 0x3, 22),
|
||||
|
||||
.yrgb_hscl_filter_mode = VOP_REG(RK3528_CLUSTER0_WIN0_CTRL1, 0x3, 12),/* supported from vop3 */
|
||||
.yrgb_vscl_filter_mode = VOP_REG(RK3528_CLUSTER0_WIN0_CTRL1, 0x3, 20),/* supported from vop3 */
|
||||
|
||||
.vsd_yrgb_gt2 = VOP_REG(RK3568_CLUSTER0_WIN0_CTRL1, 0x1, 28),
|
||||
.vsd_yrgb_gt4 = VOP_REG(RK3568_CLUSTER0_WIN0_CTRL1, 0x1, 29),
|
||||
.vsd_cbcr_gt2 = VOP_REG(RK3568_CLUSTER0_WIN0_CTRL1, 0x1, 30),
|
||||
@@ -1963,6 +1970,9 @@ static const struct vop2_scl_regs rk3568_area1_scl = {
|
||||
.vsd_yrgb_gt4 = VOP_REG(RK3568_ESMART0_REGION1_CTRL, 0x1, 9),
|
||||
.vsd_cbcr_gt2 = VOP_REG(RK3568_ESMART0_REGION1_CTRL, 0x1, 10),
|
||||
.vsd_cbcr_gt4 = VOP_REG(RK3568_ESMART0_REGION1_CTRL, 0x1, 11),
|
||||
.xavg_en = VOP_REG(RK3568_ESMART0_REGION1_CTRL, 0x1, 20),/* supported from vop3 */
|
||||
.xgt_en = VOP_REG(RK3568_ESMART0_REGION1_CTRL, 0x1, 21),
|
||||
.xgt_mode = VOP_REG(RK3568_ESMART0_REGION1_CTRL, 0x3, 22),
|
||||
};
|
||||
|
||||
static const struct vop2_scl_regs rk3568_area2_scl = {
|
||||
@@ -1983,6 +1993,9 @@ static const struct vop2_scl_regs rk3568_area2_scl = {
|
||||
.vsd_yrgb_gt4 = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x1, 9),
|
||||
.vsd_cbcr_gt2 = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x1, 10),
|
||||
.vsd_cbcr_gt4 = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x1, 11),
|
||||
.xavg_en = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x1, 20),/* supported from vop3 */
|
||||
.xgt_en = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x1, 21),
|
||||
.xgt_mode = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x3, 22),
|
||||
};
|
||||
|
||||
static const struct vop2_scl_regs rk3568_area3_scl = {
|
||||
@@ -2003,6 +2016,9 @@ static const struct vop2_scl_regs rk3568_area3_scl = {
|
||||
.vsd_yrgb_gt4 = VOP_REG(RK3568_ESMART0_REGION3_CTRL, 0x1, 9),
|
||||
.vsd_cbcr_gt2 = VOP_REG(RK3568_ESMART0_REGION3_CTRL, 0x1, 10),
|
||||
.vsd_cbcr_gt4 = VOP_REG(RK3568_ESMART0_REGION3_CTRL, 0x1, 11),
|
||||
.xavg_en = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x1, 20),/* supported from vop3 */
|
||||
.xgt_en = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x1, 21),
|
||||
.xgt_mode = VOP_REG(RK3568_ESMART0_REGION2_CTRL, 0x3, 22),
|
||||
};
|
||||
|
||||
static const struct vop2_win_regs rk3568_area1_data = {
|
||||
@@ -2244,7 +2260,6 @@ static const struct vop2_win_data rk3528_vop_win_data[] = {
|
||||
.axi_id = 0,
|
||||
.axi_yrgb_id = 0x06,
|
||||
.axi_uv_id = 0x07,
|
||||
.scale_engine_num = 0,
|
||||
.possible_crtcs = 0x1,/* vp0 only */
|
||||
.max_upscale_factor = 8,
|
||||
.max_downscale_factor = 8,
|
||||
@@ -2274,7 +2289,6 @@ static const struct vop2_win_data rk3528_vop_win_data[] = {
|
||||
.axi_id = 0,
|
||||
.axi_yrgb_id = 0x08,
|
||||
.axi_uv_id = 0x09,
|
||||
.scale_engine_num = 1,
|
||||
.possible_crtcs = 0x1,/* vp0 only */
|
||||
.max_upscale_factor = 8,
|
||||
.max_downscale_factor = 8,
|
||||
@@ -2300,11 +2314,10 @@ static const struct vop2_win_data rk3528_vop_win_data[] = {
|
||||
.regs = &rk3568_esmart_win_data,
|
||||
.area = rk3568_area_data,
|
||||
.area_size = ARRAY_SIZE(rk3568_area_data),
|
||||
.type = DRM_PLANE_TYPE_OVERLAY,
|
||||
.type = DRM_PLANE_TYPE_CURSOR,
|
||||
.axi_id = 0,
|
||||
.axi_yrgb_id = 0x0a,
|
||||
.axi_uv_id = 0x0b,
|
||||
.scale_engine_num = 2,
|
||||
.possible_crtcs = 0x3,/* vp0 or vp1 */
|
||||
.max_upscale_factor = 8,
|
||||
.max_downscale_factor = 8,
|
||||
@@ -2334,7 +2347,6 @@ static const struct vop2_win_data rk3528_vop_win_data[] = {
|
||||
.axi_id = 0,
|
||||
.axi_yrgb_id = 0x0c,
|
||||
.axi_uv_id = 0x0d,
|
||||
.scale_engine_num = 3,
|
||||
.possible_crtcs = 0x2,/* vp1 only */
|
||||
.max_upscale_factor = 8,
|
||||
.max_downscale_factor = 8,
|
||||
@@ -3136,6 +3148,7 @@ static const struct vop2_ctrl rk3528_vop_ctrl = {
|
||||
.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),
|
||||
.dsp_vs_t_sel = VOP_REG(RK3568_SYS_AXI_LUT_CTRL, 0x1, 16),
|
||||
.rgb_en = VOP_REG(RK3568_DSP_IF_EN, 0x1, 0),
|
||||
.hdmi0_en = VOP_REG(RK3568_DSP_IF_EN, 0x1, 1),
|
||||
.bt656_en = VOP_REG(RK3568_DSP_IF_EN, 0x1, 7),
|
||||
@@ -3324,50 +3337,51 @@ static const struct vop2_ctrl rk3588_vop_ctrl = {
|
||||
};
|
||||
|
||||
static const struct vop_dump_regs rk3528_dump_regs[] = {
|
||||
{ RK3568_REG_CFG_DONE, "SYS" },
|
||||
{ RK3528_OVL_SYS, "OVL_SYS" },
|
||||
{ RK3528_OVL_PORT0_CTRL, "OVL_VP0" },
|
||||
{ RK3528_OVL_PORT1_CTRL, "OVL_VP1" },
|
||||
{ RK3568_VP0_DSP_CTRL, "VP0" },
|
||||
{ RK3568_VP1_DSP_CTRL, "VP1" },
|
||||
{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0" },
|
||||
{ RK3568_ESMART0_CTRL0, "Esmart0" },
|
||||
{ RK3568_ESMART1_CTRL0, "Esmart1" },
|
||||
{ RK3568_SMART0_CTRL0, "Esmart2" },
|
||||
{ RK3568_SMART1_CTRL0, "Esmart3" },
|
||||
{ RK3568_REG_CFG_DONE, "SYS", {0}, 0 },
|
||||
{ RK3528_OVL_SYS, "OVL_SYS", {0}, 0 },
|
||||
{ RK3528_OVL_PORT0_CTRL, "OVL_VP0", VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3528_OVL_PORT1_CTRL, "OVL_VP1", VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_VP0_DSP_CTRL, "VP0", VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_VP1_DSP_CTRL, "VP1", VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", VOP_REG(RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3568_ESMART0_CTRL0, "Esmart0", VOP_REG(RK3568_ESMART0_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_ESMART1_CTRL0, "Esmart1", VOP_REG(RK3568_ESMART1_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_SMART0_CTRL0, "Esmart2", VOP_REG(RK3568_SMART0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3568_SMART1_CTRL0, "Esmart3", VOP_REG(RK3568_SMART1_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3528_HDR_LUT_CTRL, "HDR", {0}, 0 },
|
||||
};
|
||||
|
||||
static const struct vop_dump_regs rk3568_dump_regs[] = {
|
||||
{ RK3568_REG_CFG_DONE, "SYS" },
|
||||
{ RK3568_OVL_CTRL, "OVL" },
|
||||
{ RK3568_VP0_DSP_CTRL, "VP0" },
|
||||
{ RK3568_VP1_DSP_CTRL, "VP1" },
|
||||
{ RK3568_VP2_DSP_CTRL, "VP2" },
|
||||
{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0" },
|
||||
{ RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1" },
|
||||
{ RK3568_ESMART0_CTRL0, "Esmart0" },
|
||||
{ RK3568_ESMART1_CTRL0, "Esmart1" },
|
||||
{ RK3568_SMART0_CTRL0, "Smart0" },
|
||||
{ RK3568_SMART1_CTRL0, "Smart1" },
|
||||
{ RK3568_HDR_LUT_CTRL, "HDR" },
|
||||
{ RK3568_REG_CFG_DONE, "SYS", {0}, 0 },
|
||||
{ RK3568_OVL_CTRL, "OVL", {0}, 0 },
|
||||
{ RK3568_VP0_DSP_CTRL, "VP0", VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_VP1_DSP_CTRL, "VP1", VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_VP2_DSP_CTRL, "VP2", VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", VOP_REG(RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", VOP_REG(RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3568_ESMART0_CTRL0, "Esmart0", VOP_REG(RK3568_ESMART0_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_ESMART1_CTRL0, "Esmart1", VOP_REG(RK3568_ESMART1_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_SMART0_CTRL0, "Smart0", VOP_REG(RK3568_SMART0_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_SMART1_CTRL0, "Smart1", VOP_REG(RK3568_SMART1_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_HDR_LUT_CTRL, "HDR", {0}, 0 },
|
||||
};
|
||||
|
||||
static const struct vop_dump_regs rk3588_dump_regs[] = {
|
||||
{ RK3568_REG_CFG_DONE, "SYS" },
|
||||
{ RK3568_OVL_CTRL, "OVL" },
|
||||
{ RK3568_VP0_DSP_CTRL, "VP0" },
|
||||
{ RK3568_VP1_DSP_CTRL, "VP1" },
|
||||
{ RK3568_VP2_DSP_CTRL, "VP2" },
|
||||
{ RK3588_VP3_DSP_CTRL, "VP3" },
|
||||
{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0" },
|
||||
{ RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1" },
|
||||
{ RK3588_CLUSTER2_WIN0_CTRL0, "Cluster2" },
|
||||
{ RK3588_CLUSTER3_WIN0_CTRL0, "Cluster3" },
|
||||
{ RK3568_ESMART0_CTRL0, "Esmart0" },
|
||||
{ RK3568_ESMART1_CTRL0, "Esmart1" },
|
||||
{ RK3568_SMART0_CTRL0, "Esmart2" },
|
||||
{ RK3568_SMART1_CTRL0, "Esmart3" },
|
||||
{ RK3568_HDR_LUT_CTRL, "HDR" },
|
||||
{ RK3568_REG_CFG_DONE, "SYS", {0}, 0 },
|
||||
{ RK3568_OVL_CTRL, "OVL", {0}, 0 },
|
||||
{ RK3568_VP0_DSP_CTRL, "VP0", VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_VP1_DSP_CTRL, "VP1", VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_VP2_DSP_CTRL, "VP2", VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3588_VP3_DSP_CTRL, "VP3", VOP_REG(RK3588_VP3_DSP_CTRL, 0x1, 31), 0 },
|
||||
{ RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", VOP_REG(RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", VOP_REG(RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3588_CLUSTER2_WIN0_CTRL0, "Cluster2", VOP_REG(RK3588_CLUSTER2_WIN0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3588_CLUSTER3_WIN0_CTRL0, "Cluster3", VOP_REG(RK3588_CLUSTER3_WIN0_CTRL0, 0x1, 0), 1 },
|
||||
{ RK3568_ESMART0_CTRL0, "Esmart0", VOP_REG(RK3568_ESMART0_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_ESMART1_CTRL0, "Esmart1", VOP_REG(RK3568_ESMART1_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_SMART0_CTRL0, "Esmart2", VOP_REG(RK3568_SMART0_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_SMART1_CTRL0, "Esmart3", VOP_REG(RK3568_SMART1_REGION0_CTRL, 0x1, 0), 1 },
|
||||
{ RK3568_HDR_LUT_CTRL, "HDR", {0}, 0 },
|
||||
};
|
||||
|
||||
static const struct vop2_data rk3528_vop = {
|
||||
@@ -3375,10 +3389,10 @@ static const struct vop2_data rk3528_vop = {
|
||||
.nr_vps = 2,
|
||||
.nr_mixers = 4,
|
||||
.nr_layers = 4,
|
||||
.nr_gammas = 1,
|
||||
.esmart_lb_mode = VOP3_ESMART_FOUR_2K_MODE,
|
||||
.max_input = { 4096, 2304 },
|
||||
.max_output = { 4096, 2304 },
|
||||
.nr_gammas = 2,
|
||||
.esmart_lb_mode = VOP3_ESMART_4K_2K_2K_MODE,
|
||||
.max_input = { 4096, 4096 },
|
||||
.max_output = { 4096, 4096 },
|
||||
.ctrl = &rk3528_vop_ctrl,
|
||||
.axi_intr = rk3528_vop_axi_intr,
|
||||
.nr_axi_intr = ARRAY_SIZE(rk3528_vop_axi_intr),
|
||||
|
||||
Reference in New Issue
Block a user