blob: 12f5f98e78dcb366a956f894d38a0001febbb1ab [file] [log] [blame]
/*
* drivers/amlogic/media/enhancement/amvecm/amcsc.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
/* Standard Linux headers */
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/video_common.h>
#include <linux/amlogic/media/amvecm/amvecm.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include "arch/vpp_regs.h"
#include "../../vin/tvin/tvin_global.h"
#include "arch/vpp_hdr_regs.h"
#include "arch/hdr_curve.h"
/* use osd rdma reg w/r */
#include "../../osd/osd_rdma.h"
#include "amcsc.h"
#include "set_hdr2_v0.h"
#include <linux/amlogic/media/amdolbyvision/dolby_vision.h>
#include "hdr/am_hdr10_plus.h"
#define pr_csc(fmt, args...)\
do {\
if (debug_csc)\
pr_info(fmt, ## args);\
} while (0)
signed int vd1_contrast_offset;
signed int saturation_offset;
/*hdr------------------------------------*/
static struct hdr_data_t *phdr;
struct hdr_data_t *hdr_get_data(void)
{
return phdr;
}
int is_hdr_cfg_osd_100(void)
{
int ret = 0;
if (phdr) {
if (phdr->hdr_cfg.en_osd_lut_100)
ret = phdr->hdr_cfg.en_osd_lut_100;
}
return ret;
}
void hdr_set_cfg_osd_100(int val)
{
if (val > 0)
phdr->hdr_cfg.en_osd_lut_100 = val;
else
phdr->hdr_cfg.en_osd_lut_100 = 0;
}
static ssize_t read_file_hdr_cfgosd(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[20];
ssize_t len;
len = snprintf(buf, 20, "%d\n", phdr->hdr_cfg.en_osd_lut_100);
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
static ssize_t write_file_hdr_cfgosd(
struct file *file, const char __user *userbuf,
size_t count, loff_t *ppos)
{
int val;
char buf[20];
int ret = 0;
count = min_t(size_t, count, (sizeof(buf)-1));
if (copy_from_user(buf, userbuf, count))
return -EFAULT;
buf[count] = 0;
ret = kstrtoint(buf, 0, &val);
if (ret != 0) {
pr_info("cfg_en_osd_100 do nothing!\n");
return -EINVAL;
}
hdr_set_cfg_osd_100(val);
pr_info("hdr:en_osd_lut_100: %d\n", phdr->hdr_cfg.en_osd_lut_100);
return count;
}
static const struct file_operations file_ops_hdr_cfgosd = {
.open = simple_open,
.read = read_file_hdr_cfgosd,
.write = write_file_hdr_cfgosd,
};
struct hdr_debugfs_files_t {
const char *name;
const umode_t mode;
const struct file_operations *fops;
};
static struct hdr_debugfs_files_t hdr_debugfs_files[] = {
{"cfg_en_osd_100", S_IFREG | 0644, &file_ops_hdr_cfgosd},
};
static void hdr_debugfs_init(void)
{
int i;
struct dentry *ent;
if (phdr == NULL)
return;
if (phdr->dbg_root)
return;
phdr->dbg_root = debugfs_create_dir("hdr", NULL);
if (!phdr->dbg_root) {
pr_err("can't create debugfs dir hdr\n");
return;
}
for (i = 0; i < ARRAY_SIZE(hdr_debugfs_files); i++) {
ent = debugfs_create_file(hdr_debugfs_files[i].name,
hdr_debugfs_files[i].mode,
phdr->dbg_root, NULL,
hdr_debugfs_files[i].fops);
if (!ent)
pr_err("debugfs create failed\n");
}
}
static void hdr_debugfs_exit(void)
{
if (phdr && phdr->dbg_root)
debugfs_remove(phdr->dbg_root);
}
void hdr_init(struct hdr_data_t *phdr_data)
{
if (phdr_data) {
phdr = phdr_data;
} else {
phdr = NULL;
pr_err("%s failed\n", __func__);
return;
}
hdr_debugfs_init();
}
void hdr_exit(void)
{
hdr_debugfs_exit();
}
/*-----------------------------------------*/
static void vpp_set_mtx_en_read(void);
static void vpp_set_mtx_en_write(void);
struct hdr_osd_reg_s hdr_osd_reg = {
0x00000001, /* VIU_OSD1_MATRIX_CTRL 0x1a90 */
0x00ba0273, /* VIU_OSD1_MATRIX_COEF00_01 0x1a91 */
0x003f1f9a, /* VIU_OSD1_MATRIX_COEF02_10 0x1a92 */
0x1ea801c0, /* VIU_OSD1_MATRIX_COEF11_12 0x1a93 */
0x01c01e6a, /* VIU_OSD1_MATRIX_COEF20_21 0x1a94 */
0x00000000, /* VIU_OSD1_MATRIX_COLMOD_COEF42 0x1a95 */
0x00400200, /* VIU_OSD1_MATRIX_OFFSET0_1 0x1a96 */
0x00000200, /* VIU_OSD1_MATRIX_PRE_OFFSET2 0x1a97 */
0x00000000, /* VIU_OSD1_MATRIX_PRE_OFFSET0_1 0x1a98 */
0x00000000, /* VIU_OSD1_MATRIX_PRE_OFFSET2 0x1a99 */
0x1fd80000, /* VIU_OSD1_MATRIX_COEF22_30 0x1a9d */
0x00000000, /* VIU_OSD1_MATRIX_COEF31_32 0x1a9e */
0x00000000, /* VIU_OSD1_MATRIX_COEF40_41 0x1a9f */
0x00000000, /* VIU_OSD1_EOTF_CTL 0x1ad4 */
0x08000000, /* VIU_OSD1_EOTF_COEF00_01 0x1ad5 */
0x00000000, /* VIU_OSD1_EOTF_COEF02_10 0x1ad6 */
0x08000000, /* VIU_OSD1_EOTF_COEF11_12 0x1ad7 */
0x00000000, /* VIU_OSD1_EOTF_COEF20_21 0x1ad8 */
0x08000001, /* VIU_OSD1_EOTF_COEF22_RS 0x1ad9 */
0x0, /* VIU_OSD1_EOTF_3X3_OFST_0 0x1aa0 */
0x0, /* VIU_OSD1_EOTF_3X3_OFST_1 0x1aa1 */
0x01c00000, /* VIU_OSD1_OETF_CTL 0x1adc */
{
/* eotf table */
{ /* r map */
0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00,
0x0c00, 0x0e00, 0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00, 0x2000, 0x2200,
0x2400, 0x2600, 0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600, 0x3800, 0x3a00,
0x3c00, 0x3e00, 0x4000
},
{ /* g map */
0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00,
0x0c00, 0x0e00, 0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00, 0x2000, 0x2200,
0x2400, 0x2600, 0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600, 0x3800, 0x3a00,
0x3c00, 0x3e00, 0x4000
},
{ /* b map */
0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00,
0x0c00, 0x0e00, 0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00, 0x2000, 0x2200,
0x2400, 0x2600, 0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600, 0x3800, 0x3a00,
0x3c00, 0x3e00, 0x4000
},
/* oetf table */
{ /* or map */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000
},
{ /* og map */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000
},
{ /* ob map */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000
}
},
-1 /* shadow mode */
};
#define HDR_VERSION "----gxl_20180830---g12a_20180917-----\n"
static struct vframe_s *dbg_vf;
static struct master_display_info_s dbg_hdr_send;
static struct hdr_info receiver_hdr_info;
static uint debug_csc;
module_param(debug_csc, uint, 0664);
MODULE_PARM_DESC(debug_csc, "\n debug_csc\n");
static bool print_lut_mtx;
module_param(print_lut_mtx, bool, 0664);
MODULE_PARM_DESC(print_lut_mtx, "\n print_lut_mtx\n");
/* bit 0: enable csc */
/* bit 1: enable osd csc */
/* bit 2: enable video csc */
/* bit 4: csc delay one frame */
static uint csc_en = 0x7;
module_param(csc_en, uint, 0664);
MODULE_PARM_DESC(csc_en, "\n csc_en\n");
/* white balance adjust */
static bool cur_eye_protect_mode;
static int num_wb_val = 10;
static int wb_val[10] = {
0, /* wb enable */
0, /* -1024~1023, r_pre_offset */
0, /* -1024~1023, g_pre_offset */
0, /* -1024~1023, b_pre_offset */
1024, /* 0~2047, r_gain */
1024, /* 0~2047, g_gain */
1024, /* 0~2047, b_gain */
0, /* -1024~1023, r_post_offset */
0, /* -1024~1023, g_post_offset */
0 /* -1024~1023, b_post_offset */
};
module_param_array(wb_val, int, &num_wb_val, 0664);
MODULE_PARM_DESC(wb_val, "\n white balance setting\n");
static enum vframe_source_type_e pre_src_type = VFRAME_SOURCE_TYPE_COMP;
uint cur_csc_type = 0xffff;
module_param(cur_csc_type, uint, 0444);
MODULE_PARM_DESC(cur_csc_type, "\n current color space convert type\n");
static uint hdmi_csc_type = 0xffff;
module_param(hdmi_csc_type, uint, 0444);
MODULE_PARM_DESC(hdmi_csc_type, "\n current color space convert type\n");
static uint hdr_mode = 2; /* 0: hdr->hdr, 1:hdr->sdr, 2:auto */
module_param(hdr_mode, uint, 0664);
MODULE_PARM_DESC(hdr_mode, "\n set hdr_mode\n");
static uint hdr_process_mode = 1; /* 0: hdr->hdr, 1:hdr->sdr */
static uint cur_hdr_process_mode = 2; /* 0: hdr->hdr, 1:hdr->sdr */
module_param(hdr_process_mode, uint, 0444);
MODULE_PARM_DESC(hdr_process_mode, "\n current hdr_process_mode\n");
static uint hdr10_plus_process_mode; /* 0: bypass, 1:hdr10p->sdr */
static uint cur_hdr10_plus_process_mode = 2; /* 0: bypass, 1:hdr10p->sdr */
/* 0: tx don't support hdr10+, 1: tx support hdr10+*/
static uint tx_hdr10_plus_support;
/* 0: hlg->hlg, 1:hlg->hdr*/
static uint hlg_process_mode = 1;
/* 0: hdr->hdr, 1:hdr->sdr 2:hlg->hdr*/
static uint cur_hlg_process_mode = 2;
module_param(hlg_process_mode, uint, 0444);
MODULE_PARM_DESC(hlg_process_mode, "\n current hlg_process_mode\n");
static uint force_pure_hlg;
module_param(force_pure_hlg, uint, 0664);
MODULE_PARM_DESC(force_pure_hlg, "\n current force_pure_hlg\n");
uint sdr_mode; /* 0: sdr->sdr, 1:sdr->hdr, 2:auto */
static uint sdr_process_mode = 2; /* 0: sdr->sdr, 1:sdr->hdr */
static uint cur_sdr_process_mode = 2; /* 0: sdr->sdr, 1:sdr->hdr */
static int sdr_saturation_offset = 20; /* 0: sdr->sdr, 1:sdr->hdr */
module_param(sdr_mode, uint, 0664);
MODULE_PARM_DESC(sdr_mode, "\n set sdr_mode\n");
module_param(sdr_process_mode, uint, 0444);
MODULE_PARM_DESC(sdr_process_mode, "\n current hdr_process_mode\n");
module_param(sdr_saturation_offset, int, 0664);
MODULE_PARM_DESC(sdr_saturation_offset, "\n add saturation\n");
static uint force_csc_type = 0xff;
module_param(force_csc_type, uint, 0664);
MODULE_PARM_DESC(force_csc_type, "\n force colour space convert type\n");
static uint cur_hdr_support;
module_param(cur_hdr_support, uint, 0664);
MODULE_PARM_DESC(cur_hdr_support, "\n cur_hdr_support\n");
static uint cur_hlg_support;
module_param(cur_hlg_support, uint, 0664);
MODULE_PARM_DESC(cur_hlg_support, "\n cur_hlg_support\n");
static uint cur_output_mode;
module_param(cur_output_mode, uint, 0664);
MODULE_PARM_DESC(cur_output_mode, "\n cur_output_mode\n");
static uint range_control;
module_param(range_control, uint, 0664);
MODULE_PARM_DESC(range_control, "\n range_control 0:limit 1:full\n");
/* bit 0: use source primary,*/
/* bit 1: use display primary,*/
/* bit 2: adjust contrast according to source lumin,*/
/* bit 3: adjust saturation according to source lumin */
uint hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3);
module_param(hdr_flag, uint, 0664);
MODULE_PARM_DESC(hdr_flag, "\n set hdr_flag\n");
static uint rdma_flag =
(1 << VPP_MATRIX_OSD) |
(1 << VPP_MATRIX_VD1) |
(1 << VPP_MATRIX_VD2) |
(1 << VPP_MATRIX_POST) |
(1 << VPP_MATRIX_XVYCC);
module_param(rdma_flag, uint, 0664);
MODULE_PARM_DESC(rdma_flag, "\n set rdma_flag\n");
#define MAX_KNEE_SETTING 35
/* recommended setting for 100 nits panel: */
/* 0,16,96,224,320,544,720,864,1000,1016,1023 */
/* knee factor = 256 */
static int num_knee_setting = MAX_KNEE_SETTING;
static int knee_setting[MAX_KNEE_SETTING] = {
/* 0, 16, 96, 224, 320, 544, 720, 864, 1000, 1016, 1023 */
0, 16, 36, 59, 71, 96,
120, 145, 170, 204, 230, 258,
288, 320, 355, 390, 428, 470,
512, 554, 598, 650, 720, 758,
790, 832, 864, 894, 920, 945,
968, 980, 1000, 1016, 1023
};
static int num_knee_linear_setting = MAX_KNEE_SETTING;
static int knee_linear_setting[MAX_KNEE_SETTING] = {
0x000,
0x010,
0x02f,
0x04e,
0x06d,
0x08c,
0x0ab,
0x0ca,
0x0e9,
0x108,
0x127,
0x146,
0x165,
0x184,
0x1a3,
0x1c2,
0x1e1,
0x200,
0x21f,
0x23e,
0x25d,
0x27c,
0x29b,
0x2ba,
0x2d9,
0x2f8,
0x317,
0x336,
0x355,
0x374,
0x393,
0x3b2,
0x3d1,
0x3f0,
0x3ff
};
static bool lut_289_en = 1;
module_param(lut_289_en, bool, 0664);
MODULE_PARM_DESC(lut_289_en, "\n if enable 289 lut\n");
/*for gxtvbb(968), only 289 point lut for hdr curve set */
/*default for 350nit panel*/
unsigned int lut_289_mapping[LUT_289_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0x9, 0xa, 0xb, 0xd, 0xe, 0x10, 0x11, 0x12,
0x14, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1d, 0x1f,
0x20, 0x22, 0x24, 0x26, 0x27, 0x29, 0x2b, 0x2d,
0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x3d,
0x40, 0x42, 0x44, 0x46, 0x49, 0x4b, 0x4e, 0x50,
0x53, 0x55, 0x58, 0x5a, 0x5d, 0x60, 0x62, 0x65,
0x68, 0x6b, 0x6e, 0x71, 0x74, 0x77, 0x7a, 0x7e,
0x81, 0x84, 0x87, 0x8b, 0x8e, 0x92, 0x95, 0x99,
0x9d, 0xa1, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8,
0xbc, 0xc1, 0xc5, 0xc9, 0xce, 0xd2, 0xd7, 0xdc,
0xe0, 0xe5, 0xea, 0xef, 0xf4, 0xf9, 0xfe, 0x104,
0x109, 0x10e, 0x114, 0x11a, 0x11f, 0x125, 0x12b, 0x131,
0x137, 0x13d, 0x143, 0x14a, 0x150, 0x156, 0x15d, 0x164,
0x16b, 0x172, 0x179, 0x180, 0x187, 0x18e, 0x196, 0x19d,
0x1a5, 0x1ad, 0x1b5, 0x1bd, 0x1c5, 0x1cd, 0x1d6, 0x1de,
0x1e7, 0x1f0, 0x1f9, 0x202, 0x20b, 0x214, 0x21e, 0x227,
0x231, 0x23b, 0x245, 0x24f, 0x25a, 0x264, 0x26f, 0x27a,
0x285, 0x290, 0x29c, 0x2a7, 0x2b3, 0x2bf, 0x2cb, 0x2d7,
0x2e3, 0x2f0, 0x2fd, 0x30a, 0x317, 0x325, 0x332, 0x33e,
0x34a, 0x356, 0x362, 0x36d, 0x377, 0x381, 0x38b, 0x394,
0x39c, 0x3a4, 0x3ac, 0x3b3, 0x3ba, 0x3c1, 0x3c7, 0x3cd,
0x3d2, 0x3d7, 0x3db, 0x3df, 0x3e3, 0x3e6, 0x3e9, 0x3ec,
0x3ef, 0x3f1, 0x3f3, 0x3f5, 0x3f6, 0x3f7, 0x3f8, 0x3f9,
0x3fa, 0x3fa, 0x3fb, 0x3fb, 0x3fb, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x3fc,
0x3fc, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff,
0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff,
0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff,
0x3ff
};
static int knee_factor; /* 0 ~ 256, 128 = 0.5 */
static int knee_interpolation_mode = 1; /* 0: linear, 1: cubic */
module_param_array(knee_setting, int, &num_knee_setting, 0664);
MODULE_PARM_DESC(knee_setting, "\n knee_setting, 256=1.0\n");
module_param_array(knee_linear_setting, int, &num_knee_linear_setting, 0444);
MODULE_PARM_DESC(knee_linear_setting, "\n reference linear knee_setting\n");
module_param(knee_factor, int, 0664);
MODULE_PARM_DESC(knee_factor, "\n knee_factor, 255=1.0\n");
module_param(knee_interpolation_mode, int, 0664);
MODULE_PARM_DESC(knee_interpolation_mode, "\n 0: linear, 1: cubic\n");
#define NUM_MATRIX_PARAM 16
static uint num_customer_matrix_param = NUM_MATRIX_PARAM;
static uint customer_matrix_param[NUM_MATRIX_PARAM] = {
0, 0, 0,
0x0d49, 0x1b4d, 0x1f6b,
0x1f01, 0x0910, 0x1fef,
0x1fdb, 0x1f32, 0x08f3,
0, 0, 0,
1
};
static bool customer_matrix_en = true;
#define INORM 50000
#define BL 16
static u32 bt709_primaries[3][2] = {
{0.30 * INORM + 0.5, 0.60 * INORM + 0.5}, /* G */
{0.15 * INORM + 0.5, 0.06 * INORM + 0.5}, /* B */
{0.64 * INORM + 0.5, 0.33 * INORM + 0.5}, /* R */
};
static u32 bt709_white_point[2] = {
0.3127 * INORM + 0.5, 0.3290 * INORM + 0.5
};
static u32 bt2020_primaries[3][2] = {
{0.17 * INORM + 0.5, 0.797 * INORM + 0.5}, /* G */
{0.131 * INORM + 0.5, 0.046 * INORM + 0.5}, /* B */
{0.708 * INORM + 0.5, 0.292 * INORM + 0.5}, /* R */
};
static u32 bt2020_white_point[2] = {
0.3127 * INORM + 0.5, 0.3290 * INORM + 0.5
};
/* 0: off, 1: on */
static int customer_master_display_en;
static uint num_customer_master_display_param = 12;
static uint customer_master_display_param[12] = {
0.17 * INORM + 0.5, 0.797 * INORM + 0.5, /* G */
0.131 * INORM + 0.5, 0.046 * INORM + 0.5, /* B */
0.708 * INORM + 0.5, 0.292 * INORM + 0.5, /* R */
0.3127 * INORM + 0.5, 0.3290 * INORM + 0.5, /* W */
5000 * 10000, 50,
/* man/min lumin */
5000, 50
/* content lumin and frame average */
};
module_param(customer_matrix_en, bool, 0664);
MODULE_PARM_DESC(customer_matrix_en, "\n if enable customer matrix\n");
module_param_array(customer_matrix_param, uint,
&num_customer_matrix_param, 0664);
MODULE_PARM_DESC(customer_matrix_param,
"\n matrix from source primary to panel primary\n");
module_param(customer_master_display_en, int, 0664);
MODULE_PARM_DESC(customer_master_display_en,
"\n if enable customer primaries and white point\n");
module_param_array(customer_master_display_param, uint,
&num_customer_master_display_param, 0664);
MODULE_PARM_DESC(customer_master_display_param,
"\n matrix from source primary and white point\n");
/* 0: off, 1: on */
static int customer_hdmi_display_en;
static uint num_customer_hdmi_display_param = 14;
static uint customer_hdmi_display_param[14] = {
9, /* color priamry = bt2020 */
16, /* characteristic = st2084 */
0.17 * INORM + 0.5, 0.797 * INORM + 0.5, /* G */
0.131 * INORM + 0.5, 0.046 * INORM + 0.5, /* B */
0.708 * INORM + 0.5, 0.292 * INORM + 0.5, /* R */
0.3127 * INORM + 0.5, 0.3290 * INORM + 0.5, /* W */
9997 * 10000, 0,
/* man/min lumin */
5000, 50
/* content lumin and frame average */
};
module_param(customer_hdmi_display_en, int, 0664);
MODULE_PARM_DESC(customer_hdmi_display_en,
"\n if enable customer primaries and white point\n");
module_param_array(customer_hdmi_display_param, uint,
&num_customer_hdmi_display_param, 0664);
MODULE_PARM_DESC(customer_hdmi_display_param,
"\n matrix from source primary and white point\n");
/* sat offset when > 1200 and <= 1200 */
static uint num_extra_sat_lut = 2;
static uint extra_sat_lut[] = {16, 32};
module_param_array(extra_sat_lut, uint,
&num_extra_sat_lut, 0664);
MODULE_PARM_DESC(extra_sat_lut,
"\n lookup table for saturation match source luminance.\n");
/* norm to 128 as 1, LUT can be changed */
static uint num_extra_con_lut = 5;
static uint extra_con_lut[] = {144, 136, 132, 130, 128};
module_param_array(extra_con_lut, uint,
&num_extra_con_lut, 0664);
MODULE_PARM_DESC(extra_con_lut,
"\n lookup table for contrast match source luminance.\n");
#define clip(y, ymin, ymax) ((y > ymax) ? ymax : ((y < ymin) ? ymin : y))
static const int coef[] = {
0, 256, 0, 0, /* phase 0 */
-2, 256, 2, 0, /* phase 1 */
-4, 256, 4, 0, /* phase 2 */
-5, 254, 7, 0, /* phase 3 */
-7, 254, 10, -1, /* phase 4 */
-8, 252, 13, -1, /* phase 5 */
-10, 251, 16, -1, /* phase 6 */
-11, 249, 19, -1, /* phase 7 */
-12, 247, 23, -2, /* phase 8 */
-13, 244, 27, -2, /* phase 9 */
-14, 242, 31, -3, /* phase 10 */
-15, 239, 35, -3, /* phase 11 */
-16, 236, 40, -4, /* phase 12 */
-17, 233, 44, -4, /* phase 13 */
-17, 229, 49, -5, /* phase 14 */
-18, 226, 53, -5, /* phase 15 */
-18, 222, 58, -6, /* phase 16 */
-18, 218, 63, -7, /* phase 17 */
-19, 214, 68, -7, /* phase 18 */
-19, 210, 73, -8, /* phase 19 */
-19, 205, 79, -9, /* phase 20 */
-19, 201, 83, -9, /* phase 21 */
-19, 196, 89, -10, /* phase 22 */
-19, 191, 94, -10, /* phase 23 */
-19, 186, 100, -11, /* phase 24 */
-18, 181, 105, -12, /* phase 25 */
-18, 176, 111, -13, /* phase 26 */
-18, 171, 116, -13, /* phase 27 */
-18, 166, 122, -14, /* phase 28 */
-17, 160, 127, -14, /* phase 28 */
-17, 155, 133, -15, /* phase 30 */
-16, 149, 138, -15, /* phase 31 */
-16, 144, 144, -16 /* phase 32 */
};
int cubic_interpolation(int y0, int y1, int y2, int y3, int mu)
{
int c0, c1, c2, c3;
int d0, d1, d2, d3;
if (mu <= 32) {
c0 = coef[(mu << 2) + 0];
c1 = coef[(mu << 2) + 1];
c2 = coef[(mu << 2) + 2];
c3 = coef[(mu << 2) + 3];
d0 = y0; d1 = y1; d2 = y2; d3 = y3;
} else {
c0 = coef[((64 - mu) << 2) + 0];
c1 = coef[((64 - mu) << 2) + 1];
c2 = coef[((64 - mu) << 2) + 2];
c3 = coef[((64 - mu) << 2) + 3];
d0 = y3; d1 = y2; d2 = y1; d3 = y0;
}
return (d0 * c0 + d1 * c1 + d2 * c2 + d3 * c3 + 128) >> 8;
}
static int knee_lut_on;
static int cur_knee_factor = -1;
static void load_knee_lut(int on)
{
int i, j, k;
int value;
int final_knee_setting[MAX_KNEE_SETTING];
if ((cur_knee_factor != knee_factor) && (!lut_289_en) && (on)) {
pr_csc("Knee_factor changed from %d to %d\n",
cur_knee_factor, knee_factor);
for (i = 0; i < MAX_KNEE_SETTING; i++) {
final_knee_setting[i] =
knee_linear_setting[i] + (((knee_setting[i]
- knee_linear_setting[i]) * knee_factor) >> 8);
if (final_knee_setting[i] > 0x3ff)
final_knee_setting[i] = 0x3ff;
else if (final_knee_setting[i] < 0)
final_knee_setting[i] = 0;
}
VSYNC_WR_MPEG_REG(XVYCC_LUT_CTL, 0x0);
for (j = 0; j < 3; j++) {
for (i = 0; i < 16; i++) {
VSYNC_WR_MPEG_REG(
XVYCC_LUT_R_ADDR_PORT + 2 * j, i);
value = final_knee_setting[0]
+ (((final_knee_setting[1]
- final_knee_setting[0]) * i) >> 4);
value = clip(value, 0, 0x3ff);
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 2 * j,
value);
if (j == 0)
pr_csc("xvycc_lut[%1d][%3d] = 0x%03x\n",
j, i, value);
}
for (i = 16; i < 272; i++) {
k = 1 + ((i - 16) >> 3);
VSYNC_WR_MPEG_REG(
XVYCC_LUT_R_ADDR_PORT + 2 * j, i);
if (knee_interpolation_mode == 0)
value = final_knee_setting[k]
+ (((final_knee_setting[k+1]
- final_knee_setting[k])
* ((i - 16) & 0x7)) >> 3);
else
value = cubic_interpolation(
final_knee_setting[k-1],
final_knee_setting[k],
final_knee_setting[k+1],
final_knee_setting[k+2],
((i - 16) & 0x7) << 3);
value = clip(value, 0, 0x3ff);
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 2 * j,
value);
if (j == 0)
pr_csc("xvycc_lut[%1d][%3d] = 0x%03x\n",
j, i, value);
}
for (i = 272; i < 289; i++) {
k = MAX_KNEE_SETTING - 2;
VSYNC_WR_MPEG_REG(
XVYCC_LUT_R_ADDR_PORT + 2 * j, i);
value = final_knee_setting[k]
+ (((final_knee_setting[k+1]
- final_knee_setting[k])
* (i - 272)) >> 4);
value = clip(value, 0, 0x3ff);
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 2 * j,
value);
if (j == 0)
pr_csc("xvycc_lut[%1d][%3d] = 0x%03x\n",
j, i, value);
}
}
cur_knee_factor = knee_factor;
}
if ((cur_knee_factor != knee_factor) && (lut_289_en) && (on)) {
VSYNC_WR_MPEG_REG(XVYCC_LUT_CTL, 0x0);
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_ADDR_PORT, 0);
for (i = 0; i < LUT_289_SIZE; i++)
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT,
lut_289_mapping[i]);
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_ADDR_PORT + 2, 0);
for (i = 0; i < LUT_289_SIZE; i++)
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 2,
lut_289_mapping[i]);
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_ADDR_PORT + 4, 0);
for (i = 0; i < LUT_289_SIZE; i++)
VSYNC_WR_MPEG_REG(XVYCC_LUT_R_DATA_PORT + 4,
lut_289_mapping[i]);
cur_knee_factor = knee_factor;
}
if (on) {
VSYNC_WR_MPEG_REG(XVYCC_LUT_CTL, 0x7f);
knee_lut_on = 1;
} else {
VSYNC_WR_MPEG_REG(XVYCC_LUT_CTL, 0x0f);
knee_lut_on = 0;
}
}
/***************************** gxl hdr ****************************/
/* 16 for [-2048, 0), 32 for [0, 1024), 17 for [1024, 2048) */
#define EOTF_INV_LUT_NEG2048_SIZE 16
#define EOTF_INV_LUT_SIZE 32
#define EOTF_INV_LUT_1024_SIZE 17
#define INVLUT_SDR2HDR 0x1
#define INVLUT_HLG 0x2
static unsigned int int_lut_sel[] = {0};
static unsigned int num_invlut_neg_mapping = EOTF_INV_LUT_NEG2048_SIZE;
static int invlut_y_neg[EOTF_INV_LUT_NEG2048_SIZE] = {
-2048, -1920, -1792, -1664,
-1536, -1408, -1280, -1152,
-1024, -896, -768, -640,
-512, -384, -256, -128
};
static unsigned int num_invlut_mapping = EOTF_INV_LUT_SIZE;
static unsigned int invlut_y[EOTF_INV_LUT_SIZE] = {
0, 32, 64, 96, 128, 160, 192, 224,
256, 288, 320, 352, 384, 416, 448, 480,
512, 544, 576, 608, 640, 672, 704, 736,
768, 800, 832, 864, 896, 928, 960, 992
};
static unsigned int num_invlut_1024_mapping = EOTF_INV_LUT_1024_SIZE;
static unsigned int invlut_y_1024[EOTF_INV_LUT_1024_SIZE] = {
1024, 1088, 1152, 1216,
1280, 1344, 1408, 1472,
1536, 1600, 1664, 1728,
1792, 1856, 1920, 1984,
2047
};
static unsigned int num_invlut_hlg_mapping = EOTF_INV_LUT_SIZE;
static unsigned int invlut_hlg_y[EOTF_INV_LUT_SIZE] = {
0, 14, 28, 48, 69, 91, 114, 138,
163, 188, 215, 241, 269, 297, 325, 354,
383, 415, 450, 490, 535, 579, 622, 663,
705, 745, 786, 826, 866, 905, 945, 985
};
#define EOTF_LUT_SIZE 33
static unsigned int num_osd_eotf_r_mapping = EOTF_LUT_SIZE;
static unsigned int osd_eotf_r_mapping[EOTF_LUT_SIZE] = {
0x0000, 0x0200, 0x0400, 0x0600,
0x0800, 0x0a00, 0x0c00, 0x0e00,
0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00,
0x2000, 0x2200, 0x2400, 0x2600,
0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600,
0x3800, 0x3a00, 0x3c00, 0x3e00,
0x4000
};
static unsigned int num_osd_eotf_g_mapping = EOTF_LUT_SIZE;
static unsigned int osd_eotf_g_mapping[EOTF_LUT_SIZE] = {
0x0000, 0x0200, 0x0400, 0x0600,
0x0800, 0x0a00, 0x0c00, 0x0e00,
0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00,
0x2000, 0x2200, 0x2400, 0x2600,
0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600,
0x3800, 0x3a00, 0x3c00, 0x3e00,
0x4000
};
static unsigned int num_osd_eotf_b_mapping = EOTF_LUT_SIZE;
static unsigned int osd_eotf_b_mapping[EOTF_LUT_SIZE] = {
0x0000, 0x0200, 0x0400, 0x0600,
0x0800, 0x0a00, 0x0c00, 0x0e00,
0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00,
0x2000, 0x2200, 0x2400, 0x2600,
0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600,
0x3800, 0x3a00, 0x3c00, 0x3e00,
0x4000
};
static unsigned int num_video_eotf_r_mapping = EOTF_LUT_SIZE;
static unsigned int video_eotf_r_mapping[EOTF_LUT_SIZE] = {
0x0000, 0x0200, 0x0400, 0x0600,
0x0800, 0x0a00, 0x0c00, 0x0e00,
0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00,
0x2000, 0x2200, 0x2400, 0x2600,
0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600,
0x3800, 0x3a00, 0x3c00, 0x3e00,
0x4000
};
static unsigned int num_video_eotf_g_mapping = EOTF_LUT_SIZE;
static unsigned int video_eotf_g_mapping[EOTF_LUT_SIZE] = {
0x0000, 0x0200, 0x0400, 0x0600,
0x0800, 0x0a00, 0x0c00, 0x0e00,
0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00,
0x2000, 0x2200, 0x2400, 0x2600,
0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600,
0x3800, 0x3a00, 0x3c00, 0x3e00,
0x4000
};
static unsigned int num_video_eotf_b_mapping = EOTF_LUT_SIZE;
static unsigned int video_eotf_b_mapping[EOTF_LUT_SIZE] = {
0x0000, 0x0200, 0x0400, 0x0600,
0x0800, 0x0a00, 0x0c00, 0x0e00,
0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00,
0x2000, 0x2200, 0x2400, 0x2600,
0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600,
0x3800, 0x3a00, 0x3c00, 0x3e00,
0x4000
};
#define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
#define EOTF_COEFF_SIZE 10
#define EOTF_COEFF_RIGHTSHIFT 1
static unsigned int num_osd_eotf_coeff = EOTF_COEFF_SIZE;
static int osd_eotf_coeff[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
EOTF_COEFF_RIGHTSHIFT /* right shift */
};
static unsigned int num_video_eotf_coeff = EOTF_COEFF_SIZE;
static int video_eotf_coeff[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
EOTF_COEFF_RIGHTSHIFT /* right shift */
};
static unsigned int reload_mtx;
static unsigned int reload_lut;
/******************** osd oetf **************/
static unsigned int num_osd_oetf_r_mapping = OSD_OETF_LUT_SIZE;
static unsigned int osd_oetf_r_mapping[OSD_OETF_LUT_SIZE] = {
0, 4, 8, 12,
16, 20, 24, 28,
31, 62, 93, 124,
155, 186, 217, 248,
279, 310, 341, 372,
403, 434, 465, 496,
527, 558, 589, 620,
651, 682, 713, 744,
775, 806, 837, 868,
899, 930, 961, 992,
1023
};
static unsigned int num_osd_oetf_g_mapping = OSD_OETF_LUT_SIZE;
static unsigned int osd_oetf_g_mapping[OSD_OETF_LUT_SIZE] = {
0, 4, 8, 12,
16, 20, 24, 28,
31, 62, 93, 124,
155, 186, 217, 248,
279, 310, 341, 372,
403, 434, 465, 496,
527, 558, 589, 620,
651, 682, 713, 744,
775, 806, 837, 868,
899, 930, 961, 992,
1023
};
static unsigned int num_osd_oetf_b_mapping = OSD_OETF_LUT_SIZE;
static unsigned int osd_oetf_b_mapping[OSD_OETF_LUT_SIZE] = {
0, 4, 8, 12,
16, 20, 24, 28,
31, 62, 93, 124,
155, 186, 217, 248,
279, 310, 341, 372,
403, 434, 465, 496,
527, 558, 589, 620,
651, 682, 713, 744,
775, 806, 837, 868,
899, 930, 961, 992,
1023
};
/************ video oetf ***************/
#define VIDEO_OETF_LUT_SIZE 289
static unsigned int num_video_oetf_r_mapping = VIDEO_OETF_LUT_SIZE;
static unsigned int video_oetf_r_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 8, 12, 16, 20, 24, 28, 32,
36, 40, 44, 48, 52, 56, 60, 64,
68, 72, 76, 80, 84, 88, 92, 96,
100, 104, 108, 112, 116, 120, 124, 128,
132, 136, 140, 144, 148, 152, 156, 160,
164, 168, 172, 176, 180, 184, 188, 192,
196, 200, 204, 208, 212, 216, 220, 224,
228, 232, 236, 240, 244, 248, 252, 256,
260, 264, 268, 272, 276, 280, 284, 288,
292, 296, 300, 304, 308, 312, 316, 320,
324, 328, 332, 336, 340, 344, 348, 352,
356, 360, 364, 368, 372, 376, 380, 384,
388, 392, 396, 400, 404, 408, 412, 416,
420, 424, 428, 432, 436, 440, 444, 448,
452, 456, 460, 464, 468, 472, 476, 480,
484, 488, 492, 496, 500, 504, 508, 512,
516, 520, 524, 528, 532, 536, 540, 544,
548, 552, 556, 560, 564, 568, 572, 576,
580, 584, 588, 592, 596, 600, 604, 608,
612, 616, 620, 624, 628, 632, 636, 640,
644, 648, 652, 656, 660, 664, 668, 672,
676, 680, 684, 688, 692, 696, 700, 704,
708, 712, 716, 720, 724, 728, 732, 736,
740, 744, 748, 752, 756, 760, 764, 768,
772, 776, 780, 784, 788, 792, 796, 800,
804, 808, 812, 816, 820, 824, 828, 832,
836, 840, 844, 848, 852, 856, 860, 864,
868, 872, 876, 880, 884, 888, 892, 896,
900, 904, 908, 912, 916, 920, 924, 928,
932, 936, 940, 944, 948, 952, 956, 960,
964, 968, 972, 976, 980, 984, 988, 992,
996, 1000, 1004, 1008, 1012, 1016, 1020, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
static unsigned int num_video_oetf_g_mapping = VIDEO_OETF_LUT_SIZE;
static unsigned int video_oetf_g_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 8, 12, 16, 20, 24, 28, 32,
36, 40, 44, 48, 52, 56, 60, 64,
68, 72, 76, 80, 84, 88, 92, 96,
100, 104, 108, 112, 116, 120, 124, 128,
132, 136, 140, 144, 148, 152, 156, 160,
164, 168, 172, 176, 180, 184, 188, 192,
196, 200, 204, 208, 212, 216, 220, 224,
228, 232, 236, 240, 244, 248, 252, 256,
260, 264, 268, 272, 276, 280, 284, 288,
292, 296, 300, 304, 308, 312, 316, 320,
324, 328, 332, 336, 340, 344, 348, 352,
356, 360, 364, 368, 372, 376, 380, 384,
388, 392, 396, 400, 404, 408, 412, 416,
420, 424, 428, 432, 436, 440, 444, 448,
452, 456, 460, 464, 468, 472, 476, 480,
484, 488, 492, 496, 500, 504, 508, 512,
516, 520, 524, 528, 532, 536, 540, 544,
548, 552, 556, 560, 564, 568, 572, 576,
580, 584, 588, 592, 596, 600, 604, 608,
612, 616, 620, 624, 628, 632, 636, 640,
644, 648, 652, 656, 660, 664, 668, 672,
676, 680, 684, 688, 692, 696, 700, 704,
708, 712, 716, 720, 724, 728, 732, 736,
740, 744, 748, 752, 756, 760, 764, 768,
772, 776, 780, 784, 788, 792, 796, 800,
804, 808, 812, 816, 820, 824, 828, 832,
836, 840, 844, 848, 852, 856, 860, 864,
868, 872, 876, 880, 884, 888, 892, 896,
900, 904, 908, 912, 916, 920, 924, 928,
932, 936, 940, 944, 948, 952, 956, 960,
964, 968, 972, 976, 980, 984, 988, 992,
996, 1000, 1004, 1008, 1012, 1016, 1020, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
static unsigned int num_video_oetf_b_mapping = VIDEO_OETF_LUT_SIZE;
static unsigned int video_oetf_b_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 8, 12, 16, 20, 24, 28, 32,
36, 40, 44, 48, 52, 56, 60, 64,
68, 72, 76, 80, 84, 88, 92, 96,
100, 104, 108, 112, 116, 120, 124, 128,
132, 136, 140, 144, 148, 152, 156, 160,
164, 168, 172, 176, 180, 184, 188, 192,
196, 200, 204, 208, 212, 216, 220, 224,
228, 232, 236, 240, 244, 248, 252, 256,
260, 264, 268, 272, 276, 280, 284, 288,
292, 296, 300, 304, 308, 312, 316, 320,
324, 328, 332, 336, 340, 344, 348, 352,
356, 360, 364, 368, 372, 376, 380, 384,
388, 392, 396, 400, 404, 408, 412, 416,
420, 424, 428, 432, 436, 440, 444, 448,
452, 456, 460, 464, 468, 472, 476, 480,
484, 488, 492, 496, 500, 504, 508, 512,
516, 520, 524, 528, 532, 536, 540, 544,
548, 552, 556, 560, 564, 568, 572, 576,
580, 584, 588, 592, 596, 600, 604, 608,
612, 616, 620, 624, 628, 632, 636, 640,
644, 648, 652, 656, 660, 664, 668, 672,
676, 680, 684, 688, 692, 696, 700, 704,
708, 712, 716, 720, 724, 728, 732, 736,
740, 744, 748, 752, 756, 760, 764, 768,
772, 776, 780, 784, 788, 792, 796, 800,
804, 808, 812, 816, 820, 824, 828, 832,
836, 840, 844, 848, 852, 856, 860, 864,
868, 872, 876, 880, 884, 888, 892, 896,
900, 904, 908, 912, 916, 920, 924, 928,
932, 936, 940, 944, 948, 952, 956, 960,
964, 968, 972, 976, 980, 984, 988, 992,
996, 1000, 1004, 1008, 1012, 1016, 1020, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
#define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
#define MATRIX_5x3_COEF_SIZE 24
/******* osd1 matrix0 *******/
/* default rgb to yuv_limit */
static unsigned int num_osd_matrix_coeff = MATRIX_5x3_COEF_SIZE;
static int osd_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(0.2126), COEFF_NORM(0.7152), COEFF_NORM(0.0722),
COEFF_NORM(-0.11457), COEFF_NORM(-0.38543), COEFF_NORM(0.5),
COEFF_NORM(0.5), COEFF_NORM(-0.45415), COEFF_NORM(-0.045847),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static unsigned int num_vd1_matrix_coeff = MATRIX_5x3_COEF_SIZE;
static int vd1_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static unsigned int num_vd2_matrix_coeff = MATRIX_5x3_COEF_SIZE;
static int vd2_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static unsigned int num_post_matrix_coeff = MATRIX_5x3_COEF_SIZE;
static int post_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static unsigned int num_xvycc_matrix_coeff = MATRIX_5x3_COEF_SIZE;
static int xvycc_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
/****************** osd eotf ********************/
module_param_array(osd_eotf_coeff, int,
&num_osd_eotf_coeff, 0664);
MODULE_PARM_DESC(osd_eotf_coeff, "\n matrix for osd eotf\n");
module_param_array(osd_eotf_r_mapping, uint,
&num_osd_eotf_r_mapping, 0664);
MODULE_PARM_DESC(osd_eotf_r_mapping, "\n lut for osd r eotf\n");
module_param_array(osd_eotf_g_mapping, uint,
&num_osd_eotf_g_mapping, 0664);
MODULE_PARM_DESC(osd_eotf_g_mapping, "\n lut for osd g eotf\n");
module_param_array(osd_eotf_b_mapping, uint,
&num_osd_eotf_b_mapping, 0664);
MODULE_PARM_DESC(osd_eotf_b_mapping, "\n lut for osd b eotf\n");
module_param_array(osd_matrix_coeff, int,
&num_osd_matrix_coeff, 0664);
MODULE_PARM_DESC(osd_matrix_coeff, "\n coef for osd matrix\n");
/****************** video eotf ********************/
module_param_array(invlut_y_neg, int,
&num_invlut_neg_mapping, 0664);
MODULE_PARM_DESC(invlut_y_neg, "\n lut for inv y -2048..0 eotf\n");
module_param_array(invlut_y, uint,
&num_invlut_mapping, 0664);
MODULE_PARM_DESC(invlut_y, "\n lut for inv y 0..1024 eotf\n");
module_param_array(invlut_y_1024, uint,
&num_invlut_1024_mapping, 0664);
MODULE_PARM_DESC(invlut_y_1024, "\n lut for inv y 1024..2048 eotf\n");
module_param_array(invlut_hlg_y, int,
&num_invlut_hlg_mapping, 0664);
MODULE_PARM_DESC(invlut_hlg_y, "\n lut for hlg 0..1024 eotf\n");
module_param_array(video_eotf_coeff, int,
&num_video_eotf_coeff, 0664);
MODULE_PARM_DESC(video_eotf_coeff, "\n matrix for video eotf\n");
module_param_array(video_eotf_r_mapping, uint,
&num_video_eotf_r_mapping, 0664);
MODULE_PARM_DESC(video_eotf_r_mapping, "\n lut for video r eotf\n");
module_param_array(video_eotf_g_mapping, uint,
&num_video_eotf_g_mapping, 0664);
MODULE_PARM_DESC(video_eotf_g_mapping, "\n lut for video g eotf\n");
module_param_array(video_eotf_b_mapping, uint,
&num_video_eotf_b_mapping, 0664);
MODULE_PARM_DESC(video_eotf_b_mapping, "\n lut for video b eotf\n");
/****************** osd oetf ********************/
module_param_array(osd_oetf_r_mapping, uint,
&num_osd_oetf_r_mapping, 0664);
MODULE_PARM_DESC(osd_oetf_r_mapping, "\n lut for osd r oetf\n");
module_param_array(osd_oetf_g_mapping, uint,
&num_osd_oetf_g_mapping, 0664);
MODULE_PARM_DESC(osd_oetf_g_mapping, "\n lut for osd g oetf\n");
module_param_array(osd_oetf_b_mapping, uint,
&num_osd_oetf_b_mapping, 0664);
MODULE_PARM_DESC(osd_oetf_b_mapping, "\n lut for osd b oetf\n");
/****************** video oetf ********************/
module_param_array(video_oetf_r_mapping, uint,
&num_video_oetf_r_mapping, 0664);
MODULE_PARM_DESC(video_oetf_r_mapping, "\n lut for video r oetf\n");
module_param_array(video_oetf_g_mapping, uint,
&num_video_oetf_g_mapping, 0664);
MODULE_PARM_DESC(video_oetf_g_mapping, "\n lut for video g oetf\n");
module_param_array(video_oetf_b_mapping, uint,
&num_video_oetf_b_mapping, 0664);
MODULE_PARM_DESC(video_oetf_b_mapping, "\n lut for video b oetf\n");
/****************** vpp matrix ********************/
module_param_array(vd1_matrix_coeff, int,
&num_vd1_matrix_coeff, 0664);
MODULE_PARM_DESC(vd1_matrix_coeff, "\n vd1 matrix\n");
module_param_array(vd2_matrix_coeff, int,
&num_vd2_matrix_coeff, 0664);
MODULE_PARM_DESC(vd2_matrix_coeff, "\n vd2 matrix\n");
module_param_array(post_matrix_coeff, int,
&num_post_matrix_coeff, 0664);
MODULE_PARM_DESC(post_matrix_coeff, "\n post matrix\n");
module_param_array(xvycc_matrix_coeff, int,
&num_xvycc_matrix_coeff, 0664);
MODULE_PARM_DESC(xvycc_matrix_coeff, "\n xvycc matrix\n");
static unsigned int mtx_en_mux;
module_param(mtx_en_mux, uint, 0664);
MODULE_PARM_DESC(mtx_en_mux, "\n mtx enable mux\n");
/****************** matrix/lut reload********************/
module_param(reload_mtx, uint, 0664);
MODULE_PARM_DESC(reload_mtx, "\n reload matrix coeff\n");
module_param(reload_lut, uint, 0664);
MODULE_PARM_DESC(reload_lut, "\n reload lut settings\n");
static int RGB709_to_YUV709_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(0.2126), COEFF_NORM(0.7152), COEFF_NORM(0.0722),
COEFF_NORM(-0.114572), COEFF_NORM(-0.385428), COEFF_NORM(0.5),
COEFF_NORM(0.5), COEFF_NORM(-0.454153), COEFF_NORM(-0.045847),
0, 0, 0, /* 10'/11'/12' */
0, 0, 0, /* 20'/21'/22' */
0, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int RGB709_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
0, 0, 0, /* 10'/11'/12' */
0, 0, 0, /* 20'/21'/22' */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int RGB2020_to_YUV2020l_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(0.224732), COEFF_NORM(0.580008), COEFF_NORM(0.050729),
COEFF_NORM(-0.122176), COEFF_NORM(-0.315324), COEFF_NORM(0.437500),
COEFF_NORM(0.437500), COEFF_NORM(-0.402312), COEFF_NORM(-0.035188),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV709f_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
0, -512, -512, /* pre offset */
COEFF_NORM(0.859), COEFF_NORM(0), COEFF_NORM(0),
COEFF_NORM(0), COEFF_NORM(0.878), COEFF_NORM(0),
COEFF_NORM(0), COEFF_NORM(0), COEFF_NORM(0.878),
0, 0, 0, /* 10'/11'/12' */
0, 0, 0, /* 20'/21'/22' */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV709l_to_YUV709f_coeff[MATRIX_5x3_COEF_SIZE] = {
64, -512, -512, /* pre offset */
COEFF_NORM(1.16895), COEFF_NORM(0), COEFF_NORM(0),
COEFF_NORM(0), COEFF_NORM(1.14286), COEFF_NORM(0),
COEFF_NORM(0), COEFF_NORM(0), COEFF_NORM(1.14286),
0, 0, 0, /* 10'/11'/12' */
0, 0, 0, /* 20'/21'/22' */
0, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV709l_to_RGB709_coeff[MATRIX_5x3_COEF_SIZE] = {
-64, -512, -512, /* pre offset */
COEFF_NORM(1.16895), COEFF_NORM(0.00000), COEFF_NORM(1.79977),
COEFF_NORM(1.16895), COEFF_NORM(-0.21408), COEFF_NORM(-0.53500),
COEFF_NORM(1.16895), COEFF_NORM(2.12069), COEFF_NORM(0.00000),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV709l_to_YUV2020_coeff[MATRIX_5x3_COEF_SIZE] = {
-64, -512, -512, /* pre offset */
0x400, 0x1fe4, 0x2b,
0, 0x39f, 0x1fe5,
0x0, 0xc, 0x321,
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV709f_to_RGB709_coeff[MATRIX_5x3_COEF_SIZE] = {
0, -512, -512, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(0.00000), COEFF_NORM(1.575),
COEFF_NORM(1.0), COEFF_NORM(-0.187), COEFF_NORM(-0.468),
COEFF_NORM(1.0), COEFF_NORM(1.856), COEFF_NORM(0.00000),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV601l_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
-64, -512, -512, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(-0.115), COEFF_NORM(-0.207),
COEFF_NORM(0), COEFF_NORM(1.018), COEFF_NORM(0.114),
COEFF_NORM(0), COEFF_NORM(0.075), COEFF_NORM(1.025),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV601f_to_YUV709f_coeff[MATRIX_5x3_COEF_SIZE] = {
0, -512, -512, /* pre offset */
COEFF_NORM(1.00000), COEFF_NORM(-0.118), COEFF_NORM(-0.212),
COEFF_NORM(0.00000), COEFF_NORM(1.018), COEFF_NORM(0.114),
COEFF_NORM(0.00000), COEFF_NORM(0.075), COEFF_NORM(1.025),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV709l_to_YUV601l_coeff[MATRIX_5x3_COEF_SIZE] = {
-64, -512, -512, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(0.1), COEFF_NORM(0.192),
COEFF_NORM(0), COEFF_NORM(0.990), COEFF_NORM(-0.110),
COEFF_NORM(0), COEFF_NORM(-0.072), COEFF_NORM(0.984),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV601l_to_YUV709f_coeff[MATRIX_5x3_COEF_SIZE] = {
-64, -512, -512, /* pre offset */
COEFF_NORM(1.164), COEFF_NORM(-0.134), COEFF_NORM(-0.241),
COEFF_NORM(0), COEFF_NORM(1.160), COEFF_NORM(-0.129),
COEFF_NORM(0), COEFF_NORM(-0.085), COEFF_NORM(1.167),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
static int YUV601f_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
0, -512, -512, /* pre offset */
COEFF_NORM(0.859), COEFF_NORM(-0.101), COEFF_NORM(-0.182),
COEFF_NORM(0), COEFF_NORM(0.894), COEFF_NORM(-0.100),
COEFF_NORM(0), COEFF_NORM(-0.066), COEFF_NORM(0.900),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
#if 0
static int YUV709f_to_YUV601f_coeff[MATRIX_5x3_COEF_SIZE] = {
0, -512, -512, /* pre offset */
COEFF_NORM(1.00000), COEFF_NORM(0.08835), COEFF_NORM(0.37521),
COEFF_NORM(0.00000), COEFF_NORM(1.03570), COEFF_NORM(-0.20445),
COEFF_NORM(0.00000), COEFF_NORM(-0.11088), COEFF_NORM(1.57010),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
#endif
#if 0
/* eotf matrix: RGB2020 to RGB709 */
static int eotf_RGB2020_to_RGB709_coeff[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(1.6607056/2), EOTF_COEFF_NORM(-0.5877533/2),
EOTF_COEFF_NORM(-0.0729065/2),
EOTF_COEFF_NORM(-0.1245575/2), EOTF_COEFF_NORM(1.1329346/2),
EOTF_COEFF_NORM(-0.0083771/2),
EOTF_COEFF_NORM(-0.0181122/2), EOTF_COEFF_NORM(-0.1005249/2),
EOTF_COEFF_NORM(1.1186371/2),
EOTF_COEFF_RIGHTSHIFT
};
#endif
static int bypass_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
0, 0, 0, /* 10'/11'/12' */
0, 0, 0, /* 20'/21'/22' */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
/* eotf matrix: bypass */
static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
EOTF_COEFF_RIGHTSHIFT /* right shift */
};
static int eotf_RGB709_to_RGB2020_coeff[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(0.627441), EOTF_COEFF_NORM(0.329285),
EOTF_COEFF_NORM(0.043274),
EOTF_COEFF_NORM(0.069092), EOTF_COEFF_NORM(0.919556),
EOTF_COEFF_NORM(0.011322),
EOTF_COEFF_NORM(0.016418), EOTF_COEFF_NORM(0.088058),
EOTF_COEFF_NORM(0.895554),
EOTF_COEFF_RIGHTSHIFT /* right shift */
};
/* post matrix: YUV2020 limit to RGB2020 */
static int YUV2020l_to_RGB2020_coeff[MATRIX_5x3_COEF_SIZE] = {
-64, -512, -512, /* pre offset */
COEFF_NORM(1.16895), COEFF_NORM(0.00000), COEFF_NORM(1.68526),
COEFF_NORM(1.16895), COEFF_NORM(-0.18806), COEFF_NORM(-0.65298),
COEFF_NORM(1.16895), COEFF_NORM(2.15017), COEFF_NORM(0.00000),
0, 0, 0, /* 30/31/32 */
0, 0, 0, /* 40/41/42 */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
/* eotf lut: linear */
static unsigned int eotf_33_linear_mapping[EOTF_LUT_SIZE] = {
0x0000, 0x0200, 0x0400, 0x0600,
0x0800, 0x0a00, 0x0c00, 0x0e00,
0x1000, 0x1200, 0x1400, 0x1600,
0x1800, 0x1a00, 0x1c00, 0x1e00,
0x2000, 0x2200, 0x2400, 0x2600,
0x2800, 0x2a00, 0x2c00, 0x2e00,
0x3000, 0x3200, 0x3400, 0x3600,
0x3800, 0x3a00, 0x3c00, 0x3e00,
0x4000
};
/* osd oetf lut: linear */
static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
0, 4, 8, 12,
16, 20, 24, 28,
31, 62, 93, 124,
155, 186, 217, 248,
279, 310, 341, 372,
403, 434, 465, 496,
527, 558, 589, 620,
651, 682, 713, 744,
775, 806, 837, 868,
899, 930, 961, 992,
1023
};
/* following array generated from model, do not edit */
static int video_lut_swtich;
module_param(video_lut_swtich, int, 0664);
MODULE_PARM_DESC(video_lut_swtich, "\n video_lut_swtich\n");
/* gamma=2.200000 lumin=500 boost=0.075000 */
static unsigned int display_scale_factor =
(unsigned int)((((1.000000) * 4096.0) + 1) / 2);
static unsigned int eotf_33_2084_mapping[EOTF_LUT_SIZE] = {
0, 3, 6, 11, 18, 27, 40, 58,
84, 119, 169, 237, 329, 455, 636, 881,
1209, 1648, 2234, 3014, 4050, 5425, 7251, 9673,
12889, 13773, 14513, 15117, 15594, 15951, 16196, 16338,
16383
};
static unsigned int oetf_289_gamma22_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 125, 171, 206, 235, 259, 281, 302,
321, 339, 356, 371, 386, 401, 414, 427,
440, 453, 465, 476, 488, 498, 509, 519,
529, 539, 549, 558, 568, 577, 586, 595,
603, 612, 620, 628, 637, 645, 652, 660,
668, 675, 683, 690, 697, 705, 712, 719,
726, 733, 740, 748, 755, 763, 771, 778,
786, 793, 801, 808, 814, 821, 827, 832,
837, 842, 846, 849, 852, 854, 856, 858,
860, 862, 864, 866, 867, 869, 871, 873,
875, 877, 879, 880, 882, 884, 886, 887,
889, 891, 893, 894, 896, 898, 899, 901,
902, 904, 906, 907, 909, 910, 912, 914,
915, 917, 918, 920, 921, 923, 924, 925,
927, 928, 930, 931, 933, 934, 935, 937,
938, 939, 941, 942, 943, 945, 946, 947,
948, 950, 951, 952, 953, 954, 956, 957,
958, 959, 960, 961, 962, 963, 965, 966,
967, 968, 969, 970, 971, 972, 973, 974,
975, 976, 977, 978, 979, 980, 981, 981,
982, 983, 984, 985, 986, 987, 987, 988,
989, 990, 991, 991, 992, 993, 994, 995,
995, 996, 997, 997, 998, 999, 999, 1000,
1001, 1001, 1002, 1003, 1003, 1004, 1004, 1005,
1006, 1006, 1007, 1007, 1008, 1008, 1009, 1009,
1010, 1010, 1011, 1011, 1012, 1012, 1012, 1013,
1013, 1014, 1014, 1015, 1015, 1015, 1016, 1016,
1016, 1017, 1017, 1017, 1018, 1018, 1018, 1019,
1019, 1019, 1019, 1020, 1020, 1020, 1020, 1020,
1021, 1021, 1021, 1021, 1021, 1022, 1022, 1022,
1022, 1022, 1022, 1022, 1022, 1023, 1023, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
/* osd eotf lut: 709 */
static unsigned int osd_eotf_33_709_mapping[EOTF_LUT_SIZE] = {
0, 512, 1024, 1536, 2048, 2560, 3072, 3584,
4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680,
8192, 8704, 9216, 9728, 10240, 10752, 11264, 11776,
12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872,
16383
};
/* osd oetf lut: 2084 */
static unsigned int osd_oetf_41_2084_mapping[OSD_OETF_LUT_SIZE] = {
0, 21, 43, 64, 79, 90, 101, 111,
120, 174, 208, 233, 277, 313, 344, 372,
398, 420, 440, 459, 476, 492, 507, 522,
536, 549, 561, 574, 585, 596, 606, 616,
624, 632, 642, 661, 684, 706, 727, 749,
1023
};
/* osd eotf lut: 709 from baozheng */
static unsigned int osd_eotf_33_709_mapping_100[EOTF_LUT_SIZE] = {
0, 8, 37, 90, 169, 276, 412, 579,
776, 1006, 1268, 1564, 1894, 2258, 2658, 3094,
3566, 4075, 4621, 5204, 5826, 6486, 7185, 7923,
8701, 9518, 10376, 11274, 12213, 13194, 14215, 15279,
16384
};
/* osd oetf lut: 2084 from baozheng */
static unsigned int osd_oetf_41_2084_mapping_100[OSD_OETF_LUT_SIZE] = {
0, 110, 141, 162, 178, 191, 203, 212,
221, 270, 302, 325, 344, 360, 374, 386,
396, 406, 415, 423, 431, 438, 445, 451,
457, 462, 468, 473, 478, 482, 487, 491,
495, 499, 503, 507, 510, 514, 517, 520,
523
};
static unsigned int osd_eotf_33_709_mapping_290[EOTF_LUT_SIZE] = {
0, 8, 37, 90, 169, 276, 412, 579,
776, 1006, 1268, 1564, 1894, 2258, 2658, 3094,
3566, 4075, 4621, 5204, 5826, 6486, 7185, 7923,
8701, 9518, 10376, 11274, 12213, 13194, 14215, 15279,
16384
};
/* osd oetf lut: 2084 from baozheng */
static unsigned int osd_oetf_41_2084_mapping_290[OSD_OETF_LUT_SIZE] = {
0, 141, 178, 203, 221, 236, 249, 260,
270, 325, 360, 386, 406, 423, 438, 451,
462, 473, 482, 491, 499, 507, 514, 520,
527, 532, 538, 543, 548, 553, 558, 562,
567, 571, 575, 579, 583, 586, 590, 593,
596
};
/* osd eotf lut: sdr->hlg */
static unsigned int osd_eotf_33_sdr2hlg_mapping[EOTF_LUT_SIZE] = {
0, 512, 1024, 1536, 2048, 2560, 3072, 3584,
4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680,
8192, 8704, 9216, 9728, 10240, 10752, 11264, 11776,
12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872,
16383
};
/* osd oetf lut: sdr->hlg */
static unsigned int osd_oetf_41_sdr2hlg_mapping[OSD_OETF_LUT_SIZE] = {
0, 23, 36, 43, 49, 54, 59, 64,
69, 96, 127, 172, 218, 267, 316, 365,
415, 468, 519, 567, 607, 643, 676, 706,
733, 758, 782, 805, 826, 847, 866, 885,
903, 920, 936, 951, 965, 980, 994, 1009,
1023
};
/* sdr eotf lut: 709 */
static unsigned int eotf_33_sdr_709_mapping[EOTF_LUT_SIZE] = {
0, 512, 1024, 1536, 2048, 2560, 3072, 3584,
4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680,
8192, 8704, 9216, 9728, 10240, 10752, 11264, 11776,
12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872,
16383
};
/* sdr oetf lut: 2084 */
static unsigned int oetf_sdr_2084_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 32, 55, 72, 85, 96, 106, 115,
124, 132, 140, 147, 154, 160, 166, 171,
176, 181, 186, 190, 194, 198, 204, 208,
211, 215, 218, 221, 224, 227, 230, 233,
239, 245, 252, 257, 263, 268, 274, 279,
283, 288, 292, 296, 302, 306, 310, 315,
319, 323, 326, 331, 334, 339, 342, 346,
350, 354, 357, 361, 365, 368, 372, 376,
379, 382, 386, 389, 392, 396, 399, 402,
405, 408, 411, 413, 416, 419, 422, 424,
427, 429, 432, 434, 437, 439, 442, 444,
446, 449, 451, 454, 456, 459, 461, 463,
465, 468, 470, 472, 474, 476, 478, 481,
483, 485, 487, 489, 491, 493, 495, 497,
499, 501, 503, 505, 507, 509, 511, 513,
515, 516, 518, 520, 522, 524, 526, 527,
529, 531, 533, 535, 536, 538, 540, 541,
543, 545, 546, 548, 550, 551, 553, 555,
556, 558, 559, 561, 562, 564, 566, 567,
569, 570, 572, 573, 575, 576, 578, 579,
580, 582, 584, 585, 586, 588, 589, 591,
592, 594, 595, 596, 598, 599, 600, 602,
603, 604, 606, 607, 608, 609, 611, 612,
613, 615, 616, 617, 618, 619, 620, 621,
622, 623, 624, 625, 626, 627, 628, 629,
630, 631, 632, 634, 635, 636, 637, 638,
640, 641, 642, 644, 646, 648, 651, 654,
657, 661, 664, 666, 670, 672, 676, 678,
681, 684, 687, 690, 692, 695, 698, 701,
704, 706, 709, 712, 715, 718, 720, 723,
726, 729, 731, 734, 737, 740, 743, 746,
748, 751, 754, 758, 763, 772, 797, 833,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
/* end of array generated from model */
module_param(display_scale_factor, uint, 0664);
MODULE_PARM_DESC(display_scale_factor, "\n display scale factor\n");
/*HLG eotf and oetf curve*/
static unsigned int eotf_33_hlg_mapping[EOTF_LUT_SIZE] = {
0, 5, 21, 48, 85, 133, 192, 261,
341, 432, 533, 645, 768, 901, 1045, 1200,
1365, 1552, 1774, 2038, 2353, 2729, 3175, 3707,
4341, 5096, 5995, 7065, 8340, 9858, 11666, 13819,
16383
};
static unsigned int oetf_289_2084_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 249, 301, 335, 360, 379, 396, 410,
423, 434, 444, 453, 462, 470, 477, 484,
491, 497, 502, 508, 513, 518, 523, 528,
532, 536, 540, 544, 548, 552, 555, 559,
562, 565, 568, 571, 574, 577, 580, 583,
586, 588, 591, 593, 596, 598, 601, 603,
605, 607, 609, 612, 614, 616, 618, 620,
622, 624, 625, 627, 629, 631, 633, 634,
636, 638, 640, 641, 643, 644, 646, 647,
649, 651, 652, 653, 655, 656, 658, 659,
661, 662, 663, 665, 666, 667, 668, 670,
671, 672, 673, 675, 676, 677, 678, 679,
681, 682, 683, 684, 685, 686, 687, 688,
689, 690, 691, 692, 694, 695, 696, 697,
698, 699, 699, 700, 701, 702, 703, 704,
705, 706, 707, 708, 709, 710, 711, 711,
712, 713, 714, 715, 716, 717, 717, 718,
719, 720, 721, 721, 722, 723, 724, 725,
725, 726, 727, 728, 728, 729, 730, 731,
731, 732, 733, 734, 734, 735, 736, 736,
737, 738, 738, 739, 740, 741, 741, 742,
743, 743, 744, 744, 745, 746, 746, 747,
748, 748, 749, 750, 750, 751, 751, 752,
753, 753, 754, 754, 755, 756, 756, 757,
757, 758, 759, 759, 760, 760, 761, 761,
762, 762, 763, 764, 764, 765, 765, 766,
766, 767, 767, 768, 768, 769, 769, 770,
771, 771, 772, 772, 773, 773, 774, 774,
775, 775, 776, 776, 777, 777, 778, 778,
778, 779, 779, 780, 780, 781, 781, 782,
782, 783, 783, 784, 784, 785, 785, 785,
786, 786, 787, 787, 788, 788, 789, 789,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
static int dvll_RGB_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
0, 0, 0, /* pre offset */
COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
0, 0, 0, /* 10'/11'/12' */
0, 0, 0, /* 20'/21'/22' */
64, 512, 512, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
/*static unsigned int oetf_289_709_mapping[VIDEO_OETF_LUT_SIZE] = {*/
/* 0, 0, 0, 0, 0, 0, 0, 0,*/
/* 0, 0, 0, 0, 0, 0, 0, 0,*/
/* 0, 17, 35, 52, 70, 84, 100, 114,*/
/* 127, 140, 151, 163, 173, 183, 193, 202,*/
/* 211, 220, 228, 236, 244, 252, 259, 266,*/
/* 274, 280, 287, 294, 300, 307, 313, 319,*/
/* 325, 331, 337, 343, 349, 354, 360, 365,*/
/* 371, 376, 381, 386, 391, 396, 401, 406,*/
/* 411, 416, 421, 425, 430, 435, 439, 444,*/
/* 448, 453, 457, 461, 466, 470, 474, 478,*/
/* 482, 486, 491, 495, 499, 503, 506, 510,*/
/* 514, 518, 522, 526, 530, 533, 537, 541,*/
/* 544, 548, 552, 555, 559, 562, 566, 569,*/
/* 573, 576, 580, 583, 586, 590, 593, 597,*/
/* 600, 603, 606, 610, 613, 616, 619, 623,*/
/* 626, 629, 632, 635, 638, 641, 644, 647,*/
/* 651, 654, 657, 660, 663, 666, 668, 671,*/
/* 674, 677, 680, 683, 686, 689, 692, 695,*/
/* 697, 700, 703, 706, 709, 711, 714, 717,*/
/* 720, 722, 725, 728, 730, 733, 736, 738,*/
/* 741, 744, 746, 749, 752, 754, 757, 759,*/
/* 762, 765, 767, 770, 772, 775, 777, 780,*/
/* 782, 785, 787, 790, 792, 795, 797, 800,*/
/* 802, 804, 807, 809, 812, 814, 817, 819,*/
/* 821, 824, 826, 828, 831, 833, 835, 838,*/
/* 840, 842, 845, 847, 849, 852, 854, 856,*/
/* 858, 861, 863, 865, 867, 870, 872, 874,*/
/* 876, 878, 881, 883, 885, 887, 889, 892,*/
/* 894, 896, 898, 900, 902, 905, 907, 909,*/
/* 911, 913, 915, 917, 919, 922, 924, 926,*/
/* 928, 930, 932, 934, 936, 938, 940, 942,*/
/* 944, 946, 948, 950, 952, 954, 956, 958,*/
/* 960, 962, 964, 966, 968, 970, 972, 974,*/
/* 976, 978, 980, 982, 984, 986, 988, 990,*/
/* 992, 994, 996, 998, 1000, 1002, 1004, 1006,*/
/* 1008, 1010, 1012, 1014, 1016, 1018, 1020, 1022,*/
/* 1023*/
/*};*/
/*end HLG eotf and oetf curve*/
/* video oetf: linear */
#if 0
static unsigned int oetf_289_linear_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 8, 12, 16, 20, 24, 28, 32,
36, 40, 44, 48, 52, 56, 60, 64,
68, 72, 76, 80, 84, 88, 92, 96,
100, 104, 108, 112, 116, 120, 124, 128,
132, 136, 140, 144, 148, 152, 156, 160,
164, 168, 172, 176, 180, 184, 188, 192,
196, 200, 204, 208, 212, 216, 220, 224,
228, 232, 236, 240, 244, 248, 252, 256,
260, 264, 268, 272, 276, 280, 284, 288,
292, 296, 300, 304, 308, 312, 316, 320,
324, 328, 332, 336, 340, 344, 348, 352,
356, 360, 364, 368, 372, 376, 380, 384,
388, 392, 396, 400, 404, 408, 412, 416,
420, 424, 428, 432, 436, 440, 444, 448,
452, 456, 460, 464, 468, 472, 476, 480,
484, 488, 492, 496, 500, 504, 508, 512,
516, 520, 524, 528, 532, 536, 540, 544,
548, 552, 556, 560, 564, 568, 572, 576,
580, 584, 588, 592, 596, 600, 604, 608,
612, 616, 620, 624, 628, 632, 636, 640,
644, 648, 652, 656, 660, 664, 668, 672,
676, 680, 684, 688, 692, 696, 700, 704,
708, 712, 716, 720, 724, 728, 732, 736,
740, 744, 748, 752, 756, 760, 764, 768,
772, 776, 780, 784, 788, 792, 796, 800,
804, 808, 812, 816, 820, 824, 828, 832,
836, 840, 844, 848, 852, 856, 860, 864,
868, 872, 876, 880, 884, 888, 892, 896,
900, 904, 908, 912, 916, 920, 924, 928,
932, 936, 940, 944, 948, 952, 956, 960,
964, 968, 972, 976, 980, 984, 988, 992,
996, 1000, 1004, 1008, 1012, 1016, 1020, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
/* video oetf: 709 */
static unsigned int oetf_289_709_mapping[VIDEO_OETF_LUT_SIZE] = {
0, 2, 4, 6, 8, 10, 12, 14,
16, 18, 20, 22, 24, 26, 28, 30,
32, 34, 36, 54, 72, 90, 106, 121,
135, 148, 160, 172, 183, 193, 203, 213,
222, 231, 239, 248, 256, 264, 272, 279,
286, 294, 301, 308, 314, 321, 327, 334,
340, 346, 352, 358, 364, 370, 376, 381,
387, 392, 398, 403, 408, 413, 418, 423,
428, 433, 438, 443, 448, 453, 457, 462,
467, 471, 476, 480, 484, 489, 493, 497,
502, 506, 510, 514, 518, 522, 527, 531,
535, 538, 542, 546, 550, 554, 558, 562,
565, 569, 573, 577, 580, 584, 587, 591,
595, 598, 602, 605, 609, 612, 616, 619,
622, 626, 629, 633, 636, 639, 642, 646,
649, 652, 655, 659, 662, 665, 668, 671,
674, 678, 681, 684, 687, 690, 693, 696,
699, 702, 705, 708, 711, 714, 717, 720,
722, 725, 728, 731, 734, 737, 740, 742,
745, 748, 751, 754, 756, 759, 762, 765,
767, 770, 773, 775, 778, 781, 783, 786,
789, 791, 794, 797, 799, 802, 804, 807,
809, 812, 815, 817, 820, 822, 825, 827,
830, 832, 835, 837, 840, 842, 845, 847,
849, 852, 854, 857, 859, 861, 864, 866,
869, 871, 873, 876, 878, 880, 883, 885,
887, 890, 892, 894, 897, 899, 901, 903,
906, 908, 910, 912, 915, 917, 919, 921,
924, 926, 928, 930, 932, 935, 937, 939,
941, 943, 945, 948, 950, 952, 954, 956,
958, 960, 963, 965, 967, 969, 971, 973,
975, 977, 979, 981, 984, 986, 988, 990,
992, 994, 996, 998, 1000, 1002, 1004, 1006,
1008, 1010, 1012, 1014, 1016, 1018, 1020, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
1023
};
#endif
#define SIGN(a) ((a < 0) ? "-" : "+")
#define DECI(a) ((a) / 1024)
#define FRAC(a) ((((a) >= 0) ? \
((a) & 0x3ff) : ((~(a) + 1) & 0x3ff)) * 10000 / 1024)
const char matrix_name[7][16] = {
"OSD",
"VD1",
"POST",
"XVYCC",
"EOTF",
"OSD_EOTF",
"VD2"
};
static void print_vpp_matrix(int m_select, int *s, int on)
{
unsigned int size;
if (s == NULL)
return;
if (m_select == VPP_MATRIX_OSD)
size = MATRIX_5x3_COEF_SIZE;
else if (m_select == VPP_MATRIX_POST)
size = MATRIX_5x3_COEF_SIZE;
else if (m_select == VPP_MATRIX_VD1)
size = MATRIX_5x3_COEF_SIZE;
else if (m_select == VPP_MATRIX_VD2)
size = MATRIX_5x3_COEF_SIZE;
else if (m_select == VPP_MATRIX_XVYCC)
size = MATRIX_5x3_COEF_SIZE;
else if (m_select == VPP_MATRIX_EOTF)
size = EOTF_COEFF_SIZE;
else if (m_select == VPP_MATRIX_OSD_EOTF)
size = EOTF_COEFF_SIZE;
else
return;
pr_csc("%s matrix %s:\n", matrix_name[m_select],
on ? "on" : "off");
if (size == MATRIX_5x3_COEF_SIZE) {
pr_csc(
"\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[0]), DECI(s[0]), FRAC(s[0]),
SIGN(s[3]), DECI(s[3]), FRAC(s[3]),
SIGN(s[4]), DECI(s[4]), FRAC(s[4]),
SIGN(s[5]), DECI(s[5]), FRAC(s[5]),
SIGN(s[18]), DECI(s[18]), FRAC(s[18]));
pr_csc(
"\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[1]), DECI(s[1]), FRAC(s[1]),
SIGN(s[6]), DECI(s[6]), FRAC(s[6]),
SIGN(s[7]), DECI(s[7]), FRAC(s[7]),
SIGN(s[8]), DECI(s[8]), FRAC(s[8]),
SIGN(s[19]), DECI(s[19]), FRAC(s[19]));
pr_csc(
"\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[2]), DECI(s[2]), FRAC(s[2]),
SIGN(s[9]), DECI(s[9]), FRAC(s[9]),
SIGN(s[10]), DECI(s[10]), FRAC(s[10]),
SIGN(s[11]), DECI(s[11]), FRAC(s[11]),
SIGN(s[20]), DECI(s[20]), FRAC(s[20]));
if (s[21]) {
pr_csc("\t\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[12]), DECI(s[12]), FRAC(s[12]),
SIGN(s[13]), DECI(s[13]), FRAC(s[13]),
SIGN(s[14]), DECI(s[14]), FRAC(s[14]));
pr_csc("\t\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[15]), DECI(s[15]), FRAC(s[15]),
SIGN(s[16]), DECI(s[16]), FRAC(s[16]),
SIGN(s[17]), DECI(s[17]), FRAC(s[17]));
}
if (s[22])
pr_csc("\tright shift=%d\n", s[22]);
} else {
pr_csc("\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[0]), DECI(s[0]), FRAC(s[0]),
SIGN(s[1]), DECI(s[1]), FRAC(s[1]),
SIGN(s[2]), DECI(s[2]), FRAC(s[2]));
pr_csc("\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[3]), DECI(s[3]), FRAC(s[3]),
SIGN(s[4]), DECI(s[4]), FRAC(s[4]),
SIGN(s[5]), DECI(s[5]), FRAC(s[5]));
pr_csc("\t%s%1d.%04d\t%s%1d.%04d\t%s%1d.%04d\n",
SIGN(s[6]), DECI(s[6]), FRAC(s[6]),
SIGN(s[7]), DECI(s[7]), FRAC(s[7]),
SIGN(s[8]), DECI(s[8]), FRAC(s[8]));
if (s[9])
pr_csc("\tright shift=%d\n", s[9]);
}
pr_csc("\n");
}
static int *cur_osd_mtx = RGB709_to_YUV709l_coeff;
static int *cur_post_mtx = bypass_coeff;
static int *cur_vd1_mtx = bypass_coeff;
static int cur_vd1_on = CSC_OFF;
static int cur_post_on = CSC_OFF;
void set_vpp_matrix(int m_select, int *s, int on)
{
int *m = NULL;
int size = 0;
int i, reg_value;
if (debug_csc && print_lut_mtx)
print_vpp_matrix(m_select, s, on);
if (m_select == VPP_MATRIX_OSD) {
m = osd_matrix_coeff;
size = MATRIX_5x3_COEF_SIZE;
cur_osd_mtx = s;
} else if (m_select == VPP_MATRIX_POST) {
m = post_matrix_coeff;
size = MATRIX_5x3_COEF_SIZE;
cur_post_mtx = s;
cur_post_on = on;
} else if (m_select == VPP_MATRIX_VD1) {
m = vd1_matrix_coeff;
size = MATRIX_5x3_COEF_SIZE;
cur_vd1_mtx = s;
cur_vd1_on = on;
} else if (m_select == VPP_MATRIX_VD2) {
m = vd2_matrix_coeff;
size = MATRIX_5x3_COEF_SIZE;
} else if (m_select == VPP_MATRIX_XVYCC) {
m = xvycc_matrix_coeff;
size = MATRIX_5x3_COEF_SIZE;
} else if (m_select == VPP_MATRIX_EOTF) {
m = video_eotf_coeff;
size = EOTF_COEFF_SIZE;
} else if (m_select == VPP_MATRIX_OSD_EOTF) {
m = osd_eotf_coeff;
size = EOTF_COEFF_SIZE;
} else
return;
if (s)
for (i = 0; i < size; i++)
m[i] = s[i];
else
reload_mtx &= ~(1 << m_select);
reg_value = READ_VPP_REG(VPP_MATRIX_CTRL);
if (m_select == VPP_MATRIX_OSD) {
/* osd matrix, VPP_MATRIX_0 */
if (!is_meson_txlx_cpu() &&
!is_meson_gxlx_cpu() &&
!is_meson_txhd_cpu()) {
/* not enable latched */
hdr_osd_reg.viu_osd1_matrix_pre_offset0_1 =
((m[0] & 0xfff) << 16) | (m[1] & 0xfff);
hdr_osd_reg.viu_osd1_matrix_pre_offset2 =
m[2] & 0xfff;
hdr_osd_reg.viu_osd1_matrix_coef00_01 =
((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff);
hdr_osd_reg.viu_osd1_matrix_coef02_10 =
((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff);
hdr_osd_reg.viu_osd1_matrix_coef11_12 =
((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff);
hdr_osd_reg.viu_osd1_matrix_coef20_21 =
((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff);
if (m[21]) {
hdr_osd_reg.viu_osd1_matrix_coef22_30 =
((m[11] & 0x1fff) << 16) |
(m[12] & 0x1fff);
hdr_osd_reg.viu_osd1_matrix_coef31_32 =
((m[13] & 0x1fff) << 16) |
(m[14] & 0x1fff);
hdr_osd_reg.viu_osd1_matrix_coef40_41 =
((m[15] & 0x1fff) << 16) |
(m[16] & 0x1fff);
hdr_osd_reg.viu_osd1_matrix_colmod_coef42 =
m[17] & 0x1fff;
} else {
hdr_osd_reg.viu_osd1_matrix_coef22_30 =
(m[11] & 0x1fff) << 16;
}
hdr_osd_reg.viu_osd1_matrix_offset0_1 =
((m[18] & 0xfff) << 16) | (m[19] & 0xfff);
hdr_osd_reg.viu_osd1_matrix_offset2 =
m[20] & 0xfff;
hdr_osd_reg.viu_osd1_matrix_colmod_coef42 &= 0x3ff8ffff;
hdr_osd_reg.viu_osd1_matrix_colmod_coef42 |=
(m[21] << 30) | (m[22] << 16);
/* 23 reserved for clipping control */
hdr_osd_reg.viu_osd1_matrix_ctrl &= 0xfffffffc;
hdr_osd_reg.viu_osd1_matrix_ctrl |= on;
} else {
/* move the matrix from osd to vpp in txlx */
m = osd_matrix_coeff;
if (is_meson_gxlx_cpu()) {
if (on) {
/*VSYNC_WR_MPEG_REG_BITS(*/
/*VPP_MATRIX_CTRL,*/
/*4, 8, 3);*/
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_PRE_OFFSET0_1,
((m[0] & 0xfff) << 16)
| (m[1] & 0xfff));
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_PRE_OFFSET2,
m[2] & 0xfff);
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_COEF00_01,
((m[3] & 0x1fff) << 16)
| (m[4] & 0x1fff));
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_COEF02_10,
((m[5] & 0x1fff) << 16)
| (m[6] & 0x1fff));
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_COEF11_12,
((m[7] & 0x1fff) << 16)
| (m[8] & 0x1fff));
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_COEF20_21,
((m[9] & 0x1fff) << 16)
| (m[10] & 0x1fff));
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_COLMOD_COEF42,
m[11] & 0x1fff);
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_OFFSET0_1,
((m[18] & 0xfff) << 16)
| (m[19] & 0xfff));
VSYNC_WR_MPEG_REG(
VIU_OSD1_MATRIX_OFFSET2,
m[20] & 0xfff);
}
/*VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CTRL,*/
/*on, 7, 1);*/
VSYNC_WR_MPEG_REG_BITS(
VIU_OSD1_MATRIX_CTRL,
on, 0, 1);
} else {
if (on) {
/*VSYNC_WR_MPEG_REG_BITS(*/
/*VPP_MATRIX_CTRL,*/
/*4, 8, 3);*/
reg_value = (reg_value &
(~(7 << 8)))
| (4 << 8);
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL,
reg_value);
VSYNC_WR_MPEG_REG(
VPP_MATRIX_PRE_OFFSET0_1,
((m[0] & 0xfff) << 16)
| (m[1] & 0xfff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_PRE_OFFSET2,
m[2] & 0xfff);
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF00_01,
((m[3] & 0x1fff) << 16)
| (m[4] & 0x1fff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF02_10,
((m[5] & 0x1fff) << 16)
| (m[6] & 0x1fff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF11_12,
((m[7] & 0x1fff) << 16)
| (m[8] & 0x1fff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF20_21,
((m[9] & 0x1fff) << 16)
| (m[10] & 0x1fff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF22,
m[11] & 0x1fff);
if (m[21]) {
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF13_14,
((m[12] & 0x1fff) << 16)
| (m[13] & 0x1fff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF15_25,
((m[14] & 0x1fff) << 16)
| (m[17] & 0x1fff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_COEF23_24,
((m[15] & 0x1fff) << 16)
| (m[16] & 0x1fff));
}
if (is_meson_txhd_cpu()) {
VSYNC_WR_MPEG_REG(
VPP_MATRIX_OFFSET0_1,
(((m[18]>>2)&0xfff)<<16)
| ((m[19]>>2)&0xfff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_OFFSET2,
(m[20] >> 2) & 0xfff);
} else {
VSYNC_WR_MPEG_REG(
VPP_MATRIX_OFFSET0_1,
((m[18] & 0xfff) << 16)
| (m[19] & 0xfff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_OFFSET2,
m[20] & 0xfff);
}
VSYNC_WR_MPEG_REG_BITS(
VPP_MATRIX_CLIP,
m[21], 3, 2);
VSYNC_WR_MPEG_REG_BITS(
VPP_MATRIX_CLIP,
m[22], 5, 3);
}
/*VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CTRL,*/
/*on, 7, 1);*/
if (on)
mtx_en_mux |= OSD1_MTX_EN_MASK;
else
mtx_en_mux &= ~OSD1_MTX_EN_MASK;
}
}
} else if (m_select == VPP_MATRIX_EOTF) {
/* eotf matrix, VPP_MATRIX_EOTF */
/* enable latched */
for (i = 0; i < 5; i++)
VSYNC_WR_MPEG_REG(VIU_EOTF_CTL + i + 1,
((m[i * 2] & 0x1fff) << 16)
| (m[i * 2 + 1] & 0x1fff));
if (is_meson_txlx_cpu() ||
is_meson_gxlx_cpu() ||
is_meson_txhd_cpu()) {
VSYNC_WR_MPEG_REG(VIU_EOTF_CTL + 8, 0);
VSYNC_WR_MPEG_REG(VIU_EOTF_CTL + 9, 0);
}
WRITE_VPP_REG_BITS(VIU_EOTF_CTL, on, 30, 1);
WRITE_VPP_REG_BITS(VIU_EOTF_CTL, on, 31, 1);
} else if (m_select == VPP_MATRIX_OSD_EOTF) {
/* osd eotf matrix, VPP_MATRIX_OSD_EOTF */
if (!is_meson_txlx_cpu() &&
!is_meson_gxlx_cpu() &&
!is_meson_txhd_cpu()) {
/* enable latched */
hdr_osd_reg.viu_osd1_eotf_coef00_01 =
((m[0 * 2] & 0x1fff) << 16)
| (m[0 * 2 + 1] & 0x1fff);
hdr_osd_reg.viu_osd1_eotf_coef02_10 =
((m[1 * 2] & 0x1fff) << 16)
| (m[1 * 2 + 1] & 0x1fff);
hdr_osd_reg.viu_osd1_eotf_coef11_12 =
((m[2 * 2] & 0x1fff) << 16)
| (m[2 * 2 + 1] & 0x1fff);
hdr_osd_reg.viu_osd1_eotf_coef20_21 =
((m[3 * 2] & 0x1fff) << 16)
| (m[3 * 2 + 1] & 0x1fff);
hdr_osd_reg.viu_osd1_eotf_coef22_rs =
((m[4 * 2] & 0x1fff) << 16)
| (m[4 * 2 + 1] & 0x1fff);
hdr_osd_reg.viu_osd1_eotf_ctl &= 0x3fffffff;
hdr_osd_reg.viu_osd1_eotf_ctl |=
(on << 30) | (on << 31);
} else {
/* latch enable */
WRITE_VPP_REG_BITS(VIU_OSD1_EOTF_CTL, 1, 26, 1);
if (on) {
VSYNC_WR_MPEG_REG(VIU_OSD1_EOTF_COEF00_01,
((m[0 * 2] & 0x1fff) << 16) |
(m[0 * 2 + 1] & 0x1fff));
VSYNC_WR_MPEG_REG(VIU_OSD1_EOTF_COEF02_10,
((m[1 * 2] & 0x1fff) << 16) |
(m[1 * 2 + 1] & 0x1fff));
VSYNC_WR_MPEG_REG(VIU_OSD1_EOTF_COEF11_12,
((m[2 * 2] & 0x1fff) << 16) |
(m[2 * 2 + 1] & 0x1fff));
VSYNC_WR_MPEG_REG(VIU_OSD1_EOTF_COEF20_21,
((m[3 * 2] & 0x1fff) << 16) |
(m[3 * 2 + 1] & 0x1fff));
VSYNC_WR_MPEG_REG(VIU_OSD1_EOTF_COEF22_RS,
((m[4 * 2] & 0x1fff) << 16) |
(m[4 * 2 + 1] & 0x1fff));
}
WRITE_VPP_REG_BITS(VIU_OSD1_EOTF_CTL,
(on | (on << 1)), 30, 2);
}
} else {
/* vd1 matrix, VPP_MATRIX_1 */
/* post matrix, VPP_MATRIX_2 */
/* xvycc matrix, VPP_MATRIX_3 */
/* vd2 matrix, VPP_MATRIX_6 */
if (m_select == VPP_MATRIX_POST) {
/* post matrix */
m = post_matrix_coeff;
if (rdma_flag & (1 << m_select)) {
/* set bit for disable latched */
WRITE_VPP_REG_BITS(VPP_XVYCC_MISC, 0, 14, 1);
if (on)
mtx_en_mux |= POST_MTX_EN_MASK;
else
mtx_en_mux &= ~POST_MTX_EN_MASK;
} else {
WRITE_VPP_REG_BITS(VPP_XVYCC_MISC, 1, 14, 1);
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, on, 0, 1);
}
if (on) {
if (rdma_flag & (1 << m_select)) {
/*VSYNC_WR_MPEG_REG_BITS(*/
/*VPP_MATRIX_CTRL, 0, 8, 3);*/
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL,
(reg_value & (~(7 << 8)))
| (0 << 8));
} else
WRITE_VPP_REG_BITS(
VPP_MATRIX_CTRL, 0, 8, 3);
}
} else if (m_select == VPP_MATRIX_VD1) {
/* vd1 matrix, latched */
m = vd1_matrix_coeff;
if (rdma_flag & (1 << m_select)) {
/* set bit for disable latched */
WRITE_VPP_REG_BITS(VPP_XVYCC_MISC, 0, 9, 1);
/*WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL,*/
/*on, 5, 1);*/
if (on)
mtx_en_mux |= VD1_MTX_EN_MASK;
else
mtx_en_mux &= ~VD1_MTX_EN_MASK;
} else {
/* set bit for enable latched */
WRITE_VPP_REG_BITS(VPP_XVYCC_MISC, 1, 9, 1);
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, on, 5, 1);
}
if (on) {
if (rdma_flag & (1 << m_select)) {
/*VSYNC_WR_MPEG_REG_BITS(*/
/*VPP_MATRIX_CTRL, 1, 8, 3);*/
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL,
(reg_value & (~(7 << 8)))
| (1 << 8));
} else
WRITE_VPP_REG_BITS(
VPP_MATRIX_CTRL, 1, 8, 3);
}
} else if (m_select == VPP_MATRIX_VD2) {
/* vd2 matrix, not latched */
m = vd2_matrix_coeff;
if (rdma_flag & (1 << m_select)) {
if (on)
mtx_en_mux |= VD2_MTX_EN_MASK;
else
mtx_en_mux &= ~VD2_MTX_EN_MASK;
} else {
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, on, 4, 1);
}
if (on) {
if (rdma_flag & (1 << m_select)) {
/*VSYNC_WR_MPEG_REG_BITS(*/
/*VPP_MATRIX_CTRL, 2, 8, 3);*/
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL,
(reg_value & (~(7 << 8)))
| (2 << 8));
} else
WRITE_VPP_REG_BITS(
VPP_MATRIX_CTRL, 2, 8, 3);
}
} else if (m_select == VPP_MATRIX_XVYCC) {
/* xvycc matrix, not latched */
m = xvycc_matrix_coeff;
if (on) {
if (rdma_flag & (1 << m_select)) {
mtx_en_mux |= XVY_MTX_EN_MASK;
reg_value = (reg_value & (~(7 << 8)))
| (3 << 8);
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL,
reg_value);
} else {
WRITE_VPP_REG_BITS(
VPP_MATRIX_CTRL, on, 6, 1);
WRITE_VPP_REG_BITS(
VPP_MATRIX_CTRL, 3, 8, 3);
}
} else {
if (rdma_flag & (1 << m_select)) {
mtx_en_mux &= ~XVY_MTX_EN_MASK;
} else
WRITE_VPP_REG_BITS(
VPP_MATRIX_CTRL, on, 6, 1);
}
}
if (on) {
if (rdma_flag & (1 << m_select)) {
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET0_1,
((m[0] & 0xfff) << 16)
| (m[1] & 0xfff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET2,
m[2] & 0xfff);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01,
((m[3] & 0x1fff) << 16)
| (m[4] & 0x1fff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10,
((m[5] & 0x1fff) << 16)
| (m[6] & 0x1fff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12,
((m[7] & 0x1fff) << 16)
| (m[8] & 0x1fff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21,
((m[9] & 0x1fff) << 16)
| (m[10] & 0x1fff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22,
m[11] & 0x1fff);
if (m[21]) {
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF13_14,
((m[12] & 0x1fff) << 16)
| (m[13] & 0x1fff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF15_25,
((m[14] & 0x1fff) << 16)
| (m[17] & 0x1fff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF23_24,
((m[15] & 0x1fff) << 16)
| (m[16] & 0x1fff));
}
if (is_meson_txhd_cpu() &&
(m_select == VPP_MATRIX_XVYCC)) {
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1,
(((m[18] >> 2) & 0xfff) << 16)
| ((m[19] >> 2) & 0xfff));
VSYNC_WR_MPEG_REG(
VPP_MATRIX_OFFSET2,
(m[20] >> 2) & 0xfff);
} else {
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1,
((m[18] & 0xfff) << 16)
| (m[19] & 0xfff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2,
m[20] & 0xfff);
}
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP,
m[21], 3, 2);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP,
m[22], 5, 3);
} else {
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1,
((m[0] & 0xfff) << 16)
| (m[1] & 0xfff));
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2,
m[2] & 0xfff);
WRITE_VPP_REG(VPP_MATRIX_COEF00_01,
((m[3] & 0x1fff) << 16)
| (m[4] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF02_10,
((m[5] & 0x1fff) << 16)
| (m[6] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF11_12,
((m[7] & 0x1fff) << 16)
| (m[8] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF20_21,
((m[9] & 0x1fff) << 16)
| (m[10] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF22,
m[11] & 0x1fff);
if (m[21]) {
WRITE_VPP_REG(VPP_MATRIX_COEF13_14,
((m[12] & 0x1fff) << 16)
| (m[13] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF15_25,
((m[14] & 0x1fff) << 16)
| (m[17] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF23_24,
((m[15] & 0x1fff) << 16)
| (m[16] & 0x1fff));
}
if (is_meson_txhd_cpu() &&
(m_select == VPP_MATRIX_XVYCC)) {
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1,
(((m[18] >> 2) & 0xfff) << 16)
| ((m[19] >> 2) & 0xfff));
WRITE_VPP_REG(VPP_MATRIX_OFFSET2,
(m[20] >> 2) & 0xfff);
} else {
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1,
((m[18] & 0xfff) << 16)
| (m[19] & 0xfff));
WRITE_VPP_REG(VPP_MATRIX_OFFSET2,
m[20] & 0xfff);
}
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP,
m[21], 3, 2);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP,
m[22], 5, 3);
}
}
}
}
void enable_osd_path(int on, int shadow_mode)
{
static int *osd1_mtx_backup;
static uint32_t osd1_eotf_ctl_backup;
static uint32_t osd1_oetf_ctl_backup;
if (!on) {
osd1_mtx_backup = cur_osd_mtx;
osd1_eotf_ctl_backup = hdr_osd_reg.viu_osd1_eotf_ctl;
osd1_oetf_ctl_backup = hdr_osd_reg.viu_osd1_oetf_ctl;
set_vpp_matrix(VPP_MATRIX_OSD, bypass_coeff, CSC_ON);
hdr_osd_reg.viu_osd1_eotf_ctl &= 0x07ffffff;
hdr_osd_reg.viu_osd1_oetf_ctl &= 0x1fffffff;
hdr_osd_reg.shadow_mode = shadow_mode;
} else {
set_vpp_matrix(VPP_MATRIX_OSD, osd1_mtx_backup, CSC_ON);
hdr_osd_reg.viu_osd1_eotf_ctl = osd1_eotf_ctl_backup;
hdr_osd_reg.viu_osd1_oetf_ctl = osd1_oetf_ctl_backup;
hdr_osd_reg.shadow_mode = shadow_mode;
}
}
EXPORT_SYMBOL(enable_osd_path);
/* coeff: pointer to target coeff array */
/* bits: how many bits for target coeff, could be 10 ~ 12, default 10 */
static int32_t *post_mtx_backup;
static int32_t post_on_backup;
static bool restore_post_table;
static int32_t *vd1_mtx_backup;
static int32_t vd1_on_backup;
int enable_rgb_to_yuv_matrix_for_dvll(
int32_t on, uint32_t *coeff_orig, uint32_t bits)
{
int32_t i;
uint32_t coeff01, coeff23, coeff45, coeff67, coeff89;
uint32_t scale, shift, offset[3];
int32_t *coeff = dvll_RGB_to_YUV709l_coeff;
if ((bits < 10) || (bits > 12))
return -1;
if (on && !coeff_orig)
return -2;
if (on) {
/* only store the start one */
if (cur_post_mtx !=
dvll_RGB_to_YUV709l_coeff) {
post_mtx_backup = cur_post_mtx;
post_on_backup = cur_post_on;
vd1_mtx_backup = cur_vd1_mtx;
vd1_on_backup = cur_vd1_on;
}
coeff01 = coeff_orig[0];
coeff23 = coeff_orig[1];
coeff45 = coeff_orig[2];
coeff67 = coeff_orig[3];
coeff89 = coeff_orig[4] & 0xffff;
scale = (coeff_orig[4] >> 16) & 0x0f;
offset[0] = coeff_orig[5];
offset[1] = 0; /* coeff_orig[6]; */
offset[2] = 0; /* coeff_orig[7]; */
coeff[0] = coeff[1] = coeff[2] = 0; /* pre offset */
coeff[5] = (int32_t)((coeff01 & 0xffff) << 16) >> 16;
coeff[3] = (int32_t)coeff01 >> 16;
coeff[4] = (int32_t)((coeff23 & 0xffff) << 16) >> 16;
coeff[8] = (int32_t)coeff23 >> 16;
coeff[6] = (int32_t)((coeff45 & 0xffff) << 16) >> 16;
coeff[7] = (int32_t)coeff45 >> 16;
coeff[11] = (int32_t)((coeff67 & 0xffff) << 16) >> 16;
coeff[9] = (int32_t)coeff67 >> 16;
coeff[10] = (int32_t)((coeff89 & 0xffff) << 16) >> 16;
if (scale > 12) {
shift = scale - 12;
for (i = 3; i < 12; i++)
coeff[i] =
(coeff[i] + (1 << (shift - 1)))
>> shift;
} else if (scale < 12) {
shift = 12 - scale;
for (i = 3; i < 12; i++)
coeff[i] <<= shift;
}
/* post offset */
coeff[18] = offset[0];
coeff[19] = offset[1];
coeff[20] = offset[2];
coeff[5] =
((coeff[3] + coeff[4] + coeff[5]) & 0xfffe)
- coeff[3] - coeff[4];
coeff[8] = 0 - coeff[6] - coeff[7];
coeff[11] = 0 - coeff[9] - coeff[10];
coeff[18] -= (0x1000 - coeff[3] - coeff[4] - coeff[5]) >> 1;
coeff[22] = 2;
vpp_set_mtx_en_read();
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, 0);
set_vpp_matrix(VPP_MATRIX_OSD,
cur_osd_mtx, CSC_OFF);
set_vpp_matrix(VPP_MATRIX_VD1,
cur_vd1_mtx, CSC_OFF);
set_vpp_matrix(VPP_MATRIX_POST,
coeff, CSC_ON);
vpp_set_mtx_en_write();
restore_post_table = true;
} else if (restore_post_table) {
vpp_set_mtx_en_read();
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, 0);
set_vpp_matrix(VPP_MATRIX_OSD,
cur_osd_mtx, CSC_OFF);
set_vpp_matrix(VPP_MATRIX_VD1,
vd1_mtx_backup, cur_vd1_on);
set_vpp_matrix(VPP_MATRIX_POST,
post_mtx_backup, post_on_backup);
vpp_set_mtx_en_write();
restore_post_table = false;
}
return 0;
}
EXPORT_SYMBOL(enable_rgb_to_yuv_matrix_for_dvll);
const char lut_name[NUM_LUT][16] = {
"OSD_EOTF",
"OSD_OETF",
"EOTF",
"OETF",
"INV_EOTF"
};
/* VIDEO_OETF_LUT_SIZE 289 >*/
/* OSD_OETF_LUT_SIZE 41 >*/
/* OSD_OETF_LUT_SIZE 33 */
static void print_vpp_lut(
enum vpp_lut_sel_e lut_sel,
int on)
{
unsigned short r_map[VIDEO_OETF_LUT_SIZE];
unsigned short g_map[VIDEO_OETF_LUT_SIZE];
unsigned short b_map[VIDEO_OETF_LUT_SIZE];
unsigned int addr_port;
unsigned int data_port;
unsigned int ctrl_port;
unsigned int data;
int i;
if (lut_sel == VPP_LUT_OSD_EOTF) {
addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
ctrl_port = VIU_OSD1_EOTF_CTL;
} else if (lut_sel == VPP_LUT_EOTF) {
addr_port = VIU_EOTF_LUT_ADDR_PORT;
data_port = VIU_EOTF_LUT_DATA_PORT;
ctrl_port = VIU_EOTF_CTL;
} else if (lut_sel == VPP_LUT_OSD_OETF) {
addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
ctrl_port = VIU_OSD1_OETF_CTL;
} else if (lut_sel == VPP_LUT_OETF) {
addr_port = XVYCC_LUT_R_ADDR_PORT;
data_port = XVYCC_LUT_R_DATA_PORT;
ctrl_port = XVYCC_LUT_CTL;
} else if (lut_sel == VPP_LUT_INV_EOTF) {
addr_port = XVYCC_INV_LUT_Y_ADDR_PORT;
data_port = XVYCC_INV_LUT_Y_DATA_PORT;
ctrl_port = XVYCC_INV_LUT_CTL;
} else
return;
if (lut_sel == VPP_LUT_OSD_OETF) {
for (i = 0; i < 20; i++) {
WRITE_VPP_REG(addr_port, i);
data = READ_VPP_REG(data_port);
r_map[i * 2] = data & 0xffff;
r_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
WRITE_VPP_REG(addr_port, 20);
data = READ_VPP_REG(data_port);
r_map[OSD_OETF_LUT_SIZE - 1] = data & 0xffff;
g_map[0] = (data >> 16) & 0xffff;
for (i = 0; i < 20; i++) {
WRITE_VPP_REG(addr_port, 21 + i);
data = READ_VPP_REG(data_port);
g_map[i * 2 + 1] = data & 0xffff;
g_map[i * 2 + 2] = (data >> 16) & 0xffff;
}
for (i = 0; i < 20; i++) {
WRITE_VPP_REG(addr_port, 41 + i);
data = READ_VPP_REG(data_port);
b_map[i * 2] = data & 0xffff;
b_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
WRITE_VPP_REG(addr_port, 61);
data = READ_VPP_REG(data_port);
b_map[OSD_OETF_LUT_SIZE - 1] = data & 0xffff;
pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off");
for (i = 0; i < OSD_OETF_LUT_SIZE; i++) {
pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i, r_map[i], g_map[i], b_map[i]);
}
pr_csc("\n");
} else if (lut_sel == VPP_LUT_OSD_EOTF) {
WRITE_VPP_REG(addr_port, 0);
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
r_map[i * 2] = data & 0xffff;
r_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
data = READ_VPP_REG(data_port);
r_map[EOTF_LUT_SIZE - 1] = data & 0xffff;
g_map[0] = (data >> 16) & 0xffff;
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
g_map[i * 2 + 1] = data & 0xffff;
g_map[i * 2 + 2] = (data >> 16) & 0xffff;
}
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
b_map[i * 2] = data & 0xffff;
b_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
data = READ_VPP_REG(data_port);
b_map[EOTF_LUT_SIZE - 1] = data & 0xffff;
pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off");
for (i = 0; i < EOTF_LUT_SIZE; i++) {
pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i, r_map[i], g_map[i], b_map[i]);
}
pr_csc("\n");
} else if (lut_sel == VPP_LUT_EOTF) {
WRITE_VPP_REG(addr_port, 0);
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
r_map[i * 2] = data & 0xffff;
r_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
data = READ_VPP_REG(data_port);
r_map[EOTF_LUT_SIZE - 1] = data & 0xffff;
g_map[0] = (data >> 16) & 0xffff;
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
g_map[i * 2 + 1] = data & 0xffff;
g_map[i * 2 + 2] = (data >> 16) & 0xffff;
}
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
b_map[i * 2] = data & 0xffff;
b_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
data = READ_VPP_REG(data_port);
b_map[EOTF_LUT_SIZE - 1] = data & 0xffff;
pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off");
for (i = 0; i < EOTF_LUT_SIZE; i++) {
pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i, r_map[i], g_map[i], b_map[i]);
}
pr_csc("\n");
} else if (lut_sel == VPP_LUT_OETF) {
WRITE_VPP_REG(ctrl_port, 0x0);
WRITE_VPP_REG(addr_port, 0);
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
r_map[i] = READ_VPP_REG(data_port) & 0x3ff;
WRITE_VPP_REG(addr_port + 2, 0);
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
g_map[i] = READ_VPP_REG(data_port + 2) & 0x3ff;
WRITE_VPP_REG(addr_port + 4, 0);
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
b_map[i] = READ_VPP_REG(data_port + 4) & 0x3ff;
pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off");
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++) {
pr_csc("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i, r_map[i], g_map[i], b_map[i]);
}
pr_csc("\n");
if (on)
WRITE_VPP_REG(ctrl_port, 0x7f);
} else if (lut_sel == VPP_LUT_INV_EOTF) {
WRITE_VPP_REG_BITS(ctrl_port, 0, 12, 3);
pr_csc("%s lut %s:\n", lut_name[lut_sel], on ? "on" : "off");
for (i = 0;
i < EOTF_INV_LUT_NEG2048_SIZE +
EOTF_INV_LUT_SIZE + EOTF_INV_LUT_1024_SIZE;
i++) {
WRITE_VPP_REG(addr_port, i);
data = READ_VPP_REG(data_port) & 0xfff;
if (data & 0x800)
pr_csc("\t[%d] = %d\n",
i, -(~(data|0xfffff000) + 1));
else
pr_csc("\t[%d] = %d\n", i, data);
}
pr_csc("\n");
if (on)
WRITE_VPP_REG_BITS(ctrl_port, 1<<2, 12, 3);
}
}
void set_vpp_lut(
enum vpp_lut_sel_e lut_sel,
unsigned int *r,
unsigned int *g,
unsigned int *b,
int on)
{
unsigned int *r_map = NULL;
unsigned int *g_map = NULL;
unsigned int *b_map = NULL;
unsigned int addr_port;
unsigned int data_port;
unsigned int ctrl_port;
int i;
if (reload_lut & (1 << lut_sel))
reload_lut &= ~(1 << lut_sel);
if (lut_sel == VPP_LUT_OSD_EOTF) {
r_map = osd_eotf_r_mapping;
g_map = osd_eotf_g_mapping;
b_map = osd_eotf_b_mapping;
addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
ctrl_port = VIU_OSD1_EOTF_CTL;
} else if (lut_sel == VPP_LUT_EOTF) {
r_map = video_eotf_r_mapping;
g_map = video_eotf_g_mapping;
b_map = video_eotf_b_mapping;
addr_port = VIU_EOTF_LUT_ADDR_PORT;
data_port = VIU_EOTF_LUT_DATA_PORT;
ctrl_port = VIU_EOTF_CTL;
} else if (lut_sel == VPP_LUT_OSD_OETF) {
r_map = osd_oetf_r_mapping;
g_map = osd_oetf_g_mapping;
b_map = osd_oetf_b_mapping;
addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
ctrl_port = VIU_OSD1_OETF_CTL;
} else if (lut_sel == VPP_LUT_OETF) {
#if 0
load_knee_lut(on);
return;
#else
r_map = video_oetf_r_mapping;
g_map = video_oetf_g_mapping;
b_map = video_oetf_b_mapping;
addr_port = XVYCC_LUT_R_ADDR_PORT;
data_port = XVYCC_LUT_R_DATA_PORT;
ctrl_port = XVYCC_LUT_CTL;
#endif
} else if (lut_sel == VPP_LUT_INV_EOTF) {
addr_port = XVYCC_INV_LUT_Y_ADDR_PORT;
data_port = XVYCC_INV_LUT_Y_DATA_PORT;
ctrl_port = XVYCC_INV_LUT_CTL;
} else
return;
if (lut_sel == VPP_LUT_OSD_OETF) {
/* enable latched */
if (r && r_map)
for (i = 0; i < OSD_OETF_LUT_SIZE; i++)
r_map[i] = r[i];
if (g && g_map)
for (i = 0; i < OSD_OETF_LUT_SIZE; i++)
g_map[i] = g[i];
if (r && r_map)
for (i = 0; i < OSD_OETF_LUT_SIZE; i++)
b_map[i] = b[i];
if (!is_meson_txlx_cpu()) {
for (i = 0; i < OSD_OETF_LUT_SIZE; i++) {
hdr_osd_reg.lut_val.or_map[i] = r_map[i];
hdr_osd_reg.lut_val.og_map[i] = g_map[i];
hdr_osd_reg.lut_val.ob_map[i] = b_map[i];
}
hdr_osd_reg.viu_osd1_oetf_ctl &= 0x1fffffff;
hdr_osd_reg.viu_osd1_oetf_ctl |= 7 << 22;
if (on)
hdr_osd_reg.viu_osd1_oetf_ctl |= 7 << 29;
} else {
/* latch enable */
WRITE_VPP_REG_BITS(VIU_OSD1_OETF_CTL, 1, 28, 1);
if (on) {
/* change to 12bit from txlx */
if (is_meson_txlx_cpu())
for (i = 0;
i < OSD_OETF_LUT_SIZE;
i++) {
r_map[i] = 4 * r_map[i];
g_map[i] = 4 * g_map[i];
b_map[i] = 4 * b_map[i];
}
for (i = 0; i < 20; i++) {
VSYNC_WR_MPEG_REG(addr_port, i);
VSYNC_WR_MPEG_REG(data_port,
r_map[i * 2]
| (r_map[i * 2 + 1] << 16));
}
VSYNC_WR_MPEG_REG(addr_port, 20);
VSYNC_WR_MPEG_REG(data_port,
r_map[41 - 1]
| (g_map[0] << 16));
for (i = 0; i < 20; i++) {
VSYNC_WR_MPEG_REG(addr_port, 21 + i);
VSYNC_WR_MPEG_REG(data_port,
g_map[i * 2 + 1]
| (g_map[i * 2 + 2] << 16));
}
for (i = 0; i < 20; i++) {
VSYNC_WR_MPEG_REG(addr_port, 41 + i);
VSYNC_WR_MPEG_REG(data_port,
b_map[i * 2]
| (b_map[i * 2 + 1] << 16));
}
VSYNC_WR_MPEG_REG(addr_port, 61);
VSYNC_WR_MPEG_REG(data_port,
b_map[41 - 1]);
}
WRITE_VPP_REG_BITS(VIU_OSD1_OETF_CTL, 7, 22, 3);
WRITE_VPP_REG_BITS(VIU_OSD1_OETF_CTL,
(on | (on << 1) | (on << 2)), 29, 3);
}
} else if (lut_sel == VPP_LUT_OSD_EOTF) {
/* enable latched */
if (r && r_map)
for (i = 0; i < EOTF_LUT_SIZE; i++)
r_map[i] = r[i];
if (g && g_map)
for (i = 0; i < EOTF_LUT_SIZE; i++)
g_map[i] = g[i];
if (r && r_map)
for (i = 0; i < EOTF_LUT_SIZE; i++)
b_map[i] = b[i];
if (!is_meson_txlx_cpu() &&
!is_meson_gxlx_cpu() &&
!is_meson_txhd_cpu()) {
for (i = 0; i < EOTF_LUT_SIZE; i++) {
hdr_osd_reg.lut_val.r_map[i] = r_map[i];
hdr_osd_reg.lut_val.g_map[i] = g_map[i];
hdr_osd_reg.lut_val.b_map[i] = b_map[i];
}
hdr_osd_reg.viu_osd1_eotf_ctl &= 0xc7ffffff;
if (on)
hdr_osd_reg.viu_osd1_eotf_ctl |= 7 << 27;
hdr_osd_reg.viu_osd1_eotf_ctl |= 1 << 31;
} else {
/* latch enable */
WRITE_VPP_REG_BITS(VIU_OSD1_EOTF_CTL, 1, 26, 1);
if (on) {
VSYNC_WR_MPEG_REG(
addr_port, 0);
for (i = 0; i < 16; i++)
VSYNC_WR_MPEG_REG(
data_port,
r_map[i * 2]
| (r_map[i * 2 + 1] << 16));
VSYNC_WR_MPEG_REG(
data_port,
r_map[EOTF_LUT_SIZE - 1]
| (g_map[0] << 16));
for (i = 0; i < 16; i++)
VSYNC_WR_MPEG_REG(
data_port,
g_map[i * 2 + 1]
| (b_map[i * 2 + 2] << 16));
for (i = 0; i < 16; i++)
VSYNC_WR_MPEG_REG(
data_port,
b_map[i * 2]
| (b_map[i * 2 + 1] << 16));
VSYNC_WR_MPEG_REG(
data_port, b_map[EOTF_LUT_SIZE - 1]);
}
WRITE_VPP_REG_BITS(VIU_OSD1_EOTF_CTL,
1, 31, 1);
WRITE_VPP_REG_BITS(VIU_OSD1_EOTF_CTL,
(on | (on << 1) | (on << 2)), 27, 3);
}
} else if (lut_sel == VPP_LUT_EOTF) {
/* enable latched */
if (r && r_map)
for (i = 0; i < EOTF_LUT_SIZE; i++)
r_map[i] = r[i];
if (g && g_map)
for (i = 0; i < EOTF_LUT_SIZE; i++)
g_map[i] = g[i];
if (r && r_map)
for (i = 0; i < EOTF_LUT_SIZE; i++)
b_map[i] = b[i];
/*txlx add eotf latch ctl bit 26*/
if (is_meson_txlx_cpu() ||
is_meson_gxlx_cpu() ||
is_meson_txhd_cpu())
WRITE_VPP_REG_BITS(ctrl_port, 1, 26, 1);
if (on) {
for (i = 0; i < 16; i++) {
VSYNC_WR_MPEG_REG(addr_port, i);
VSYNC_WR_MPEG_REG(data_port,
r_map[i * 2]
| (r_map[i * 2 + 1] << 16));
}
VSYNC_WR_MPEG_REG(addr_port, 16);
VSYNC_WR_MPEG_REG(data_port,
r_map[EOTF_LUT_SIZE - 1]
| (g_map[0] << 16));
for (i = 0; i < 16; i++) {
VSYNC_WR_MPEG_REG(addr_port, i + 17);
VSYNC_WR_MPEG_REG(data_port,
g_map[i * 2 + 1]
| (g_map[i * 2 + 2] << 16));
}
for (i = 0; i < 16; i++) {
VSYNC_WR_MPEG_REG(addr_port, i + 33);
VSYNC_WR_MPEG_REG(data_port,
b_map[i * 2]
| (b_map[i * 2 + 1] << 16));
}
VSYNC_WR_MPEG_REG(addr_port, 49);
VSYNC_WR_MPEG_REG(data_port, b_map[EOTF_LUT_SIZE - 1]);
WRITE_VPP_REG_BITS(ctrl_port, 7, 27, 3);
} else
WRITE_VPP_REG_BITS(ctrl_port, 0, 27, 3);
WRITE_VPP_REG_BITS(ctrl_port, 1, 31, 1);
} else if (lut_sel == VPP_LUT_OETF) {
/* set bit to disable latched */
WRITE_VPP_REG_BITS(VPP_XVYCC_MISC, 0, 18, 3);
if (r && r_map)
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
r_map[i] = r[i];
if (g && g_map)
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
g_map[i] = g[i];
if (r && r_map)
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
b_map[i] = b[i];
if (on) {
VSYNC_WR_MPEG_REG(ctrl_port, 0x0f);
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++) {
VSYNC_WR_MPEG_REG(addr_port, i);
VSYNC_WR_MPEG_REG(data_port, r_map[i]);
}
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++) {
VSYNC_WR_MPEG_REG(addr_port + 2, i);
VSYNC_WR_MPEG_REG(data_port + 2, g_map[i]);
}
for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++) {
VSYNC_WR_MPEG_REG(addr_port + 4, i);
VSYNC_WR_MPEG_REG(data_port + 4, b_map[i]);
}
VSYNC_WR_MPEG_REG(ctrl_port, 0x7f);
knee_lut_on = 1;
} else {
VSYNC_WR_MPEG_REG(ctrl_port, 0x0f);
knee_lut_on = 0;
}
cur_knee_factor = knee_factor;
} else if (lut_sel == VPP_LUT_INV_EOTF) {
/* set bit to enable latched */
WRITE_VPP_REG_BITS(VPP_XVYCC_MISC, 0x7, 4, 3);
if (on) {
if (r[0] & INVLUT_HLG) {
for (i = 0; i < EOTF_INV_LUT_SIZE; i++)
invlut_y[i] = invlut_hlg_y[i];
r[0] = 0;
}
VSYNC_WR_MPEG_REG(addr_port, 0);
for (i = 0; i < EOTF_INV_LUT_NEG2048_SIZE; i++) {
VSYNC_WR_MPEG_REG(addr_port, i);
VSYNC_WR_MPEG_REG(data_port, invlut_y_neg[i]);
}
for (i = 0; i < EOTF_INV_LUT_SIZE; i++) {
VSYNC_WR_MPEG_REG(addr_port,
EOTF_INV_LUT_NEG2048_SIZE + i);
VSYNC_WR_MPEG_REG(data_port, invlut_y[i]);
}
for (i = 0; i < EOTF_INV_LUT_1024_SIZE; i++) {
VSYNC_WR_MPEG_REG(addr_port,
EOTF_INV_LUT_NEG2048_SIZE +
EOTF_INV_LUT_SIZE + i);
VSYNC_WR_MPEG_REG(data_port, invlut_y_1024[i]);
}
WRITE_VPP_REG_BITS(ctrl_port, 1<<2, 12, 3);
} else
WRITE_VPP_REG_BITS(ctrl_port, 0, 12, 3);
}
if (debug_csc && print_lut_mtx)
print_vpp_lut(lut_sel, on);
}
/***************************** end of gxl hdr **************************/
/* extern unsigned int cm_size; */
/* extern unsigned int ve_size; */
/* extern unsigned int cm2_patch_flag; */
/* extern struct ve_dnlp_s am_ve_dnlp; */
/* extern struct ve_dnlp_table_s am_ve_new_dnlp; */
/* extern int cm_en; //0:disabel;1:enable */
/* extern struct tcon_gamma_table_s video_gamma_table_r; */
/* extern struct tcon_gamma_table_s video_gamma_table_g; */
/* extern struct tcon_gamma_table_s video_gamma_table_b; */
/* extern struct tcon_gamma_table_s video_gamma_table_r_adj; */
/* extern struct tcon_gamma_table_s video_gamma_table_g_adj; */
/* extern struct tcon_gamma_table_s video_gamma_table_b_adj; */
/* extern struct tcon_rgb_ogo_s video_rgb_ogo; */
/* csc mode:*/
/* 0: 601 limit to RGB*/
/* vd1 for ycbcr to rgb*/
/* 1: 601 full to RGB*/
/* vd1 for ycbcr to rgb*/
/* 2: 709 limit to RGB*/
/* vd1 for ycbcr to rgb*/
/* 3: 709 full to RGB*/
/* vd1 for ycbcr to rgb*/
/* 4: 2020 limit to RGB*/
/* vd1 for ycbcr to rgb*/
/* post for rgb to r'g'b'*/
/* 5: 2020(G:33c2,86c4 B:1d4c,0bb8 R:84d0,3e80) limit to RGB*/
/* vd1 for ycbcr to rgb*/
/* post for rgb to r'g'b'*/
/* 6: customer matrix calculation according to src and dest primary*/
/* vd1 for ycbcr to rgb*/
/* post for rgb to r'g'b' */
static void vpp_set_mtx_en_write(void)
{
int reg_val;
reg_val = READ_VPP_REG(VPP_MATRIX_CTRL);
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, (reg_val &
(~(POST_MTX_EN_MASK |
VD2_MTX_EN_MASK |
VD1_MTX_EN_MASK |
XVY_MTX_EN_MASK |
OSD1_MTX_EN_MASK))) |
mtx_en_mux);
}
static void vpp_set_mtx_en_read(void)
{
int reg_value;
reg_value = READ_VPP_REG(VPP_MATRIX_CTRL);
mtx_en_mux = reg_value &
(POST_MTX_EN_MASK |
VD2_MTX_EN_MASK |
VD1_MTX_EN_MASK |
XVY_MTX_EN_MASK |
OSD1_MTX_EN_MASK);
}
static void vpp_set_matrix(
enum vpp_matrix_sel_e vd1_or_vd2_or_post,
unsigned int on,
enum vpp_matrix_csc_e csc_mode,
struct matrix_s *m)
{
int reg_value;
if (force_csc_type != 0xff)
csc_mode = force_csc_type;
reg_value = READ_VPP_REG(VPP_MATRIX_CTRL);
if (vd1_or_vd2_or_post == VPP_MATRIX_VD1) {
/* vd1 matrix */
reg_value = (reg_value & (~(7 << 8))) |
(1 << 8);
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, reg_value);
if (on)
mtx_en_mux |= VD1_MTX_EN_MASK;
else
mtx_en_mux &= ~VD1_MTX_EN_MASK;
} else if (vd1_or_vd2_or_post == VPP_MATRIX_VD2) {
/* vd2 matrix */
reg_value = (reg_value & (~(7 << 8))) |
(2 << 8);
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, reg_value);
if (on)
mtx_en_mux |= VD2_MTX_EN_MASK;
else
mtx_en_mux &= ~VD2_MTX_EN_MASK;
} else {
/* post matrix */
reg_value = (reg_value & (~(7 << 8))) |
(0 << 8);
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL, reg_value);
if (on)
mtx_en_mux |= POST_MTX_EN_MASK;
else
mtx_en_mux &= ~POST_MTX_EN_MASK;
}
if (!on)
return;
if (csc_mode == VPP_MATRIX_YUV601_RGB) {
/* ycbcr limit, 601 to RGB */
/* -16 1.164 0 1.596 0*/
/* -128 1.164 -0.392 -0.813 0*/
/* -128 1.164 2.017 0 0 */
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, 0x04A80000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, 0x066204A8);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12, 0x1e701cbf);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, 0x04A80812);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x00000000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x00000000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x00000000);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (csc_mode == VPP_MATRIX_YUV601F_RGB) {
/* ycbcr full range, 601F to RGB */
/* 0 1 0 1.402 0*/
/* -128 1 -0.34414 -0.71414 0*/
/* -128 1 1.772 0 0 */
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, (0x400 << 16) | 0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, (0x59c << 16) | 0x400);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12,
(0x1ea0 << 16) | 0x1d24);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, (0x400 << 16) | 0x718);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x0);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (csc_mode == VPP_MATRIX_YUV709_RGB) {
/* ycbcr limit range, 709 to RGB */
/* -16 1.164 0 1.793 0 */
/* -128 1.164 -0.213 -0.534 0 */
/* -128 1.164 2.115 0 0 */
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, 0x04A80000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, 0x072C04A8);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12, 0x1F261DDD);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, 0x04A80876);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x0);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (csc_mode == VPP_MATRIX_YUV709F_RGB) {
/* ycbcr full range, 709F to RGB */
/* 0 1 0 1.575 0*/
/* -128 1 -0.187 -0.468 0*/
/* -128 1 1.856 0 0 */
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, 0x04000000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, 0x064D0400);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12, 0x1F411E21);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, 0x0400076D);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x0);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (csc_mode == VPP_MATRIX_NULL) {
/* bypass matrix */
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, 0x04000000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, 0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12, 0x04000000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, 0x00000000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x00000400);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x0);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (csc_mode >= VPP_MATRIX_BT2020YUV_BT2020RGB) {
if (vd1_or_vd2_or_post == VPP_MATRIX_VD1) {
/* bt2020 limit to bt2020 RGB */
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, 0x4ad0000);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, 0x6e50492);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12, 0x1f3f1d63);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, 0x492089a);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x0);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
}
if (vd1_or_vd2_or_post == VPP_MATRIX_POST) {
if (csc_mode == VPP_MATRIX_BT2020YUV_BT2020RGB) {
/* 2020 RGB to R'G'B */
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET0_1,
0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET2, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01,
0xd491b4d);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10,
0x1f6b1f01);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12,
0x9101fef);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21,
0x1fdb1f32);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x108f3);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x0);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP,
1, 5, 3);
#if 0 /* disable this case after calculate mtx on the fly*/
} else if (csc_mode == VPP_MATRIX_BT2020RGB_709RGB) {
/*to R'G'B' */
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x0);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0);
/* from Jason */
WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x9cd1e33);
WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x00001faa);
WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x8560000);
WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x1fd81f5f);
WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x108c9);
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x0);
WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x0);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 1, 5, 3);
#endif
} else if (csc_mode == VPP_MATRIX_BT2020RGB_CUSRGB) {
/* customer matrix 2020 RGB to R'G'B' */
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET0_1,
(m->pre_offset[0] << 16)
| (m->pre_offset[1] & 0xffff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET2,
m->pre_offset[2] & 0xffff);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01,
(m->matrix[0][0] << 16)
| (m->matrix[0][1] & 0xffff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10,
(m->matrix[0][2] << 16)
| (m->matrix[1][0] & 0xffff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12,
(m->matrix[1][1] << 16)
| (m->matrix[1][2] & 0xffff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21,
(m->matrix[2][0] << 16)
| (m->matrix[2][1] & 0xffff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22,
(m->right_shift << 16)
| (m->matrix[2][2] & 0xffff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1,
(m->offset[0] << 16)
| (m->offset[1] & 0xffff));
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2,
m->offset[2] & 0xffff);
VSYNC_WR_MPEG_REG_BITS(VPP_MATRIX_CLIP,
m->right_shift, 5, 3);
}
}
}
}
/* matrix betreen xvycclut and linebuffer*/
static uint cur_csc_mode = 0xff;
static void vpp_set_matrix3(
unsigned int on,
enum vpp_matrix_csc_e csc_mode)
{
int reg_value;
reg_value = READ_VPP_REG(VPP_MATRIX_CTRL);
if (on)
mtx_en_mux |= XVY_MTX_EN_MASK;
else
mtx_en_mux &= ~XVY_MTX_EN_MASK;
if (!on)
return;
if (cur_csc_mode == csc_mode)
return;
reg_value = READ_VPP_REG(VPP_MATRIX_CTRL);
VSYNC_WR_MPEG_REG(VPP_MATRIX_CTRL,
(reg_value & (~(7 << 8))) | (3 << 8));
if (csc_mode == VPP_MATRIX_RGB_YUV709F) {
/* RGB -> 709F*/
/*WRITE_VPP_REG(VPP_MATRIX_CTRL, 0x7360);*/
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, 0xda02dc);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, 0x4a1f8a);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12, 0x1e760200);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, 0x2001e2f);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x1fd1);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x200);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x200);
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET2, 0x0);
} else if (csc_mode == VPP_MATRIX_RGB_YUV709) {
/* RGB -> 709 limit */
/*WRITE_VPP_REG(VPP_MATRIX_CTRL, 0x7360);*/
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF00_01, 0x00bb0275);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF02_10, 0x003f1f99);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF11_12, 0x1ea601c2);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF20_21, 0x01c21e67);
VSYNC_WR_MPEG_REG(VPP_MATRIX_COEF22, 0x00001fd7);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET0_1, 0x00400200);
VSYNC_WR_MPEG_REG(VPP_MATRIX_OFFSET2, 0x00000200);
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x0);
VSYNC_WR_MPEG_REG(VPP_MATRIX_PRE_OFFSET2, 0x0);
}
cur_csc_mode = csc_mode;
}
static uint cur_signal_type = 0xffffffff;
module_param(cur_signal_type, uint, 0664);
MODULE_PARM_DESC(cur_signal_type, "\n cur_signal_type\n");
static struct vframe_master_display_colour_s cur_master_display_colour = {
0,
{
{0, 0},
{0, 0},
{0, 0},
},
{0, 0},
{0, 0}
};
#define SIG_CS_CHG 0x01
#define SIG_SRC_CHG 0x02
#define SIG_PRI_INFO 0x04
#define SIG_KNEE_FACTOR 0x08
#define SIG_HDR_MODE 0x10
#define SIG_HDR_SUPPORT 0x20
#define SIG_WB_CHG 0x40
#define SIG_HLG_MODE 0x80
#define SIG_HLG_SUPPORT 0x100
#define SIG_OP_CHG 0x200
#define SIG_SRC_OUTPUT_CHG 0x400/*for box*/
#define SIG_HDR10_PLUS_MODE 0x800
unsigned int pre_vd1_mtx_sel = VPP_MATRIX_NULL;
module_param(pre_vd1_mtx_sel, uint, 0664);
MODULE_PARM_DESC(pre_vd1_mtx_sel, "\n pre_vd1_mtx_sel\n");
unsigned int vd1_mtx_sel = VPP_MATRIX_NULL;
static int src_timing_outputmode_changed(struct vframe_s *vf,
struct vinfo_s *vinfo)
{
unsigned int width, height;
if (vinfo->viu_color_fmt == COLOR_FMT_RGB444)
return 0;
width = (vf->type & VIDTYPE_COMPRESS) ?
vf->compWidth : vf->width;
height = (vf->type & VIDTYPE_COMPRESS) ?
vf->compHeight : vf->height;
if ((height < 720) && (vinfo->height < 720))
vd1_mtx_sel = VPP_MATRIX_NULL;
else if ((height < 720) && (vinfo->height >= 720))
vd1_mtx_sel = VPP_MATRIX_YUV601L_YUV709L;
else if ((height >= 720) && (vinfo->height < 720))
vd1_mtx_sel = VPP_MATRIX_YUV709L_YUV601L;
else if ((height >= 720) && (vinfo->height >= 720))
vd1_mtx_sel = VPP_MATRIX_NULL;
else
vd1_mtx_sel = VPP_MATRIX_NULL;
if (pre_vd1_mtx_sel != vd1_mtx_sel) {
pre_vd1_mtx_sel = vd1_mtx_sel;
return 1;
}
return 0;
}
int signal_type_changed(struct vframe_s *vf, struct vinfo_s *vinfo)
{
u32 signal_type = 0;
u32 default_signal_type;
int change_flag = 0;
int i, j;
struct vframe_master_display_colour_s *p_cur;
struct vframe_master_display_colour_s *p_new;
struct vframe_master_display_colour_s cus;
if (!vf)
return 0;
if ((vf->source_type == VFRAME_SOURCE_TYPE_TUNER) ||
(vf->source_type == VFRAME_SOURCE_TYPE_CVBS) ||
(vf->source_type == VFRAME_SOURCE_TYPE_COMP) ||
(vf->source_type == VFRAME_SOURCE_TYPE_HDMI)) {
if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB)
default_signal_type =
/* default 709 full */
(1 << 29) /* video available */
| (5 << 26) /* unspecified */
| (1 << 25) /* limit */
| (1 << 24) /* color available */
| (1 << 16) /* bt709 */
| (1 << 8) /* bt709 */
| (1 << 0); /* bt709 */
else
default_signal_type =
/* default 709 limit */
(1 << 29) /* video available */
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /* color available */
| (1 << 16) /* bt709 */
| (1 << 8) /* bt709 */
| (1 << 0); /* bt709 */
} else { /* for local play */
if (vf->height >= 720)
default_signal_type =
/* HD default 709 limit */
(1 << 29) /* video available */
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /* color available */
| (1 << 16) /* bt709 */
| (1 << 8) /* bt709 */
| (1 << 0); /* bt709 */
else
default_signal_type =
/* SD default 601 limited */
(1 << 29) /* video available */
| (5 << 26) /* unspecified */
| (0 << 25) /* limited */
| (1 << 24) /* color available */
| (3 << 16) /* bt601 */
| (3 << 8) /* bt601 */
| (3 << 0); /* bt601 */
}
if (vf->signal_type & (1 << 29))
signal_type = vf->signal_type;
else
signal_type = default_signal_type;
p_new = &vf->prop.master_display_colour;
p_cur = &cur_master_display_colour;
/* customer overwrite */
if (customer_master_display_en
&& ((p_new->present_flag & 0x80000000) == 0)) {
signal_type = (1 << 29) /* video available */
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /* color available */
| (9 << 16) /* 2020 */
| (16 << 8) /* 2084 */
| (9 << 0); /* 2020 */
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
cus.primaries[i][j] =
customer_master_display_param[i*2+j];
for (i = 0; i < 2; i++)
cus.white_point[i] =
customer_master_display_param[6+i];
for (i = 0; i < 2; i++)
cus.luminance[i] =
customer_master_display_param[8+i];
cus.present_flag = 1;
p_new = &cus;
}
/* For txhd, must skip HDR process */
if (is_meson_txhd_cpu()) {
if (((signal_type & 0xff) != 1) &&
((signal_type & 0xff) != 3)) {
signal_type &= 0xffffff00;
signal_type |= 0x00000001;
}
if (((signal_type & 0xff00) >> 8 != 1) &&
((signal_type & 0xff00) >> 8 != 3)) {
signal_type &= 0xffff00ff;
signal_type |= 0x00000100;
}
if (((signal_type & 0xff0000) >> 16 != 1) &&
((signal_type & 0xff0000) >> 16 != 3)) {
signal_type &= 0xff00ffff;
signal_type |= 0x00010000;
}
/*pr_err("Signal type changed from 0x%x to 0x%x.\n",*/
/*vf->signal_type, signal_type);*/
}
if (p_new->present_flag & 1) {
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++) {
if (p_cur->primaries[i][j]
!= p_new->primaries[i][j])
change_flag |= SIG_PRI_INFO;
p_cur->primaries[i][j]
= p_new->primaries[i][j];
}
for (i = 0; i < 2; i++) {
if (p_cur->white_point[i]
!= p_new->white_point[i])
change_flag |= SIG_PRI_INFO;
p_cur->white_point[i]
= p_new->white_point[i];
}
for (i = 0; i < 2; i++) {
if (p_cur->luminance[i]
!= p_new->luminance[i])
change_flag |= SIG_PRI_INFO;
p_cur->luminance[i]
= p_new->luminance[i];
}
if (p_cur->content_light_level.present_flag !=
p_new->content_light_level.present_flag) {
change_flag |= SIG_PRI_INFO;
p_cur->content_light_level.present_flag =
p_new->content_light_level.present_flag;
}
if (p_cur->content_light_level.max_content !=
p_new->content_light_level.max_content) {
change_flag |= SIG_PRI_INFO;
p_cur->content_light_level.max_content =
p_new->content_light_level.max_content;
}
if (p_cur->content_light_level.max_pic_average !=
p_new->content_light_level.max_pic_average) {
change_flag |= SIG_PRI_INFO;
p_cur->content_light_level.max_pic_average =
p_new->content_light_level.max_pic_average;
}
if (!p_cur->present_flag) {
p_cur->present_flag = 1;
change_flag |= SIG_PRI_INFO;
}
} else if (p_cur->present_flag) {
p_cur->present_flag = 0;
change_flag |= SIG_PRI_INFO;
}
if (change_flag & SIG_PRI_INFO)
pr_csc("Master_display_colour changed.\n");
if (signal_type != cur_signal_type) {
pr_csc("Signal type changed from 0x%x to 0x%x.\n",
cur_signal_type, signal_type);
change_flag |= SIG_CS_CHG;
cur_signal_type = signal_type;
}
if (pre_src_type != vf->source_type) {
pr_csc("Signal source changed from 0x%x to 0x%x.\n",
pre_src_type, vf->source_type);
change_flag |= SIG_SRC_CHG;
pre_src_type = vf->source_type;
}
if (cur_knee_factor != knee_factor) {
pr_csc("Knee factor changed.\n");
change_flag |= SIG_KNEE_FACTOR;
cur_knee_factor = knee_factor;
}
if (cur_hdr_process_mode != hdr_process_mode) {
pr_csc("HDR mode changed.\n");
change_flag |= SIG_HDR_MODE;
}
if (cur_hlg_process_mode != hlg_process_mode) {
pr_csc("HLG mode changed.\n");
change_flag |= SIG_HLG_MODE;
}
if (cur_sdr_process_mode != sdr_process_mode) {
pr_csc("SDR mode changed.\n");
change_flag |= SIG_HDR_MODE;
}
if (cur_hdr_support != (vinfo->hdr_info.hdr_support & 0x4)) {
pr_csc("Tx HDR support changed.\n");
change_flag |= SIG_HDR_SUPPORT;
cur_hdr_support = vinfo->hdr_info.hdr_support & 0x4;
}
if (cur_output_mode != vinfo->viu_color_fmt) {
pr_csc("output mode changed.\n");
change_flag |= SIG_OP_CHG;
cur_output_mode = vinfo->viu_color_fmt;
}
if (cur_hlg_support != (vinfo->hdr_info.hdr_support & 0x8)) {
pr_csc("Tx HLG support changed.\n");
change_flag |= SIG_HLG_SUPPORT;
cur_hlg_support = vinfo->hdr_info.hdr_support & 0x8;
}
if (cur_hdr10_plus_process_mode != hdr10_plus_process_mode) {
pr_csc("HDR10 plus mode changed.\n");
change_flag |= SIG_HDR10_PLUS_MODE;
cur_hdr10_plus_process_mode = hdr10_plus_process_mode;
}
if ((cur_eye_protect_mode != wb_val[0]) ||
(cur_eye_protect_mode == 1)) {
pr_csc(" eye protect mode changed.\n");
change_flag |= SIG_WB_CHG;
}
if (src_timing_outputmode_changed(vf, vinfo)) {
pr_csc(" source timing output mode changed.\n");
change_flag |= SIG_SRC_OUTPUT_CHG;
}
return change_flag;
}
#define signal_range ((cur_signal_type >> 25) & 1)
#define signal_color_primaries ((cur_signal_type >> 16) & 0xff)
#define signal_transfer_characteristic ((cur_signal_type >> 8) & 0xff)
enum vpp_matrix_csc_e get_csc_type(void)
{
enum vpp_matrix_csc_e csc_type = VPP_MATRIX_NULL;
if ((signal_color_primaries == 1) &&
(signal_transfer_characteristic < 14)) {
if (signal_range == 0)
csc_type = VPP_MATRIX_YUV709_RGB;
else
csc_type = VPP_MATRIX_YUV709F_RGB;
} else if ((signal_color_primaries == 3) &&
(signal_transfer_characteristic < 14)) {
if (signal_range == 0)
csc_type = VPP_MATRIX_YUV601_RGB;
else
csc_type = VPP_MATRIX_YUV601F_RGB;
} else if ((signal_color_primaries == 9) ||
(signal_transfer_characteristic >= 14)) {
if (signal_transfer_characteristic == 16) {
/* smpte st-2084 */
if (signal_color_primaries != 9)
pr_csc("\tWARNING: non-standard HDR!!!\n");
csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB;
} else if (signal_transfer_characteristic == 14) {
/* bt2020-10 */
pr_csc("\tWARNING: bt2020-10 HDR!!!\n");
csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB;
} else if (signal_transfer_characteristic == 15) {
/* bt2020-12 */
pr_csc("\tWARNING: bt2020-12 HDR!!!\n");
if (signal_range == 0)
csc_type = VPP_MATRIX_YUV709_RGB;
else
csc_type = VPP_MATRIX_YUV709F_RGB;
} else if (signal_transfer_characteristic == 18) {
/* bt2020-12 */
pr_csc("\tWARNING: HLG!!!\n");
csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB;
} else if (signal_transfer_characteristic == 0x30) {
pr_csc("\tWARNING: HDR10 PLUS!!!\n");
csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC;
} else {
/* unknown transfer characteristic */
pr_csc("\tWARNING: unknown HDR!!!\n");
if (signal_range == 0)
csc_type = VPP_MATRIX_YUV709_RGB;
else
csc_type = VPP_MATRIX_YUV709F_RGB;
}
} else {
pr_csc("\tWARNING: unsupported colour space!!!\n");
if (signal_range == 0)
csc_type = VPP_MATRIX_YUV601_RGB;
else
csc_type = VPP_MATRIX_YUV601F_RGB;
}
return csc_type;
}
/*hdr10: return 0; hlg: return 1*/
#define HLG_FLAG 0x1
static int get_hdr_type(void)
{
int change_flag = 0;
if ((signal_transfer_characteristic == 18) ||
(signal_transfer_characteristic == 14))
change_flag |= HLG_FLAG;
return change_flag;
}
void get_hdr_source_type(void)
{
if ((signal_transfer_characteristic == 18) ||
(signal_transfer_characteristic == 14))
hdr_source_type = HLG_SOURCE;
else if ((signal_color_primaries == 9) ||
(signal_transfer_characteristic == 16))
hdr_source_type = HDR10_SOURCE;
else
hdr_source_type = SDR_SOURCE;
}
enum color_primary_e get_color_primary(void)
{
enum color_primary_e color_pri;
if (signal_color_primaries == 1)
color_pri = VPP_COLOR_PRI_BT709;
else if (signal_color_primaries == 3)
color_pri = VPP_COLOR_PRI_BT601;
else if (signal_color_primaries == 9)
color_pri = VPP_COLOR_PRI_BT2020;
else
color_pri = VPP_COLOR_PRI_NULL;
return color_pri;
}
static void cal_out_curve(uint panel_luma)
{
int index;
if (panel_luma == 0)
return;
if (panel_luma <= 500) {
if (panel_luma < 250)
panel_luma = 250;
index = (panel_luma - 250) / 20;
} else {
if (panel_luma > 1000)
panel_luma = 1000;
index = ((500 - 260) / 20) + (panel_luma - 500) / 100;
}
memcpy(eotf_33_2084_mapping,
eotf_33_2084_table[index], sizeof(int) * EOTF_LUT_SIZE);
memcpy(oetf_289_gamma22_mapping,
oetf_289_gamma22_table[index],
sizeof(int) * VIDEO_OETF_LUT_SIZE);
}
static void mtx_dot_mul(
int64_t (*a)[3], int64_t (*b)[3],
int64_t (*out)[3], int32_t norm)
{
int i, j;
int64_t tmp;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
tmp = a[i][j] * b[i][j] + (norm >> 1);
out[i][j] = div64_s64(tmp, norm);
}
}
static void mtx_mul(int64_t (*a)[3], int64_t *b, int64_t *out, int32_t norm)
{
int j, k;
int64_t tmp;
for (j = 0; j < 3; j++) {
out[j] = 0;
for (k = 0; k < 3; k++)
out[j] += a[k][j] * b[k];
tmp = out[j] + (norm >> 1);
out[j] = div64_s64(tmp, norm);
}
}
static void mtx_mul_mtx(
int64_t (*a)[3], int64_t (*b)[3],
int64_t (*out)[3], int32_t norm)
{
int i, j, k;
int64_t tmp;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
out[i][j] = 0;
for (k = 0; k < 3; k++)
out[i][j] += a[k][j] * b[i][k];
tmp = out[i][j] + (norm >> 1);
out[i][j] = div64_s64(tmp, norm);
}
}
static void inverse_3x3(
int64_t (*in)[3], int64_t (*out)[3],
int32_t norm, int32_t obl)
{
int i, j;
int64_t determinant = 0;
int64_t tmp;
for (i = 0; i < 3; i++)
determinant +=
in[0][i] * (in[1][(i + 1) % 3] * in[2][(i + 2) % 3]
- in[1][(i + 2) % 3] * in[2][(i + 1) % 3]);
determinant = (determinant + 1) >> 1;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
out[j][i] = (in[(i + 1) % 3][(j + 1) % 3]
* in[(i + 2) % 3][(j + 2) % 3]);
out[j][i] -= (in[(i + 1) % 3][(j + 2) % 3]
* in[(i + 2) % 3][(j + 1) % 3]);
out[j][i] = (out[j][i] * norm) << (obl - 1);
tmp = out[j][i] + (determinant >> 1);
out[j][i] = div64_s64(tmp, determinant);
}
}
}
static void calc_T(
int64_t (*prmy)[2], int64_t (*Tout)[3],
int32_t norm, int32_t obl)
{
int i, j;
int64_t z[4];
int64_t A[3][3];
int64_t B[3];
int64_t C[3];
int64_t D[3][3];
int64_t E[3][3];
int64_t tmp;
for (i = 0; i < 4; i++)
z[i] = norm - prmy[i][0] - prmy[i][1];
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++)
A[i][j] = prmy[i][j];
A[i][2] = z[i];
}
tmp = norm * prmy[3][0] * 2;
tmp = div64_s64(tmp, prmy[3][1]);
B[0] = (tmp + 1) >> 1;
B[1] = norm;
tmp = norm * z[3] * 2;
tmp = div64_s64(tmp, prmy[3][1]);
B[2] = (tmp + 1) >> 1;
inverse_3x3(A, D, norm, obl);
mtx_mul(D, B, C, norm);
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
E[i][j] = C[i];
mtx_dot_mul(A, E, Tout, norm);
}
static void gamut_mtx(
int64_t (*src_prmy)[2], int64_t (*dst_prmy)[2],
int64_t (*Tout)[3], int32_t norm, int32_t obl)
{
int64_t Tsrc[3][3];
int64_t Tdst[3][3];
int64_t out[3][3];
calc_T(src_prmy, Tsrc, norm, obl);
calc_T(dst_prmy, Tdst, norm, obl);
inverse_3x3(Tdst, out, 1 << obl, obl);
mtx_mul_mtx(out, Tsrc, Tout, 1 << obl);
}
static void apply_scale_factor(int64_t (*in)[3], int32_t *rs)
{
int i, j;
int32_t right_shift;
if (display_scale_factor > 2 * 2048)
right_shift = -2;
else if (display_scale_factor > 2048)
right_shift = -1;
else
right_shift = 0;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
in[i][j] *= display_scale_factor;
in[i][j] >>= 11 - right_shift;
}
right_shift += 1;
if (right_shift < 0)
*rs = 8 + right_shift;
else
*rs = right_shift;
}
static void N2C(int64_t (*in)[3], int32_t ibl, int32_t obl)
{
int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
in[i][j] =
(in[i][j] + (1 << (ibl - 12))) >> (ibl - 11);
if (in[i][j] < 0)
in[i][j] += 1 << obl;
}
}
static void cal_mtx_seting(
int64_t (*in)[3],
int32_t ibl, int32_t obl,
struct matrix_s *m)
{
int i, j;
int32_t right_shift;
if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB) {
apply_scale_factor(in, &right_shift);
m->right_shift = right_shift;
}
N2C(in, ibl, obl);
pr_csc("\tHDR color convert matrix:\n");
for (i = 0; i < 3; i++) {
m->pre_offset[i] = 0;
for (j = 0; j < 3; j++)
m->matrix[i][j] = in[j][i];
m->offset[i] = 0;
pr_csc("\t\t%04x %04x %04x\n",
(int)(m->matrix[i][0] & 0xffff),
(int)(m->matrix[i][1] & 0xffff),
(int)(m->matrix[i][2] & 0xffff));
}
}
static int check_primaries(
/* src primaries and white point */
uint (*p)[3][2],
uint (*w)[2],
/* dst display info from vinfo */
const struct vinfo_s *v,
/* prepare src and dst color info array */
int64_t (*si)[4][2], int64_t (*di)[4][2])
{
int i, j;
/* always calculate to apply scale factor */
int need_calculate_mtx = 1;
const struct master_display_info_s *d;
/* check and copy primaries */
if (hdr_flag & 1) {
if (((*p)[0][1] > (*p)[1][1])
&& ((*p)[0][1] > (*p)[2][1])
&& ((*p)[2][0] > (*p)[0][0])
&& ((*p)[2][0] > (*p)[1][0])) {
/* reasonable g,b,r */
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++) {
(*si)[i][j] = (*p)[(i + 2) % 3][j];
if ((*si)[i][j] !=
bt2020_primaries[(i + 2) % 3][j])
need_calculate_mtx = 1;
}
} else if (((*p)[0][0] > (*p)[1][0])
&& ((*p)[0][0] > (*p)[2][0])
&& ((*p)[1][1] > (*p)[0][1])
&& ((*p)[1][1] > (*p)[2][1])) {
/* reasonable r,g,b */
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++) {
(*si)[i][j] = (*p)[i][j];
if ((*si)[i][j] !=
bt2020_primaries[(i + 2) % 3][j])
need_calculate_mtx = 1;
}
} else {
/* source not usable, use standard bt2020 */
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
(*si)[i][j] =
bt2020_primaries
[(i + 2) % 3][j];
}
/* check white point */
if (need_calculate_mtx == 1) {
if (((*w)[0] > (*si)[2][0]) &&
((*w)[0] < (*si)[0][0]) &&
((*w)[1] > (*si)[2][1]) &&
((*w)[1] < (*si)[1][1])) {
for (i = 0; i < 2; i++)
(*si)[3][i] = (*w)[i];
} else {
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
(*si)[i][j] =
bt2020_primaries[(i + 2) % 3][j];
for (i = 0; i < 2; i++)
(*si)[3][i] = bt2020_white_point[i];
/* need_calculate_mtx = 0; */
}
} else {
if (((*w)[0] > (*si)[2][0]) &&
((*w)[0] < (*si)[0][0]) &&
((*w)[1] > (*si)[2][1]) &&
((*w)[1] < (*si)[1][1])) {
for (i = 0; i < 2; i++) {
(*si)[3][i] = (*w)[i];
if ((*si)[3][i] !=
bt2020_white_point[i])
need_calculate_mtx = 1;
}
} else {
for (i = 0; i < 2; i++)
(*si)[3][i] = bt2020_white_point[i];
}
}
} else {
/* use standard bt2020 */
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
(*si)[i][j] = bt2020_primaries[(i + 2) % 3][j];
for (i = 0; i < 2; i++)
(*si)[3][i] = bt2020_white_point[i];
}
/* check display */
if ((v->master_display_info.present_flag) && (hdr_flag & 2)) {
d = &v->master_display_info;
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
(*di)[i][j] = d->primaries[(i + 2) % 3][j];
if ((*di)[i][j] !=
bt709_primaries[(i + 2) % 3][j])
need_calculate_mtx = 1;
}
}
for (i = 0; i < 2; i++) {
(*di)[3][i] = d->white_point[i];
if ((*di)[3][i] != bt709_white_point[i])
need_calculate_mtx = 1;
}
if (v->mode == VMODE_LCD)
cal_out_curve(v->hdr_info.lumi_max);
} else {
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++)
(*di)[i][j] = bt709_primaries[(i + 2) % 3][j];
}
for (i = 0; i < 2; i++)
(*di)[3][i] = bt709_white_point[i];
}
return need_calculate_mtx;
}
enum vpp_matrix_csc_e prepare_customer_matrix(
u32 (*s)[3][2], /* source primaries */
u32 (*w)[2], /* source white point */
const struct vinfo_s *v, /* vinfo carry display primaries */
struct matrix_s *m,
bool inverse_flag)
{
int64_t prmy_src[4][2];
int64_t prmy_dst[4][2];
int64_t out[3][3];
int i, j;
if ((customer_matrix_en &&
get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB)) {
for (i = 0; i < 3; i++) {
m->pre_offset[i] =
customer_matrix_param[i];
for (j = 0; j < 3; j++)
m->matrix[i][j] =
customer_matrix_param[3 + i * 3 + j];
m->offset[i] =
customer_matrix_param[12 + i];
}
m->right_shift =
customer_matrix_param[15];
return VPP_MATRIX_BT2020RGB_CUSRGB;
} else {
if (inverse_flag) {
if (check_primaries(s, w, v, &prmy_src, &prmy_dst)) {
gamut_mtx(prmy_dst, prmy_src, out, INORM, BL);
cal_mtx_seting(out, BL, 13, m);
}
} else {
if (check_primaries(s, w, v, &prmy_src, &prmy_dst)) {
gamut_mtx(prmy_src, prmy_dst, out, INORM, BL);
cal_mtx_seting(out, BL, 13, m);
}
}
return VPP_MATRIX_BT2020RGB_CUSRGB;
}
return VPP_MATRIX_BT2020YUV_BT2020RGB;
}
/* Max luminance lookup table for contrast */
static const int maxLuma_thrd[5] = {512, 1024, 2048, 4096, 8192};
static int calculate_contrast_adj(int max_lumin)
{
int k;
int left, right, norm, alph;
int ratio, target_contrast;
if (max_lumin < maxLuma_thrd[0])
k = 0;
else if (max_lumin < maxLuma_thrd[1])
k = 1;
else if (max_lumin < maxLuma_thrd[2])
k = 2;
else if (max_lumin < maxLuma_thrd[3])
k = 3;
else if (max_lumin < maxLuma_thrd[4])
k = 4;
else
k = 5;
if (k == 0)
ratio = extra_con_lut[0];
else if (k == 5)
ratio = extra_con_lut[4];
else {
left = extra_con_lut[k - 1];
right = extra_con_lut[k];
norm = maxLuma_thrd[k] - maxLuma_thrd[k - 1];
alph = max_lumin - maxLuma_thrd[k - 1];
ratio = left + (alph * (right - left) + (norm >> 1)) / norm;
}
target_contrast = ((vd1_contrast + 1024) * ratio + 64) >> 7;
target_contrast = clip(target_contrast, 0, 2047);
target_contrast -= 1024;
return target_contrast - vd1_contrast;
}
static void print_primaries_info(struct vframe_master_display_colour_s *p)
{
int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
pr_csc(
"\t\tprimaries[%1d][%1d] = %04x\n",
i, j,
p->primaries[i][j]);
pr_csc("\t\twhite_point = (%04x, %04x)\n",
p->white_point[0], p->white_point[1]);
pr_csc("\t\tmax,min luminance = %08x, %08x\n",
p->luminance[0], p->luminance[1]);
}
static void amvecm_cp_hdr_info(struct master_display_info_s *hdr_data,
struct vframe_master_display_colour_s *p)
{
int i, j;
if (customer_hdmi_display_en) {
hdr_data->features =
(1 << 29) /* video available */
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /* color available */
| (customer_hdmi_display_param[0] << 16) /* bt2020 */
| (customer_hdmi_display_param[1] << 8) /* 2084 */
| (10 << 0); /* bt2020c */
memcpy(hdr_data->primaries,
&customer_hdmi_display_param[2],
sizeof(u32)*6);
memcpy(hdr_data->white_point,
&customer_hdmi_display_param[8],
sizeof(u32)*2);
hdr_data->luminance[0] =
customer_hdmi_display_param[10];
hdr_data->luminance[1] =
customer_hdmi_display_param[11];
hdr_data->max_content =
customer_hdmi_display_param[12];
hdr_data->max_frame_average =
customer_hdmi_display_param[13];
} else if ((((hdr_data->features >> 16) & 0xff) == 9) ||
((((hdr_data->features >> 8) & 0xff) >= 14) &&
(((hdr_data->features >> 8) & 0xff) <= 18))) {
if (p->present_flag & 1) {
memcpy(hdr_data->primaries,
p->primaries,
sizeof(u32)*6);
memcpy(hdr_data->white_point,
p->white_point,
sizeof(u32)*2);
hdr_data->luminance[0] =
p->luminance[0];
hdr_data->luminance[1] =
p->luminance[1];
if (p->content_light_level.present_flag == 1) {
hdr_data->max_content =
p->content_light_level.max_content;
hdr_data->max_frame_average =
p->content_light_level.max_pic_average;
} else {
hdr_data->max_content = 0;
hdr_data->max_frame_average = 0;
}
} else {
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
hdr_data->primaries[i][j] =
bt2020_primaries[i][j];
hdr_data->white_point[0] = bt709_white_point[0];
hdr_data->white_point[1] = bt709_white_point[1];
/* default luminance */
hdr_data->luminance[0] = 5000 * 10000;
hdr_data->luminance[1] = 50;
/* content_light_level */
hdr_data->max_content = 0;
hdr_data->max_frame_average = 0;
}
hdr_data->luminance[0] = hdr_data->luminance[0] / 10000;
hdr_data->present_flag = 1;
} else
memset(hdr_data->primaries, 0, sizeof(hdr_data->primaries));
/* hdr send information debug */
memcpy(&dbg_hdr_send, hdr_data,
sizeof(struct master_display_info_s));
}
static void hdr_process_pq_enable(int enable)
{
dnlp_en = enable;
/*cm_en = enable;*/
}
static void vpp_lut_curve_set(enum vpp_lut_sel_e lut_sel,
struct vinfo_s *vinfo)
{
if (lut_sel == VPP_LUT_EOTF) {
/* eotf lut 2048 */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444) {
if (video_lut_swtich == 1)
/*350nit alpha_low = 0.12; */
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_2084_mapping_level1_box, /* R */
eotf_33_2084_mapping_level1_box, /* G */
eotf_33_2084_mapping_level1_box, /* B */
CSC_ON);
else if (video_lut_swtich == 2)
/*800nit alpha_low = 0.12; */
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_2084_mapping_level2_box, /* R */
eotf_33_2084_mapping_level2_box, /* G */
eotf_33_2084_mapping_level2_box, /* B */
CSC_ON);
else if (video_lut_swtich == 3)
/*400nit alpha_low = 0.20; */
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_2084_mapping_level3_box, /* R */
eotf_33_2084_mapping_level3_box, /* G */
eotf_33_2084_mapping_level3_box, /* B */
CSC_ON);
else if (video_lut_swtich == 4)
/*450nit alpha_low = 0.12; */
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_2084_mapping_level4_box, /* R */
eotf_33_2084_mapping_level4_box, /* G */
eotf_33_2084_mapping_level4_box, /* B */
CSC_ON);
else
/* eotf lut 2048 */
/*600nit alpha_low = 0.12;*/
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_2084_mapping_box, /* R */
eotf_33_2084_mapping_box, /* G */
eotf_33_2084_mapping_box, /* B */
CSC_ON);
} else
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_2084_mapping, /* R */
eotf_33_2084_mapping, /* G */
eotf_33_2084_mapping, /* B */
CSC_ON);
} else if (lut_sel == VPP_LUT_OETF) {
/* oetf lut bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444) {
if (video_lut_swtich == 1)
set_vpp_lut(VPP_LUT_OETF,
oetf_289_gamma22_mapping_level1_box,
oetf_289_gamma22_mapping_level1_box,
oetf_289_gamma22_mapping_level1_box,
CSC_ON);
else if (video_lut_swtich == 2)
set_vpp_lut(VPP_LUT_OETF,
oetf_289_gamma22_mapping_level2_box,
oetf_289_gamma22_mapping_level2_box,
oetf_289_gamma22_mapping_level2_box,
CSC_ON);
else if (video_lut_swtich == 3)
set_vpp_lut(VPP_LUT_OETF,
oetf_289_gamma22_mapping_level3_box,
oetf_289_gamma22_mapping_level3_box,
oetf_289_gamma22_mapping_level3_box,
CSC_ON);
else if (video_lut_swtich == 4)
set_vpp_lut(VPP_LUT_OETF,
oetf_289_gamma22_mapping_level4_box,
oetf_289_gamma22_mapping_level4_box,
oetf_289_gamma22_mapping_level4_box,
CSC_ON);
else
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OETF,
oetf_289_gamma22_mapping_box,
oetf_289_gamma22_mapping_box,
oetf_289_gamma22_mapping_box,
CSC_ON);
} else
set_vpp_lut(VPP_LUT_OETF,
oetf_289_gamma22_mapping,
oetf_289_gamma22_mapping,
oetf_289_gamma22_mapping,
CSC_ON);
}
}
static int hdr_process(
enum vpp_matrix_csc_e csc_type,
struct vinfo_s *vinfo,
struct vframe_master_display_colour_s *master_info)
{
int need_adjust_contrast_saturation = 0;
int max_lumin = 10000;
struct matrix_s m = {
{0, 0, 0},
{
{0x0d49, 0x1b4d, 0x1f6b},
{0x1f01, 0x0910, 0x1fef},
{0x1fdb, 0x1f32, 0x08f3},
},
{0, 0, 0},
1
};
struct matrix_s osd_m = {
{0, 0, 0},
{
{0x505, 0x2A2, 0x059},
{0x08E, 0x75B, 0x017},
{0x022, 0x0B4, 0x72A},
},
{0, 0, 0},
1
};
int mtx[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(1.6607056/2), EOTF_COEFF_NORM(-0.5877533/2),
EOTF_COEFF_NORM(-0.0729065/2),
EOTF_COEFF_NORM(-0.1245575/2), EOTF_COEFF_NORM(1.1329346/2),
EOTF_COEFF_NORM(-0.0083771/2),
EOTF_COEFF_NORM(-0.0181122/2), EOTF_COEFF_NORM(-0.1005249/2),
EOTF_COEFF_NORM(1.1186371/2),
EOTF_COEFF_RIGHTSHIFT,
};
int osd_mtx[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(0.627441), EOTF_COEFF_NORM(0.329285),
EOTF_COEFF_NORM(0.043274),
EOTF_COEFF_NORM(0.069092), EOTF_COEFF_NORM(0.919556),
EOTF_COEFF_NORM(0.011322),
EOTF_COEFF_NORM(0.016418), EOTF_COEFF_NORM(0.088058),
EOTF_COEFF_NORM(0.895554),
EOTF_COEFF_RIGHTSHIFT
};
int i, j;
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) {
hdr_func(VD1_HDR, HDR_SDR);
hdr_func(OSD1_HDR, HDR_BYPASS);
return need_adjust_contrast_saturation;
}
if (master_info->present_flag & 1) {
pr_csc("\tMaster_display_colour available.\n");
print_primaries_info(master_info);
/* for VIDEO */
csc_type =
prepare_customer_matrix(
&master_info->primaries,
&master_info->white_point,
vinfo, &m, 0);
/* for OSD */
if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
prepare_customer_matrix(
&master_info->primaries,
&master_info->white_point,
vinfo, &osd_m, 1);
need_adjust_contrast_saturation |= 1;
} else {
/* use bt2020 primaries */
pr_csc("\tNo master_display_colour.\n");
/* for VIDEO */
csc_type =
prepare_customer_matrix(
&bt2020_primaries,
&bt2020_white_point,
vinfo, &m, 0);
/* for OSD */
if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
prepare_customer_matrix(
&bt2020_primaries,
&bt2020_white_point,
vinfo, &osd_m, 1);
}
/************** OSD ***************/
/*vpp matrix mux read*/
vpp_set_mtx_en_read();
if ((get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
&& (csc_en & 0x2)) {
/* RGB to YUV */
/* not using old RGB2YUV convert HW */
/* use new 10bit OSD convert matrix */
/* WRITE_VPP_REG_BITS */
/*(VIU_OSD1_BLK0_CFG_W0,0, 7, 1); */
/* eotf lut 709 */
if (is_hdr_cfg_osd_100() == 1) {
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping_100, /* R */
osd_eotf_33_709_mapping_100, /* G */
osd_eotf_33_709_mapping_100, /* B */
CSC_ON);
} else if ((is_hdr_cfg_osd_100() == 2)) {
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping_290, /* R */
osd_eotf_33_709_mapping_290, /* G */
osd_eotf_33_709_mapping_290, /* B */
CSC_ON);
} else {
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping, /* R */
osd_eotf_33_709_mapping, /* G */
osd_eotf_33_709_mapping, /* B */
CSC_ON);
}
/* eotf matrix 709->2020 */
osd_mtx[EOTF_COEFF_SIZE - 1] = osd_m.right_shift;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
if (osd_m.matrix[i][j] & 0x1000)
osd_mtx[i * 3 + j] =
-(((~osd_m.matrix[i][j]) & 0xfff) + 1);
else
osd_mtx[i * 3 + j] = osd_m.matrix[i][j];
}
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
osd_mtx,
CSC_ON);
/* oetf lut 2084 */
if (is_hdr_cfg_osd_100() == 1) {
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping_100, /* R */
osd_oetf_41_2084_mapping_100, /* G */
osd_oetf_41_2084_mapping_100, /* B */
CSC_ON);
} else if (is_hdr_cfg_osd_100() == 2) {
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping_290, /* R */
osd_oetf_41_2084_mapping_290, /* G */
osd_oetf_41_2084_mapping_290, /* B */
CSC_ON);
} else {
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping, /* R */
osd_oetf_41_2084_mapping, /* G */
osd_oetf_41_2084_mapping, /* B */
CSC_ON);
}
/* osd matrix RGB2020 to YUV2020 limit */
set_vpp_matrix(VPP_MATRIX_OSD,
RGB2020_to_YUV2020l_coeff,
CSC_ON);
}
/************** VIDEO **************/
if ((get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
&& (csc_en & 0x4)) {
/* vd1 matrix bypass */
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF);
/*INV LUT*/
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_OFF);
/* post matrix YUV2020 to RGB2020 */
set_vpp_matrix(VPP_MATRIX_POST,
YUV2020l_to_RGB2020_coeff,
CSC_ON);
/* eotf lut 2048 */
vpp_lut_curve_set(VPP_LUT_EOTF, vinfo);
need_adjust_contrast_saturation = 0;
saturation_offset = 0;
if (hdr_flag & 8) {
need_adjust_contrast_saturation |= 2;
saturation_offset = extra_sat_lut[0];
}
if (master_info->present_flag & 1) {
max_lumin = master_info->luminance[0]
/ 10000;
if ((max_lumin <= 1200) && (max_lumin > 0)) {
if (hdr_flag & 4)
need_adjust_contrast_saturation |= 1;
if (hdr_flag & 8)
saturation_offset =
extra_sat_lut[1];
}
}
/* eotf matrix RGB2020 to RGB709 */
mtx[EOTF_COEFF_SIZE - 1] = m.right_shift;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
if (m.matrix[i][j] & 0x1000)
mtx[i * 3 + j] =
-(((~m.matrix[i][j]) & 0xfff) + 1);
else
mtx[i * 3 + j] = m.matrix[i][j];
}
set_vpp_matrix(VPP_MATRIX_EOTF,
mtx,
CSC_ON);
vpp_lut_curve_set(VPP_LUT_OETF, vinfo);
/* xvyccc matrix3: bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444)
set_vpp_matrix(VPP_MATRIX_XVYCC,
RGB709_to_YUV709l_coeff,
CSC_ON);
}
if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) {
/* turn vd1 matrix on */
vpp_set_matrix(VPP_MATRIX_VD1, CSC_ON,
csc_type, NULL);
/* turn post matrix on */
vpp_set_matrix(VPP_MATRIX_POST, CSC_ON,
csc_type, &m);
/* xvycc lut on */
load_knee_lut(CSC_ON);
vecm_latch_flag |= FLAG_VADJ1_BRI;
hdr_process_pq_enable(0);
/* if GXTVBB HDMI output(YUV) case */
/* xvyccc matrix3: RGB to YUV */
/* other cases */
/* xvyccc matrix3: bypass */
if ((vinfo->viu_color_fmt != COLOR_FMT_RGB444) &&
(get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB))
vpp_set_matrix3(CSC_ON, VPP_MATRIX_RGB_YUV709);
else
vpp_set_matrix3(CSC_OFF, VPP_MATRIX_NULL);
}
/*vpp matrix mux write*/
vpp_set_mtx_en_write();
return need_adjust_contrast_saturation;
}
static int hlg_process(
enum vpp_matrix_csc_e csc_type,
struct vinfo_s *vinfo,
struct vframe_master_display_colour_s *master_info)
{
int need_adjust_contrast_saturation = 0;
int max_lumin = 10000;
struct matrix_s m = {
{0, 0, 0},
{
{0x0d49, 0x1b4d, 0x1f6b},
{0x1f01, 0x0910, 0x1fef},
{0x1fdb, 0x1f32, 0x08f3},
},
{0, 0, 0},
1
};
struct matrix_s osd_m = {
{0, 0, 0},
{
{0x505, 0x2A2, 0x059},
{0x08E, 0x75B, 0x017},
{0x022, 0x0B4, 0x72A},
},
{0, 0, 0},
1
};
int mtx[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(1.6607056/2), EOTF_COEFF_NORM(-0.5877533/2),
EOTF_COEFF_NORM(-0.0729065/2),
EOTF_COEFF_NORM(-0.1245575/2), EOTF_COEFF_NORM(1.1329346/2),
EOTF_COEFF_NORM(-0.0083771/2),
EOTF_COEFF_NORM(-0.0181122/2), EOTF_COEFF_NORM(-0.1005249/2),
EOTF_COEFF_NORM(1.1186371/2),
EOTF_COEFF_RIGHTSHIFT,
};
int osd_mtx[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(0.627441), EOTF_COEFF_NORM(0.329285),
EOTF_COEFF_NORM(0.043274),
EOTF_COEFF_NORM(0.069092), EOTF_COEFF_NORM(0.919556),
EOTF_COEFF_NORM(0.011322),
EOTF_COEFF_NORM(0.016418), EOTF_COEFF_NORM(0.088058),
EOTF_COEFF_NORM(0.895554),
EOTF_COEFF_RIGHTSHIFT
};
int i, j;
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) {
hdr_func(VD1_HDR, HLG_SDR);
hdr_func(OSD1_HDR, HDR_BYPASS);
return need_adjust_contrast_saturation;
}
if (master_info->present_flag & 1) {
pr_csc("\tMaster_display_colour available.\n");
print_primaries_info(master_info);
/* for VIDEO */
csc_type =
prepare_customer_matrix(
&master_info->primaries,
&master_info->white_point,
vinfo, &m, 0);
/* for OSD */
if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
prepare_customer_matrix(
&master_info->primaries,
&master_info->white_point,
vinfo, &osd_m, 1);
need_adjust_contrast_saturation |= 1;
} else {
/* use bt2020 primaries */
pr_csc("\tNo master_display_colour.\n");
/* for VIDEO */
csc_type =
prepare_customer_matrix(
&bt2020_primaries,
&bt2020_white_point,
vinfo, &m, 0);
/* for OSD */
if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
prepare_customer_matrix(
&bt2020_primaries,
&bt2020_white_point,
vinfo, &osd_m, 1);
}
/*vpp matrix mux read*/
vpp_set_mtx_en_read();
if ((get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
&& (csc_en & 0x2)) {
/************** OSD ***************/
/* RGB to YUV */
/* not using old RGB2YUV convert HW */
/* use new 10bit OSD convert matrix */
/* WRITE_VPP_REG_BITS(VIU_OSD1_BLK0_CFG_W0, */
/* 0, 7, 1); */
/* eotf lut 709 */
if (get_hdr_type() & HLG_FLAG)
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_sdr2hlg_mapping, /* R */
osd_eotf_33_sdr2hlg_mapping, /* G */
osd_eotf_33_sdr2hlg_mapping, /* B */
CSC_ON);
else
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping, /* R */
osd_eotf_33_709_mapping, /* G */
osd_eotf_33_709_mapping, /* B */
CSC_ON);
/* eotf matrix 709->2020 */
osd_mtx[EOTF_COEFF_SIZE - 1] = osd_m.right_shift;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
if (osd_m.matrix[i][j] & 0x1000)
osd_mtx[i * 3 + j] =
-(((~osd_m.matrix[i][j]) & 0xfff) + 1);
else
osd_mtx[i * 3 + j] = osd_m.matrix[i][j];
}
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
osd_mtx,
CSC_ON);
/* oetf lut 2084 */
if (get_hdr_type() & HLG_FLAG)
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_sdr2hlg_mapping, /* R */
osd_oetf_41_sdr2hlg_mapping, /* G */
osd_oetf_41_sdr2hlg_mapping, /* B */
CSC_ON);
else
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping, /* R */
osd_oetf_41_2084_mapping, /* G */
osd_oetf_41_2084_mapping, /* B */
CSC_ON);
/* osd matrix RGB2020 to YUV2020 limit */
set_vpp_matrix(VPP_MATRIX_OSD,
RGB2020_to_YUV2020l_coeff,
CSC_ON);
}
/************** VIDEO **************/
if ((get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
&& (csc_en & 0x4)) {
/* vd1 matrix bypass */
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF);
/*eo oo oe*/
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_OFF);
/* post matrix YUV2020 to RGB2020 */
set_vpp_matrix(VPP_MATRIX_POST,
YUV2020l_to_RGB2020_coeff,
CSC_ON);
/* eotf lut 2048 */
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_hlg_mapping, /* R */
eotf_33_hlg_mapping, /* G */
eotf_33_hlg_mapping, /* B */
CSC_ON);
need_adjust_contrast_saturation = 0;
saturation_offset = 0;
if (hdr_flag & 8) {
need_adjust_contrast_saturation |= 2;
saturation_offset = extra_sat_lut[0];
}
if (master_info->present_flag & 1) {
max_lumin = master_info->luminance[0]
/ 10000;
if ((max_lumin <= 1200) && (max_lumin > 0)) {
if (hdr_flag & 4)
need_adjust_contrast_saturation |= 1;
if (hdr_flag & 8)
saturation_offset =
extra_sat_lut[1];
}
}
/* eotf matrix RGB2020 to RGB709 */
mtx[EOTF_COEFF_SIZE - 1] = m.right_shift;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
if (m.matrix[i][j] & 0x1000)
mtx[i * 3 + j] =
-(((~m.matrix[i][j]) & 0xfff) + 1);
else
mtx[i * 3 + j] = m.matrix[i][j];
}
set_vpp_matrix(VPP_MATRIX_EOTF,
mtx,
CSC_ON);
set_vpp_lut(VPP_LUT_OETF,
oetf_289_gamma22_mapping,
oetf_289_gamma22_mapping,
oetf_289_gamma22_mapping,
CSC_ON);
/* xvyccc matrix3: bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444)
set_vpp_matrix(VPP_MATRIX_XVYCC,
RGB709_to_YUV709l_coeff,
CSC_ON);
}
if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) {
/* turn vd1 matrix on */
vpp_set_matrix(VPP_MATRIX_VD1, CSC_ON,
csc_type, NULL);
/* turn post matrix on */
vpp_set_matrix(VPP_MATRIX_POST, CSC_ON,
csc_type, &m);
/* xvycc lut on */
load_knee_lut(CSC_ON);
vecm_latch_flag |= FLAG_VADJ1_BRI;
hdr_process_pq_enable(0);
/* if GXTVBB HDMI output(YUV) case */
/* xvyccc matrix3: RGB to YUV */
/* other cases */
/* xvyccc matrix3: bypass */
if ((vinfo->viu_color_fmt != COLOR_FMT_RGB444) &&
(get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB))
vpp_set_matrix3(CSC_ON, VPP_MATRIX_RGB_YUV709);
else
vpp_set_matrix3(CSC_OFF, VPP_MATRIX_NULL);
}
/*vpp matrix mux write*/
vpp_set_mtx_en_write();
return need_adjust_contrast_saturation;
}
static void bypass_hdr_process(
enum vpp_matrix_csc_e csc_type,
struct vinfo_s *vinfo,
struct vframe_master_display_colour_s *master_info)
{
struct matrix_s osd_m = {
{0, 0, 0},
{
{0x505, 0x2A2, 0x059},
{0x08E, 0x75B, 0x017},
{0x022, 0x0B4, 0x72A},
},
{0, 0, 0},
1
};
int osd_mtx[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(0.627441), EOTF_COEFF_NORM(0.329285),
EOTF_COEFF_NORM(0.043274),
EOTF_COEFF_NORM(0.069092), EOTF_COEFF_NORM(0.919556),
EOTF_COEFF_NORM(0.011322),
EOTF_COEFF_NORM(0.016418), EOTF_COEFF_NORM(0.088058),
EOTF_COEFF_NORM(0.895554),
EOTF_COEFF_RIGHTSHIFT
};
int i, j;
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) {
hdr_func(VD1_HDR, HDR_BYPASS);
if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
((vinfo->hdr_info.hdr_support & 0xc) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
if (get_hdr_type() & HLG_FLAG)
hdr_func(OSD1_HDR, SDR_HLG);
else
hdr_func(OSD1_HDR, SDR_HDR);
pr_csc("\t osd sdr->hdr/hlg\n");
} else
hdr_func(OSD1_HDR, HDR_BYPASS);
return;
}
/*vpp matrix mux read*/
vpp_set_mtx_en_read();
if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB) {
/************** OSD ***************/
/* RGB to YUV */
/* not using old RGB2YUV convert HW */
/* use new 10bit OSD convert matrix */
/* WRITE_VPP_REG_BITS*/
/*(VIU_OSD1_BLK0_CFG_W0,0, 7, 1);*/
if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
((vinfo->hdr_info.hdr_support & 0x4) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
/* OSD convert to HDR to match HDR video */
/* osd eotf lut 709 */
if (get_hdr_type() & HLG_FLAG) {
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_sdr2hlg_mapping, /* R */
osd_eotf_33_sdr2hlg_mapping, /* G */
osd_eotf_33_sdr2hlg_mapping, /* B */
CSC_ON);
} else {
if (is_hdr_cfg_osd_100() == 1) {
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping_100,
osd_eotf_33_709_mapping_100,
osd_eotf_33_709_mapping_100,
CSC_ON);
} else if (is_hdr_cfg_osd_100() == 2) {
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping_290,
osd_eotf_33_709_mapping_290,
osd_eotf_33_709_mapping_290,
CSC_ON);
} else {
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping, /*R*/
osd_eotf_33_709_mapping, /*G*/
osd_eotf_33_709_mapping, /*B*/
CSC_ON);
}
}
/* osd eotf matrix 709->2020 */
if (master_info->present_flag & 1) {
pr_csc("\tMaster_display_colour available.\n");
print_primaries_info(master_info);
prepare_customer_matrix(
&master_info->primaries,
&master_info->white_point,
vinfo, &osd_m, 1);
} else {
pr_csc("\tNo master_display_colour.\n");
prepare_customer_matrix(
&bt2020_primaries,
&bt2020_white_point,
vinfo, &osd_m, 1);
}
osd_mtx[EOTF_COEFF_SIZE - 1] = osd_m.right_shift;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
if (osd_m.matrix[i][j] & 0x1000) {
osd_mtx[i * 3 + j] =
(~osd_m.matrix[i][j]) & 0xfff;
osd_mtx[i * 3 + j] =
-(1 + osd_mtx[i * 3 + j]);
} else
osd_mtx[i * 3 + j] =
osd_m.matrix[i][j];
}
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
osd_mtx,
CSC_ON);
/* osd oetf lut 2084 */
if (get_hdr_type() & HLG_FLAG) {
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_sdr2hlg_mapping, /* R */
osd_oetf_41_sdr2hlg_mapping, /* G */
osd_oetf_41_sdr2hlg_mapping, /* B */
CSC_ON);
} else {
if (is_hdr_cfg_osd_100() == 1) {
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping_100,
osd_oetf_41_2084_mapping_100,
osd_oetf_41_2084_mapping_100,
CSC_ON);
} else if (is_hdr_cfg_osd_100() == 2) {
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping_290,
osd_oetf_41_2084_mapping_290,
osd_oetf_41_2084_mapping_290,
CSC_ON);
} else {
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping,
osd_oetf_41_2084_mapping,
osd_oetf_41_2084_mapping,
CSC_ON);
}
}
/* osd matrix RGB2020 to YUV2020 limit */
set_vpp_matrix(VPP_MATRIX_OSD,
RGB2020_to_YUV2020l_coeff,
CSC_ON);
} else {
/* OSD convert to 709 limited to match SDR video */
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_OSD_EOTF,
eotf_33_linear_mapping, /* R */
eotf_33_linear_mapping, /* G */
eotf_33_linear_mapping, /* B */
CSC_OFF);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
eotf_bypass_coeff,
CSC_OFF);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OSD_OETF,
oetf_41_linear_mapping, /* R */
oetf_41_linear_mapping, /* G */
oetf_41_linear_mapping, /* B */
CSC_OFF);
/* osd matrix RGB709 to YUV709 limit/full */
if (range_control)
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709_coeff,
CSC_ON); /* use full range */
else
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709l_coeff,
CSC_ON); /* use limit range */
}
/************** VIDEO **************/
/* vd1 matrix: bypass */
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF); /* limit->limit range */
else {
if (vinfo->viu_color_fmt == COLOR_FMT_RGB444) {
if (signal_range == 0) {/* limit range */
if (csc_type == VPP_MATRIX_YUV601_RGB)
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
YUV601l_to_YUV709f_coeff :
YUV601l_to_YUV709l_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
YUV709l_to_YUV709f_coeff :
bypass_coeff,
CSC_ON);
} else {
if (csc_type == VPP_MATRIX_YUV601_RGB)
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
YUV601f_to_YUV709f_coeff :
YUV601f_to_YUV709l_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
bypass_coeff :
YUV709f_to_YUV709l_coeff,
CSC_ON);
}
} else {
/*default limit range */
if (vd1_mtx_sel == VPP_MATRIX_NULL)
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF);
else if (vd1_mtx_sel ==
VPP_MATRIX_YUV601L_YUV709L)
set_vpp_matrix(VPP_MATRIX_VD1,
YUV601l_to_YUV709l_coeff,
CSC_ON);
else if (vd1_mtx_sel ==
VPP_MATRIX_YUV709L_YUV601L)
set_vpp_matrix(VPP_MATRIX_VD1,
YUV709l_to_YUV601l_coeff,
CSC_ON);
}
}
/* post matrix bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444)
/* yuv2rgb for eye protect mode */
set_vpp_matrix(VPP_MATRIX_POST,
bypass_coeff,
CSC_OFF);
else {/* matrix yuv2rgb for LCD */
if (range_control)
set_vpp_matrix(VPP_MATRIX_POST,
YUV709f_to_RGB709_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_POST,
YUV709l_to_RGB709_coeff,
CSC_ON);
}
/* xvycc inv lut */
if (sdr_process_mode &&
(csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) &&
((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) ||
(get_cpu_type() == MESON_CPU_MAJOR_ID_TXL)))
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_ON);
else
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_OFF);
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_EOTF,
NULL, /* R */
NULL, /* G */
NULL, /* B */
CSC_OFF);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_EOTF,
eotf_bypass_coeff,
CSC_OFF);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OETF,
NULL,
NULL,
NULL,
CSC_OFF);
/* xvycc matrix full2limit or bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444) {
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)
set_vpp_matrix(VPP_MATRIX_XVYCC,
bypass_coeff,
CSC_OFF);
else {
if (range_control)
set_vpp_matrix(VPP_MATRIX_XVYCC,
YUV709f_to_YUV709l_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_XVYCC,
bypass_coeff,
CSC_OFF);
}
}
} else {
/* OSD */
/* keep RGB */
/* VIDEO */
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) {
/* vd1 matrix: convert YUV to RGB */
csc_type = VPP_MATRIX_YUV709_RGB;
}
/* vd1 matrix on to convert YUV to RGB */
vpp_set_matrix(VPP_MATRIX_VD1, CSC_ON,
csc_type, NULL);
/* post matrix off */
vpp_set_matrix(VPP_MATRIX_POST, CSC_OFF,
csc_type, NULL);
/* xvycc lut off */
load_knee_lut(CSC_OFF);
/* xvycc inv lut */
if (sdr_process_mode)
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_ON);
else
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_OFF);
vecm_latch_flag |= FLAG_VADJ1_BRI;
hdr_process_pq_enable(1);
/* if GXTVBB HDMI output(YUV) case */
/* xvyccc matrix3: RGB to YUV */
/* other cases */
/* xvyccc matrix3: bypass */
if ((vinfo->viu_color_fmt != COLOR_FMT_RGB444) &&
(get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB))
vpp_set_matrix3(CSC_ON, VPP_MATRIX_RGB_YUV709);
else
vpp_set_matrix3(CSC_OFF, VPP_MATRIX_NULL);
}
/*vpp matrix mux write*/
vpp_set_mtx_en_write();
}
static void set_bt2020csc_process(
enum vpp_matrix_csc_e csc_type,
struct vinfo_s *vinfo,
struct vframe_master_display_colour_s *master_info)
{
struct matrix_s osd_m = {
{0, 0, 0},
{
{0x505, 0x2A2, 0x059},
{0x08E, 0x75B, 0x017},
{0x022, 0x0B4, 0x72A},
},
{0, 0, 0},
1
};
int osd_mtx[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(0.627441), EOTF_COEFF_NORM(0.329285),
EOTF_COEFF_NORM(0.043274),
EOTF_COEFF_NORM(0.069092), EOTF_COEFF_NORM(0.919556),
EOTF_COEFF_NORM(0.011322),
EOTF_COEFF_NORM(0.016418), EOTF_COEFF_NORM(0.088058),
EOTF_COEFF_NORM(0.895554),
EOTF_COEFF_RIGHTSHIFT
};
int i, j;
/*vpp matrix mux read*/
vpp_set_mtx_en_read();
if (get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB) {
/************** OSD ***************/
/* RGB to YUV */
/* not using old RGB2YUV convert HW */
/* use new 10bit OSD convert matrix */
/* WRITE_VPP_REG_BITS*/
/*(VIU_OSD1_BLK0_CFG_W0,0, 7, 1);*/
if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
((vinfo->hdr_info.hdr_support & 0x4) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
/* OSD convert to HDR to match HDR video */
/* osd eotf lut 709 */
if (get_hdr_type() & HLG_FLAG)
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_sdr2hlg_mapping, /* R */
osd_eotf_33_sdr2hlg_mapping, /* G */
osd_eotf_33_sdr2hlg_mapping, /* B */
CSC_ON);
else
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping, /* R */
osd_eotf_33_709_mapping, /* G */
osd_eotf_33_709_mapping, /* B */
CSC_ON);
/* osd eotf matrix 709->2020 */
if (master_info->present_flag & 1) {
pr_csc("\tMaster_display_colour available.\n");
print_primaries_info(master_info);
prepare_customer_matrix(
&master_info->primaries,
&master_info->white_point,
vinfo, &osd_m, 1);
} else {
pr_csc("\tNo master_display_colour.\n");
prepare_customer_matrix(
&bt2020_primaries,
&bt2020_white_point,
vinfo, &osd_m, 1);
}
osd_mtx[EOTF_COEFF_SIZE - 1] = osd_m.right_shift;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
if (osd_m.matrix[i][j] & 0x1000) {
osd_mtx[i * 3 + j] =
(~osd_m.matrix[i][j]) & 0xfff;
osd_mtx[i * 3 + j] =
-(1 + osd_mtx[i * 3 + j]);
} else
osd_mtx[i * 3 + j] =
osd_m.matrix[i][j];
}
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
osd_mtx,
CSC_ON);
/* osd oetf lut 2084 */
if (get_hdr_type() & HLG_FLAG)
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_sdr2hlg_mapping, /* R */
osd_oetf_41_sdr2hlg_mapping, /* G */
osd_oetf_41_sdr2hlg_mapping, /* B */
CSC_ON);
else
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping, /* R */
osd_oetf_41_2084_mapping, /* G */
osd_oetf_41_2084_mapping, /* B */
CSC_ON);
/* osd matrix RGB2020 to YUV2020 limit */
set_vpp_matrix(VPP_MATRIX_OSD,
RGB2020_to_YUV2020l_coeff,
CSC_ON);
} else {
/* OSD convert to 709 limited to match SDR video */
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_OSD_EOTF,
eotf_33_linear_mapping, /* R */
eotf_33_linear_mapping, /* G */
eotf_33_linear_mapping, /* B */
CSC_OFF);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
eotf_bypass_coeff,
CSC_OFF);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OSD_OETF,
oetf_41_linear_mapping, /* R */
oetf_41_linear_mapping, /* G */
oetf_41_linear_mapping, /* B */
CSC_OFF);
/* osd matrix RGB709 to YUV709 limit/full */
if (range_control)
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709_coeff,
CSC_ON); /* use full range */
else
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709l_coeff,
CSC_ON); /* use limit range */
}
/************** VIDEO **************/
/* vd1 matrix: bypass */
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF); /* limit->limit range */
else {
if (vinfo->viu_color_fmt == COLOR_FMT_RGB444) {
if (signal_range == 0) {/* limit range */
if (csc_type == VPP_MATRIX_YUV601_RGB)
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
YUV601l_to_YUV709f_coeff :
YUV601l_to_YUV709l_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
YUV709l_to_YUV709f_coeff :
bypass_coeff,
CSC_ON);
} else {
if (csc_type == VPP_MATRIX_YUV601_RGB)
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
YUV601f_to_YUV709f_coeff :
YUV601f_to_YUV709l_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_VD1,
range_control ?
bypass_coeff :
YUV709f_to_YUV709l_coeff,
CSC_ON);
}
} else {
/*default limit range */
if (vd1_mtx_sel == VPP_MATRIX_NULL)
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF);
else if (vd1_mtx_sel ==
VPP_MATRIX_YUV601L_YUV709L)
set_vpp_matrix(VPP_MATRIX_VD1,
YUV601l_to_YUV709l_coeff,
CSC_ON);
else if (vd1_mtx_sel ==
VPP_MATRIX_YUV709L_YUV601L)
set_vpp_matrix(VPP_MATRIX_VD1,
YUV709l_to_YUV601l_coeff,
CSC_ON);
}
}
/* post matrix bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444)
/* yuv2rgb for eye protect mode */
set_vpp_matrix(VPP_MATRIX_POST,
YUV709l_to_YUV2020_coeff,
CSC_ON);
else {/* matrix yuv2rgb for LCD */
if (range_control)
set_vpp_matrix(VPP_MATRIX_POST,
YUV709f_to_RGB709_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_POST,
YUV709l_to_RGB709_coeff,
CSC_ON);
}
/* xvycc inv lut */
if (sdr_process_mode &&
(csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) &&
((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) ||
(get_cpu_type() == MESON_CPU_MAJOR_ID_TXL)))
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_ON);
else
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_OFF);
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_EOTF,
NULL, /* R */
NULL, /* G */
NULL, /* B */
CSC_OFF);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_EOTF,
bypass_coeff,
CSC_OFF);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OETF,
NULL,
NULL,
NULL,
CSC_OFF);
/* xvycc matrix full2limit or bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444) {
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)
set_vpp_matrix(VPP_MATRIX_XVYCC,
bypass_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_XVYCC,
bypass_coeff,
CSC_OFF);
}
} else {
/* OSD */
/* keep RGB */
/* VIDEO */
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) {
/* vd1 matrix: convert YUV to RGB */
csc_type = VPP_MATRIX_YUV709_RGB;
}
/* vd1 matrix on to convert YUV to RGB */
vpp_set_matrix(VPP_MATRIX_VD1, CSC_ON,
csc_type, NULL);
/* post matrix off */
vpp_set_matrix(VPP_MATRIX_POST, CSC_OFF,
csc_type, NULL);
/* xvycc lut off */
load_knee_lut(CSC_OFF);
/* xvycc inv lut */
if (sdr_process_mode)
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_ON);
else
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_OFF);
vecm_latch_flag |= FLAG_VADJ1_BRI;
hdr_process_pq_enable(1);
/* if GXTVBB HDMI output(YUV) case */
/* xvyccc matrix3: RGB to YUV */
/* other cases */
/* xvyccc matrix3: bypass */
if ((vinfo->viu_color_fmt != COLOR_FMT_RGB444) &&
(get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB))
vpp_set_matrix3(CSC_ON, VPP_MATRIX_RGB_YUV709);
else
vpp_set_matrix3(CSC_OFF, VPP_MATRIX_NULL);
}
/*vpp matrix mux write*/
vpp_set_mtx_en_write();
}
static void hlg_hdr_process(
enum vpp_matrix_csc_e csc_type,
struct vinfo_s *vinfo,
struct vframe_master_display_colour_s *master_info)
{
struct matrix_s osd_m = {
{0, 0, 0},
{
{0x505, 0x2A2, 0x059},
{0x08E, 0x75B, 0x017},
{0x022, 0x0B4, 0x72A},
},
{0, 0, 0},
1
};
int osd_mtx[EOTF_COEFF_SIZE] = {
EOTF_COEFF_NORM(0.627441), EOTF_COEFF_NORM(0.329285),
EOTF_COEFF_NORM(0.043274),
EOTF_COEFF_NORM(0.069092), EOTF_COEFF_NORM(0.919556),
EOTF_COEFF_NORM(0.011322),
EOTF_COEFF_NORM(0.016418), EOTF_COEFF_NORM(0.088058),
EOTF_COEFF_NORM(0.895554),
EOTF_COEFF_RIGHTSHIFT
};
int i, j;
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) {
hdr_func(VD1_HDR, HLG_HDR);
hdr_func(OSD1_HDR, SDR_HDR);
return;
}
/*vpp matrix mux read*/
vpp_set_mtx_en_read();
if ((get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
&& (csc_en & 0x2)) {
/************** OSD ***************/
/* RGB to YUV */
/* not using old RGB2YUV convert HW */
/* use new 10bit OSD convert matrix */
/* WRITE_VPP_REG_BITS(VIU_OSD1_BLK0_CFG_W0, */
/* 0, 7, 1); */
if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
((vinfo->hdr_info.hdr_support & 0x4) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
/* OSD convert to HDR to match HDR video */
/* osd eotf lut 709 */
if (get_hdr_type() & HLG_FLAG)
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_sdr2hlg_mapping, /* R */
osd_eotf_33_sdr2hlg_mapping, /* G */
osd_eotf_33_sdr2hlg_mapping, /* B */
CSC_ON);
else
set_vpp_lut(VPP_LUT_OSD_EOTF,
osd_eotf_33_709_mapping, /* R */
osd_eotf_33_709_mapping, /* G */
osd_eotf_33_709_mapping, /* B */
CSC_ON);
/* osd eotf matrix 709->2020 */
if (master_info->present_flag & 1) {
pr_csc("\tMaster_display_colour available.\n");
print_primaries_info(master_info);
prepare_customer_matrix(
&master_info->primaries,
&master_info->white_point,
vinfo, &osd_m, 1);
} else {
pr_csc("\tNo master_display_colour.\n");
prepare_customer_matrix(
&bt2020_primaries,
&bt2020_white_point,
vinfo, &osd_m, 1);
}
osd_mtx[EOTF_COEFF_SIZE - 1] = osd_m.right_shift;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) {
if (osd_m.matrix[i][j] & 0x1000) {
osd_mtx[i * 3 + j] =
(~osd_m.matrix[i][j]) & 0xfff;
osd_mtx[i * 3 + j] =
-(1 + osd_mtx[i * 3 + j]);
} else
osd_mtx[i * 3 + j] =
osd_m.matrix[i][j];
}
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
osd_mtx,
CSC_ON);
/* osd oetf lut 2084 */
if (get_hdr_type() & HLG_FLAG)
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_sdr2hlg_mapping, /* R */
osd_oetf_41_sdr2hlg_mapping, /* G */
osd_oetf_41_sdr2hlg_mapping, /* B */
CSC_ON);
else
set_vpp_lut(VPP_LUT_OSD_OETF,
osd_oetf_41_2084_mapping, /* R */
osd_oetf_41_2084_mapping, /* G */
osd_oetf_41_2084_mapping, /* B */
CSC_ON);
/* osd matrix RGB2020 to YUV2020 limit */
set_vpp_matrix(VPP_MATRIX_OSD,
RGB2020_to_YUV2020l_coeff,
CSC_ON);
} else {
/* OSD convert to 709 limited to match SDR video */
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_OSD_EOTF,
eotf_33_linear_mapping, /* R */
eotf_33_linear_mapping, /* G */
eotf_33_linear_mapping, /* B */
CSC_OFF);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
eotf_bypass_coeff,
CSC_OFF);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OSD_OETF,
oetf_41_linear_mapping, /* R */
oetf_41_linear_mapping, /* G */
oetf_41_linear_mapping, /* B */
CSC_OFF);
/* osd matrix RGB709 to YUV709 limit/full */
if (range_control)
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709_coeff,
CSC_ON); /* use full range */
else
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709l_coeff,
CSC_ON); /* use limit range */
}
}
/************** VIDEO **************/
if ((get_cpu_type() > MESON_CPU_MAJOR_ID_GXTVBB)
&& (csc_en & 0x4)) {
/* vd1 matrix: bypass */
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF); /* limit->limit range */
else {
if (signal_range == 0) /* limit range */
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF);
/* limit->limit range */
else
set_vpp_matrix(VPP_MATRIX_VD1,
YUV709f_to_YUV709l_coeff,
CSC_ON);
}
/*eo oo oe*/
int_lut_sel[0] |= INVLUT_HLG;
set_vpp_lut(VPP_LUT_INV_EOTF,
int_lut_sel,
int_lut_sel,
int_lut_sel,
CSC_ON);
/* post matrix bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444)
/* yuv2rgb for eye protect mode */
set_vpp_matrix(VPP_MATRIX_POST,
YUV2020l_to_RGB2020_coeff,
CSC_ON);
else /* matrix yuv2rgb for LCD */
set_vpp_matrix(VPP_MATRIX_POST,
YUV709l_to_RGB709_coeff,
CSC_ON);
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_hlg_mapping, /* R */
eotf_33_hlg_mapping, /* G */
eotf_33_hlg_mapping, /* B */
CSC_ON);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_EOTF,
eotf_bypass_coeff,
CSC_ON);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OETF,
oetf_289_2084_mapping,
oetf_289_2084_mapping,
oetf_289_2084_mapping,
CSC_ON);
/* xvycc matrix full2limit or bypass */
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444) {
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)
set_vpp_matrix(VPP_MATRIX_XVYCC,
RGB2020_to_YUV2020l_coeff,
CSC_ON);
else {
if (range_control)
set_vpp_matrix(VPP_MATRIX_XVYCC,
YUV709f_to_YUV709l_coeff,
CSC_ON);
else
set_vpp_matrix(VPP_MATRIX_XVYCC,
bypass_coeff,
CSC_OFF);
}
}
} else {
/* OSD */
/* keep RGB */
/* VIDEO */
if (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) {
/* vd1 matrix: convert YUV to RGB */
csc_type = VPP_MATRIX_YUV709_RGB;
}
/* vd1 matrix on to convert YUV to RGB */
vpp_set_matrix(VPP_MATRIX_VD1, CSC_ON,
csc_type, NULL);
/* post matrix off */
vpp_set_matrix(VPP_MATRIX_POST, CSC_OFF,
csc_type, NULL);
/* xvycc lut off */
load_knee_lut(CSC_OFF);
/* xvycc inv lut */
if (sdr_process_mode)
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_ON);
else
set_vpp_lut(VPP_LUT_INV_EOTF,
NULL,
NULL,
NULL,
CSC_OFF);
vecm_latch_flag |= FLAG_VADJ1_BRI;
hdr_process_pq_enable(1);
/* if GXTVBB HDMI output(YUV) case */
/* xvyccc matrix3: RGB to YUV */
/* other cases */
/* xvyccc matrix3: bypass */
if ((vinfo->viu_color_fmt != COLOR_FMT_RGB444) &&
(get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB))
vpp_set_matrix3(CSC_ON, VPP_MATRIX_RGB_YUV709);
else
vpp_set_matrix3(CSC_OFF, VPP_MATRIX_NULL);
}
/*vpp matrix mux write*/
vpp_set_mtx_en_write();
}
static void sdr_hdr_process(
enum vpp_matrix_csc_e csc_type,
struct vinfo_s *vinfo,
struct vframe_master_display_colour_s *master_info)
{
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444) {
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) {
hdr_func(VD1_HDR, SDR_HDR);
hdr_func(OSD1_HDR, SDR_HDR);
return;
}
/*vpp matrix mux read*/
vpp_set_mtx_en_read();
/* OSD convert to 709 limited to match SDR video */
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_OSD_EOTF,
eotf_33_linear_mapping, /* R */
eotf_33_linear_mapping, /* G */
eotf_33_linear_mapping, /* B */
CSC_OFF);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
eotf_bypass_coeff,
CSC_OFF);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OSD_OETF,
oetf_41_linear_mapping, /* R */
oetf_41_linear_mapping, /* G */
oetf_41_linear_mapping, /* B */
CSC_OFF);
/* osd matrix RGB709 to YUV709 limit/full */
if (range_control)
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709_coeff,
CSC_ON); /* use full range */
else
set_vpp_matrix(VPP_MATRIX_OSD,
RGB709_to_YUV709l_coeff,
CSC_ON); /* use limit range */
/************** VIDEO **************/
/* convert SDR Video to HDR */
if (range_control) {
if (signal_range == 0) /* limit range */
set_vpp_matrix(VPP_MATRIX_VD1,
YUV709l_to_YUV709f_coeff,
CSC_ON); /* limit->full range */
else
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF); /* full->full range */
} else {
if (signal_range == 0) /* limit range */
set_vpp_matrix(VPP_MATRIX_VD1,
bypass_coeff,
CSC_OFF); /* limit->limit range */
else
set_vpp_matrix(VPP_MATRIX_VD1,
YUV709f_to_YUV709l_coeff,
CSC_ON); /* full->limit range */
}
set_vpp_matrix(VPP_MATRIX_POST,
YUV709l_to_RGB709_coeff,
CSC_ON);
/* eotf lut bypass */
set_vpp_lut(VPP_LUT_EOTF,
eotf_33_sdr_709_mapping, /* R */
eotf_33_sdr_709_mapping, /* G */
eotf_33_sdr_709_mapping, /* B */
CSC_ON);
/* eotf matrix bypass */
set_vpp_matrix(VPP_MATRIX_EOTF,
eotf_RGB709_to_RGB2020_coeff,
CSC_ON);
/* oetf lut bypass */
set_vpp_lut(VPP_LUT_OETF,
oetf_sdr_2084_mapping,
oetf_sdr_2084_mapping,
oetf_sdr_2084_mapping,
CSC_ON);
/* xvycc matrix bypass */
set_vpp_matrix(VPP_MATRIX_XVYCC,
RGB2020_to_YUV2020l_coeff,
CSC_ON);
/*vpp matrix mux write*/
vpp_set_mtx_en_write();
} else
bypass_hdr_process(csc_type, vinfo, master_info);
}
static int vpp_eye_protection_process(
enum vpp_matrix_csc_e csc_type,
struct vinfo_s *vinfo)
{
cur_eye_protect_mode = wb_val[0];
memcpy(&video_rgb_ogo, wb_val,
sizeof(struct tcon_rgb_ogo_s));
ve_ogo_param_update();
vpp_set_mtx_en_read();
/* only SDR need switch csc */
if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
hdr_process_mode)
return 0;
if ((csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) &&
sdr_process_mode)
return 0;
if (vinfo->viu_color_fmt == COLOR_FMT_RGB444)
return 0;
/* post matrix bypass */
if (cur_eye_protect_mode == 0) {
/* yuv2rgb for eye protect mode */
if (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A)
mtx_setting(POST2_MTX, MATRIX_YUV709_RGB,
MTX_OFF);
else
set_vpp_matrix(VPP_MATRIX_POST,
bypass_coeff,
CSC_ON);
} else {/* matrix yuv2rgb for LCD */
if (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A)
mtx_setting(POST2_MTX, MATRIX_YUV709_RGB,
MTX_ON);
else
set_vpp_matrix(VPP_MATRIX_POST,
YUV709l_to_RGB709_coeff,
CSC_ON);
}
/* xvycc matrix bypass */
if (cur_eye_protect_mode == 1) {
/* for eye protect mode */
if (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) {
if (video_rgb_ogo_xvy_mtx)
video_rgb_ogo_xvy_mtx_latch |=
MTX_RGB2YUVL_RGB_OGO;
} else {
if (video_rgb_ogo_xvy_mtx) {
video_rgb_ogo_xvy_mtx_latch |=
MTX_RGB2YUVL_RGB_OGO;
mtx_en_mux |= XVY_MTX_EN_MASK;
} else
set_vpp_matrix(VPP_MATRIX_XVYCC,
RGB709_to_YUV709l_coeff,
CSC_ON);
}
} else /* matrix yuv2rgb for LCD */
if (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A)
mtx_setting(POST_MTX, MATRIX_RGB_YUV709,
MTX_OFF);
else
set_vpp_matrix(VPP_MATRIX_XVYCC,
bypass_coeff,
CSC_ON);
vpp_set_mtx_en_write();
return 0;
}
static void hdr_support_process(struct vinfo_s *vinfo)
{
/*check if hdmitx support hdr10+*/
if ((vinfo->hdr_info.hdr10plus_info.ieeeoui
== HDR_PLUS_IEEE_OUI) &&
(vinfo->hdr_info.hdr10plus_info.application_version
== 1))
tx_hdr10_plus_support = 1;
else
tx_hdr10_plus_support = 0;
/* check hdr support info from Tx or Panel */
if (hdr_mode == 2) { /* auto */
/*hdr_support & bit2 is hdr10*/
/*hdr_support & bit3 is hlg*/
if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT) &&
(vinfo->hdr_info.hdr_support & HLG_SUPPORT)) {
hdr_process_mode = 0; /* hdr->hdr*/
hlg_process_mode = 0; /* hlg->hlg*/
} else if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT) &&
!(vinfo->hdr_info.hdr_support & HLG_SUPPORT)) {
hdr_process_mode = 0; /* hdr->hdr*/
if (force_pure_hlg)
hlg_process_mode = 0;
else
hlg_process_mode = 1; /* hlg->hdr10*/
} else if (!(vinfo->hdr_info.hdr_support & HDR_SUPPORT) &&
(vinfo->hdr_info.hdr_support & HLG_SUPPORT)) {
hdr_process_mode = 1;
hlg_process_mode = 0;
} else {
hdr_process_mode = 1;
hlg_process_mode = 1;
}
if (tx_hdr10_plus_support)
hdr10_plus_process_mode = 0;
else
hdr10_plus_process_mode = 1;
} else if (hdr_mode == 1) {
hdr_process_mode = 1;
hlg_process_mode = 1;
hdr10_plus_process_mode = 1;
} else {
hdr_process_mode = 0;
if (vinfo->hdr_info.hdr_support & HDR_SUPPORT) {
if ((vinfo->hdr_info.hdr_support & HLG_SUPPORT) ||
(force_pure_hlg))
hlg_process_mode = 0;
else
hlg_process_mode = 1;
} else
hlg_process_mode = 0;
hdr10_plus_process_mode = 0;
}
if (sdr_mode == 2) { /* auto */
if ((vinfo->hdr_info.hdr_support & 0x4) &&
((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444)))
sdr_process_mode = 1; /*box sdr->hdr*/
else if ((vinfo->viu_color_fmt == COLOR_FMT_RGB444) &&
((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) ||
(get_cpu_type() == MESON_CPU_MAJOR_ID_TXL)))
sdr_process_mode = 1; /*tv sdr->hdr*/
else
sdr_process_mode = 0; /* sdr->sdr*/
} else
sdr_process_mode = sdr_mode; /* force sdr->hdr */
}
static void hdr10_plus_metadata_update(struct vframe_s *vf,
enum vpp_matrix_csc_e csc_type,
struct hdr10plus_para *hdmitx_hdr10plus_param)
{
if (!vf)
return;
if (csc_type != VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)
return;
hdr10_plus_parser_metadata(vf);
if (tx_hdr10_plus_support)
hdr10_plus_hdmitx_vsif_parser(hdmitx_hdr10plus_param);
}
static void hdr_tx_pkt_cb(
struct vinfo_s *vinfo,
int signal_change_flag,
enum vpp_matrix_csc_e csc_type,
struct vframe_master_display_colour_s *p,
int *hdmi_scs_type_changed,
struct hdr10plus_para *hdmitx_hdr10plus_param)
{
struct vout_device_s *vdev = NULL;
struct master_display_info_s send_info;
if (vinfo->vout_device)
vdev = vinfo->vout_device;
if ((vinfo->viu_color_fmt != COLOR_FMT_RGB444) &&
((vinfo->hdr_info.hdr_support & 0xc) ||
(signal_change_flag & SIG_HDR_SUPPORT) ||
(signal_change_flag & SIG_HLG_SUPPORT) ||
/*hdr10 plus*/
(tx_hdr10_plus_support) ||
(signal_change_flag & SIG_HDR10_PLUS_MODE))) {
if (sdr_process_mode &&
(csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB)) {
/* sdr source convert to hdr */
/* send hdr info */
/* use the features to discribe source info */
send_info.features =
(0 << 30) /*sdr output 709*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /* color available */
| (9 << 16) /* bt2020 */
| (16 << 8) /* bt2020-10 */
| (10 << 0); /* bt2020c */
amvecm_cp_hdr_info(&send_info, p);
if (vdev) {
if (vdev->fresh_tx_hdr_pkt)
vdev->fresh_tx_hdr_pkt(&send_info);
}
if (hdmi_csc_type != VPP_MATRIX_BT2020YUV_BT2020RGB) {
hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB;
*hdmi_scs_type_changed = 1;
}
} else if ((hdr_process_mode == 0) &&
(hlg_process_mode == 0) &&
(csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)) {
/* source is hdr, send hdr info */
/* use the features to discribe source info */
send_info.features =
(0 << 30) /*sdr output 709*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /*color available*/
/* bt2020 */
| (signal_color_primaries << 16)
/* bt2020-10 */
| (signal_transfer_characteristic << 8)
| (10 << 0); /* bt2020c */
amvecm_cp_hdr_info(&send_info, p);
if (vdev) {
if (vdev->fresh_tx_hdr_pkt)
vdev->fresh_tx_hdr_pkt(&send_info);
}
if (hdmi_csc_type != VPP_MATRIX_BT2020YUV_BT2020RGB) {
hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB;
*hdmi_scs_type_changed = 1;
}
} else if ((hdr_process_mode == 0) &&
(hlg_process_mode == 1) &&
(csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)) {
/* source is hdr, send hdr info */
/* use the features to discribe source info */
if (get_hdr_type() & HLG_FLAG)
send_info.features =
(0 << 30) /*sdr output 709*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /*color available*/
/* bt2020 */
| (9 << 16)
/* bt2020-10 */
| (16 << 8)
| (10 << 0); /* bt2020c */
else
send_info.features =
(0 << 30) /*sdr output 709*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /*color available*/
/* bt2020 */
| (signal_color_primaries << 16)
/* bt2020-10 */
| (signal_transfer_characteristic << 8)
| (10 << 0); /* bt2020c */
amvecm_cp_hdr_info(&send_info, p);
if (vdev) {
if (vdev->fresh_tx_hdr_pkt)
vdev->fresh_tx_hdr_pkt(&send_info);
}
if (hdmi_csc_type != VPP_MATRIX_BT2020YUV_BT2020RGB) {
hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB;
*hdmi_scs_type_changed = 1;
}
} else if ((hdr_process_mode == 1) &&
(hlg_process_mode == 0) &&
(csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)) {
/* source is hdr, send hdr info */
/* use the features to discribe source info */
if (get_hdr_type() & HLG_FLAG)
send_info.features =
(0 << 30) /*sdr output 709*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /*color available*/
/* bt2020 */
| (signal_color_primaries << 16)
/* bt2020-10 */
| (signal_transfer_characteristic << 8)
| (10 << 0); /* bt2020c */
else
send_info.features =
/* default 709 full */
(0 << 30) /*sdr output 709*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /*color available*/
| (1 << 16) /* bt709 */
| (1 << 8) /* bt709 */
| (1 << 0); /* bt709 */
amvecm_cp_hdr_info(&send_info, p);
if (vdev) {
if (vdev->fresh_tx_hdr_pkt)
vdev->fresh_tx_hdr_pkt(&send_info);
}
if (hdmi_csc_type != VPP_MATRIX_BT2020YUV_BT2020RGB) {
hdmi_csc_type = VPP_MATRIX_BT2020YUV_BT2020RGB;
*hdmi_scs_type_changed = 1;
}
} else if ((hdr10_plus_process_mode == 0) &&
(csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)) {
/*source is hdr10 plus, send hdr10 plus info*/
if (vdev) {
if (vdev->fresh_tx_hdr10plus_pkt)
vdev->fresh_tx_hdr10plus_pkt(1,
hdmitx_hdr10plus_param);
}
} else {
/* sdr source send normal info*/
/* use the features to discribe source info */
if (((vinfo->hdr_info.hdr_support & HDR_SUPPORT) |
(vinfo->hdr_info.hdr_support & HLG_SUPPORT)) &&
(csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) &&
tx_op_color_primary)
send_info.features =
/* default 709 limit */
(1 << 30) /*sdr output 2020*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /*color available*/
| (1 << 16) /* bt709 */
| (1 << 8) /* bt709 */
| (1 << 0); /* bt709 */
else
send_info.features =
/* default 709 limit */
(0 << 30) /*sdr output 709*/
| (1 << 29) /*video available*/
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /*color available*/
| (1 << 16) /* bt709 */
| (1 << 8) /* bt709 */
| (1 << 0); /* bt709 */
amvecm_cp_hdr_info(&send_info, p);
if (cur_csc_type <= VPP_MATRIX_BT2020YUV_BT2020RGB) {
if (vdev) {
if (vdev->fresh_tx_hdr_pkt)
vdev->fresh_tx_hdr_pkt(
&send_info);
}
} else if (cur_csc_type ==
VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)
if (vdev) {
if (vdev->fresh_tx_hdr10plus_pkt)
vdev->fresh_tx_hdr10plus_pkt(0,
hdmitx_hdr10plus_param);
}
if (hdmi_csc_type != VPP_MATRIX_YUV709_RGB) {
hdmi_csc_type = VPP_MATRIX_YUV709_RGB;
*hdmi_scs_type_changed = 1;
}
}
}
}
static void video_process(
struct vframe_s *vf,
enum vpp_matrix_csc_e csc_type,
int signal_change_flag,
struct vinfo_s *vinfo,
struct vframe_master_display_colour_s *p)
{
int need_adjust_contrast_saturation = 0;
/* decided by edid or panel info or user setting */
if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
(hdr_process_mode == 1) &&
(hlg_process_mode == 1)) {
/* hdr->sdr hlg->sdr */
if ((signal_change_flag &
(SIG_CS_CHG |
SIG_PRI_INFO |
SIG_KNEE_FACTOR |
SIG_HDR_MODE |
SIG_HDR_SUPPORT |
SIG_HLG_MODE)
) ||
(cur_csc_type <
VPP_MATRIX_BT2020YUV_BT2020RGB)) {
if (get_hdr_type() & HLG_FLAG)
need_adjust_contrast_saturation =
hlg_process(csc_type, vinfo, p);
else
need_adjust_contrast_saturation
= hdr_process(csc_type, vinfo, p);
pr_csc("hdr_process_mode = 0x%x\n"
"hlg_process_mode = 0x%x.\n",
hdr_process_mode, hlg_process_mode);
}
} else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
(hdr_process_mode == 0) &&
(hlg_process_mode == 1)) {
/* hdr->hdr hlg->hlg*/
if ((signal_change_flag &
(SIG_CS_CHG |
SIG_PRI_INFO |
SIG_KNEE_FACTOR |
SIG_HDR_MODE |
SIG_HDR_SUPPORT |
SIG_HLG_MODE)
) ||
(cur_csc_type <
VPP_MATRIX_BT2020YUV_BT2020RGB)) {
if (get_hdr_type() & HLG_FLAG)
hlg_hdr_process(csc_type, vinfo, p);
else
bypass_hdr_process(csc_type, vinfo, p);
pr_csc("hdr_process_mode = 0x%x\n"
"hlg_process_mode = 0x%x.\n",
hdr_process_mode, hlg_process_mode);
}
} else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
(hdr_process_mode == 1) && (hlg_process_mode == 0)) {
/* hdr->sdr hlg->hlg*/
if ((signal_change_flag &
(SIG_CS_CHG |
SIG_PRI_INFO |
SIG_KNEE_FACTOR |
SIG_HDR_MODE |
SIG_HDR_SUPPORT |
SIG_HLG_MODE)
) ||
(cur_csc_type <
VPP_MATRIX_BT2020YUV_BT2020RGB)) {
if (get_hdr_type() & HLG_FLAG)
bypass_hdr_process(csc_type, vinfo, p);
else
need_adjust_contrast_saturation =
hdr_process(csc_type, vinfo, p);
pr_csc("hdr_process_mode = 0x%x\n"
"hlg_process_mode = 0x%x.\n",
hdr_process_mode, hlg_process_mode);
}
} else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
(hdr_process_mode == 0) && (hlg_process_mode == 0)) {
/* hdr->hdr hlg->hlg*/
if ((signal_change_flag &
(SIG_CS_CHG |
SIG_PRI_INFO |
SIG_KNEE_FACTOR |
SIG_HDR_MODE |
SIG_HDR_SUPPORT |
SIG_HLG_MODE)) ||
(cur_csc_type <
VPP_MATRIX_BT2020YUV_BT2020RGB)) {
bypass_hdr_process(csc_type, vinfo, p);
pr_csc("bypass_hdr_process: 0x%x, 0x%x.\n",
hdr_process_mode, hlg_process_mode);
}
} else if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) &&
(hdr10_plus_process_mode == 1)) {
if ((signal_change_flag & SIG_HDR10_PLUS_MODE) ||
(cur_csc_type !=
VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC))
hdr10_plus_process(vf);
pr_csc("hdr10_plus_process.\n");
} else {
if ((csc_type < VPP_MATRIX_BT2020YUV_BT2020RGB) &&
sdr_process_mode)
/* for gxl and gxm SDR to HDR process */
sdr_hdr_process(csc_type, vinfo, p);
else {
/* for gxtvbb and gxl HDR bypass process */
if (((vinfo->hdr_info.hdr_support &
HDR_SUPPORT) ||
(vinfo->hdr_info.hdr_support &
HLG_SUPPORT)) &&
(csc_type <
VPP_MATRIX_BT2020YUV_BT2020RGB)
&& tx_op_color_primary)
set_bt2020csc_process(csc_type,
vinfo, p);
else
bypass_hdr_process(csc_type,
vinfo, p);
pr_csc("csc_type = 0x%x\n"
"sdr_process_mode = 0x%x.\n",
csc_type, sdr_process_mode);
}
}
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) {
if (vinfo->viu_color_fmt != COLOR_FMT_RGB444)
mtx_setting(POST2_MTX, MATRIX_NULL, MTX_OFF);
else
mtx_setting(POST2_MTX,
MATRIX_YUV709_RGB, MTX_ON);
}
if (cur_hdr_process_mode != hdr_process_mode) {
cur_hdr_process_mode = hdr_process_mode;
pr_csc("hdr_process_mode changed to %d",
hdr_process_mode);
}
if (cur_sdr_process_mode != sdr_process_mode) {
cur_sdr_process_mode = sdr_process_mode;
pr_csc("sdr_process_mode changed to %d",
sdr_process_mode);
}
if (cur_hlg_process_mode != hlg_process_mode) {
cur_hlg_process_mode = hlg_process_mode;
pr_csc("hlg_process_mode changed to %d",
hlg_process_mode);
}
if (need_adjust_contrast_saturation & 1) {
if (lut_289_en &&
(get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB))
vd1_contrast_offset = 0;
else
vd1_contrast_offset =
calculate_contrast_adj(p->luminance[0] / 10000);
vecm_latch_flag |= FLAG_VADJ1_CON;
} else {
vd1_contrast_offset = 0;
vecm_latch_flag |= FLAG_VADJ1_CON;
}
if (need_adjust_contrast_saturation & 2) {
vecm_latch_flag |= FLAG_VADJ1_COLOR;
} else {
if (((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) ||
(get_cpu_type() == MESON_CPU_MAJOR_ID_TXL)) &&
(sdr_process_mode == 1))
saturation_offset = sdr_saturation_offset;
else
saturation_offset = 0;
vecm_latch_flag |= FLAG_VADJ1_COLOR;
}
if (cur_csc_type != csc_type) {
pr_csc("CSC from 0x%x to 0x%x.\n",
cur_csc_type, csc_type);
pr_csc("contrast offset = %d.\n",
vd1_contrast_offset);
pr_csc("saturation offset = %d.\n",
saturation_offset);
cur_csc_type = csc_type;
if (vf) {
if ((cur_csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) &&
(cur_csc_type != 0xffff) &&
(vf->source_type == VFRAME_SOURCE_TYPE_HDMI)) {
amvecm_wakeup_queue();
pr_csc("wake up hdr status queue.\n");
}
}
}
}
static int vpp_matrix_update(
struct vframe_s *vf, struct vinfo_s *vinfo, int flags)
{
enum vpp_matrix_csc_e csc_type = VPP_MATRIX_NULL;
int signal_change_flag = 0;
struct vframe_master_display_colour_s *p = &cur_master_display_colour;
int hdmi_scs_type_changed = 0;
struct hdr10plus_para hdmitx_hdr10plus_param;
if (vinfo == NULL)
return 0;
/* Tx hdr information */
memcpy(&receiver_hdr_info, &vinfo->hdr_info,
sizeof(struct hdr_info));
hdr_support_process(vinfo);
if (vf && vinfo)
signal_change_flag = signal_type_changed(vf, vinfo);
if (force_csc_type != 0xff)
csc_type = force_csc_type;
else
csc_type = get_csc_type();
hdr10_plus_metadata_update(vf, csc_type,
&hdmitx_hdr10plus_param);
hdr_tx_pkt_cb(vinfo,
signal_change_flag,
csc_type,
p,
&hdmi_scs_type_changed,
&hdmitx_hdr10plus_param);
if (hdmi_scs_type_changed &&
(flags & CSC_FLAG_CHECK_OUTPUT) &&
csc_en & 0x10)
return 1;
if (((!signal_change_flag) && (force_csc_type == 0xff))
&& ((flags & CSC_FLAG_TOGGLE_FRAME) == 0))
return 0;
if ((cur_csc_type != csc_type)
|| (signal_change_flag
& (SIG_CS_CHG | SIG_PRI_INFO | SIG_KNEE_FACTOR | SIG_HDR_MODE |
SIG_HDR_SUPPORT | SIG_HLG_MODE | SIG_OP_CHG |
SIG_SRC_OUTPUT_CHG | SIG_HDR10_PLUS_MODE)))
video_process(vf, csc_type, signal_change_flag, vinfo, p);
/* eye protection mode */
if (signal_change_flag & SIG_WB_CHG)
vpp_eye_protection_process(csc_type, vinfo);
return 0;
}
static struct vframe_s *last_vf;
static int last_vf_signal_type;
static int null_vf_cnt;
static int prev_hdr_support;
static int prev_output_mode;
static unsigned int fg_vf_sw_dbg;
unsigned int null_vf_max = 1;
module_param(null_vf_max, uint, 0664);
MODULE_PARM_DESC(null_vf_max, "\n null_vf_max\n");
int amvecm_matrix_process(
struct vframe_s *vf, struct vframe_s *vf_rpt, int flags)
{
struct vframe_s fake_vframe;
struct vinfo_s *vinfo = get_current_vinfo();
int toggle_frame;
int i;
if ((get_cpu_type() < MESON_CPU_MAJOR_ID_GXTVBB) ||
is_meson_gxl_package_905M2() || (csc_en == 0))
return 0;
if (reload_mtx) {
for (i = 0; i < NUM_MATRIX; i++)
if (reload_mtx & (1 << i))
set_vpp_matrix(i, NULL, CSC_ON);
}
if (reload_lut) {
for (i = 0; i < NUM_LUT; i++)
if (reload_lut & (1 << i))
set_vpp_lut(i,
NULL, /* R */
NULL, /* G */
NULL, /* B */
CSC_ON);
}
if (is_dolby_vision_on())
return 0;
if (flags & CSC_FLAG_CHECK_OUTPUT) {
if (vpp_matrix_update(vf, vinfo, flags) == 1) {
pr_csc("hdr/sdr output changing ...\n");
return 1;
}
}
if (vf != NULL) {
if (debug_csc & 2)
pr_csc("new frame %x%s\n",
vf->signal_type,
get_video_enabled() ? " " : ", video off");
vpp_matrix_update(vf, vinfo, flags);
last_vf = vf;
last_vf_signal_type = vf->signal_type;
null_vf_cnt = 0;
fg_vf_sw_dbg = 1;
/* debug vframe info backup */
dbg_vf = vf;
} else if (vf_rpt != NULL) {
if (debug_csc & 2)
pr_csc("rpt frame\n");
null_vf_cnt = 0;
fg_vf_sw_dbg = 2;
} else if (get_video_enabled() && (last_vf != NULL)) {
if (debug_csc & 2)
pr_csc("rpt frame local\n");
null_vf_cnt = 0;
fg_vf_sw_dbg = 3;
} else {
/* handle change between TV support/not support HDR */
if (prev_hdr_support != vinfo->hdr_info.hdr_support) {
null_vf_cnt = 0;
prev_hdr_support = vinfo->hdr_info.hdr_support;
}
/* handle change between output mode*/
if (prev_output_mode != vinfo->viu_color_fmt) {
null_vf_cnt = 0;
prev_output_mode = vinfo->viu_color_fmt;
}
/* handle eye protect mode */
if (cur_eye_protect_mode != wb_val[0])
null_vf_cnt = 0;
if (csc_en & 0x10)
toggle_frame = null_vf_max;
else
toggle_frame = 0;
/* when sdr mode change */
if ((vinfo->hdr_info.hdr_support & 0x4) &&
((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444)))
if (((sdr_process_mode != 1) && (sdr_mode > 0))
|| ((sdr_process_mode > 0) && (sdr_mode == 0)))
null_vf_cnt = toggle_frame;
if ((null_vf_cnt == 0) || (null_vf_cnt == toggle_frame)) {
pr_csc("Fake SDR frame\n");
/*send a faked vframe to switch matrix*/
/*from 2020 to 601 when video disabled */
fake_vframe.source_type = VFRAME_SOURCE_TYPE_OTHERS;
fake_vframe.signal_type = 0;
fake_vframe.width = 1920;
fake_vframe.height = 1080;
fake_vframe.prop.master_display_colour.present_flag
= 0x80000000;
if (null_vf_cnt == toggle_frame)
vpp_matrix_update(
&fake_vframe, vinfo,
CSC_FLAG_TOGGLE_FRAME);
else if (null_vf_cnt == 0)
vpp_matrix_update(
&fake_vframe, vinfo,
CSC_FLAG_CHECK_OUTPUT);
last_vf = NULL;
fg_vf_sw_dbg = 4;
dbg_vf = NULL;
}
if (null_vf_cnt <= null_vf_max)
null_vf_cnt++;
}
return 0;
}
int amvecm_hdr_dbg(u32 sel)
{
int i, j;
struct vframe_content_light_level_s *content_light_level;
/* select debug information */
if (sel == 1) /* dump reg */
goto reg_dump;
if (dbg_vf == NULL)
goto hdr_dump;
/*pr_err("----vframe info----\n");*/
/*pr_err("index:%d, type:0x%x, type_backup:0x%x, blend_mode:%d\n",*/
/* dbg_vf->index, dbg_vf->type,*/
/* dbg_vf->type_backup, dbg_vf->blend_mode);*/
/*pr_err("duration:%d, duration_pulldown:%d, pts:%d, flag:0x%x\n",*/
/* dbg_vf->duration, dbg_vf->duration_pulldown,*/
/* dbg_vf->pts, dbg_vf->flag);*/
/*pr_err("canvas0Addr:0x%x, canvas1Addr:0x%x, bufWidth:%d\n",*/
/* dbg_vf->canvas0Addr, dbg_vf->canvas1Addr,*/
/* dbg_vf->bufWidth);*/
/*pr_err("width:%d, height:%d, ratio_control:0x%x, bitdepth:%d\n",*/
/* dbg_vf->width, dbg_vf->height,*/
/* dbg_vf->ratio_control, dbg_vf->bitdepth);*/
/*pr_err("signal_type:%x, orientation:%d, video_angle:0x%x\n",*/
/* dbg_vf->signal_type, dbg_vf->orientation,*/
/* dbg_vf->video_angle);*/
/*pr_err("source_type:%d, phase:%d, soruce_mode:%d, sig_fmt:0x%x\n",*/
/* dbg_vf->source_type, dbg_vf->phase,*/
/* dbg_vf->source_mode, dbg_vf->sig_fmt);*/
/*pr_err(*/
/* "trans_fmt 0x%x, lefteye(%d %d %d %d),*/
/*righteye(%d %d %d %d)\n",*/
/* vf->trans_fmt, vf->left_eye.start_x, vf->left_eye.start_y,*/
/* vf->left_eye.width, vf->left_eye.height,*/
/* vf->right_eye.start_x, vf->right_eye.start_y,*/
/* vf->right_eye.width, vf->right_eye.height);*/
/*pr_err("mode_3d_enable %d",*/
/* vf->mode_3d_enable);*/
/*pr_err("early_process_fun 0x%p, process_fun 0x%p,*/
/*private_data %p\n",*/
/* vf->early_process_fun, vf->process_fun, vf->private_data);*/
/*pr_err("hist_pow %d, luma_sum %d, chroma_sum %d, pixel_sum %d\n",*/
/* vf->prop.hist.hist_pow, vf->prop.hist.luma_sum,*/
/* vf->prop.hist.chroma_sum, vf->prop.hist.pixel_sum);*/
/*pr_err("height %d, width %d, luma_max %d, luma_min %d\n",*/
/* vf->prop.hist.hist_pow, vf->prop.hist.hist_pow,*/
/* vf->prop.hist.hist_pow, vf->prop.hist.hist_pow);*/
/*pr_err("vpp_luma_sum %d, vpp_chroma_sum %d, vpp_pixel_sum %d\n",*/
/* vf->prop.hist.vpp_luma_sum, vf->prop.hist.vpp_chroma_sum,*/
/* vf->prop.hist.vpp_pixel_sum);*/
/*pr_err("vpp_height %d, vpp_width %d, vpp_luma_max %d,*/
/* vpp_luma_min %d\n",*/
/* vf->prop.hist.vpp_height, vf->prop.hist.vpp_width,*/
/* vf->prop.hist.vpp_luma_max, vf->prop.hist.vpp_luma_min);*/
/*pr_err("vs_span_cnt %d, vs_cnt %d, hs_cnt0 %d, hs_cnt1 %d\n",*/
/* vf->prop.meas.vs_span_cnt, vf->prop.meas.vs_cnt,*/
/* vf->prop.meas.hs_cnt0, vf->prop.meas.hs_cnt1);*/
/*pr_err("hs_cnt2 %d, vs_cnt %d, hs_cnt3 %d,*/
/* vs_cycle %d, vs_stamp %d\n",*/
/* vf->prop.meas.hs_cnt2, vf->prop.meas.hs_cnt3,*/
/* vf->prop.meas.vs_cycle, vf->prop.meas.vs_stamp);*/
/*pr_err("pixel_ratio:%d list:%p ready_jiffies64:%lld,*/
/*frame_dirty %d\n",*/
/* dbg_vf->pixel_ratio, &dbg_vf->list,*/
/* dbg_vf->ready_jiffies64, dbg_vf->frame_dirty);*/
pr_err("----Video frame info----\n");
pr_err("bitdepth:0x%x, signal_type:0x%x, present_flag:0x%x\n",
dbg_vf->bitdepth,
dbg_vf->signal_type,
dbg_vf->prop.master_display_colour.present_flag);
if (((dbg_vf->signal_type >> 16) & 0xff) == 9) {
pr_err("HDR color primaries:0x%x\n",
((dbg_vf->signal_type >> 16) & 0xff));
pr_err("HDR transfer_characteristic:0x%x\n",
((dbg_vf->signal_type >> 8) & 0xff));
} else
pr_err("SDR color primaries:0x%x\n", signal_color_primaries);
if (dbg_vf->prop.master_display_colour.present_flag == 1) {
pr_err("----SEI info----\n");
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
pr_err(
"\tprimaries[%1d][%1d] = %04x\n",
i, j,
dbg_vf->prop.master_display_colour.primaries[i][j]);
pr_err("\twhite_point = (%04x, %04x)\n",
dbg_vf->prop.master_display_colour.white_point[0],
dbg_vf->prop.master_display_colour.white_point[1]);
pr_err("\tmax,min luminance = %08x, %08x\n",
dbg_vf->prop.master_display_colour.luminance[0],
dbg_vf->prop.master_display_colour.luminance[1]);
content_light_level =
&dbg_vf->prop.master_display_colour.content_light_level;
pr_err("\tcontent_light_level.present_flag = %08x\n",
content_light_level->present_flag);
pr_err("\tmax_content,min max_pic_average = %08x, %08x\n",
content_light_level->max_content,
content_light_level->max_pic_average);
}
pr_err(HDR_VERSION);
hdr_dump:
pr_err("----HDR process info----\n");
pr_err("customer_master_display_en:0x%x\n", customer_master_display_en);
pr_err("hdr_mode:0x%x, hdr_process_mode:0x%x, cur_hdr_process_mode:0x%x\n",
hdr_mode, hdr_process_mode, cur_hdr_process_mode);
pr_err("hlg_process_mode: 0x%x :0->hlg->hlg,1->hlg->sdr,2->hlg->hdr10\n",
hlg_process_mode);
pr_err("sdr_mode:0x%x, sdr_process_mode:0x%x, cur_sdr_process_mode:0x%x\n",
sdr_mode, sdr_process_mode, cur_sdr_process_mode);
pr_err("hdr_flag:0x%x, fg_vf_sw_dbg:0x%x\n",
hdr_flag, fg_vf_sw_dbg);
pr_err("cur_signal_type:0x%x, cur_csc_mode:0x%x, cur_csc_type:0x%x\n",
cur_signal_type, cur_csc_mode, cur_csc_type);
pr_err("knee_lut_on:0x%x,knee_interpolation_mode:0x%x,cur_knee_factor:0x%x\n",
knee_lut_on, knee_interpolation_mode, cur_knee_factor);
pr_err("tx_hdr10_plus_support = 0x%x\n", tx_hdr10_plus_support);
pr_err("hdr10_plus_process_mode = 0x%x\n", hdr10_plus_process_mode);
//if (signal_transfer_characteristic == 0x30)
if (cur_csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)
hdr10_plus_debug();
if ((receiver_hdr_info.hdr_support & 0xc) == 0)
goto dbg_end;
pr_err("----TV EDID info----\n");
pr_err("hdr_support:0x%x, lumi_max:%d, lumi_avg:%d, lumi_min:%d\n",
receiver_hdr_info.hdr_support,
receiver_hdr_info.lumi_max,
receiver_hdr_info.lumi_avg,
receiver_hdr_info.lumi_min);
pr_err("----Tx HDR package info----\n");
pr_err("\tfeatures = 0x%08x\n", dbg_hdr_send.features);
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
pr_err(
"\tprimaries[%1d][%1d] = %04x\n",
i, j,
dbg_hdr_send.primaries[i][j]);
pr_err("\twhite_point = (%04x, %04x)\n",
dbg_hdr_send.white_point[0],
dbg_hdr_send.white_point[1]);
pr_err("\tmax,min luminance = %08x, %08x\n",
dbg_hdr_send.luminance[0], dbg_hdr_send.luminance[1]);
goto dbg_end;
/************************dump reg start***************************/
reg_dump:
/* osd matrix, VPP_MATRIX_0 */
pr_err("----dump regs VPP_MATRIX_OSD----\n");
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_PRE_OFFSET0_1,
READ_VPP_REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_PRE_OFFSET2,
READ_VPP_REG(VIU_OSD1_MATRIX_PRE_OFFSET2));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF00_01,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF00_01));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF02_10,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF02_10));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF11_12,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF11_12));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF20_21,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF20_21));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF22_30,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF22_30));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF31_32,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF31_32));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF40_41,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF40_41));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COLMOD_COEF42,
READ_VPP_REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COEF22_30,
READ_VPP_REG(VIU_OSD1_MATRIX_COEF22_30));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_OFFSET0_1,
READ_VPP_REG(VIU_OSD1_MATRIX_OFFSET0_1));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_OFFSET2,
READ_VPP_REG(VIU_OSD1_MATRIX_OFFSET2));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COLMOD_COEF42,
READ_VPP_REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_COLMOD_COEF42,
READ_VPP_REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_PRE_OFFSET0_1,
READ_VPP_REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_MATRIX_CTRL,
READ_VPP_REG(VIU_OSD1_MATRIX_CTRL));
/* osd eotf matrix, VPP_MATRIX_OSD_EOTF */
pr_err("----dump regs VPP_MATRIX_OSD_EOTF----\n");
for (i = 0; i < 5; i++)
pr_err("\taddr = %08x, val = %08x\n",
(VIU_OSD1_EOTF_CTL + i + 1),
READ_VPP_REG(VIU_OSD1_EOTF_CTL + i + 1));
pr_err("\taddr = %08x, val = %08x\n",
VIU_OSD1_EOTF_CTL,
READ_VPP_REG(VIU_OSD1_EOTF_CTL));
{
unsigned short r_map[VIDEO_OETF_LUT_SIZE];
unsigned short g_map[VIDEO_OETF_LUT_SIZE];
unsigned short b_map[VIDEO_OETF_LUT_SIZE];
unsigned int addr_port;
unsigned int data_port;
unsigned int ctrl_port;
unsigned int data;
int i;
pr_err("----dump regs VPP_LUT_OSD_OETF----\n");
addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
ctrl_port = VIU_OSD1_OETF_CTL;
pr_err("\taddr = %08x, val = %08x\n",
ctrl_port, READ_VPP_REG(ctrl_port));
for (i = 0; i < 20; i++) {
WRITE_VPP_REG(addr_port, i);
data = READ_VPP_REG(data_port);
r_map[i * 2] = data & 0xffff;
r_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
WRITE_VPP_REG(addr_port, 20);
data = READ_VPP_REG(data_port);
r_map[OSD_OETF_LUT_SIZE - 1] = data & 0xffff;
g_map[0] = (data >> 16) & 0xffff;
for (i = 0; i < 20; i++) {
WRITE_VPP_REG(addr_port, 21 + i);
data = READ_VPP_REG(data_port);
g_map[i * 2 + 1] = data & 0xffff;
g_map[i * 2 + 2] = (data >> 16) & 0xffff;
}
for (i = 0; i < 20; i++) {
WRITE_VPP_REG(addr_port, 41 + i);
data = READ_VPP_REG(data_port);
b_map[i * 2] = data & 0xffff;
b_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
WRITE_VPP_REG(addr_port, 61);
data = READ_VPP_REG(data_port);
b_map[OSD_OETF_LUT_SIZE - 1] = data & 0xffff;
for (i = 0; i < OSD_OETF_LUT_SIZE; i++) {
pr_err("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i, r_map[i], g_map[i], b_map[i]);
}
addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
ctrl_port = VIU_OSD1_EOTF_CTL;
pr_err("----dump regs VPP_LUT_OSD_EOTF----\n");
WRITE_VPP_REG(addr_port, 0);
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
r_map[i * 2] = data & 0xffff;
r_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
data = READ_VPP_REG(data_port);
r_map[EOTF_LUT_SIZE - 1] = data & 0xffff;
g_map[0] = (data >> 16) & 0xffff;
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
g_map[i * 2 + 1] = data & 0xffff;
g_map[i * 2 + 2] = (data >> 16) & 0xffff;
}
for (i = 0; i < 16; i++) {
data = READ_VPP_REG(data_port);
b_map[i * 2] = data & 0xffff;
b_map[i * 2 + 1] = (data >> 16) & 0xffff;
}
data = READ_VPP_REG(data_port);
b_map[EOTF_LUT_SIZE - 1] = data & 0xffff;
for (i = 0; i < EOTF_LUT_SIZE; i++) {
pr_err("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i, r_map[i], g_map[i], b_map[i]);
}
pr_err("----dump hdr_osd_reg structure ----\n");
pr_err("\tviu_osd1_matrix_ctrl = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_ctrl);
pr_err("\tviu_osd1_matrix_coef00_01 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_coef00_01);
pr_err("\tviu_osd1_matrix_coef02_10 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_coef02_10);
pr_err("\tviu_osd1_matrix_coef11_12 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_coef11_12);
pr_err("\tviu_osd1_matrix_coef20_21 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_coef20_21);
pr_err("\tviu_osd1_matrix_colmod_coef42 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_colmod_coef42);
pr_err("\tviu_osd1_matrix_offset0_1 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_offset0_1);
pr_err("\tviu_osd1_matrix_offset2 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_offset2);
pr_err("\tviu_osd1_matrix_pre_offset0_1 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_pre_offset0_1);
pr_err("\tviu_osd1_matrix_pre_offset2 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_pre_offset2);
pr_err("\tviu_osd1_matrix_coef22_30 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_coef22_30);
pr_err("\tviu_osd1_matrix_coef31_32 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_coef31_32);
pr_err("\tviu_osd1_matrix_coef40_41 = 0x%04x\n",
hdr_osd_reg.viu_osd1_matrix_coef40_41);
pr_err("\tviu_osd1_eotf_ctl = 0x%04x\n",
hdr_osd_reg.viu_osd1_eotf_ctl);
pr_err("\tviu_osd1_eotf_coef00_01 = 0x%04x\n",
hdr_osd_reg.viu_osd1_eotf_coef00_01);
pr_err("\tviu_osd1_eotf_coef02_10 = 0x%04x\n",
hdr_osd_reg.viu_osd1_eotf_coef02_10);
pr_err("\tviu_osd1_eotf_coef11_12 = 0x%04x\n",
hdr_osd_reg.viu_osd1_eotf_coef11_12);
pr_err("\tviu_osd1_eotf_coef20_21 = 0x%04x\n",
hdr_osd_reg.viu_osd1_eotf_coef20_21);
pr_err("\tviu_osd1_eotf_coef22_rs = 0x%04x\n",
hdr_osd_reg.viu_osd1_eotf_coef22_rs);
pr_err("\tviu_osd1_oetf_ctl = 0x%04x\n",
hdr_osd_reg.viu_osd1_oetf_ctl);
for (i = 0; i < EOTF_LUT_SIZE; i++) {
pr_err("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i,
hdr_osd_reg.lut_val.r_map[i],
hdr_osd_reg.lut_val.g_map[i],
hdr_osd_reg.lut_val.b_map[i]);
}
for (i = 0; i < OSD_OETF_LUT_SIZE; i++) {
pr_err("\t[%d] = 0x%04x 0x%04x 0x%04x\n",
i,
hdr_osd_reg.lut_val.or_map[i],
hdr_osd_reg.lut_val.og_map[i],
hdr_osd_reg.lut_val.ob_map[i]);
}
pr_err("\n");
}
pr_err("----dump regs VPP_LUT_EOTF----\n");
print_vpp_lut(VPP_LUT_EOTF, READ_VPP_REG(VIU_EOTF_CTL) & (7 << 27));
pr_err("----dump regs VPP_LUT_OETF----\n");
print_vpp_lut(VPP_LUT_OETF, READ_VPP_REG(XVYCC_LUT_CTL) & 0x7f);
/*********************dump reg end*********************/
dbg_end:
return 0;
}