module_param(dolby_vision_flags, uint, 0664);
MODULE_PARM_DESC(dolby_vision_flags, "\n dolby_vision_flags\n");
+#define DV_NAME_LEN_MAX 32
+
static unsigned int htotal_add = 0x140;
static unsigned int vtotal_add = 0x40;
static unsigned int vsize_add;
static bool dolby_vision_on;
static bool dolby_vision_core1_on;
static bool dolby_vision_wait_on;
+static bool dolby_vision_on_in_uboot;
static bool dolby_vision_wait_init;
static unsigned int frame_count;
static struct hdr10_param_s hdr10_param;
0x80200);
/* osd rgb to yuv, vpp out yuv to rgb */
VSYNC_WR_DV_REG(VPP_MATRIX_CTRL, 0x81);
- pr_dolby_dbg("Dolby Vision TV core turn on\n");
+ pr_info("Dolby Vision TV core turn on\n");
} else if (is_meson_txlx_stbmode()
|| force_stb_mode) {
size = 8 * STB_DMA_TBL_SIZE;
last_dolby_vision_ll_policy =
dolby_vision_ll_policy;
#endif
- pr_dolby_dbg("Dolby Vision STB cores turn on\n");
+ pr_info("Dolby Vision STB cores turn on\n");
} else if (is_meson_g12() || is_meson_tm2_stbmode()) {
hdr_osd_off();
hdr_vd1_off();
last_dolby_vision_ll_policy =
dolby_vision_ll_policy;
#endif
- pr_dolby_dbg("Dolby Vision G12a turn on\n");
+ pr_info("Dolby Vision G12a turn on\n");
} else {
VSYNC_WR_DV_REG(VPP_DOLBY_CTRL,
/* cm_datx4_mode */
last_dolby_vision_ll_policy =
dolby_vision_ll_policy;
#endif
- pr_dolby_dbg("Dolby Vision turn on\n");
+ pr_info("Dolby Vision turn on\n");
}
} else {
if (!dolby_vision_core1_on
core1_disp_vsize = 0;
dolby_vision_on = false;
force_reset_core2 = true;
+ dolby_vision_on_in_uboot = false;
dolby_vision_core1_on = false;
dolby_vision_wait_on = false;
dolby_vision_wait_init = false;
mode_change = 0;
return mode_change;
}
-
if (((src_format == FORMAT_HLG) ||
(src_format == FORMAT_HDR10PLUS))
&& !(dolby_vision_hdr10_policy & 4)) {
/* TV support DOVI, All -> DOVI */
if (dolby_vision_mode !=
DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) {
- pr_dolby_dbg("src=%d, dovi output -> DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL\n",
+ pr_info("src=%d, dovi output -> DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL\n",
src_format);
*mode = DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL;
mode_change = 1;
/* TV support HDR, All -> HDR */
if (dolby_vision_mode !=
DOLBY_VISION_OUTPUT_MODE_HDR10) {
- pr_dolby_dbg("src=%d, dovi output -> DOLBY_VISION_OUTPUT_MODE_HDR10\n",
+ pr_info("src=%d, dovi output -> DOLBY_VISION_OUTPUT_MODE_HDR10\n",
src_format);
*mode = DOLBY_VISION_OUTPUT_MODE_HDR10;
mode_change = 1;
}
EXPORT_SYMBOL(dolby_vision_process);
+/* when dolby on in uboot, other module cannot get dolby status
+ * in time through dolby_vision_on due to dolby_vision_on
+ * is set in register_dv_functions
+ * Add dolby_vision_on_in_uboot condition for this case.
+ */
bool is_dolby_vision_on(void)
{
return dolby_vision_on
- || dolby_vision_wait_on;
+ || dolby_vision_wait_on
+ || dolby_vision_on_in_uboot;
}
EXPORT_SYMBOL(is_dolby_vision_on);
}
EXPORT_SYMBOL(is_dolby_vision_video_on);
-
bool for_dolby_vision_certification(void)
{
return is_dolby_vision_on() &&
unsigned int reg_clk;
unsigned int reg_value;
struct pq_config_s *pq_config;
+ const struct vinfo_s *vinfo = get_current_vinfo();
+
+ /*when dv ko load into kernel, this flag will be disabled
+ *otherwise it will effect hdr module
+ */
+ if (dolby_vision_on_in_uboot) {
+ if (is_vinfo_available(vinfo)) {
+ is_sink_cap_changed(vinfo);
+ dolby_vision_on = true;
+ } else
+ pr_info("sink not available\n");
+ dolby_vision_wait_on = false;
+ dolby_vision_wait_init = false;
+ dolby_vision_on_in_uboot = 0;
+ }
if ((!p_funcs_stb || !p_funcs_tv) && func) {
if (func->control_path && !p_funcs_stb) {
"SDR8",
"BYPASS"
};
+unsigned int dolby_vision_check_enable(void)
+{
+ int dv_mode = 0;
+ /*check if dovi enable in uboot*/
+ if (is_meson_g12()) {
+ if (dolby_vision_on_in_uboot) {
+ dolby_vision_enable = 1;
+ if ((READ_VPP_DV_REG(DOLBY_CORE3_DIAG_CTRL) & 0xff)
+ == 0x20) {
+ /*LL YUV422 mode*/
+ dv_mode = dv_mode_table[1];
+ /*set_dolby_vision_mode(dv_mode);*/
+ dolby_vision_mode = dv_mode;
+ dolby_vision_ll_policy = DOLBY_VISION_LL_YUV422;
+ pr_info("dovi enable in uboot and mode is LL 422\n");
+ } else if ((READ_VPP_DV_REG(DOLBY_CORE3_DIAG_CTRL)
+ & 0xff) == 0x3) {
+ /*LL RGB444 mode*/
+ dv_mode = dv_mode_table[1];
+ /*set_dolby_vision_mode(dv_mode);*/
+ dolby_vision_mode = dv_mode;
+ dolby_vision_ll_policy = DOLBY_VISION_LL_RGB444;
+ pr_info("dovi enable in uboot and mode is LL RGB\n");
+ } else {
+ if (READ_VPP_DV_REG(DOLBY_CORE3_REG_START + 1)
+ == 2) {
+ /*HDR10 mode*/
+ dolby_vision_hdr10_policy = 1;
+ dv_mode = dv_mode_table[3];
+ /*set_dolby_vision_mode(dv_mmde);*/
+ dolby_vision_mode = dv_mode;
+ pr_info("dovi enable in uboot and mode is HDR10\n");
+ } else if (READ_VPP_DV_REG(DOLBY_CORE3_REG_START
+ + 1) == 4) {
+ /*SDR mode*/
+ dv_mode = dv_mode_table[4];
+ /*set_dolby_vision_mode(dv_mode);*/
+ dolby_vision_mode = dv_mode;
+ pr_info("dovi enable in uboot and mode is SDR\n");
+ } else {
+ /*STANDARD RGB444 mode*/
+ dv_mode = dv_mode_table[2];
+ /*set_dolby_vision_mode(dv_mode);*/
+ dolby_vision_mode = dv_mode;
+ dolby_vision_ll_policy =
+ DOLBY_VISION_LL_DISABLE;
+ pr_info("dovi enable in uboot and mode is DV ST\n");
+ }
+ }
+ } else
+ pr_info("dovi disable in uboot\n");
+ }
+
+ return 0;
+}
static ssize_t amdolby_vision_dv_mode_show(struct class *cla,
struct class_attribute *attr, char *buf)
dolby_vision_init_receiver(pdev);
init_waitqueue_head(&devp->dv_queue);
pr_info("%s: ok\n", __func__);
+ dolby_vision_check_enable();
return 0;
fail_create_device:
.remove = __exit_p(amdolby_vision_remove),
};
+static int __init get_dolby_uboot_status(char *str)
+{
+ char uboot_dolby_status[DV_NAME_LEN_MAX] = {0};
+
+ snprintf(uboot_dolby_status, DV_NAME_LEN_MAX, "%s", str);
+ pr_info("get_dolby_on: %s\n", uboot_dolby_status);
+
+ if (!strcmp(uboot_dolby_status, "1"))
+ dolby_vision_on_in_uboot = 1;
+ return 0;
+}
+__setup("dolby_vision_on=", get_dolby_uboot_status);
+
static int __init amdolby_vision_init(void)
{
pr_info("%s:module init\n", __func__);
static void Edid_DTD_parsing(struct rx_cap *pRXCap, unsigned char *data);
static void hdmitx_edid_set_default_aud(struct hdmitx_dev *hdev);
-static void edid_save_checkvalue(unsigned char *buf, unsigned int block_cnt)
+static int xtochar(int num, unsigned char *checksum)
+{
+ if (((edid_checkvalue[num] >> 4) & 0xf) <= 9)
+ checksum[0] = ((edid_checkvalue[num] >> 4) & 0xf) + '0';
+ else
+ checksum[0] = ((edid_checkvalue[num] >> 4) & 0xf) - 10 + 'a';
+
+ if ((edid_checkvalue[num] & 0xf) <= 9)
+ checksum[1] = (edid_checkvalue[num] & 0xf) + '0';
+ else
+ checksum[1] = (edid_checkvalue[num] & 0xf) - 10 + 'a';
+
+ return 0;
+}
+
+static void edid_save_checkvalue(unsigned char *buf, unsigned int block_cnt,
+ struct rx_cap *RXCap)
{
unsigned int i, length, max;
for (i = 0; i < max; i++)
edid_checkvalue[i] = *(buf+(i+1)*128-1);
+
+ RXCap->chksum[0] = '0';
+ RXCap->chksum[1] = 'x';
+
+ for (i = 0; i < 4; i++)
+ xtochar(i, &RXCap->chksum[2 * i + 2]);
}
static int Edid_DecodeHeader(struct hdmitx_info *info, unsigned char *buff)
if ((!pRXCap->AUD_count) && (!pRXCap->ieeeoui))
hdmitx_edid_set_default_aud(hdmitx_device);
- edid_save_checkvalue(EDID_buf, BlockCount+1);
+ edid_save_checkvalue(EDID_buf, BlockCount + 1, pRXCap);
i = hdmitx_edid_dump(hdmitx_device, (char *)(hdmitx_device->tmp_buf),
HDMI_TMP_BUF_SIZE);
/* update RX HDR information */
info = get_current_vinfo();
if (info) {
+ /*update hdmi checksum to vout*/
+ memcpy(info->hdmichecksum, pRXCap->chksum, 10);
if (!((strncmp(info->name, "480cvbs", 7) == 0) ||
(strncmp(info->name, "576cvbs", 7) == 0) ||
(strncmp(info->name, "null", 4) == 0))) {
static char cvbsmode[VMODE_NAME_LEN_MAX] = {
'i', 'n', 'v', 'a', 'l', 'i', 'd', '\0'
};
+static char hdmichecksum[VMODE_NAME_LEN_MAX] = {
+ 'i', 'n', 'v', 'a', 'l', 'i', 'd', 'c', 'r', 'c', '\0'
+};
+static char invalidchecksum[VMODE_NAME_LEN_MAX] = {
+ 'i', 'n', 'v', 'a', 'l', 'i', 'd', 'c', 'r', 'c', '\0'
+};
+static char emptychecksum[VMODE_NAME_LEN_MAX] = {0};
+
static enum vmode_e last_vmode = VMODE_MAX;
static int tvout_monitor_flag = 1;
static unsigned int tvout_monitor_timeout_cnt = 20;
enum vmode_e cur_vmode = VMODE_MAX;
char cur_mode_str[VMODE_NAME_LEN_MAX];
int hpd_state = 0;
+ struct vinfo_s *info = get_current_vinfo();
if (tvout_monitor_flag == 0)
return 0;
hpd_state = vout_get_hpd_state();
if (hpd_state) {
- cur_vmode = validate_vmode(hdmimode);
- snprintf(cur_mode_str, VMODE_NAME_LEN_MAX, "%s", hdmimode);
+ /* Vout will check the checksum of EDID of uboot and kernel.
+ * If checksum is different. Vout will set null to display/mode.
+ * When systemcontrol bootup, it will set the correct mode and
+ * colorspace according to current EDID from kernel.
+ */
+ VOUTPR("hdmichecksum [%s], kernel hdmichecksum [%s]\n",
+ hdmichecksum, info->hdmichecksum);
+ if ((memcmp(hdmichecksum, info->hdmichecksum, 10)) &&
+ (memcmp(emptychecksum, info->hdmichecksum, 10)) &&
+ (memcmp(invalidchecksum, hdmichecksum, 10))) {
+ VOUTPR("hdmi crc is diff between uboot and kernel\n");
+ cur_vmode = validate_vmode("null");
+ snprintf(cur_mode_str, VMODE_NAME_LEN_MAX, "null");
+
+ } else {
+ cur_vmode = validate_vmode(hdmimode);
+ snprintf(cur_mode_str, VMODE_NAME_LEN_MAX,
+ "%s", hdmimode);
+ }
} else {
cur_vmode = validate_vmode(cvbsmode);
snprintf(cur_mode_str, VMODE_NAME_LEN_MAX, "%s", cvbsmode);
}
__setup("cvbsmode=", get_cvbs_mode);
+static int __init get_hdmi_checksum(char *str)
+{
+ snprintf(hdmichecksum, VMODE_NAME_LEN_MAX, "%s", str);
+
+ VOUTPR("get hdmi checksum: %s\n", hdmichecksum);
+ return 0;
+}
+__setup("hdmichecksum=", get_hdmi_checksum);
+
MODULE_AUTHOR("Platform-BJ <platform.bj@amlogic.com>");
MODULE_DESCRIPTION("VOUT Server Module");
MODULE_LICENSE("GPL");