blob: 47435be4218478faa6bfb22f7351c5ac7ce6ee6b [file] [log] [blame]
/*
* drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.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.
*
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#include <linux/amlogic/media/vpu/vpu.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/amlogic/media/video_sink/video.h>
#include "../tvin_global.h"
#include "../tvin_format_table.h"
#include "vdin_ctl.h"
#include "vdin_regs.h"
#include "vdin_drv.h"
#include "vdin_vf.h"
#include "vdin_canvas.h"
#define VDIN_VSHRINK_HLIMIT 1280
#define TVIN_MAX_PIXCLK 20000
#define META_RETRY_MAX 10
#define VDIN_MAX_HACTIVE 4096 /*the max hactive of vdin*/
/*0: 1 word in 1burst, 1: 2 words in 1burst;
*2: 4 words in 1burst;
*/
#define VDIN_WR_BURST_MODE 2
#define DV_META_PACKET_SIZE 128
#define DV_META_HEADER_LEN 2
#define DV_META_TAIL_CRC_SIZE 4
#define DV_META_PACKET_TYPE_SIZE 3
static bool cm_enable = 1;
module_param(cm_enable, bool, 0644);
MODULE_PARM_DESC(cm_enable, "cm_enable");
static bool rgb_info_enable;
static unsigned int rgb_info_x;
static unsigned int rgb_info_y;
static unsigned int rgb_info_r;
static unsigned int rgb_info_g;
static unsigned int rgb_info_b;
static int vdin_det_idle_wait = 100;
static unsigned int delay_line_num;
static bool invert_top_bot;
#ifdef DEBUG_SUPPORT
module_param(rgb_info_enable, bool, 0644);
MODULE_PARM_DESC(rgb_info_enable, "rgb_info_enable");
module_param(rgb_info_x, uint, 0644);
MODULE_PARM_DESC(rgb_info_x, "rgb_info_x");
module_param(rgb_info_y, uint, 0644);
MODULE_PARM_DESC(rgb_info_y, "rgb_info_y");
module_param(rgb_info_r, uint, 0644);
MODULE_PARM_DESC(rgb_info_r, "rgb_info_r");
module_param(rgb_info_g, uint, 0644);
MODULE_PARM_DESC(rgb_info_g, "rgb_info_g");
module_param(rgb_info_b, uint, 0644);
MODULE_PARM_DESC(rgb_info_b, "rgb_info_b");
module_param(vdin_det_idle_wait, int, 0664);
MODULE_PARM_DESC(vdin_det_idle_wait, "vdin_det_idle_wait");
module_param(delay_line_num, uint, 0644);
MODULE_PARM_DESC(delay_line_num, "delay_line_num");
module_param(invert_top_bot, bool, 0644);
MODULE_PARM_DESC(invert_top_bot, "invert field type top or bottom");
#endif
bool enable_reset;
module_param(enable_reset, bool, 0664);
MODULE_PARM_DESC(enable_reset, "enable_reset");
static int vsync_reset_mask;
module_param(vsync_reset_mask, int, 0664);
MODULE_PARM_DESC(vsync_reset_mask, "vsync_reset_mask");
static unsigned int dv_dbg_log;
module_param(dv_dbg_log, uint, 0664);
MODULE_PARM_DESC(dv_dbg_log, "enable/disable dv_dbg_log");
unsigned int dv_dbg_mask = (DV_BUF_START_RESET | DV_CRC_CHECK);
module_param(dv_dbg_mask, uint, 0664);
MODULE_PARM_DESC(dv_dbg_mask, "enable/disable dv_dbg_mask");
static int vdin_ctl_dbg;
module_param(vdin_ctl_dbg, int, 0664);
MODULE_PARM_DESC(vdin_ctl_dbg, "vdin_ctl_dbg");
/*bit0/1:game mode enable for vdin0/1*/
unsigned int game_mode;
module_param(game_mode, uint, 0664);
MODULE_PARM_DESC(game_mode, "game_mode");
static unsigned int vpu_reg_27af = 0x3;
/***************************Local defines**********************************/
#define BBAR_BLOCK_THR_FACTOR 3
#define BBAR_LINE_THR_FACTOR 7
#define VDIN_MUX_NULL 0
#define VDIN_MUX_MPEG 1
#define VDIN_MUX_656 2
#define VDIN_MUX_TVFE 3
#define VDIN_MUX_CVD2 4
#define VDIN_MUX_HDMI 5
#define VDIN_MUX_DVIN 6
#define VDIN_MUX_VIU_1 7
#define VDIN_MUX_MIPI 8
#define VDIN_MUX_ISP 9
/*g12a new add*/
#define VDIN_MUX_VIU_2 9
#define VDIN_MUX_656_B 10
#define VDIN_MAP_Y_G 0
#define VDIN_MAP_BPB 1
#define VDIN_MAP_RCR 2
#define MEAS_MUX_NULL 0
#define MEAS_MUX_656 1
#define MEAS_MUX_TVFE 2
#define MEAS_MUX_CVD2 3
#define MEAS_MUX_HDMI 4
#define MEAS_MUX_DVIN 5
#define MEAS_MUX_DTV 6
#define MEAS_MUX_ISP 8
#define MEAS_MUX_656_B 9
#define MEAS_MUX_VIU1 6
#define MEAS_MUX_VIU2 8
#define HDMI_DE_REPEAT_DONE_FLAG 0xF0
#define DECIMATION_REAL_RANGE 0x0F
#define VDIN_PIXELCLK_4K_30HZ 248832000
#define VDIN_PIXELCLK_4K_60HZ 497664000
#if 0/*ndef VDIN_DEBUG*/
#undef pr_info
#define pr_info(fmt, ...)
#endif
/*reset reg mif value of vdin0:
* VDIN_WR_CTRL \VDIN_COM_CTRL0\ VDIN_MISC_CTRL
*/
static void vdin0_wr_mif_reset(void)
{
if (vsync_reset_mask & 0x08) {
W_VCBUS_BIT(VDIN_WR_CTRL, 1, FRAME_SOFT_RST_EN_BIT, 1);
W_VCBUS_BIT(VDIN_COM_CTRL0, 1, VDIN_FORCEGOLINE_EN_BIT, 1);
udelay(1);
W_VCBUS_BIT(VDIN_WR_CTRL, 0, FRAME_SOFT_RST_EN_BIT, 1);
} else {
W_VCBUS_BIT(VDIN_WR_CTRL, 0, VDIN_WRCTRLREG_PAUSE_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, 2, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_RST_BIT, 1);
udelay(1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_MIF_RST_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 2, 1);
W_VCBUS_BIT(VDIN_WR_CTRL, 1, VDIN_WRREQUEST_EN_BT, 1);
W_VCBUS_BIT(VDIN_WR_CTRL, 1, VDIN_WRCTRLREG_PAUSE_BIT, 1);
}
};
/*reset reg mif value of vdin1:
* VDIN_WR_CTRL \VDIN_COM_CTRL1\ VDIN_MISC_CTRL
*/
static void vdin1_wr_mif_reset(void)
{
if (vsync_reset_mask & 0x08) {
W_VCBUS_BIT(VDIN1_WR_CTRL, 1, FRAME_SOFT_RST_EN_BIT, 1);
W_VCBUS_BIT(VDIN_COM_CTRL1, 1, VDIN_FORCEGOLINE_EN_BIT, 1);
udelay(1);
W_VCBUS_BIT(VDIN1_WR_CTRL, 0, FRAME_SOFT_RST_EN_BIT, 1);
} else {
W_VCBUS_BIT(VDIN1_WR_CTRL, 0, VDIN_WRCTRLREG_PAUSE_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_RST_BIT, 1);
udelay(1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_MIF_RST_BIT, 1);
W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN_WRREQUEST_EN_BT, 1);
W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN_WRCTRLREG_PAUSE_BIT, 1);
}
}
/***************************Local Structures**********************************/
static struct vdin_matrix_lup_s vdin_matrix_lup[] = {
{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x0400200, 0x00000200,},
/* VDIN_MATRIX_RGB_YUV601 */
/* 0 0.257 0.504 0.098 16 */
/* 0 -0.148 -0.291 0.439 128 */
/* 0 0.439 -0.368 -0.071 128 */
{0x00000000, 0x00000000, 0x01070204, 0x00641f68, 0x1ed601c2, 0x01c21e87,
0x00001fb7, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_GBR_YUV601 */
/* 0 0.504 0.098 0.257 16 */
/* 0 -0.291 0.439 -0.148 128 */
/* 0 -0.368 -0.071 0.439 128 */
{0x00000000, 0x00000000, 0x02040064, 0x01071ed6, 0x01c21f68, 0x1e871fb7,
0x000001c2, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_BRG_YUV601 */
/* 0 0.098 0.257 0.504 16 */
/* 0 0.439 -0.148 -0.291 128 */
/* 0 -0.071 0.439 -0.368 128 */
{0x00000000, 0x00000000, 0x00640107, 0x020401c2, 0x1f681ed6, 0x1fb701c2,
0x00001e87, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV601_RGB */
/* -16 1.164 0 1.596 0 */
/* -128 1.164 -0.391 -0.813 0 */
/* -128 1.164 2.018 0 0 */
{0x07c00600, 0x00000600, 0x04a80000, 0x066204a8, 0x1e701cbf, 0x04a80812,
0x00000000, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_YUV601_GBR */
/* -16 1.164 -0.391 -0.813 0 */
/* -128 1.164 2.018 0 0 */
/* -128 1.164 0 1.596 0 */
{0x07c00600, 0x00000600, 0x04a81e70, 0x1cbf04a8, 0x08120000, 0x04a80000,
0x00000662, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_YUV601_BRG */
/* -16 1.164 2.018 0 0 */
/* -128 1.164 0 1.596 0 */
/* -128 1.164 -0.391 -0.813 0 */
{0x07c00600, 0x00000600, 0x04a80812, 0x000004a8, 0x00000662, 0x04a81e70,
0x00001cbf, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_RGB_YUV601F */
/* 0 0.299 0.587 0.114 0 */
/* 0 -0.169 -0.331 0.5 128 */
/* 0 0.5 -0.419 -0.081 128 */
{0x00000000, 0x00000000, 0x01320259, 0x00751f53, 0x1ead0200, 0x02001e53,
0x00001fad, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_YUV601F_RGB */
/* 0 1 0 1.402 0 */
/* -128 1 -0.344 -0.714 0 */
/* -128 1 1.772 0 0 */
{0x00000600, 0x00000600, 0x04000000, 0x059c0400, 0x1ea01d25, 0x04000717,
0x00000000, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_RGBS_YUV601 */
/* -16 0.299 0.587 0.114 16 */
/* -16 -0.173 -0.339 0.511 128 */
/* -16 0.511 -0.429 -0.083 128 */
{0x07c007c0, 0x000007c0, 0x01320259, 0x00751f4f, 0x1ea5020b, 0x020b1e49,
0x00001fab, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV601_RGBS */
/* -16 1 0 1.371 16 */
/* -128 1 -0.336 -0.698 16 */
/* -128 1 1.733 0 16 */
{0x07c00600, 0x00000600, 0x04000000, 0x057c0400, 0x1ea81d35, 0x040006ef,
0x00000000, 0x00400040, 0x00000040,},
/* VDIN_MATRIX_RGBS_YUV601F */
/* -16 0.348 0.683 0.133 0 */
/* -16 -0.197 -0.385 0.582 128 */
/* -16 0.582 -0.488 -0.094 128 */
{0x07c007c0, 0x000007c0, 0x016402bb, 0x00881f36, 0x1e760254, 0x02541e0c,
0x00001fa0, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_YUV601F_RGBS */
/* 0 0.859 0 1.204 16 */
/* -128 0.859 -0.295 -0.613 16 */
/* -128 0.859 1.522 0 16 */
{0x00000600, 0x00000600, 0x03700000, 0x04d10370, 0x1ed21d8c, 0x03700617,
0x00000000, 0x00400040, 0x00000040,},
/* VDIN_MATRIX_YUV601F_YUV601 */
/* 0 0.859 0 0 16 */
/* -128 0 0.878 0 128 */
/* -128 0 0 0.878 128 */
{0x00000600, 0x00000600, 0x03700000, 0x00000000, 0x03830000, 0x00000000,
0x00000383, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV601_YUV601F */
/* -16 1.164 0 0 0 */
/* -128 0 1.138 0 128 */
/* -128 0 0 1.138 128 */
{0x07c00600, 0x00000600, 0x04a80000, 0x00000000, 0x048d0000, 0x00000000,
0x0000048d, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_RGB_YUV709 */
/* 0 0.183 0.614 0.062 16 */
/* 0 -0.101 -0.338 0.439 128 */
/* 0 0.439 -0.399 -0.04 128 */
{0x00000000, 0x00000000, 0x00bb0275, 0x003f1f99, 0x1ea601c2, 0x01c21e67,
0x00001fd7, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV709_RGB */
/* -16 1.164 0 1.793 0 */
/* -128 1.164 -0.213 -0.534 0 */
/* -128 1.164 2.115 0 0 */
{0x07c00600, 0x00000600, 0x04a80000, 0x072c04a8, 0x1f261ddd, 0x04a80876,
0x00000000, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_YUV709_GBR */
/* -16 1.164 -0.213 -0.534 0 */
/* -128 1.164 2.115 0 0 */
/* -128 1.164 0 1.793 0 */
{0x07c00600, 0x00000600, 0x04a81f26, 0x1ddd04a8, 0x08760000, 0x04a80000,
0x0000072c, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_YUV709_BRG */
/* -16 1.164 2.115 0 0 */
/* -128 1.164 0 1.793 0 */
/* -128 1.164 -0.213 -0.534 0 */
{0x07c00600, 0x00000600, 0x04a80876, 0x000004a8, 0x0000072c, 0x04a81f26,
0x00001ddd, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_RGB_YUV709F */
/* 0 0.213 0.715 0.072 0 */
/* 0 -0.115 -0.385 0.5 128 */
/* 0 0.5 -0.454 -0.046 128 */
{0x00000000, 0x00000000, 0x00da02dc, 0x004a1f8a, 0x1e760200, 0x02001e2f,
0x00001fd1, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_YUV709F_RGB */
/* 0 1 0 1.575 0 */
/* -128 1 -0.187 -0.468 0 */
/* -128 1 1.856 0 0 */
{0x00000600, 0x00000600, 0x04000000, 0x064d0400, 0x1f411e21, 0x0400076d,
0x00000000, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_RGBS_YUV709 */
/* -16 0.213 0.715 0.072 16 */
/* -16 -0.118 -0.394 0.511 128 */
/* -16 0.511 -0.464 -0.047 128 */
{0x07c007c0, 0x000007c0, 0x00da02dc, 0x004a1f87, 0x1e6d020b, 0x020b1e25,
0x00001fd0, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV709_RGBS */
/* -16 1 0 1.54 16 */
/* -128 1 -0.183 -0.459 16 */
/* -128 1 1.816 0 16 */
{0x07c00600, 0x00000600, 0x04000000, 0x06290400, 0x1f451e2a, 0x04000744,
0x00000000, 0x00400040, 0x00000040,},
/* VDIN_MATRIX_RGBS_YUV709F */
/* -16 0.248 0.833 0.084 0 */
/* -16 -0.134 -0.448 0.582 128 */
/* -16 0.582 -0.529 -0.054 128 */
{0x07c007c0, 0x000007c0, 0x00fe0355, 0x00561f77, 0x1e350254, 0x02541de2,
0x00001fc9, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_YUV709F_RGBS */
/* 0 0.859 0 1.353 16 */
/* -128 0.859 -0.161 -0.402 16 */
/* -128 0.859 1.594 0 16 */
{0x00000600, 0x00000600, 0x03700000, 0x05690370, 0x1f5b1e64, 0x03700660,
0x00000000, 0x00400040, 0x00000040,},
/* VDIN_MATRIX_YUV709F_YUV709 */
/* 0 0.859 0 0 16 */
/* -128 0 0.878 0 128 */
/* -128 0 0 0.878 128 */
{0x00000600, 0x00000600, 0x03700000, 0x00000000, 0x03830000, 0x00000000,
0x00000383, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV709_YUV709F */
/* -16 1.164 0 0 0 */
/* -128 0 1.138 0 128 */
/* -128 0 0 1.138 128 */
{0x07c00600, 0x00000600, 0x04a80000, 0x00000000, 0x048d0000, 0x00000000,
0x0000048d, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_YUV601_YUV709 */
/* -16 1 -0.115 -0.207 16 */
/* -128 0 1.018 0.114 128 */
/* -128 0 0.075 1.025 128 */
{0x07c00600, 0x00000600, 0x04001f8a, 0x1f2c0000, 0x04120075, 0x0000004d,
0x0000041a, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV709_YUV601 */
/* -16 1 0.100 0.192 16 */
/* -128 0 0.990 -0.110 128 */
/* -128 0 -0.072 0.984 128 */
{0x07c00600, 0x00000600, 0x04000066, 0x00c50000, 0x03f61f8f, 0x00001fb6,
0x000003f0, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV601_YUV709F */
/* -16 1.164 -0.134 -0.241 0 */
/* -128 0 1.160 0.129 128 */
/* -128 0 0.085 1.167 128 */
{0x07c00600, 0x00000600, 0x04a81f77, 0x1f090000, 0x04a40084, 0x00000057,
0x000004ab, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_YUV709F_YUV601 */
/* 0 0.859 0.088 0.169 16 */
/* -128 0 0.869 -0.097 128 */
/* -128 0 -0.063 0.864 128 */
{0x00000600, 0x00000600, 0x0370005a, 0x00ad0000, 0x037a1f9d, 0x00001fbf,
0x00000375, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV601F_YUV709 */
/* 0 0.859 -0.101 -0.182 16 */
/* -128 0 0.894 0.100 128 */
/* -128 0 0.066 0.900 128 */
{0x00000600, 0x00000600, 0x03701f99, 0x1f460000, 0x03930066, 0x00000044,
0x0000039a, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV709_YUV601F */
/* -16 1.164 0.116 0.223 0 */
/* -128 0 1.128 -0.126 128 */
/* -128 0 -0.082 1.120 128 */
{0x07c00600, 0x00000600, 0x04a80077, 0x00e40000, 0x04831f7f, 0x00001fac,
0x0000047b, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_YUV601F_YUV709F */
/* 0 1 -0.118 -0.212 16 */
/* -128 0 1.018 0.114 128 */
/* -128 0 0.075 1.025 128 */
{0x00000600, 0x00000600, 0x04001f87, 0x1f270000, 0x04120075, 0x0000004d,
0x0000041a, 0x00400200, 0x00000200,},
/* VDIN_MATRIX_YUV709F_YUV601F */
/* 0 1 0.102 0.196 0 */
/* -128 0 0.990 -0.111 128 */
/* -128 0 -0.072 0.984 128 */
{0x00000600, 0x00000600, 0x04000068, 0x00c90000, 0x03f61f8e, 0x00001fb6,
0x000003f0, 0x00000200, 0x00000200,},
/* VDIN_MATRIX_RGBS_RGB */
/* -16 1.164 0 0 0 */
/* -16 0 1.164 0 0 */
/* -16 0 0 1.164 0 */
{0x07c007c0, 0x000007c0, 0x04a80000, 0x00000000, 0x04a80000, 0x00000000,
0x000004a8, 0x00000000, 0x00000000,},
/* VDIN_MATRIX_RGB_RGBS */
/* 0 0.859 0 0 16 */
/* 0 0 0.859 0 16 */
/* 0 0 0 0.859 16 */
{0x00000000, 0x00000000, 0x03700000, 0x00000000, 0x03700000, 0x00000000,
0x00000370, 0x00400040, 0x00000040,},
};
/***************************Local function**********************************/
/*set format_convert
*base on parameters:
* a.color_format
* b.dest_cfmt
*/
void vdin_get_format_convert(struct vdin_dev_s *devp)
{
enum vdin_format_convert_e format_convert;
if (devp->prop.color_format == devp->prop.dest_cfmt) {
switch (devp->prop.color_format) {
case TVIN_YUV422:
case TVIN_YUYV422:
case TVIN_YVYU422:
case TVIN_UYVY422:
case TVIN_VYUY422:
format_convert = VDIN_FORMAT_CONVERT_YUV_YUV422;
break;
case TVIN_YUV444:
format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444;
break;
case TVIN_RGB444:
format_convert = VDIN_FORMAT_CONVERT_RGB_RGB;
break;
default:
format_convert = VDIN_FORMAT_CONVERT_MAX;
break;
}
} else {
switch (devp->prop.color_format) {
case TVIN_YUV422:
case TVIN_YUV444:
case TVIN_YUYV422:
case TVIN_YVYU422:
case TVIN_UYVY422:
case TVIN_VYUY422:
if (devp->prop.dest_cfmt == TVIN_NV21)
format_convert = VDIN_FORMAT_CONVERT_YUV_NV21;
else if (devp->prop.dest_cfmt == TVIN_NV12)
format_convert = VDIN_FORMAT_CONVERT_YUV_NV12;
else if (devp->prop.dest_cfmt == TVIN_YUV444)
format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444;
else
format_convert = VDIN_FORMAT_CONVERT_YUV_YUV422;
break;
case TVIN_RGB444:
if (devp->prop.dest_cfmt == TVIN_YUV444)
format_convert = VDIN_FORMAT_CONVERT_RGB_YUV444;
else if (devp->prop.dest_cfmt == TVIN_NV21)
format_convert = VDIN_FORMAT_CONVERT_RGB_NV21;
else if (devp->prop.dest_cfmt == TVIN_NV12)
format_convert = VDIN_FORMAT_CONVERT_RGB_NV12;
else
format_convert = VDIN_FORMAT_CONVERT_RGB_YUV422;
break;
default:
format_convert = VDIN_FORMAT_CONVERT_MAX;
break;
}
}
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if ((devp->dv.dolby_input & (1 << devp->index)) ||
(devp->dv.dv_flag && is_dolby_vision_enable()))
format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444;
#endif
devp->format_convert = format_convert;
}
/*functiong:
* format_convert
* based on dest_cfmt
*/
enum vdin_format_convert_e vdin_get_format_convert_matrix0(
struct vdin_dev_s *devp)
{
enum vdin_format_convert_e format_convert = VDIN_FORMAT_CONVERT_MAX;
if (devp->prop.dest_cfmt == TVIN_NV21)
format_convert = VDIN_FORMAT_CONVERT_RGB_NV21;
else if (devp->prop.dest_cfmt == TVIN_NV12)
format_convert = VDIN_FORMAT_CONVERT_RGB_NV12;
else if (devp->prop.dest_cfmt == TVIN_RGB444)
format_convert = VDIN_FORMAT_CONVERT_RGB_RGB;
else if (devp->prop.dest_cfmt == TVIN_YUV444)
format_convert = VDIN_FORMAT_CONVERT_RGB_YUV444;
else
format_convert = VDIN_FORMAT_CONVERT_RGB_YUV422;
return format_convert;
}
/*functiong:
* format_convert
* based on color_cfmt
*/
enum vdin_format_convert_e vdin_get_format_convert_matrix1(
struct vdin_dev_s *devp)
{
enum vdin_format_convert_e format_convert = VDIN_FORMAT_CONVERT_MAX;
switch (devp->prop.color_format) {
case TVIN_YUV422:
case TVIN_YUYV422:
case TVIN_YVYU422:
case TVIN_UYVY422:
case TVIN_VYUY422:
case TVIN_YUV444:
format_convert = VDIN_FORMAT_CONVERT_YUV_RGB;
break;
case TVIN_RGB444:
format_convert = VDIN_FORMAT_CONVERT_RGB_RGB;
break;
default:
format_convert = VDIN_FORMAT_CONVERT_MAX;
break;
}
return format_convert;
}
/*get prob of r/g/b
* r 9:0
* g 19:10
* b 29:20
*/
void vdin_get_prob_rgb(unsigned int offset,
unsigned int *r, unsigned int *g, unsigned int *b)
{
*b = rgb_info_b = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR,
COMPONENT0_PROBE_COLOR_BIT, COMPONENT0_PROBE_COLOR_WID);
*g = rgb_info_g = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR,
COMPONENT1_PROBE_COLOR_BIT, COMPONENT1_PROBE_COLOR_WID);
*r = rgb_info_r = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR,
COMPONENT0_PROBE_COLOR_BIT, COMPONENT0_PROBE_COLOR_WID);
}
/*function:
* 1.set meas mux based on port_:
* 0x01: /mpeg/ 0x10: /CVBS/
* 0x02: /bt656/ 0x20: /SVIDEO/
* 0x04: /VGA/ 0x40: /hdmi/
* 0x08: /COMPONENT/ 0x80: /dvin/
* 0xc0:/viu/ 0x100:/dtv mipi/
* 0x200:/isp/
* 2.set VDIN_MEAS in accumulation mode
* 3.set VPP_VDO_MEAS in accumulation mode
* 4.set VPP_MEAS in latch-on-falling-edge mode
* 5.set VDIN_MEAS mux
* 6.manual reset VDIN_MEAS & VPP_VDO_MEAS at the same time
*/
static void vdin_set_meas_mux(unsigned int offset, enum tvin_port_e port_,
enum bt_path_e bt_path)
{
/* unsigned int offset = devp->addr_offset; */
unsigned int meas_mux = MEAS_MUX_NULL;
switch ((port_)>>8) {
case 0x01: /* mpeg */
meas_mux = MEAS_MUX_NULL;
break;
case 0x02: /* bt656 , txl and txlx do not support bt656 */
if ((is_meson_gxbb_cpu() || is_meson_gxtvbb_cpu()) &&
(bt_path == BT_PATH_GPIO_B))
meas_mux = MEAS_MUX_656_B;
else if ((is_meson_gxl_cpu() || is_meson_gxm_cpu() ||
is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
is_meson_tl1_cpu() || is_meson_sm1_cpu()) &&
(bt_path == BT_PATH_GPIO))
meas_mux = MEAS_MUX_656;
else
pr_info("cpu not define or do not support bt656");
break;
case 0x04: /* VGA */
meas_mux = MEAS_MUX_TVFE;
break;
case 0x08: /* COMPONENT */
meas_mux = MEAS_MUX_TVFE;
break;
case 0x10: /* CVBS */
meas_mux = MEAS_MUX_CVD2;
break;
case 0x20: /* SVIDEO */
meas_mux = MEAS_MUX_CVD2;
break;
case 0x40: /* hdmi */
meas_mux = MEAS_MUX_HDMI;
break;
case 0x80: /* dvin */
meas_mux = MEAS_MUX_DVIN;
break;
case 0xa0:/* viu */
meas_mux = MEAS_MUX_VIU1;
break;
case 0xc0:/* viu */
meas_mux = MEAS_MUX_VIU2;
break;
case 0x100:/* dtv mipi */
meas_mux = MEAS_MUX_DTV;
break;
case 0x200:/* isp */
meas_mux = MEAS_MUX_ISP;
break;
default:
meas_mux = MEAS_MUX_NULL;
break;
}
/* set VDIN_MEAS in accumulation mode */
wr_bits(offset, VDIN_MEAS_CTRL0, 1,
MEAS_VS_TOTAL_CNT_EN_BIT, MEAS_VS_TOTAL_CNT_EN_WID);
/* set VPP_VDO_MEAS in accumulation mode */
wr_bits(0, VPP_VDO_MEAS_CTRL, 1, 8, 1);
/* set VPP_MEAS in latch-on-falling-edge mode */
wr_bits(0, VPP_VDO_MEAS_CTRL, 1, 9, 1);
/* set VDIN_MEAS mux */
wr_bits(offset, VDIN_MEAS_CTRL0, meas_mux,
MEAS_HS_VS_SEL_BIT, MEAS_HS_VS_SEL_WID);
/* manual reset VDIN_MEAS & VPP_VDO_MEAS at the same time,
* rst = 1 & 0
*/
wr_bits(offset, VDIN_MEAS_CTRL0, 1, MEAS_RST_BIT, MEAS_RST_WID);
W_VCBUS_BIT(VPP_VDO_MEAS_CTRL, 1, 10, 1);
wr_bits(offset, VDIN_MEAS_CTRL0, 0, MEAS_RST_BIT, MEAS_RST_WID);
W_VCBUS_BIT(VPP_VDO_MEAS_CTRL, 0, 10, 1);
}
/*function:set VDIN_COM_CTRL0
*Bit 3:0 vdin selection,
* 1: mpeg_in from dram, 2: bt656 input,3: component input
* 4: tvdecoder input, 5: hdmi rx input,6: digtial video input,
* 7: loopback from Viu1, 8: MIPI.
*/
/* Bit 7:6, component0 output switch,
* 00: select component0 in,01: select component1 in,
* 10: select component2 in
*/
/* Bit 9:8, component1 output switch,
* 00: select component0 in,
* 01: select component1 in, 10: select component2 in
*/
/* Bit 11:10, component2 output switch,
* 00: select component0 in, 01: select component1 in,
* 10: select component2 in
*/
/*attention:new add for bt656
*0x02: /bt656/
a.BT_PATH_GPIO: gxl & gxm & g12a
b.BT_PATH_GPIO_B:gxtvbb & gxbb
c.txl and txlx don't support bt656
*/
void vdin_set_top(unsigned int offset,
enum tvin_port_e port,
enum tvin_color_fmt_e input_cfmt, unsigned int h,
enum bt_path_e bt_path)
{
/* unsigned int offset = devp->addr_offset; */
unsigned int vdin_mux = VDIN_MUX_NULL;
unsigned int vdin_data_bus_0 = VDIN_MAP_Y_G;
unsigned int vdin_data_bus_1 = VDIN_MAP_BPB;
unsigned int vdin_data_bus_2 = VDIN_MAP_RCR;
/* [28:16] top.input_width_m1 = h-1 */
/* [12: 0] top.output_width_m1 = h-1 */
wr(offset, VDIN_WIDTHM1I_WIDTHM1O, ((h-1)<<16)|(h-1));
switch ((port)>>8) {
case 0x01: /* mpeg */
vdin_mux = VDIN_MUX_MPEG;
wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe0,
VDI1_ASFIFO_CTRL_BIT, VDI1_ASFIFO_CTRL_WID);
break;
case 0x02: /* bt656 ,txl and txlx do not support bt656 */
if ((is_meson_gxbb_cpu() || is_meson_gxtvbb_cpu()) &&
(bt_path == BT_PATH_GPIO_B)) {
vdin_mux = VDIN_MUX_656_B;
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4,
VDI9_ASFIFO_CTRL_BIT, VDI9_ASFIFO_CTRL_WID);
} else if ((is_meson_gxm_cpu() || is_meson_gxl_cpu() ||
is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
is_meson_tl1_cpu() || is_meson_sm1_cpu()) &&
(bt_path == BT_PATH_GPIO)) {
vdin_mux = VDIN_MUX_656;
wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4,
VDI1_ASFIFO_CTRL_BIT, VDI1_ASFIFO_CTRL_WID);
} else
pr_info("cpu not define or do not support bt656");
break;
case 0x04: /* VGA */
vdin_mux = VDIN_MUX_TVFE;
wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4,
VDI2_ASFIFO_CTRL_BIT, VDI2_ASFIFO_CTRL_WID);
/* In the order of RGB for further
* RGB->YUV601 or RGB->YUV709 conversion
*/
vdin_data_bus_0 = VDIN_MAP_RCR;
vdin_data_bus_1 = VDIN_MAP_Y_G;
vdin_data_bus_2 = VDIN_MAP_BPB;
break;
case 0x08: /* COMPONENT */
vdin_mux = VDIN_MUX_TVFE;
wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4,
VDI2_ASFIFO_CTRL_BIT, VDI2_ASFIFO_CTRL_WID);
break;
case 0x10: /* CVBS */
vdin_mux = VDIN_MUX_CVD2;
wr_bits(offset, VDIN_ASFIFO_CTRL1, 0xe4,
VDI3_ASFIFO_CTRL_BIT, VDI3_ASFIFO_CTRL_WID);
break;
case 0x20: /* SVIDEO */
vdin_mux = VDIN_MUX_CVD2;
wr_bits(offset, VDIN_ASFIFO_CTRL1, 0xe4,
VDI3_ASFIFO_CTRL_BIT, VDI3_ASFIFO_CTRL_WID);
break;
case 0x40: /* hdmi */
vdin_mux = VDIN_MUX_HDMI;
wr_bits(offset, VDIN_ASFIFO_CTRL1, 0xe4,
VDI4_ASFIFO_CTRL_BIT, VDI4_ASFIFO_CTRL_WID);
break;
case 0x80: /* dvin */
vdin_mux = VDIN_MUX_DVIN;
wr_bits(offset, VDIN_ASFIFO_CTRL2, 0xe4,
VDI5_ASFIFO_CTRL_BIT, VDI5_ASFIFO_CTRL_WID);
break;
case 0xa0:/*viu1*/
vdin_mux = VDIN_MUX_VIU_1;
if (port != TVIN_PORT_VIU1)
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4,
VDI6_ASFIFO_CTRL_BIT, VDI6_ASFIFO_CTRL_WID);
else {
if (/*is_meson_gxlx2_cpu() || */is_meson_g12b_cpu()
|| is_meson_tl1_cpu() || is_meson_sm1_cpu())
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4,
VDI6_ASFIFO_CTRL_BIT,
VDI6_ASFIFO_CTRL_WID);
else
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4,
VDI6_ASFIFO_CTRL_BIT,
VDI6_ASFIFO_CTRL_WID);
}
break;
case 0xc0: /* viu2 */
vdin_mux = VDIN_MUX_VIU_2;
if (port != TVIN_PORT_VIU2)
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4,
VDI8_ASFIFO_CTRL_BIT, VDI8_ASFIFO_CTRL_WID);
else {
if (/*is_meson_gxlx2_cpu() || */is_meson_g12b_cpu()
|| is_meson_tl1_cpu() || is_meson_sm1_cpu())
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4,
VDI6_ASFIFO_CTRL_BIT,
VDI6_ASFIFO_CTRL_WID);
else
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4,
VDI6_ASFIFO_CTRL_BIT,
VDI6_ASFIFO_CTRL_WID);
}
break;
case 0x100:/* mipi in mybe need modify base on truth */
vdin_mux = VDIN_MUX_MIPI;
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe0,
VDI7_ASFIFO_CTRL_BIT, VDI7_ASFIFO_CTRL_WID);
break;
case 0x200:
vdin_mux = VDIN_MUX_ISP;
wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4,
VDI8_ASFIFO_CTRL_BIT, VDI8_ASFIFO_CTRL_WID);
break;
default:
vdin_mux = VDIN_MUX_NULL;
break;
}
switch (input_cfmt) {
case TVIN_YVYU422:
vdin_data_bus_1 = VDIN_MAP_RCR;
vdin_data_bus_2 = VDIN_MAP_BPB;
break;
case TVIN_UYVY422:
vdin_data_bus_0 = VDIN_MAP_BPB;
vdin_data_bus_1 = VDIN_MAP_RCR;
vdin_data_bus_2 = VDIN_MAP_Y_G;
break;
case TVIN_VYUY422:
vdin_data_bus_0 = VDIN_MAP_BPB;
vdin_data_bus_1 = VDIN_MAP_RCR;
vdin_data_bus_2 = VDIN_MAP_Y_G;
break;
default:
break;
}
wr_bits(offset, VDIN_COM_CTRL0, vdin_mux, VDIN_SEL_BIT, VDIN_SEL_WID);
wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_0,
COMP0_OUT_SWT_BIT, COMP0_OUT_SWT_WID);
wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_1,
COMP1_OUT_SWT_BIT, COMP1_OUT_SWT_WID);
wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_2,
COMP2_OUT_SWT_BIT, COMP2_OUT_SWT_WID);
}
/*this function will set the bellow parameters of devp:
*1.h_active
*2.v_active
*/
void vdin_set_decimation(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
unsigned int new_clk = 0;
bool decimation_in_frontend = false;
if (devp->prop.decimation_ratio & HDMI_DE_REPEAT_DONE_FLAG) {
decimation_in_frontend = true;
if (vdin_ctl_dbg)
pr_info("decimation_in_frontend\n");
}
devp->prop.decimation_ratio = devp->prop.decimation_ratio &
DECIMATION_REAL_RANGE;
new_clk = devp->fmt_info_p->pixel_clk /
(devp->prop.decimation_ratio + 1);
if (vdin_ctl_dbg)
pr_info("%s decimation_ratio=%u,new_clk=%u.\n",
__func__, devp->prop.decimation_ratio, new_clk);
devp->h_active = devp->fmt_info_p->h_active /
(devp->prop.decimation_ratio + 1);
devp->v_active = devp->fmt_info_p->v_active;
if ((devp->prop.decimation_ratio) && (!decimation_in_frontend)) {
/* ratio */
wr_bits(offset, VDIN_ASFIFO_CTRL2,
devp->prop.decimation_ratio,
ASFIFO_DECIMATION_NUM_BIT, ASFIFO_DECIMATION_NUM_WID);
/* en */
wr_bits(offset, VDIN_ASFIFO_CTRL2, 1,
ASFIFO_DECIMATION_DE_EN_BIT,
ASFIFO_DECIMATION_DE_EN_WID);
/* manual reset, rst = 1 & 0 */
wr_bits(offset, VDIN_ASFIFO_CTRL2, 1,
ASFIFO_DECIMATION_SYNC_WITH_DE_BIT,
ASFIFO_DECIMATION_SYNC_WITH_DE_WID);
wr_bits(offset, VDIN_ASFIFO_CTRL2, 0,
ASFIFO_DECIMATION_SYNC_WITH_DE_BIT,
ASFIFO_DECIMATION_SYNC_WITH_DE_WID);
}
/* output_width_m1 */
wr_bits(offset, VDIN_INTF_WIDTHM1, (devp->h_active - 1),
VDIN_INTF_WIDTHM1_BIT, VDIN_INTF_WIDTHM1_WID);
return;
}
void vdin_fix_nonstd_vsync(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
wr_bits(offset, VDIN_INTF_WIDTHM1, 3,
VDIN_FIX_NONSTDVSYNC_BIT, VDIN_FIX_NONSTDVSYNC_WID);
}
/*this function will set the bellow parameters of devp:
* 1.h_active
* 2.v_active
* set VDIN_WIN_H_START_END
* Bit 28:16 input window H start
* Bit 12:0 input window H end
* set VDIN_WIN_V_START_END
* Bit 28:16 input window V start
* Bit 12:0 input window V start
*/
void vdin_set_cutwin(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
unsigned int he = 0, ve = 0;
if (((devp->prop.hs) || (devp->prop.he) ||
(devp->prop.vs) || (devp->prop.ve)) &&
(devp->h_active > (devp->prop.hs + devp->prop.he)) &&
(devp->v_active > (devp->prop.vs + devp->prop.ve))
) {
devp->h_active -= (devp->prop.he + devp->prop.hs);
devp->v_active -= (devp->prop.ve + devp->prop.vs);
he = devp->prop.hs + devp->h_active - 1;
ve = devp->prop.vs + devp->v_active - 1;
wr(offset, VDIN_WIN_H_START_END,
(devp->prop.hs << INPUT_WIN_H_START_BIT) |
(he << INPUT_WIN_H_END_BIT));
wr(offset, VDIN_WIN_V_START_END,
(devp->prop.vs << INPUT_WIN_V_START_BIT) |
(ve << INPUT_WIN_V_END_BIT));
wr_bits(offset, VDIN_COM_CTRL0, 1,
INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID);
if (vdin_ctl_dbg)
pr_info("%s enable cutwin hs=%d, he=%d, vs=%d, ve=%d\n",
__func__,
devp->prop.hs, devp->prop.he,
devp->prop.vs, devp->prop.ve);
} else {
wr(offset, VDIN_WIN_H_START_END, 0);
wr(offset, VDIN_WIN_V_START_END, 0);
wr_bits(offset, VDIN_COM_CTRL0, 0,
INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID);
if (vdin_ctl_dbg)
pr_info("%s disable cutwin!!! hs=%d, he=%d, vs=%d, ve=%d\n",
__func__,
devp->prop.hs, devp->prop.he,
devp->prop.vs, devp->prop.ve);
}
}
/*adjust the brightness for txhd hardware snow*/
void vdin_adjust_tvafesnow_brightness(void)
{
wr(0, VDIN_MATRIX_CTRL, 0x7);
wr(0, VDIN_MATRIX_OFFSET0_1, 0x200);
wr(0, VDIN_MATRIX_OFFSET2, 0x200);
wr(0, VDIN_MATRIX_COEF00_01, 0x6000000);
}
EXPORT_SYMBOL(vdin_adjust_tvafesnow_brightness);
void vdin_set_config(struct vdin_dev_s *devp)
{
if (is_meson_gxbb_cpu() || is_meson_gxm_cpu() || is_meson_gxl_cpu())
/* max pixel clk of vdin for gxbb/gxm/gxl */
devp->vdin_max_pixelclk =
VDIN_PIXELCLK_4K_30HZ; /* 2160p30hz*/
else
devp->vdin_max_pixelclk =
VDIN_PIXELCLK_4K_60HZ; /* 2160p60hz*/
}
/*set matrix_csc
* based on parameters:
* a.format_convert
* b.port
* c.color_range_mode
* d.vdin_hdr_flag
*/
static inline void vdin_set_color_matrix1(unsigned int offset,
struct tvin_format_s *tvin_fmt_p,
enum vdin_format_convert_e format_convert,
enum tvin_port_e port,
enum tvin_color_fmt_range_e color_fmt_range,
unsigned int vdin_hdr_flag,
unsigned int color_range_mode)
{
/* unsigned int offset = devp->addr_offset; */
enum vdin_matrix_csc_e matrix_csc = VDIN_MATRIX_NULL;
struct vdin_matrix_lup_s *matrix_tbl;
struct tvin_format_s *fmt_info = tvin_fmt_p;
switch (format_convert) {
case VDIN_MATRIX_XXX_YUV_BLACK:
matrix_csc = VDIN_MATRIX_XXX_YUV601_BLACK;
break;
case VDIN_FORMAT_CONVERT_RGB_YUV422:
case VDIN_FORMAT_CONVERT_RGB_NV12:
case VDIN_FORMAT_CONVERT_RGB_NV21:
if ((port >= TVIN_PORT_HDMI0) &&
(port <= TVIN_PORT_HDMI7)) {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_RGB_FULL) {
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGB_YUV709;
} else {
matrix_csc = VDIN_MATRIX_RGBS_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_fmt_range == TVIN_RGB_FULL)
matrix_csc = VDIN_MATRIX_RGB_YUV709;
else
matrix_csc = VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_range_mode == 1)
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
else
matrix_csc = VDIN_MATRIX_RGB_YUV709;
}
break;
case VDIN_FORMAT_CONVERT_BRG_YUV422:
matrix_csc = VDIN_MATRIX_BRG_YUV601;
break;
case VDIN_FORMAT_CONVERT_GBR_YUV422:
matrix_csc = VDIN_MATRIX_GBR_YUV601;
break;
case VDIN_FORMAT_CONVERT_RGB_YUV444:
if ((port >= TVIN_PORT_HDMI0) &&
(port <= TVIN_PORT_HDMI7)) {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_RGB_FULL) {
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGB_YUV709;
} else {
matrix_csc = VDIN_MATRIX_RGBS_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_fmt_range == TVIN_RGB_FULL)
matrix_csc = VDIN_MATRIX_RGB_YUV709;
else
matrix_csc = VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_range_mode == 1)
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
else
matrix_csc = VDIN_MATRIX_RGB_YUV709;
}
break;
case VDIN_FORMAT_CONVERT_YUV_RGB:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_RGB;
else
matrix_csc = VDIN_MATRIX_YUV601_RGB;
break;
case VDIN_FORMAT_CONVERT_YUV_GBR:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_GBR;
else
matrix_csc = VDIN_MATRIX_YUV601_GBR;
break;
case VDIN_FORMAT_CONVERT_YUV_BRG:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_BRG;
else
matrix_csc = VDIN_MATRIX_YUV601_BRG;
break;
case VDIN_FORMAT_CONVERT_YUV_YUV422:
case VDIN_FORMAT_CONVERT_YUV_YUV444:
case VDIN_FORMAT_CONVERT_YUV_NV12:
case VDIN_FORMAT_CONVERT_YUV_NV21:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
) {
if ((color_range_mode == 1) &&
(color_fmt_range != TVIN_YUV_FULL))
matrix_csc = VDIN_MATRIX_YUV709_YUV709F;
else if ((color_range_mode == 0) &&
(color_fmt_range == TVIN_YUV_FULL))
matrix_csc = VDIN_MATRIX_YUV709F_YUV709;
} else {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_YUV_FULL)
matrix_csc =
VDIN_MATRIX_YUV601F_YUV709F;
else
matrix_csc = VDIN_MATRIX_YUV601_YUV709F;
} else {
if (color_fmt_range == TVIN_YUV_FULL)
matrix_csc = VDIN_MATRIX_YUV601F_YUV709;
else
matrix_csc = VDIN_MATRIX_YUV601_YUV709;
}
}
if (vdin_hdr_flag == 1)
matrix_csc = VDIN_MATRIX_NULL;
break;
default:
matrix_csc = VDIN_MATRIX_NULL;
break;
}
if (matrix_csc == VDIN_MATRIX_NULL) {
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID);
} else {
matrix_tbl = &vdin_matrix_lup[matrix_csc - 1];
/*select matrix1 post probe and postion(200,100)*/
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID);
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID);
wr(offset, VDIN_MATRIX_PROBE_POS, 0xc812);
/*coefficient index select matrix1*/
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID);
wr(offset,
VDIN_MATRIX_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1);
wr(offset, VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2);
wr(offset, VDIN_MATRIX_COEF00_01, matrix_tbl->coef00_01);
wr(offset, VDIN_MATRIX_COEF02_10, matrix_tbl->coef02_10);
wr(offset, VDIN_MATRIX_COEF11_12, matrix_tbl->coef11_12);
wr(offset, VDIN_MATRIX_COEF20_21, matrix_tbl->coef20_21);
wr(offset, VDIN_MATRIX_COEF22, matrix_tbl->coef22);
wr(offset, VDIN_MATRIX_OFFSET0_1, matrix_tbl->post_offset0_1);
wr(offset, VDIN_MATRIX_OFFSET2, matrix_tbl->post_offset2);
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX1_BYPASS_BIT, VDIN_MATRIX1_BYPASS_WID);
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID);
}
}
static inline void vdin_set_color_matrix0(unsigned int offset,
struct tvin_format_s *tvin_fmt_p,
enum vdin_format_convert_e format_convert,
enum tvin_port_e port,
enum tvin_color_fmt_range_e color_fmt_range,
unsigned int vdin_hdr_flag,
unsigned int color_range_mode)
{
enum vdin_matrix_csc_e matrix_csc = VDIN_MATRIX_NULL;
struct vdin_matrix_lup_s *matrix_tbl;
struct tvin_format_s *fmt_info = tvin_fmt_p;
switch (format_convert) {
case VDIN_MATRIX_XXX_YUV_BLACK:
matrix_csc = VDIN_MATRIX_XXX_YUV601_BLACK;
break;
case VDIN_FORMAT_CONVERT_RGB_YUV422:
case VDIN_FORMAT_CONVERT_RGB_NV12:
case VDIN_FORMAT_CONVERT_RGB_NV21:
if ((port >= TVIN_PORT_HDMI0) &&
(port <= TVIN_PORT_HDMI7)) {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_RGB_FULL) {
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGB_YUV709;
} else {
matrix_csc =
VDIN_MATRIX_RGBS_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_fmt_range == TVIN_RGB_FULL)
matrix_csc = VDIN_MATRIX_RGB_YUV709;
else
matrix_csc = VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_range_mode == 1)
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
else
matrix_csc = VDIN_MATRIX_RGB_YUV709;
}
break;
case VDIN_FORMAT_CONVERT_GBR_YUV422:
matrix_csc = VDIN_MATRIX_GBR_YUV601;
break;
case VDIN_FORMAT_CONVERT_BRG_YUV422:
matrix_csc = VDIN_MATRIX_BRG_YUV601;
break;
case VDIN_FORMAT_CONVERT_RGB_YUV444:
if ((port >= TVIN_PORT_HDMI0) &&
(port <= TVIN_PORT_HDMI7)) {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_RGB_FULL) {
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGB_YUV709;
} else {
matrix_csc = VDIN_MATRIX_RGBS_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_fmt_range == TVIN_RGB_FULL)
matrix_csc = VDIN_MATRIX_RGB_YUV709;
else
matrix_csc = VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_range_mode == 1)
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
else
matrix_csc = VDIN_MATRIX_RGB_YUV709;
}
break;
case VDIN_FORMAT_CONVERT_YUV_RGB:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_RGB;
else
matrix_csc = VDIN_MATRIX_YUV601_RGB;
break;
case VDIN_FORMAT_CONVERT_YUV_GBR:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_GBR;
else
matrix_csc = VDIN_MATRIX_YUV601_GBR;
break;
case VDIN_FORMAT_CONVERT_YUV_BRG:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_BRG;
else
matrix_csc = VDIN_MATRIX_YUV601_BRG;
break;
case VDIN_FORMAT_CONVERT_YUV_YUV422:
case VDIN_FORMAT_CONVERT_YUV_YUV444:
case VDIN_FORMAT_CONVERT_YUV_NV12:
case VDIN_FORMAT_CONVERT_YUV_NV21:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
) {
if ((color_range_mode == 1) &&
(color_fmt_range != TVIN_YUV_FULL))
matrix_csc = VDIN_MATRIX_YUV709_YUV709F;
else if ((color_range_mode == 0) &&
(color_fmt_range == TVIN_YUV_FULL))
matrix_csc = VDIN_MATRIX_YUV709F_YUV709;
} else {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_YUV_FULL)
matrix_csc =
VDIN_MATRIX_YUV601F_YUV709F;
else
matrix_csc = VDIN_MATRIX_YUV601_YUV709F;
} else {
if (color_fmt_range == TVIN_YUV_FULL)
matrix_csc = VDIN_MATRIX_YUV601F_YUV709;
else
matrix_csc = VDIN_MATRIX_YUV601_YUV709;
}
}
if (vdin_hdr_flag == 1)
matrix_csc = VDIN_MATRIX_NULL;
break;
default:
matrix_csc = VDIN_MATRIX_NULL;
break;
}
if (matrix_csc == VDIN_MATRIX_NULL) {
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID);
} else {
matrix_tbl = &vdin_matrix_lup[matrix_csc - 1];
/*coefficient index select matrix0*/
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID);
wr(offset,
VDIN_MATRIX_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1);
wr(offset,
VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2);
wr(offset, VDIN_MATRIX_COEF00_01, matrix_tbl->coef00_01);
wr(offset, VDIN_MATRIX_COEF02_10, matrix_tbl->coef02_10);
wr(offset, VDIN_MATRIX_COEF11_12, matrix_tbl->coef11_12);
wr(offset, VDIN_MATRIX_COEF20_21, matrix_tbl->coef20_21);
wr(offset, VDIN_MATRIX_COEF22, matrix_tbl->coef22);
wr(offset, VDIN_MATRIX_OFFSET0_1, matrix_tbl->post_offset0_1);
wr(offset, VDIN_MATRIX_OFFSET2, matrix_tbl->post_offset2);
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX0_BYPASS_BIT, VDIN_MATRIX0_BYPASS_WID);
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID);
}
}
static void vdin_set_color_matrix0_g12a(unsigned int offset,
struct tvin_format_s *tvin_fmt_p,
enum vdin_format_convert_e format_convert,
enum tvin_port_e port,
enum tvin_color_fmt_range_e color_fmt_range,
unsigned int vdin_hdr_flag,
unsigned int color_range_mode)
{
enum vdin_matrix_csc_e matrix_csc = VDIN_MATRIX_NULL;
struct vdin_matrix_lup_s *matrix_tbl;
struct tvin_format_s *fmt_info = tvin_fmt_p;
switch (format_convert) {
case VDIN_MATRIX_XXX_YUV_BLACK:
matrix_csc = VDIN_MATRIX_XXX_YUV601_BLACK;
break;
case VDIN_FORMAT_CONVERT_RGB_YUV422:
case VDIN_FORMAT_CONVERT_RGB_NV12:
case VDIN_FORMAT_CONVERT_RGB_NV21:
if ((port >= TVIN_PORT_HDMI0) &&
(port <= TVIN_PORT_HDMI7)) {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_RGB_FULL) {
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGB_YUV709;
} else {
matrix_csc =
VDIN_MATRIX_RGBS_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_fmt_range == TVIN_RGB_FULL)
matrix_csc = VDIN_MATRIX_RGB_YUV709;
else
matrix_csc = VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_range_mode == 1)
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
else
matrix_csc = VDIN_MATRIX_RGB_YUV709;
}
break;
case VDIN_FORMAT_CONVERT_GBR_YUV422:
matrix_csc = VDIN_MATRIX_GBR_YUV601;
break;
case VDIN_FORMAT_CONVERT_BRG_YUV422:
matrix_csc = VDIN_MATRIX_BRG_YUV601;
break;
case VDIN_FORMAT_CONVERT_RGB_YUV444:
if ((port >= TVIN_PORT_HDMI0) &&
(port <= TVIN_PORT_HDMI7)) {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_RGB_FULL) {
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGB_YUV709;
} else {
matrix_csc = VDIN_MATRIX_RGBS_YUV709F;
if (vdin_hdr_flag == 1)
matrix_csc =
VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_fmt_range == TVIN_RGB_FULL)
matrix_csc = VDIN_MATRIX_RGB_YUV709;
else
matrix_csc = VDIN_MATRIX_RGBS_YUV709;
}
} else {
if (color_range_mode == 1)
matrix_csc = VDIN_MATRIX_RGB_YUV709F;
else
matrix_csc = VDIN_MATRIX_RGB_YUV709;
}
break;
case VDIN_FORMAT_CONVERT_YUV_RGB:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_RGB;
else
matrix_csc = VDIN_MATRIX_YUV601_RGB;
break;
case VDIN_FORMAT_CONVERT_YUV_GBR:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_GBR;
else
matrix_csc = VDIN_MATRIX_YUV601_GBR;
break;
case VDIN_FORMAT_CONVERT_YUV_BRG:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
)
matrix_csc = VDIN_MATRIX_YUV709_BRG;
else
matrix_csc = VDIN_MATRIX_YUV601_BRG;
break;
case VDIN_FORMAT_CONVERT_YUV_YUV422:
case VDIN_FORMAT_CONVERT_YUV_YUV444:
case VDIN_FORMAT_CONVERT_YUV_NV12:
case VDIN_FORMAT_CONVERT_YUV_NV21:
if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) &&
(fmt_info->v_active >= 720)) || /* 720p & above */
((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED) &&
(fmt_info->v_active >= 540)) /* 1080i & above */
) {
if ((color_range_mode == 1) &&
(color_fmt_range != TVIN_YUV_FULL))
matrix_csc = VDIN_MATRIX_YUV709_YUV709F;
else if ((color_range_mode == 0) &&
(color_fmt_range == TVIN_YUV_FULL))
matrix_csc = VDIN_MATRIX_YUV709F_YUV709;
} else {
if (color_range_mode == 1) {
if (color_fmt_range == TVIN_YUV_FULL)
matrix_csc =
VDIN_MATRIX_YUV601F_YUV709F;
else
matrix_csc = VDIN_MATRIX_YUV601_YUV709F;
} else {
if (color_fmt_range == TVIN_YUV_FULL)
matrix_csc = VDIN_MATRIX_YUV601F_YUV709;
else
matrix_csc = VDIN_MATRIX_YUV601_YUV709;
}
}
if (vdin_hdr_flag == 1)
matrix_csc = VDIN_MATRIX_NULL;
break;
default:
matrix_csc = VDIN_MATRIX_NULL;
break;
}
if (matrix_csc == VDIN_MATRIX_NULL) {
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID);
} else {
matrix_tbl = &vdin_matrix_lup[matrix_csc - 1];
/*coefficient index select matrix0*/
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID);
wr(offset,
VDIN_MATRIX_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1);
wr(offset,
VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2);
wr(offset, VDIN_HDR2_MATRIXI_COEF00_01, matrix_tbl->coef00_01);
wr(offset, VDIN_HDR2_MATRIXI_COEF02_10, matrix_tbl->coef02_10);
wr(offset, VDIN_HDR2_MATRIXI_COEF11_12, matrix_tbl->coef11_12);
wr(offset, VDIN_HDR2_MATRIXI_COEF20_21, matrix_tbl->coef20_21);
wr(offset, VDIN_HDR2_MATRIXI_COEF22, matrix_tbl->coef22);
wr(offset, VDIN_HDR2_MATRIXI_OFFSET0_1,
matrix_tbl->post_offset0_1);
wr(offset, VDIN_HDR2_MATRIXI_OFFSET2, matrix_tbl->post_offset2);
wr_bits(offset, VDIN_HDR2_MATRIXI_EN_CTRL, 1, 0, 1);
wr_bits(offset, VDIN_HDR2_CTRL, 1, 16, 1);
wr_bits(offset, VDIN_HDR2_CTRL, 0, 13, 1);
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX0_BYPASS_BIT, VDIN_MATRIX0_BYPASS_WID);
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID);
}
}
/*set matrix based on rgb_info_enable:
* 0:set matrix0, disable matrix1
* 1:set matrix1, set matrix0
*/
void vdin_set_matrix(struct vdin_dev_s *devp)
{
enum vdin_format_convert_e format_convert_matrix0;
enum vdin_format_convert_e format_convert_matrix1;
unsigned int offset = devp->addr_offset;
if (rgb_info_enable == 0) {
/* vdin_set_color_matrix1(devp->addr_offset, devp->fmt_info_p,
* devp->format_convert);
* disable matrix1
*/
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID);
if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
is_meson_sm1_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
else
vdin_set_color_matrix0(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if ((devp->dv.dolby_input & (1 << devp->index)) ||
(devp->dv.dv_flag && is_dolby_vision_enable()))
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID);
#endif
wr_bits(offset, VDIN_MATRIX_CTRL, 3,
VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID);
} else {
format_convert_matrix0 = vdin_get_format_convert_matrix0(devp);
format_convert_matrix1 = vdin_get_format_convert_matrix1(devp);
vdin_set_color_matrix1(devp->addr_offset, devp->fmt_info_p,
format_convert_matrix1,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
is_meson_sm1_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
else
vdin_set_color_matrix0(devp->addr_offset,
devp->fmt_info_p,
format_convert_matrix0,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
/* set xy */
wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y,
PROBE_POX_Y_BIT, PROBE_POX_Y_WID);
wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x,
PROBE_POS_X_BIT, PROBE_POS_X_WID);
/* 1:probe pixel data after matrix */
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID);
/* 1:select matrix 1 */
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID);
}
}
void vdin_set_matrixs(struct vdin_dev_s *devp, unsigned char id,
enum vdin_format_convert_e csc)
{
switch (id) {
case 0:
if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
is_meson_sm1_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
else
vdin_set_color_matrix0(devp->addr_offset,
devp->fmt_info_p, csc,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
break;
case 1:
vdin_set_color_matrix1(devp->addr_offset,
devp->fmt_info_p, csc,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
break;
default:
break;
}
}
/* this function set flowing parameters:
*a.rgb_info_x b.rgb_info_y
*debug usage:
*echo rgb_xy x y > /sys/class/vdin/vdinx/attr
*/
void vdin_set_prob_xy(unsigned int offset,
unsigned int x, unsigned int y, struct vdin_dev_s *devp)
{
enum vdin_format_convert_e format_convert_matrix0;
enum vdin_format_convert_e format_convert_matrix1;
/* set matrix */
rgb_info_enable = 1;
format_convert_matrix0 = vdin_get_format_convert_matrix0(devp);
format_convert_matrix1 = vdin_get_format_convert_matrix1(devp);
vdin_set_color_matrix1(devp->addr_offset, devp->fmt_info_p,
format_convert_matrix1,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_sm1_cpu())
vdin_set_color_matrix0_g12a(devp->addr_offset,
devp->fmt_info_p,
devp->format_convert,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
else
vdin_set_color_matrix0(devp->addr_offset, devp->fmt_info_p,
format_convert_matrix0,
devp->parm.port,
devp->prop.color_fmt_range,
devp->prop.vdin_hdr_Flag,
devp->color_range_mode);
/* set position */
rgb_info_x = x;
if (devp->fmt_info_p->scan_mode == TVIN_SCAN_MODE_INTERLACED)
rgb_info_y = y/2;
else
rgb_info_y = y;
/* #if defined(VDIN_V1) */
wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y,
PROBE_POX_Y_BIT, PROBE_POX_Y_WID);
wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x,
PROBE_POS_X_BIT, PROBE_POS_X_WID);
/* 1:probe pixel data after matrix */
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID);
/* 1:select matrix 1 */
wr_bits(offset, VDIN_MATRIX_CTRL, 1,
VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID);
/* #endif */
}
/*set block bar
*base on flowing parameters:
*a.h_active b.v_active
*/
static inline void vdin_set_bbar(unsigned int offset, unsigned int v,
unsigned int h)
{
unsigned int region_width = 1, block_thr = 0, line_thr = 0;
while ((region_width<<1) < h)
region_width <<= 1;
block_thr = (region_width>>1) * v;
/* bblk=(bpix>thr) */
block_thr = block_thr - (block_thr >> BBAR_BLOCK_THR_FACTOR);
/* bln=!(wpix>=thr) */
line_thr = h >> BBAR_LINE_THR_FACTOR;
/* region_width */
wr_bits(offset, VDIN_BLKBAR_CTRL0,
region_width, BLKBAR_H_WIDTH_BIT, BLKBAR_H_WIDTH_WID);
/* win_he */
wr_bits(offset, VDIN_BLKBAR_H_START_END,
(h - 1), BLKBAR_HEND_BIT, BLKBAR_HEND_WID);
/* win_ve */
wr_bits(offset, VDIN_BLKBAR_V_START_END,
(v - 1), BLKBAR_VEND_BIT, BLKBAR_VEND_WID);
/* bblk_thr_on_bpix */
wr_bits(offset, VDIN_BLKBAR_CNT_THRESHOLD,
block_thr, BLKBAR_CNT_TH_BIT, BLKBAR_CNT_TH_WID);
/* blnt_thr_on_wpix */
wr_bits(offset, VDIN_BLKBAR_ROW_TH1_TH2,
line_thr, BLKBAR_ROW_TH1_BIT, BLKBAR_ROW_TH1_WID);
/* blnb_thr_on_wpix */
wr_bits(offset, VDIN_BLKBAR_ROW_TH1_TH2,
line_thr, BLKBAR_ROW_TH2_BIT, BLKBAR_ROW_TH2_WID);
/* en */
wr_bits(offset, VDIN_BLKBAR_CTRL0,
1, BLKBAR_DET_TOP_EN_BIT, BLKBAR_DET_TOP_EN_WID);
/* manual reset, rst = 0 & 1, raising edge mode */
wr_bits(offset, VDIN_BLKBAR_CTRL0, 0,
BLKBAR_DET_SOFT_RST_N_BIT, BLKBAR_DET_SOFT_RST_N_WID);
wr_bits(offset, VDIN_BLKBAR_CTRL0, 1,
BLKBAR_DET_SOFT_RST_N_BIT, BLKBAR_DET_SOFT_RST_N_WID);
}
/*set histogram window
* pow\h_start\h_end\v_start\v_end
*/
static inline void vdin_set_histogram(unsigned int offset, unsigned int hs,
unsigned int he, unsigned int vs, unsigned int ve)
{
unsigned int pixel_sum = 0, record_len = 0, hist_pow = 0;
if ((hs < he) && (vs < ve)) {
pixel_sum = (he - hs + 1) * (ve - vs + 1);
record_len = 0xffff<<3;
while ((pixel_sum > record_len) && (hist_pow < 3)) {
hist_pow++;
record_len <<= 1;
}
/* #ifdef CONFIG_MESON2_CHIP */
/* pow */
wr_bits(offset, VDIN_HIST_CTRL, hist_pow,
HIST_POW_BIT, HIST_POW_WID);
/* win_hs */
wr_bits(offset, VDIN_HIST_H_START_END, hs,
HIST_HSTART_BIT, HIST_HSTART_WID);
/* win_he */
wr_bits(offset, VDIN_HIST_H_START_END, he,
HIST_HEND_BIT, HIST_HEND_WID);
/* win_vs */
wr_bits(offset, VDIN_HIST_V_START_END, vs,
HIST_VSTART_BIT, HIST_VSTART_WID);
/* win_ve */
wr_bits(offset, VDIN_HIST_V_START_END, ve,
HIST_VEND_BIT, HIST_VEND_WID);
}
}
/*set hist mux
*VDIN_HIST_CTRL
* Bit 3:2 hist_din_sel the source used for hist statistics.
* 00: from matrix0 dout, 01: from vsc_dout,
* 10: from matrix1 dout, 11: form matrix1 din
*/
static inline void vdin_set_hist_mux(struct vdin_dev_s *devp)
{
enum tvin_port_e port = TVIN_PORT_NULL;
port = devp->parm.port;
if ((port < TVIN_PORT_HDMI0) || (port > TVIN_PORT_HDMI7))
return;
/* use 11: form matrix1 din */
wr_bits(devp->addr_offset, VDIN_HIST_CTRL, 3,
HIST_HIST_DIN_SEL_BIT, HIST_HIST_DIN_SEL_WID);
/*for project get vdin1 hist*/
//if (devp->index == 1)
// wr_bits(devp->addr_offset, VDIN_WR_CTRL2, 1, 8, 1);
}
/* urgent ctr config */
/*if vdin fifo over up_th,will trigger increase
* urgent responds to vdin write,
*if vdin fifo lower dn_th,will trigger decrease
* urgent responds to vdin write
*/
static void vdin_urgent_patch(unsigned int offset, unsigned int v,
unsigned int h)
{
if ((h >= 1920) && (v >= 1080)) {
wr_bits(offset, VDIN_LFIFO_URG_CTRL, 1,
VDIN_LFIFO_URG_CTRL_EN_BIT, VDIN_LFIFO_URG_CTRL_EN_WID);
wr_bits(offset, VDIN_LFIFO_URG_CTRL, 1,
VDIN_LFIFO_URG_WR_EN_BIT, VDIN_LFIFO_URG_WR_EN_WID);
wr_bits(offset, VDIN_LFIFO_URG_CTRL, 20,
VDIN_LFIFO_URG_UP_TH_BIT, VDIN_LFIFO_URG_UP_TH_WID);
wr_bits(offset, VDIN_LFIFO_URG_CTRL, 8,
VDIN_LFIFO_URG_DN_TH_BIT, VDIN_LFIFO_URG_DN_TH_WID);
/*vlsi guys suggest setting:*/
W_VCBUS_BIT(VPU_ARB_URG_CTRL, 1,
VDIN_LFF_URG_CTRL_BIT, VDIN_LFF_URG_CTRL_WID);
W_VCBUS_BIT(VPU_ARB_URG_CTRL, 1,
VPP_OFF_URG_CTRL_BIT, VPP_OFF_URG_CTRL_WID);
} else {
wr(offset, VDIN_LFIFO_URG_CTRL, 0);
aml_write_vcbus(VPU_ARB_URG_CTRL, 0);
}
}
void vdin_urgent_patch_resume(unsigned int offset)
{
/* urgent ctr config */
wr(offset, VDIN_LFIFO_URG_CTRL, 0);
aml_write_vcbus(VPU_ARB_URG_CTRL, 0);
}
/*set write ctrl regs:
*VDIN_WR_H_START_END
*VDIN_WR_V_START_END
*VDIN_WR_CTRL
*VDIN_LFIFO_URG_CTRL
*/
static inline void vdin_set_wr_ctrl(struct vdin_dev_s *devp,
unsigned int offset, unsigned int v,
unsigned int h, enum vdin_format_convert_e format_convert,
unsigned int color_depth_mode, unsigned int source_bitdeth)
{
unsigned int write_format444 = 0, swap_cbcr = 0;
/* unsigned int def_canvas_id = offset?
* vdin_canvas_ids[1][0]:vdin_canvas_ids[0][0];
*/
switch (format_convert) {
case VDIN_FORMAT_CONVERT_YUV_YUV422:
case VDIN_FORMAT_CONVERT_RGB_YUV422:
write_format444 = 0;
break;
case VDIN_FORMAT_CONVERT_YUV_NV12:
case VDIN_FORMAT_CONVERT_RGB_NV12:
write_format444 = 2;
swap_cbcr = 1;
break;
case VDIN_FORMAT_CONVERT_YUV_NV21:
case VDIN_FORMAT_CONVERT_RGB_NV21:
write_format444 = 2;
swap_cbcr = 0;
break;
default:
write_format444 = 1;
break;
}
/*yuv422 full pack mode for 10bit*/
if (((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) ||
(format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) ||
(format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) ||
(format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) &&
color_depth_mode && (source_bitdeth > 8))
write_format444 = 3;
/* win_he */
if ((h%2) && (devp->source_bitdepth > 8) &&
(devp->color_depth_mode == 1) &&
((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)))
h += 1;
wr_bits(offset, VDIN_WR_H_START_END, (h - 1), WR_HEND_BIT, WR_HEND_WID);
/* win_ve */
wr_bits(offset, VDIN_WR_V_START_END, (v - 1), WR_VEND_BIT, WR_VEND_WID);
/* hconv_mode */
wr_bits(offset, VDIN_WR_CTRL, 2, HCONV_MODE_BIT, HCONV_MODE_WID);
/* vconv_mode */
wr_bits(offset, VDIN_WR_CTRL, 0, VCONV_MODE_BIT, VCONV_MODE_WID);
if (write_format444 == 2) {
/* swap_cbcr */
wr_bits(offset, VDIN_WR_CTRL, swap_cbcr,
SWAP_CBCR_BIT, SWAP_CBCR_WID);
/* output even lines's cbcr */
wr_bits(offset, VDIN_WR_CTRL, 0,
VCONV_MODE_BIT, VCONV_MODE_WID);
wr_bits(offset, VDIN_WR_CTRL, 2,
HCONV_MODE_BIT, HCONV_MODE_WID);
/* chroma canvas */
/* wr_bits(offset, VDIN_WR_CTRL2, def_canvas_id+1,
* WRITE_CHROMA_CANVAS_ADDR_BIT,
* WRITE_CHROMA_CANVAS_ADDR_WID);
*/
} else if (write_format444 == 1) {
/* output all cbcr */
wr_bits(offset, VDIN_WR_CTRL, 3,
VCONV_MODE_BIT, VCONV_MODE_WID);
} else {
/* swap_cbcr */
wr_bits(offset, VDIN_WR_CTRL, 0, SWAP_CBCR_BIT, SWAP_CBCR_WID);
/* chroma canvas */
/* wr_bits(offset, VDIN_WR_CTRL2, 0,
* WRITE_CHROMA_CANVAS_ADDR_BIT,
*/
/* WRITE_CHROMA_CANVAS_ADDR_WID); */
}
/* format444 */
wr_bits(offset, VDIN_WR_CTRL, write_format444, WR_FMT_BIT, WR_FMT_WID);
/* canvas_id
* wr_bits(offset, VDIN_WR_CTRL,
* def_canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID);
*/
/* req_urgent */
wr_bits(offset, VDIN_WR_CTRL, 1, WR_REQ_URGENT_BIT, WR_REQ_URGENT_WID);
/* req_en */
wr_bits(offset, VDIN_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID);
/*only for vdin0*/
if (devp->urgent_en && (devp->index == 0))
vdin_urgent_patch(offset, v, h);
/* dis ctrl reg wpulse */
/*if (is_meson_g9tv_cpu() || is_meson_m8_cpu() ||
* is_meson_m8m2_cpu() || is_meson_gxbb_cpu() ||
* is_meson_m8b_cpu())
*/
wr_bits(offset, VDIN_WR_CTRL, 1,
VDIN_WRCTRLREG_PAUSE_BIT, 1);
/* swap the 2 64bits word in 128 words */
/*if (is_meson_gxbb_cpu())*/
wr_bits(offset, VDIN_WR_CTRL, 1, 19, 1);
}
void vdin_set_wr_ctrl_vsync(struct vdin_dev_s *devp,
unsigned int offset, enum vdin_format_convert_e format_convert,
unsigned int color_depth_mode, unsigned int source_bitdeth,
unsigned int rdma_enable)
{
unsigned int write_format444 = 0, swap_cbcr = 0;
unsigned int hconv_mode, vconv_mode;
switch (format_convert) {
case VDIN_FORMAT_CONVERT_YUV_YUV422:
case VDIN_FORMAT_CONVERT_RGB_YUV422:
write_format444 = 0;
break;
case VDIN_FORMAT_CONVERT_YUV_NV12:
case VDIN_FORMAT_CONVERT_RGB_NV12:
write_format444 = 2;
swap_cbcr = 1;
break;
case VDIN_FORMAT_CONVERT_YUV_NV21:
case VDIN_FORMAT_CONVERT_RGB_NV21:
write_format444 = 2;
swap_cbcr = 0;
break;
default:
write_format444 = 1;
break;
}
/*yuv422 full pack mode for 10bit*/
if (((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) ||
(format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) ||
(format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) ||
(format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) &&
color_depth_mode && (source_bitdeth > 8))
write_format444 = 3;
/* hconv_mode */
hconv_mode = 0;
/* vconv_mode */
vconv_mode = 0;
if (write_format444 == 2) {
hconv_mode = 2;
vconv_mode = 0;
} else if (write_format444 == 1) {
vconv_mode = 3;
} else {
hconv_mode = 2;
swap_cbcr = 0;
}
#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (rdma_enable) {
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL+devp->addr_offset,
hconv_mode, HCONV_MODE_BIT, HCONV_MODE_WID);
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL+devp->addr_offset,
vconv_mode, VCONV_MODE_BIT, VCONV_MODE_WID);
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL+devp->addr_offset,
swap_cbcr, SWAP_CBCR_BIT, SWAP_CBCR_WID);
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL+devp->addr_offset,
write_format444, WR_FMT_BIT, WR_FMT_WID);
} else
#endif
{
wr_bits(offset, VDIN_WR_CTRL, hconv_mode,
HCONV_MODE_BIT, HCONV_MODE_WID);
wr_bits(offset, VDIN_WR_CTRL, vconv_mode,
VCONV_MODE_BIT, VCONV_MODE_WID);
wr_bits(offset, VDIN_WR_CTRL, swap_cbcr,
SWAP_CBCR_BIT, SWAP_CBCR_WID);
wr_bits(offset, VDIN_WR_CTRL, write_format444,
WR_FMT_BIT, WR_FMT_WID);
}
}
/* set vdin_wr_mif for video only */
void vdin_set_wr_mif(struct vdin_dev_s *devp)
{
int height, width;
static unsigned int temp_height;
static unsigned int temp_width;
height = ((rd(0, VPP_POSTBLEND_VD1_V_START_END) & 0xfff) -
((rd(0, VPP_POSTBLEND_VD1_V_START_END) >> 16) &
0xfff) + 1);
width = ((rd(0, VPP_POSTBLEND_VD1_H_START_END) & 0xfff) -
((rd(0, VPP_POSTBLEND_VD1_H_START_END) >> 16) &
0xfff) + 1);
if ((devp->parm.port == TVIN_PORT_VIU1_VIDEO) && (devp->index == 1) &&
((height != temp_height) && (width != temp_width))) {
if ((width%2) && (devp->source_bitdepth >
VDIN_MIN_SOURCE_BITDEPTH) &&
(devp->color_depth_mode == 1) &&
((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)))
width += 1;
wr_bits(devp->addr_offset, VDIN_WR_H_START_END,
(width - 1), WR_HEND_BIT, WR_HEND_WID);
wr_bits(devp->addr_offset, VDIN_WR_V_START_END,
(height - 1), WR_VEND_BIT, WR_VEND_WID);
temp_height = height;
temp_width = width;
}
}
/***************************global function**********************************/
unsigned int vdin_get_meas_hcnt64(unsigned int offset)
{
return rd_bits(offset, VDIN_MEAS_HS_COUNT,
MEAS_HS_CNT_BIT, MEAS_HS_CNT_WID);
}
unsigned int vdin_get_meas_vstamp(unsigned int offset)
{
return rd(offset, VDIN_MEAS_VS_COUNT_LO);
}
unsigned int vdin_get_active_h(unsigned int offset)
{
return rd_bits(offset, VDIN_ACTIVE_MAX_PIX_CNT_STATUS,
ACTIVE_MAX_PIX_CNT_SDW_BIT, ACTIVE_MAX_PIX_CNT_SDW_WID);
}
unsigned int vdin_get_active_v(unsigned int offset)
{
return rd_bits(offset, VDIN_LCNT_SHADOW_STATUS,
ACTIVE_LN_CNT_SDW_BIT, ACTIVE_LN_CNT_SDW_WID);
}
unsigned int vdin_get_total_v(unsigned int offset)
{
return rd_bits(offset, VDIN_LCNT_SHADOW_STATUS,
GO_LN_CNT_SDW_BIT, GO_LN_CNT_SDW_WID);
}
void vdin_set_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable,
unsigned int canvas_id)
{
#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (rdma_enable) {
if (is_meson_g12a_cpu() || is_meson_g12b_cpu() ||
is_meson_sm1_cpu()) {
rdma_write_reg_bits(devp->rdma_handle,
VDIN_COM_CTRL0+devp->addr_offset, 1,
VDIN_FORCEGOLINE_EN_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle,
VDIN_COM_CTRL0+devp->addr_offset, 0,
VDIN_FORCEGOLINE_EN_BIT, 1);
}
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL+devp->addr_offset,
canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID);
} else
#endif
wr_bits(devp->addr_offset, VDIN_WR_CTRL, canvas_id,
WR_CANVAS_BIT, WR_CANVAS_WID);
}
unsigned int vdin_get_canvas_id(unsigned int offset)
{
return rd_bits(offset, VDIN_WR_CTRL, WR_CANVAS_BIT, WR_CANVAS_WID);
}
void vdin_set_chma_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable,
unsigned int canvas_id)
{
#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
if (rdma_enable)
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WR_CTRL2+devp->addr_offset,
canvas_id, WRITE_CHROMA_CANVAS_ADDR_BIT,
WRITE_CHROMA_CANVAS_ADDR_WID);
else
#endif
wr_bits(devp->addr_offset, VDIN_WR_CTRL2, canvas_id,
WRITE_CHROMA_CANVAS_ADDR_BIT,
WRITE_CHROMA_CANVAS_ADDR_WID);
}
unsigned int vdin_get_chma_canvas_id(unsigned int offset)
{
return rd_bits(offset, VDIN_WR_CTRL2, WRITE_CHROMA_CANVAS_ADDR_BIT,
WRITE_CHROMA_CANVAS_ADDR_WID);
}
/* reset default writing cavnas register */
void vdin_set_def_wr_canvas(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
unsigned int def_canvas;
def_canvas = vdin_canvas_ids[devp->index][0];
/* [31:24] write.out_ctrl = 0x0b */
/* [ 23] write.frame_rst_on_vs = 1 */
/* [ 22] write.lfifo_rst_on_vs = 1 */
/* [ 21] write.clr_direct_done = 0 */
/* [ 20] write.clr_nr_done = 0 */
/* [ 12] write.format444 = 1/(422, 444) */
/* [ 11] write.canvas_latch_en = 0 */
/* [ 9] write.req_urgent = 0 ***sub_module.enable*** */
/* [ 8] write.req_en = 0 ***sub_module.enable*** */
/* [ 7: 0] write.canvas = 0 */
if (enable_reset)
wr(offset, VDIN_WR_CTRL, (0x0b401000 | def_canvas));
else
wr(offset, VDIN_WR_CTRL, (0x0bc01000 | def_canvas));
}
/*set local dimming*/
#ifdef CONFIG_AML_LOCAL_DIMMING
#define VDIN_LDIM_PIC_ROWMAX 1080
#define VDIN_LDIM_PIC_COLMAX 1920
#define VDIN_LDIMMAX_HIDX 4095
#define VDIN_LDIM_BLK_VNUM 2
#define VDIN_LDIM_BLK_HNUM 8
static void vdin_set_ldim_max_init(unsigned int offset,
int pic_h, int pic_v, int blk_vnum, int blk_hnum)
{
int k;
struct ldim_max_s ldimmax;
int ldim_pic_rowmax = VDIN_LDIM_PIC_ROWMAX;
int ldim_pic_colmax = VDIN_LDIM_PIC_COLMAX;
int ldim_blk_vnum = VDIN_LDIM_BLK_VNUM;
int ldim_blk_hnum = VDIN_LDIM_BLK_HNUM;
ldim_pic_rowmax = pic_v;
ldim_pic_colmax = pic_h;
ldim_blk_vnum = blk_vnum; /* 8; */
ldim_blk_hnum = blk_hnum; /* 2; */
ldimmax.ld_stamax_hidx[0] = 0;
/* check ic type */
if (!is_meson_gxtvbb_cpu())
return;
if (vdin_ctl_dbg)
pr_info("\n****************vdin_set_ldim_max_init:hidx start********\n");
for (k = 1; k < 11; k++) {
ldimmax.ld_stamax_hidx[k] =
((ldim_pic_colmax + ldim_blk_hnum - 1)/ldim_blk_hnum)*k;
if (ldimmax.ld_stamax_hidx[k] > VDIN_LDIMMAX_HIDX)
/* clip U12 */
ldimmax.ld_stamax_hidx[k] = VDIN_LDIMMAX_HIDX;
if (ldimmax.ld_stamax_hidx[k] == ldim_pic_colmax)
ldimmax.ld_stamax_hidx[k] = ldim_pic_colmax - 1;
if (vdin_ctl_dbg)
pr_info("%d\t", ldimmax.ld_stamax_hidx[k]);
}
if (vdin_ctl_dbg)
pr_info("\n****************vdin_set_ldim_max_init:hidx end*********\n");
ldimmax.ld_stamax_vidx[0] = 0;
if (vdin_ctl_dbg)
pr_info("\n***********vdin_set_ldim_max_init:vidx start************\n");
for (k = 1; k < 11; k++) {
ldimmax.ld_stamax_vidx[k] = ((ldim_pic_rowmax +
ldim_blk_vnum - 1)/ldim_blk_vnum)*k;
if (ldimmax.ld_stamax_vidx[k] > VDIN_LDIMMAX_HIDX)
/* clip to U12 */
ldimmax.ld_stamax_vidx[k] = VDIN_LDIMMAX_HIDX;
if (ldimmax.ld_stamax_vidx[k] == ldim_pic_rowmax)
ldimmax.ld_stamax_vidx[k] = ldim_pic_rowmax - 1;
if (vdin_ctl_dbg)
pr_info("%d\t", ldimmax.ld_stamax_vidx[k]);
}
if (vdin_ctl_dbg)
pr_info("\n*******vdin_set_ldim_max_init:vidx end*******\n");
wr(offset, VDIN_LDIM_STTS_HIST_REGION_IDX,
(1 << LOCAL_DIM_STATISTIC_EN_BIT) |
(0 << EOL_EN_BIT) |
(2 << VLINE_OVERLAP_NUMBER_BIT) |
(1 << HLINE_OVERLAP_NUMBER_BIT) |
(1 << LPF_BEFORE_STATISTIC_EN_BIT) |
(1 << REGION_RD_INDEX_INC_BIT)
);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 0,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_vidx[0]<<16|ldimmax.ld_stamax_hidx[0]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 1,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_hidx[2]<<16|ldimmax.ld_stamax_hidx[1]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 2,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_vidx[2]<<16|ldimmax.ld_stamax_vidx[1]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 3,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_hidx[4]<<16|ldimmax.ld_stamax_hidx[3]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 4,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_vidx[4]<<16|ldimmax.ld_stamax_vidx[3]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 5,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_hidx[6]<<16|ldimmax.ld_stamax_hidx[5]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 6,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_vidx[6]<<16|ldimmax.ld_stamax_vidx[5]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 7,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_hidx[8]<<16|ldimmax.ld_stamax_hidx[7]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 8,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_vidx[8]<<16|ldimmax.ld_stamax_vidx[7]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 9,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_hidx[10]<<16|ldimmax.ld_stamax_hidx[9]);
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 10,
BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID);
wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION,
ldimmax.ld_stamax_vidx[10]<<16|ldimmax.ld_stamax_vidx[9]);
wr_bits(offset, VDIN_HIST_CTRL, 3, 9, 2);
wr_bits(offset, VDIN_HIST_CTRL, 1, 8, 1);
}
#endif
static unsigned int vdin_luma_max;
void vdin_set_vframe_prop_info(struct vframe_s *vf,
struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
u64 divid;
struct vframe_bbar_s bbar = {0};
#ifdef CONFIG_AML_LOCAL_DIMMING
/*int i;*/
#endif
/* fetch hist info */
/* vf->prop.hist.luma_sum = READ_CBUS_REG_BITS(VDIN_HIST_SPL_VAL,
* HIST_LUMA_SUM_BIT, HIST_LUMA_SUM_WID );
*/
vf->prop.hist.hist_pow = rd_bits(offset, VDIN_HIST_CTRL,
HIST_POW_BIT, HIST_POW_WID);
vf->prop.hist.luma_sum = rd(offset, VDIN_HIST_SPL_VAL);
/* vf->prop.hist.chroma_sum = READ_CBUS_REG_BITS(VDIN_HIST_CHROMA_SUM,
* HIST_CHROMA_SUM_BIT, HIST_CHROMA_SUM_WID );
*/
vf->prop.hist.chroma_sum = rd(offset, VDIN_HIST_CHROMA_SUM);
vf->prop.hist.pixel_sum = rd_bits(offset, VDIN_HIST_SPL_PIX_CNT,
HIST_PIX_CNT_BIT, HIST_PIX_CNT_WID);
vf->prop.hist.height = rd_bits(offset, VDIN_HIST_V_START_END,
HIST_VEND_BIT, HIST_VEND_WID) -
rd_bits(offset, VDIN_HIST_V_START_END,
HIST_VSTART_BIT, HIST_VSTART_WID)+1;
vf->prop.hist.width = rd_bits(offset, VDIN_HIST_H_START_END,
HIST_HEND_BIT, HIST_HEND_WID) -
rd_bits(offset, VDIN_HIST_H_START_END,
HIST_HSTART_BIT, HIST_HSTART_WID)+1;
vf->prop.hist.luma_max = rd_bits(offset, VDIN_HIST_MAX_MIN,
HIST_MAX_BIT, HIST_MAX_WID);
vf->prop.hist.luma_min = rd_bits(offset, VDIN_HIST_MAX_MIN,
HIST_MIN_BIT, HIST_MIN_WID);
vf->prop.hist.gamma[0] = rd_bits(offset, VDIN_DNLP_HIST00,
HIST_ON_BIN_00_BIT, HIST_ON_BIN_00_WID);
vf->prop.hist.gamma[1] = rd_bits(offset, VDIN_DNLP_HIST00,
HIST_ON_BIN_01_BIT, HIST_ON_BIN_01_WID);
vf->prop.hist.gamma[2] = rd_bits(offset, VDIN_DNLP_HIST01,
HIST_ON_BIN_02_BIT, HIST_ON_BIN_02_WID);
vf->prop.hist.gamma[3] = rd_bits(offset, VDIN_DNLP_HIST01,
HIST_ON_BIN_03_BIT, HIST_ON_BIN_03_WID);
vf->prop.hist.gamma[4] = rd_bits(offset, VDIN_DNLP_HIST02,
HIST_ON_BIN_04_BIT, HIST_ON_BIN_04_WID);
vf->prop.hist.gamma[5] = rd_bits(offset, VDIN_DNLP_HIST02,
HIST_ON_BIN_05_BIT, HIST_ON_BIN_05_WID);
vf->prop.hist.gamma[6] = rd_bits(offset, VDIN_DNLP_HIST03,
HIST_ON_BIN_06_BIT, HIST_ON_BIN_06_WID);
vf->prop.hist.gamma[7] = rd_bits(offset, VDIN_DNLP_HIST03,
HIST_ON_BIN_07_BIT, HIST_ON_BIN_07_WID);
vf->prop.hist.gamma[8] = rd_bits(offset, VDIN_DNLP_HIST04,
HIST_ON_BIN_08_BIT, HIST_ON_BIN_08_WID);
vf->prop.hist.gamma[9] = rd_bits(offset, VDIN_DNLP_HIST04,
HIST_ON_BIN_09_BIT, HIST_ON_BIN_09_WID);
vf->prop.hist.gamma[10] = rd_bits(offset, VDIN_DNLP_HIST05,
HIST_ON_BIN_10_BIT, HIST_ON_BIN_10_WID);
vf->prop.hist.gamma[11] = rd_bits(offset, VDIN_DNLP_HIST05,
HIST_ON_BIN_11_BIT, HIST_ON_BIN_11_WID);
vf->prop.hist.gamma[12] = rd_bits(offset, VDIN_DNLP_HIST06,
HIST_ON_BIN_12_BIT, HIST_ON_BIN_12_WID);
vf->prop.hist.gamma[13] = rd_bits(offset, VDIN_DNLP_HIST06,
HIST_ON_BIN_13_BIT, HIST_ON_BIN_13_WID);
vf->prop.hist.gamma[14] = rd_bits(offset, VDIN_DNLP_HIST07,
HIST_ON_BIN_14_BIT, HIST_ON_BIN_14_WID);
vf->prop.hist.gamma[15] = rd_bits(offset, VDIN_DNLP_HIST07,
HIST_ON_BIN_15_BIT, HIST_ON_BIN_15_WID);
vf->prop.hist.gamma[16] = rd_bits(offset, VDIN_DNLP_HIST08,
HIST_ON_BIN_16_BIT, HIST_ON_BIN_16_WID);
vf->prop.hist.gamma[17] = rd_bits(offset, VDIN_DNLP_HIST08,
HIST_ON_BIN_17_BIT, HIST_ON_BIN_17_WID);
vf->prop.hist.gamma[18] = rd_bits(offset, VDIN_DNLP_HIST09,
HIST_ON_BIN_18_BIT, HIST_ON_BIN_18_WID);
vf->prop.hist.gamma[19] = rd_bits(offset, VDIN_DNLP_HIST09,
HIST_ON_BIN_19_BIT, HIST_ON_BIN_19_WID);
vf->prop.hist.gamma[20] = rd_bits(offset, VDIN_DNLP_HIST10,
HIST_ON_BIN_20_BIT, HIST_ON_BIN_20_WID);
vf->prop.hist.gamma[21] = rd_bits(offset, VDIN_DNLP_HIST10,
HIST_ON_BIN_21_BIT, HIST_ON_BIN_21_WID);
vf->prop.hist.gamma[22] = rd_bits(offset, VDIN_DNLP_HIST11,
HIST_ON_BIN_22_BIT, HIST_ON_BIN_22_WID);
vf->prop.hist.gamma[23] = rd_bits(offset, VDIN_DNLP_HIST11,
HIST_ON_BIN_23_BIT, HIST_ON_BIN_23_WID);
vf->prop.hist.gamma[24] = rd_bits(offset, VDIN_DNLP_HIST12,
HIST_ON_BIN_24_BIT, HIST_ON_BIN_24_WID);
vf->prop.hist.gamma[25] = rd_bits(offset, VDIN_DNLP_HIST12,
HIST_ON_BIN_25_BIT, HIST_ON_BIN_25_WID);
vf->prop.hist.gamma[26] = rd_bits(offset, VDIN_DNLP_HIST13,
HIST_ON_BIN_26_BIT, HIST_ON_BIN_26_WID);
vf->prop.hist.gamma[27] = rd_bits(offset, VDIN_DNLP_HIST13,
HIST_ON_BIN_27_BIT, HIST_ON_BIN_27_WID);
vf->prop.hist.gamma[28] = rd_bits(offset, VDIN_DNLP_HIST14,
HIST_ON_BIN_28_BIT, HIST_ON_BIN_28_WID);
vf->prop.hist.gamma[29] = rd_bits(offset, VDIN_DNLP_HIST14,
HIST_ON_BIN_29_BIT, HIST_ON_BIN_29_WID);
vf->prop.hist.gamma[30] = rd_bits(offset, VDIN_DNLP_HIST15,
HIST_ON_BIN_30_BIT, HIST_ON_BIN_30_WID);
vf->prop.hist.gamma[31] = rd_bits(offset, VDIN_DNLP_HIST15,
HIST_ON_BIN_31_BIT, HIST_ON_BIN_31_WID);
vf->prop.hist.gamma[32] = rd_bits(offset, VDIN_DNLP_HIST16,
HIST_ON_BIN_32_BIT, HIST_ON_BIN_32_WID);
vf->prop.hist.gamma[33] = rd_bits(offset, VDIN_DNLP_HIST16,
HIST_ON_BIN_33_BIT, HIST_ON_BIN_33_WID);
vf->prop.hist.gamma[34] = rd_bits(offset, VDIN_DNLP_HIST17,
HIST_ON_BIN_34_BIT, HIST_ON_BIN_34_WID);
vf->prop.hist.gamma[35] = rd_bits(offset, VDIN_DNLP_HIST17,
HIST_ON_BIN_35_BIT, HIST_ON_BIN_35_WID);
vf->prop.hist.gamma[36] = rd_bits(offset, VDIN_DNLP_HIST18,
HIST_ON_BIN_36_BIT, HIST_ON_BIN_36_WID);
vf->prop.hist.gamma[37] = rd_bits(offset, VDIN_DNLP_HIST18,
HIST_ON_BIN_37_BIT, HIST_ON_BIN_37_WID);
vf->prop.hist.gamma[38] = rd_bits(offset, VDIN_DNLP_HIST19,
HIST_ON_BIN_38_BIT, HIST_ON_BIN_38_WID);
vf->prop.hist.gamma[39] = rd_bits(offset, VDIN_DNLP_HIST19,
HIST_ON_BIN_39_BIT, HIST_ON_BIN_39_WID);
vf->prop.hist.gamma[40] = rd_bits(offset, VDIN_DNLP_HIST20,
HIST_ON_BIN_40_BIT, HIST_ON_BIN_40_WID);
vf->prop.hist.gamma[41] = rd_bits(offset, VDIN_DNLP_HIST20,
HIST_ON_BIN_41_BIT, HIST_ON_BIN_41_WID);
vf->prop.hist.gamma[42] = rd_bits(offset, VDIN_DNLP_HIST21,
HIST_ON_BIN_42_BIT, HIST_ON_BIN_42_WID);
vf->prop.hist.gamma[43] = rd_bits(offset, VDIN_DNLP_HIST21,
HIST_ON_BIN_43_BIT, HIST_ON_BIN_43_WID);
vf->prop.hist.gamma[44] = rd_bits(offset, VDIN_DNLP_HIST22,
HIST_ON_BIN_44_BIT, HIST_ON_BIN_44_WID);
vf->prop.hist.gamma[45] = rd_bits(offset, VDIN_DNLP_HIST22,
HIST_ON_BIN_45_BIT, HIST_ON_BIN_45_WID);
vf->prop.hist.gamma[46] = rd_bits(offset, VDIN_DNLP_HIST23,
HIST_ON_BIN_46_BIT, HIST_ON_BIN_46_WID);
vf->prop.hist.gamma[47] = rd_bits(offset, VDIN_DNLP_HIST23,
HIST_ON_BIN_47_BIT, HIST_ON_BIN_47_WID);
vf->prop.hist.gamma[48] = rd_bits(offset, VDIN_DNLP_HIST24,
HIST_ON_BIN_48_BIT, HIST_ON_BIN_48_WID);
vf->prop.hist.gamma[49] = rd_bits(offset, VDIN_DNLP_HIST24,
HIST_ON_BIN_49_BIT, HIST_ON_BIN_49_WID);
vf->prop.hist.gamma[50] = rd_bits(offset, VDIN_DNLP_HIST25,
HIST_ON_BIN_50_BIT, HIST_ON_BIN_50_WID);
vf->prop.hist.gamma[51] = rd_bits(offset, VDIN_DNLP_HIST25,
HIST_ON_BIN_51_BIT, HIST_ON_BIN_51_WID);
vf->prop.hist.gamma[52] = rd_bits(offset, VDIN_DNLP_HIST26,
HIST_ON_BIN_52_BIT, HIST_ON_BIN_52_WID);
vf->prop.hist.gamma[53] = rd_bits(offset, VDIN_DNLP_HIST26,
HIST_ON_BIN_53_BIT, HIST_ON_BIN_53_WID);
vf->prop.hist.gamma[54] = rd_bits(offset, VDIN_DNLP_HIST27,
HIST_ON_BIN_54_BIT, HIST_ON_BIN_54_WID);
vf->prop.hist.gamma[55] = rd_bits(offset, VDIN_DNLP_HIST27,
HIST_ON_BIN_55_BIT, HIST_ON_BIN_55_WID);
vf->prop.hist.gamma[56] = rd_bits(offset, VDIN_DNLP_HIST28,
HIST_ON_BIN_56_BIT, HIST_ON_BIN_56_WID);
vf->prop.hist.gamma[57] = rd_bits(offset, VDIN_DNLP_HIST28,
HIST_ON_BIN_57_BIT, HIST_ON_BIN_57_WID);
vf->prop.hist.gamma[58] = rd_bits(offset, VDIN_DNLP_HIST29,
HIST_ON_BIN_58_BIT, HIST_ON_BIN_58_WID);
vf->prop.hist.gamma[59] = rd_bits(offset, VDIN_DNLP_HIST29,
HIST_ON_BIN_59_BIT, HIST_ON_BIN_59_WID);
vf->prop.hist.gamma[60] = rd_bits(offset, VDIN_DNLP_HIST30,
HIST_ON_BIN_60_BIT, HIST_ON_BIN_60_WID);
vf->prop.hist.gamma[61] = rd_bits(offset, VDIN_DNLP_HIST30,
HIST_ON_BIN_61_BIT, HIST_ON_BIN_61_WID);
vf->prop.hist.gamma[62] = rd_bits(offset, VDIN_DNLP_HIST31,
HIST_ON_BIN_62_BIT, HIST_ON_BIN_62_WID);
vf->prop.hist.gamma[63] = rd_bits(offset, VDIN_DNLP_HIST31,
HIST_ON_BIN_63_BIT, HIST_ON_BIN_63_WID);
/* fetch bbar info */
bbar.top = rd_bits(offset, VDIN_BLKBAR_STATUS0,
BLKBAR_TOP_POS_BIT, BLKBAR_TOP_POS_WID);
bbar.bottom = rd_bits(offset, VDIN_BLKBAR_STATUS0,
BLKBAR_BTM_POS_BIT, BLKBAR_BTM_POS_WID);
bbar.left = rd_bits(offset, VDIN_BLKBAR_STATUS1,
BLKBAR_LEFT_POS_BIT, BLKBAR_LEFT_POS_WID);
bbar.right = rd_bits(offset, VDIN_BLKBAR_STATUS1,
BLKBAR_RIGHT_POS_BIT, BLKBAR_RIGHT_POS_WID);
if (bbar.top > bbar.bottom) {
bbar.top = 0;
bbar.bottom = vf->height - 1;
}
if (bbar.left > bbar.right) {
bbar.left = 0;
bbar.right = vf->width - 1;
}
/* Update Histgram windown with detected BlackBar window */
if (devp->hist_bar_enable)
vdin_set_histogram(offset, 0, vf->width - 1, 0, vf->height - 1);
else
vdin_set_histogram(offset, bbar.left, bbar.right,
bbar.top, bbar.bottom);
if (devp->black_bar_enable) {
vf->prop.bbar.top = bbar.top;
vf->prop.bbar.bottom = bbar.bottom;
vf->prop.bbar.left = bbar.left;
vf->prop.bbar.right = bbar.right;
} else
memset(&vf->prop.bbar, 0, sizeof(struct vframe_bbar_s));
/* fetch meas info - For M2 or further chips only, not for M1 chip */
vf->prop.meas.vs_stamp = devp->stamp;
vf->prop.meas.vs_cycle = devp->cycle;
if ((vdin_ctl_dbg & (1 << 8)) &&
(vdin_luma_max != vf->prop.hist.luma_max)) {
divid = vf->ready_clock_hist[0] = sched_clock();
do_div(divid, 1000);
pr_info("vdin write done %lld us. lum_max(0x%x-->0x%x)\n",
divid, vdin_luma_max, vf->prop.hist.luma_max);
vdin_luma_max = vf->prop.hist.luma_max;
}
#if 0
/*#ifdef CONFIG_AML_LOCAL_DIMMING*/
/* get ldim max */
if (vdin_ldim_max_en && is_meson_gxtvbb_cpu()) {
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 0,
REGION_RD_INDEX_BIT, REGION_RD_INDEX_WID);
for (i = 0; i < 100; i++)
vf->prop.hist.ldim_max[i] = rd(offset,
VDIN_LDIM_STTS_HIST_READ_REGION);
}
#endif
}
static inline ulong vdin_reg_limit(ulong val, ulong wid)
{
if (val < (1<<wid))
return val;
else
return (1<<wid)-1;
}
void vdin_set_all_regs(struct vdin_dev_s *devp)
{
/* matrix sub-module */
vdin_set_matrix(devp);
/* bbar sub-module */
vdin_set_bbar(devp->addr_offset, devp->v_active, devp->h_active);
#ifdef CONFIG_AML_LOCAL_DIMMING
/* ldim sub-module */
/* vdin_set_ldim_max_init(devp->addr_offset, 1920, 1080, 8, 2); */
vdin_set_ldim_max_init(devp->addr_offset, devp->h_active,
devp->v_active,
VDIN_LDIM_BLK_HNUM, VDIN_LDIM_BLK_VNUM);
#endif
/* hist sub-module */
vdin_set_histogram(devp->addr_offset, 0,
devp->h_active - 1, 0, devp->v_active - 1);
/* hist mux selecttion */
vdin_set_hist_mux(devp);
/* write sub-module */
vdin_set_wr_ctrl(devp, devp->addr_offset, devp->v_active,
devp->h_active, devp->format_convert,
devp->color_depth_mode, devp->source_bitdepth);
/* top sub-module */
vdin_set_top(devp->addr_offset, devp->parm.port,
devp->prop.color_format, devp->h_active,
devp->bt_path);
/* */
vdin_set_meas_mux(devp->addr_offset, devp->parm.port,
devp->bt_path);
}
static void vdin_delay_line(unsigned short num, unsigned int offset)
{
wr_bits(offset, VDIN_COM_CTRL0, num,
DLY_GO_FLD_LN_NUM_BIT, DLY_GO_FLD_LN_NUM_WID);
if (num)
wr_bits(offset, VDIN_COM_CTRL0, 1,
DLY_GO_FLD_EN_BIT, DLY_GO_FLD_EN_WID);
else
wr_bits(offset, VDIN_COM_CTRL0, 0,
DLY_GO_FLD_EN_BIT, DLY_GO_FLD_EN_WID);
}
void vdin_set_default_regmap(unsigned int offset)
{
unsigned int def_canvas_id;
/* unsigned int offset = devp->addr_offset; */
/* [ 31] mpeg.en = 0 ***sub_module.enable*** */
/* [ 30] mpeg.even_fld = 0/(odd, even) */
/* [26:20] top.hold_ln = 0 //8 */
/* [ 19] vs_dly.en = 0 ***sub_module.enable*** */
/* [18:12] vs_dly.dly_ln = 0 */
/* [11:10] map.comp2 = 2/(comp0, comp1, comp2) */
/* [ 9: 8] map.comp1 = 1/(comp0, comp1, comp2) */
/* [ 7: 6] map.comp0 = 0/(comp0, comp1, comp2) */
/* [ 4] top.datapath_en = 1 */
/* [ 3: 0] top.mux = 0/(null, mpeg, 656, tvfe, cvd2, hdmi, dvin) */
wr(offset, VDIN_COM_CTRL0, 0x00000910);
vdin_delay_line(delay_line_num, offset);
/* [ 23] asfifo_tvfe.de_en = 1 */
/* [ 22] asfifo_tvfe.vs_en = 1 */
/* [ 21] asfifo_tvfe.hs_en = 1 */
/* [ 20] asfifo_tvfe.vs_inv = 0/(positive-active, negative-active) */
/* [ 19] asfifo_tvfe.hs_inv = 0/(positive-active, negative-active) */
/* [ 18] asfifo_tvfe.rst_on_vs = 1 */
/* [ 17] asfifo_tvfe.clr_ov_flag = 0 */
/* [ 16] asfifo_tvfe.rst = 0 */
/* [ 7] asfifo_656.de_en = 1 */
/* [ 6] asfifo_656.vs_en = 1 */
/* [ 5] asfifo_656.hs_en = 1 */
/* [ 4] asfifo_656.vs_inv = 0/(positive-active, negative-active) */
/* [ 3] asfifo_656.hs_inv = 0/(positive-active, negative-active) */
/* [ 2] asfifo_656.rst_on_vs = 0 */
/* [ 1] asfifo_656.clr_ov_flag = 0 */
/* [ 0] asfifo_656.rst = 0 */
/* wr(offset, VDIN_ASFIFO_CTRL0, 0x00000000); */
/* [ 23] asfifo_hdmi.de_en = 1 */
/* [ 22] asfifo_hdmi.vs_en = 1 */
/* [ 21] asfifo_hdmi.hs_en = 1 */
/* [ 20] asfifo_hdmi.vs_inv = 0/(positive-active, negative-active) */
/* [ 19] asfifo_hdmi.hs_inv = 0/(positive-active, negative-active) */
/* [ 18] asfifo_hdmi.rst_on_vs = 1 */
/* [ 17] asfifo_hdmi.clr_ov_flag = 0 */
/* [ 16] asfifo_hdmi.rst = 0 */
/* [ 7] asfifo_cvd2.de_en = 1 */
/* [ 6] asfifo_cvd2.vs_en = 1 */
/* [ 5] asfifo_cvd2.hs_en = 1 */
/* [ 4] asfifo_cvd2.vs_inv = 0/(positive-active, negative-active) */
/* [ 3] asfifo_cvd2.hs_inv = 0/(positive-active, negative-active) */
/* [ 2] asfifo_cvd2.rst_on_vs = 1 */
/* [ 1] asfifo_cvd2.clr_ov_flag = 0 */
/* [ 0] asfifo_cvd2.rst = 0 */
/* wr(offset, VDIN_ASFIFO_CTRL1, 0x00000000); */
/* [28:16] top.input_width_m1 = 0 */
/* [12: 0] top.output_width_m1 = 0 */
wr(offset, VDIN_WIDTHM1I_WIDTHM1O, 0x00000000);
/* [14: 8] hsc.init_pix_in_ptr = 0 */
/* [ 7] hsc.phsc_en = 0 */
/* [ 6] hsc.en = 0 ***sub_module.enable*** */
/* [ 5] hsc.short_ln_en = 1 */
/* [ 4] hsc.nearest_en = 0 */
/* [ 3] hsc.phase0_always = 1 */
/* [ 2: 0] hsc.filt_dep = 0/(DEPTH4,DEPTH1, DEPTH2, DEPTH3) */
/* wr(offset, VDIN_SC_MISC_CTRL, 0x00000028); */
/* [28:24] hsc.phase_step_int = 0 <u5.0> */
/* [23: 0] hsc.phase_step_fra = 0 <u0.24> */
/* wr(offset, VDIN_HSC_PHASE_STEP, 0x00000000); */
/* [30:29] hsc.repeat_pix0_num = 1 // ?
* to confirm pix0 is always used
*/
/* [28:24] hsc.ini_receive_num = 4 // ?
* to confirm pix0 is always used
*/
/* [23: 0] hsc.ini_phase = 0 */
/* wr(offset, VDIN_HSC_INI_CTRL, 0x24000000); */
/* [ 25] decimation.rst = 0 */
/* [ 24] decimation.en = 0 ***sub_module.enable*** */
/* [23:20] decimation.phase = 0 */
/* [19:16] decimation.ratio = 0/(1, 1/2, ..., 1/16) */
/* [ 7] asfifo_dvin.de_en = 1 */
/* [ 6] asfifo_dvin.vs_en = 1 */
/* [ 5] asfifo_dvin.hs_en = 1 */
/* [ 4] asfifo_dvin.vs_inv = 0/(positive-active, negative-active) */
/* [ 3] asfifo_dvin.hs_inv = 0/(positive-active, negative-active) */
/* [ 2] asfifo_dvin.rst_on_vs = 1 */
/* [ 1] asfifo_dvin.clr_ov_flag = 0 */
/* [ 0] asfifo_dvin.rst = 0 */
wr(offset, VDIN_ASFIFO_CTRL2, 0x00000000);
/* Bit 15:8 vdi7 asfifo_ctrl */
/* Bit 7:0 vdi6 asfifo_ctrl */
/* wr(offset, VDIN_ASFIFO_CTRL3, 0x00000000); */
/* [ 0] matrix.en = 0 ***sub_module.enable*** */
wr(offset, VDIN_MATRIX_CTRL, 0x00000000);
/* [28:16] matrix.coef00 = 0 <s2.10> */
/* [12: 0] matrix.coef01 = 0 <s2.10> */
wr(offset, VDIN_MATRIX_COEF00_01, 0x00000000);
/* [28:16] matrix.coef02 = 0 <s2.10> */
/* [12: 0] matrix.coef10 = 0 <s2.10> */
wr(offset, VDIN_MATRIX_COEF02_10, 0x00000000);
/* [28:16] matrix.coef11 = 0 <s2.10> */
/* [12: 0] matrix.coef12 = 0 <s2.10> */
wr(offset, VDIN_MATRIX_COEF11_12, 0x00000000);
/* [28:16] matrix.coef20 = 0 <s2.10> */
/* [12: 0] matrix.coef21 = 0 <s2.10> */
wr(offset, VDIN_MATRIX_COEF20_21, 0x00000000);
/* [12: 0] matrix.coef22 = 0 <s2.10> */
wr(offset, VDIN_MATRIX_COEF22, 0x00000000);
/* [26:16] matrix.offset0 = 0 <s8.2> */
/* [10: 0] matrix.ofsset1 = 0 <s8.2> */
wr(offset, VDIN_MATRIX_OFFSET0_1, 0x00000000);
/* [10: 0] matrix.ofsset2 = 0 <s8.2> */
wr(offset, VDIN_MATRIX_OFFSET2, 0x00000000);
/* [26:16] matrix.pre_offset0 = 0 <s8.2> */
/* [10: 0] matrix.pre_ofsset1 = 0 <s8.2> */
wr(offset, VDIN_MATRIX_PRE_OFFSET0_1, 0x00000000);
/* [10: 0] matrix.pre_ofsset2 = 0 <s8.2> */
wr(offset, VDIN_MATRIX_PRE_OFFSET2, 0x00000000);
/* [11: 0] write.lfifo_buf_size = 0x100 */
if (is_meson_m8b_cpu() ||
is_meson_gxtvbb_cpu() || is_meson_txl_cpu() ||
is_meson_txlx_cpu() || is_meson_tl1_cpu())
wr(offset, VDIN_LFIFO_CTRL, 0x00000f00);
else
wr(offset, VDIN_LFIFO_CTRL, 0x00000780);
/* [15:14] clkgate.bbar = 0/(auto, off, on, on) */
/* [13:12] clkgate.bbar = 0/(auto, off, on, on) */
/* [11:10] clkgate.bbar = 0/(auto, off, on, on) */
/* [ 9: 8] clkgate.bbar = 0/(auto, off, on, on) */
/* [ 7: 6] clkgate.bbar = 0/(auto, off, on, on) */
/* [ 5: 4] clkgate.bbar = 0/(auto, off, on, on) */
/* [ 3: 2] clkgate.bbar = 0/(auto, off, on, on) */
/* [ 0] clkgate.bbar = 0/(auto, off!!!!!!!!) */
wr(offset, VDIN_COM_GCLK_CTRL, 0x00000000);
/* [12: 0] decimation.output_width_m1 = 0 */
wr(offset, VDIN_INTF_WIDTHM1, 0x00000000);
def_canvas_id = offset ? vdin_canvas_ids[1][0]:vdin_canvas_ids[0][0];
/* [31:24] write.out_ctrl = 0x0b */
/* [ 23] write.frame_rst_on_vs = 1 */
/* [ 22] write.lfifo_rst_on_vs = 1 */
/* [ 21] write.clr_direct_done = 0 */
/* [ 20] write.clr_nr_done = 0 */
/* [ 12] write.format444 = 1/(422, 444) */
/* [ 11] write.canvas_latch_en = 0 */
/* [ 9] write.req_urgent = 0 ***sub_module.enable*** */
/* [ 8] write.req_en = 0 ***sub_module.enable*** */
/* [ 7: 0] write.canvas = 0 */
if (enable_reset)
wr(offset, VDIN_WR_CTRL, (0x0b401000 | def_canvas_id));
else
wr(offset, VDIN_WR_CTRL, (0x0bc01000 | def_canvas_id));
/* [8] discard data before line fifo= 0 normal mode */
/* [7:0] write chroma addr = 1 */
wr_bits(offset, VDIN_WR_CTRL2, def_canvas_id+1,
WRITE_CHROMA_CANVAS_ADDR_BIT,
WRITE_CHROMA_CANVAS_ADDR_WID);
wr_bits(offset, VDIN_WR_CTRL2, 0,
DISCARD_BEF_LINE_FIFO_BIT, DISCARD_BEF_LINE_FIFO_WID);
wr_bits(offset, VDIN_WR_CTRL2, VDIN_WR_BURST_MODE,
VDIN_WR_BURST_MODE_BIT, VDIN_WR_BURST_MODE_WID);
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
wr_bits(offset, VDIN_WR_CTRL2, 1,
VDIN_WR_DATA_EXT_EN_BIT, VDIN_WR_DATA_EXT_EN_WID);
else
wr_bits(offset, VDIN_WR_CTRL2, 0,
VDIN_WR_DATA_EXT_EN_BIT, VDIN_WR_DATA_EXT_EN_WID);
/* [20:25] integer = 0 */
/* [0:19] fraction = 0 */
wr(offset, VDIN_VSC_PHASE_STEP, 0x0000000);
/* disable hscale&pre hscale */
wr_bits(offset, VDIN_SC_MISC_CTRL, 0, PRE_HSCL_EN_BIT, PRE_HSCL_EN_WID);
wr_bits(offset, VDIN_SC_MISC_CTRL, 0, HSCL_EN_BIT, HSCL_EN_WID);
/* Bit 23, vsc_en, vertical scaler enable */
/* Bit 21 vsc_phase0_always_en, when scale up,
* you have to set it to 1
*/
/* Bit 20:16 ini skip_line_num */
/* Bit 15:0 vscaler ini_phase */
wr(offset, VDIN_VSC_INI_CTRL, 0x000000);
/* Bit 12:0, scaler input height minus 1 */
/*wr(offset, VDIN_SCIN_HEIGHTM1,0x000000);*/
wr_bits(offset, VDIN_SCIN_HEIGHTM1, 0, SCALER_INPUT_HEIGHT_BIT,
SCALER_INPUT_HEIGHT_WID);
/* Bit 23:16, dummy component 0 */
/* Bit 15:8, dummy component 1 */
/* Bit 7:0, dummy component 2 */
wr(offset, VDIN_DUMMY_DATA, 0x8080);
/* Bit 23:16 component 0 */
/* Bit 15:8 component 1 */
/* Bit 7:0 component 2 */
wr(offset, VDIN_MATRIX_HL_COLOR, 0x000000);
/* 28:16 probe x, postion */
/* 12:0 probe y, position */
wr(offset, VDIN_MATRIX_PROBE_POS, 0x00000000);
/* Bit 31, local dimming statistic enable */
/* Bit 28, eol enable */
/* Bit 27:25, vertical line overlap number for max finding */
/* Bit 24:22, horizontal pixel overlap number,
* 0: 17 pix, 1: 9 pix, 2: 5 pix, 3: 3 pix, 4: 0 pix
*/
/* Bit 20, 1,2,1 low pass filter enable before max/hist statistic */
/* Bit 19:16, region H/V position index,
* refer to VDIN_LDIM_STTS_HIST_SET_REGION
*/
/* Bit 15, 1: region read index auto increase
* per read to VDIN_LDIM_STTS_HIST_READ_REGION
*/
/* Bit 6:0, region read index */
if (is_meson_gxtvbb_cpu())
wr(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 0x00000000);
/* [27:16] write.output_hs = 0 */
/* [11: 0] write.output_he = 0 */
wr(offset, VDIN_WR_H_START_END, 0x00000000);
/* [27:16] write.output_vs = 0 */
/* [11: 0] write.output_ve = 0 */
wr(offset, VDIN_WR_V_START_END, 0x00000000);
/* [ 6: 5] hist.pow = 0 */
/* [ 3: 2] hist.mux = 0/(matrix_out, hsc_out, phsc_in) */
/* [ 1] hist.win_en = 1 */
/* [ 0] hist.read_en = 1 */
wr(offset, VDIN_HIST_CTRL, 0x00000003);
/* [28:16] hist.win_hs = 0 */
/* [12: 0] hist.win_he = 0 */
wr(offset, VDIN_HIST_H_START_END, 0x00000000);
/* [28:16] hist.win_vs = 0 */
/* [12: 0] hist.win_ve = 0 */
wr(offset, VDIN_HIST_V_START_END, 0x00000000);
/* set VDIN_MEAS_CLK_CNTL, select XTAL clock */
/* if (is_meson_gxbb_cpu()) */
/* ; */
/* else */
/* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000100); */
/* [ 18] meas.rst = 0 */
/* [ 17] meas.widen_hs_vs_en = 1 */
/* [ 16] meas.vs_cnt_accum_en = 0 */
/* [14:12] meas.mux = 0/(null, 656, tvfe, cvd2, hdmi, dvin) */
/* [11: 4] meas.vs_span_m1 = 0 */
/* [ 2: 0] meas.hs_ind = 0 */
wr(offset, VDIN_MEAS_CTRL0, 0x00020000);
/* HS range0: Line #112 ~ Line #175 */
/* [28:16] meas.hs_range_start = 112*/
/* [12: 0] meas.hs_range_end = 175 */
wr(offset, VDIN_MEAS_HS_RANGE, 0x007000af);
/* [ 8] bbar.white_en = 0 */
/* [ 7: 0] bbar.white_thr = 0 */
wr(offset, VDIN_BLKBAR_CTRL1, 0x00000000);
/* [20: 8] bbar.region_width = 0 */
/* [ 7: 5] bbar.src_on_v = 0/(Y, sU, sV, U, V) */
/* [ 4] bbar.search_one_step = 0 */
/* [ 3] bbar.raising_edge_rst = 0 */
/* [ 2: 1] bbar.mux = 0/(matrix_out, hsc_out, phsc_in) */
/* [ 0] bbar.en = 0 ***sub_module.enable*** */
wr(offset, VDIN_BLKBAR_CTRL0, 0x14000000);
/* [28:16] bbar.win_hs = 0 */
/* [12: 0] bbar.win_he = 0 */
wr(offset, VDIN_BLKBAR_H_START_END, 0x00000000);
/* [28:16] bbar.win_vs = 0 */
/* [12: 0] bbar.win_ve = 0 */
wr(offset, VDIN_BLKBAR_V_START_END, 0x00000000);
/* [19: 0] bbar.bblk_thr_on_bpix = 0 */
wr(offset, VDIN_BLKBAR_CNT_THRESHOLD, 0x00000000);
/* [28:16] bbar.blnt_thr_on_wpix = 0 */
/* [12: 0] bbar.blnb_thr_on_wpix = 0 */
wr(offset, VDIN_BLKBAR_ROW_TH1_TH2, 0x00000000);
/* [28:16] input_win.hs = 0 */
/* [12: 0] input_win.he = 0 */
wr(offset, VDIN_WIN_H_START_END, 0x00000000);
/* [28:16] input_win.vs = 0 */
/* [12: 0] input_win.ve = 0 */
wr(offset, VDIN_WIN_V_START_END, 0x00000000);
}
void vdin_hw_enable(unsigned int offset)
{
/* enable video data input */
/* [ 4] top.datapath_en = 1 */
wr_bits(offset, VDIN_COM_CTRL0, 1,
VDIN_COMMONINPUT_EN_BIT, VDIN_COMMONINPUT_EN_WID);
/* mux input */
/* [ 3: 0] top.mux = 0/(null, mpeg, 656, tvfe, cvd2, hdmi, dvin) */
wr_bits(offset, VDIN_COM_CTRL0, 0, VDIN_SEL_BIT, VDIN_SEL_WID);
/* enable clock of blackbar, histogram, histogram, line fifo1, matrix,
* hscaler, pre hscaler, clock0
*/
/* [15:14] Enable blackbar clock = 00/(auto, off, on, on) */
/* [13:12] Enable histogram clock = 00/(auto, off, on, on) */
/* [11:10] Enable line fifo1 clock = 00/(auto, off, on, on) */
/* [ 9: 8] Enable matrix clock = 00/(auto, off, on, on) */
/* [ 7: 6] Enable hscaler clock = 00/(auto, off, on, on) */
/* [ 5: 4] Enable pre hscaler clock = 00/(auto, off, on, on) */
/* [ 3: 2] Enable clock0 = 00/(auto, off, on, on) */
/* [ 0] Enable register clock = 00/(auto, off!!!!!!!!) */
switch_vpu_clk_gate_vmod(offset == 0 ? VPU_VIU_VDIN0 : VPU_VIU_VDIN1,
VPU_CLK_GATE_ON);
/* wr(offset, VDIN_COM_GCLK_CTRL, 0x0); */
}
void vdin_hw_disable(unsigned int offset)
{
/* disable cm2 */
wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 0, CM_TOP_EN_BIT, CM_TOP_EN_WID);
/* disable video data input */
/* [ 4] top.datapath_en = 0 */
wr_bits(offset, VDIN_COM_CTRL0, 0,
VDIN_COMMONINPUT_EN_BIT, VDIN_COMMONINPUT_EN_WID);
/* mux null input */
/* [ 3: 0] top.mux = 0/(null, mpeg, 656, tvfe, cvd2, hdmi, dvin) */
wr_bits(offset, VDIN_COM_CTRL0, 0, VDIN_SEL_BIT, VDIN_SEL_WID);
wr(offset, VDIN_COM_CTRL0, 0x00000910);
vdin_delay_line(delay_line_num, offset);
if (enable_reset)
wr(offset, VDIN_WR_CTRL, 0x0b401000);
else
wr(offset, VDIN_WR_CTRL, 0x0bc01000);
/* disable clock of blackbar, histogram, histogram, line fifo1, matrix,
* hscaler, pre hscaler, clock0
*/
/* [15:14] Disable blackbar clock = 01/(auto, off, on, on) */
/* [13:12] Disable histogram clock = 01/(auto, off, on, on) */
/* [11:10] Disable line fifo1 clock = 01/(auto, off, on, on) */
/* [ 9: 8] Disable matrix clock = 01/(auto, off, on, on) */
/* [ 7: 6] Disable hscaler clock = 01/(auto, off, on, on) */
/* [ 5: 4] Disable pre hscaler clock = 01/(auto, off, on, on) */
/* [ 3: 2] Disable clock0 = 01/(auto, off, on, on) */
/* [ 0] Enable register clock = 00/(auto, off!!!!!!!!) */
switch_vpu_clk_gate_vmod(offset == 0 ? VPU_VIU_VDIN0:VPU_VIU_VDIN1,
VPU_CLK_GATE_OFF);
/* wr(offset, VDIN_COM_GCLK_CTRL, 0x5554); */
}
/* get current vsync field type 0:top 1 bottom */
unsigned int vdin_get_field_type(unsigned int offset)
{
return rd_bits(offset, VDIN_COM_STATUS0, 0, 1);
}
static unsigned int vdin_reset_flag;
inline int vdin_vsync_reset_mif(int index)
{
int i;
int start_line = aml_read_vcbus(VDIN_LCNT_STATUS) & 0xfff;
if (!enable_reset || vdin_reset_flag || (start_line > 0))
return 0;
vdin_reset_flag = 1;
if (index == 0) {
W_VCBUS_BIT(VDIN_WR_CTRL, 0, VDIN0_VCP_WR_EN_BIT,
VDIN0_VCP_WR_EN_WID); /* vdin->vdin mif wr en */
W_VCBUS_BIT(VDIN_WR_CTRL, 1, VDIN0_DISABLE_CLOCKGATE_BIT,
VDIN0_DISABLE_CLOCKGATE_WID); /* clock gate */
/* wr req en */
W_VCBUS_BIT(VDIN_WR_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID);
aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2, vpu_reg_27af &
(~(1 << VDIN0_REQ_EN_BIT)));
vpu_reg_27af &= (~VDIN0_REQ_EN_BIT);
if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2, VDIN_DET_IDLE_BIT,
VDIN_DET_IDLE_WIDTH) & VDIN0_IDLE_MASK) {
vdin0_wr_mif_reset();
} else {
for (i = 0; i < vdin_det_idle_wait; i++) {
if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2,
VDIN_DET_IDLE_BIT, VDIN_DET_IDLE_WIDTH)
& VDIN0_IDLE_MASK) {
vdin0_wr_mif_reset();
break;
}
}
if ((i >= vdin_det_idle_wait) && vdin_ctl_dbg)
pr_info("============== !!! idle wait timeout\n");
}
aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2,
vpu_reg_27af | (1 << VDIN0_REQ_EN_BIT));
W_VCBUS_BIT(VDIN_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID);
W_VCBUS_BIT(VDIN_WR_CTRL, 0, VDIN0_DISABLE_CLOCKGATE_BIT,
VDIN0_DISABLE_CLOCKGATE_WID);
W_VCBUS_BIT(VDIN_WR_CTRL, 1,
VDIN0_VCP_WR_EN_BIT, VDIN0_VCP_WR_EN_WID);
vpu_reg_27af |= VDIN0_REQ_EN_BIT;
} else if (index == 1) {
W_VCBUS_BIT(VDIN1_WR_CTRL2, 1, VDIN1_VCP_WR_EN_BIT,
VDIN1_VCP_WR_EN_WID); /* vdin->vdin mif wr en */
W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN1_DISABLE_CLOCKGATE_BIT,
VDIN1_DISABLE_CLOCKGATE_WID); /* clock gate */
/* wr req en */
W_VCBUS_BIT(VDIN1_WR_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID);
aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2,
vpu_reg_27af & (~(1 << VDIN1_REQ_EN_BIT)));
vpu_reg_27af &= (~(1 << VDIN1_REQ_EN_BIT));
if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2, VDIN_DET_IDLE_BIT,
VDIN_DET_IDLE_WIDTH) & VDIN1_IDLE_MASK) {
vdin1_wr_mif_reset();
} else {
for (i = 0; i < vdin_det_idle_wait; i++) {
if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2,
VDIN_DET_IDLE_BIT, VDIN_DET_IDLE_WIDTH)
& VDIN1_IDLE_MASK) {
vdin1_wr_mif_reset();
break;
}
}
}
aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2,
vpu_reg_27af | (1 << VDIN1_REQ_EN_BIT));
vpu_reg_27af |= (1 << VDIN1_REQ_EN_BIT);
W_VCBUS_BIT(VDIN1_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID);
W_VCBUS_BIT(VDIN1_WR_CTRL, 0, VDIN1_DISABLE_CLOCKGATE_BIT,
VDIN1_DISABLE_CLOCKGATE_WID);
W_VCBUS_BIT(VDIN1_WR_CTRL2, 0,
VDIN1_VCP_WR_EN_BIT, VDIN1_VCP_WR_EN_WID);
}
vdin_reset_flag = 0;
#if 0 /* TODO: if start or end line > 0, should drop this frame! */
if ((aml_read_vcbus(VDIN_LCNT_STATUS) & 0xfff) > 0) {
pr_info("============== !!! line counter = %d -> %d !!!\n",
start_line, aml_read_vcbus(VDIN_LCNT_STATUS) & 0xff);
}
#endif
return vsync_reset_mask & 0x08;
}
void vdin_enable_module(unsigned int offset, bool enable)
{
if (enable) {
/* set VDIN_MEAS_CLK_CNTL, select XTAL clock */
/* if (is_meson_gxbb_cpu()) */
/* ; */
/* else */
/* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000100); */
/* vdin_hw_enable(offset); */
/* todo: check them */
} else {
/* set VDIN_MEAS_CLK_CNTL, select XTAL clock */
/* if (is_meson_gxbb_cpu()) */
/* ; */
/* else */
/* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000000); */
vdin_hw_disable(offset);
}
}
#if 0
bool vdin_write_done_check(unsigned int offset, struct vdin_dev_s *devp)
{
if (rd_bits(offset, VDIN_COM_STATUS0,
DIRECT_DONE_STATUS_BIT, DIRECT_DONE_STATUS_WID)) {
wr_bits(offset, VDIN_WR_CTRL, 1,
DIRECT_DONE_CLR_BIT, DIRECT_DONE_CLR_WID);
wr_bits(offset, VDIN_WR_CTRL, 0,
DIRECT_DONE_CLR_BIT, DIRECT_DONE_CLR_WID);
devp->abnormal_cnt = 0;
} else if ((vdin_get_active_v(offset) >= devp->v_active) &&
(vdin_get_active_h(offset) >= devp->h_active)
)
devp->abnormal_cnt++;
else
devp->abnormal_cnt = 0;
if (devp->abnormal_cnt > max_undone_cnt) {
devp->abnormal_cnt = 0;
devp->flags |= VDIN_FLAG_FORCE_UNSTABLE;
}
/* check the event */
if (get_foreign_affairs(FOREIGN_AFFAIRS_02)) {
/* clean the event flag */
rst_foreign_affairs(FOREIGN_AFFAIRS_02);
/* notify api to stop vdin */
devp->flags |= VDIN_FLAG_FORCE_UNSTABLE;
}
}
#else
bool vdin_write_done_check(unsigned int offset, struct vdin_dev_s *devp)
{
if (rd_bits(offset, VDIN_COM_STATUS0,
DIRECT_DONE_STATUS_BIT, DIRECT_DONE_STATUS_WID)) {
wr_bits(offset, VDIN_WR_CTRL, 1,
DIRECT_DONE_CLR_BIT, DIRECT_DONE_CLR_WID);
wr_bits(offset, VDIN_WR_CTRL, 0,
DIRECT_DONE_CLR_BIT, DIRECT_DONE_CLR_WID);
return true;
}
devp->abnormal_cnt++;
return false;
}
#endif
/*
cycle = delta_stamp = ((1/fps)/(1/msr_clk))*(vsync_span+1)
msr_clk/fps unit is HZ
vsync_span(0x125a[11:4]) usually should be 0;
*/
bool vdin_check_cycle(struct vdin_dev_s *devp)
{
unsigned int stamp, cycle;
stamp = vdin_get_meas_vstamp(devp->addr_offset);
if (stamp < devp->stamp)
cycle = 0xffffffff - devp->stamp + stamp + 1;
else
cycle = stamp - devp->stamp;
if (cycle <= (devp->msr_clk_val/1000))
return true;
else {
devp->stamp = stamp;
devp->cycle = cycle;
return false;
}
}
/*function:calculate curr_wr_vf->duration
* based on parm.port\ msr_clk_val\ parm.flag and
* curr_field_type
*/
void vdin_calculate_duration(struct vdin_dev_s *devp)
{
unsigned int last_field_type, cycle_phase;
struct vframe_s *curr_wr_vf = NULL;
/* enum tvin_sig_fmt_e fmt = devp->parm.info.fmt; */
const struct tvin_format_s *fmt_info = devp->fmt_info_p;
/* unsigned int frame_rate =
* (VDIN_CRYSTAL + (devp->cycle>>3))/devp->cycle;
*/
enum tvin_port_e port = devp->parm.port;
curr_wr_vf = &devp->curr_wr_vfe->vf;
last_field_type = devp->curr_field_type;
cycle_phase = devp->msr_clk_val/96000;
if (cycle_phase == 0) {
cycle_phase = 250;
if (vdin_ctl_dbg)
pr_info("%s:cycle_phase is 0!!!!", __func__);
}
#ifdef VDIN_DYNAMIC_DURATION
devp->curr_wr_vf->duration =
(devp->cycle + cycle_phase/2) / cycle_phase;
#else
if ((devp->use_frame_rate == 1) &&
((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7))) {
curr_wr_vf->duration =
(devp->cycle + cycle_phase/2) / cycle_phase;
} else {
curr_wr_vf->duration = devp->duration;
}
#endif
/* for 2D->3D mode & interlaced format, double top field
* duration to match software frame lock
*/
#ifdef VDIN_DYNAMIC_DURATION
if ((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) &&
(last_field_type & VIDTYPE_INTERLACE))
curr_wr_vf->duration <<= 1;
#else
if ((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) &&
(last_field_type & VIDTYPE_INTERLACE)) {
if (!fmt_info->duration)
curr_wr_vf->duration = ((devp->cycle << 1) +
cycle_phase/2) / cycle_phase;
else
curr_wr_vf->duration = fmt_info->duration << 1;
}
#endif
}
/*
*just for horizontal down scale src_w is origin width,
*just dst_w is width after scale down
*/
static void vdin_set_hscale(unsigned int offset, unsigned int src_w,
unsigned int dst_w)
{
unsigned int filt_coef0[] = { /* bicubic */
0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, 0xfd7e0500,
0xfc7e0600, 0xfb7d0800, 0xfb7c0900, 0xfa7b0b00, 0xfa7a0dff,
0xf9790fff, 0xf97711ff, 0xf87613ff, 0xf87416fe, 0xf87218fe,
0xf8701afe, 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, 0xf75d31fb,
0xf75a34fb, 0xf75837fa, 0xf7553afa, 0xf8523cfa, 0xf8503ff9,
0xf84d42f9, 0xf84a45f9, 0xf84848f8
};
/*
unsigned int filt_coef1[] = {//2 point bilinear
0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, 0x00780800,
0x00760a00, 0x00740c00, 0x00720e00, 0x00701000, 0x006e1200,
0x006c1400, 0x006a1600,0x00681800, 0x00661a00, 0x00641c00,
0x00621e00, 0x00602000, 0x005e2200,0x005c2400, 0x005a2600,
0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,0x00503000,
0x004e3200, 0x004c3400, 0x004a3600, 0x00483800, 0x00463a00,
0x00443c00, 0x00423e00, 0x00404000
};
unsigned int filt_coef2[] = { //2 point bilinear, bank_length == 2
0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, 0x78080000,
0x760a0000, 0x740c0000, 0x720e0000, 0x70100000, 0x6e120000,
0x6c140000, 0x6a160000, 0x68180000, 0x661a0000, 0x641c0000,
0x621e0000, 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000,
0x58280000, 0x562a0000, 0x542c0000, 0x522e0000,0x50300000,
0x4e320000, 0x4c340000, 0x4a360000, 0x48380000, 0x463a0000,
0x443c0000, 0x423e0000, 0x40400000
};
*/
int horz_phase_step, i;
if (!dst_w) {
pr_err("[vdin..]%s parameter dst_w error.\n", __func__);
return;
}
/* disable hscale */
wr_bits(offset, VDIN_SC_MISC_CTRL, 0, HSCL_EN_BIT, HSCL_EN_WID);
/* write horz filter coefs */
wr(offset, VDIN_SCALE_COEF_IDX, 0x0100);
for (i = 0; i < 33; i++)
wr(offset, VDIN_SCALE_COEF, filt_coef0[i]); /* bicubic */
if (src_w >> 12) {/* for src_w >= 4096, avoid data overflow. */
horz_phase_step = (src_w << 18) / dst_w;
horz_phase_step = (horz_phase_step << 6);
} else {
horz_phase_step = (src_w << 20) / dst_w;
horz_phase_step = (horz_phase_step << 4);
}
wr(offset, VDIN_WIDTHM1I_WIDTHM1O, ((src_w - 1) << WIDTHM1I_BIT) |
(dst_w - 1)
);
wr(offset, VDIN_HSC_PHASE_STEP, horz_phase_step);
/* hsc_p0_num */
wr(offset, VDIN_HSC_INI_CTRL, (1 << HSCL_RPT_P0_NUM_BIT) |
(4 << HSCL_INI_RCV_NUM_BIT) |/* hsc_ini_rcv_num */
(0 << HSCL_INI_PHASE_BIT)/* hsc_ini_phase */
);
wr(offset, VDIN_SC_MISC_CTRL,
rd(offset, VDIN_SC_MISC_CTRL) |
(0 << INIT_PIX_IN_PTR_BIT) |
(1 << HSCL_EN_BIT) |/* hsc_en */
(1 << SHORT_LN_OUT_EN_BIT) |/* short_lineo_en */
(1 << HSCL_NEAREST_EN_BIT) |/* nearest_en */
(0 << PHASE0_ALWAYS_EN_BIT) |/* phase0_always_en */
(4 << HSCL_BANK_LEN_BIT)/* hsc_bank_length */
);
}
/*
*just for veritical scale src_w is origin height,
*just dst_h is the height after scale
*/
static void vdin_set_vscale(unsigned int offset, unsigned int src_h,
unsigned int dst_h)
{
int veri_phase_step, tmp;
if (!dst_h) {
pr_err("[vdin..]%s parameter dst_h error.\n", __func__);
return;
}
/* disable vscale */
wr_bits(offset, VDIN_VSC_INI_CTRL, 0, VSC_EN_BIT, VSC_EN_WID);
veri_phase_step = (src_h << 20) / dst_h;
tmp = veri_phase_step >> 25;
if (tmp) {
pr_err("[vdin..]%s error. cannot be divided more than 31.9999.\n",
__func__);
return;
}
wr(offset, VDIN_VSC_PHASE_STEP, veri_phase_step);
if (!(veri_phase_step>>20)) {/* scale up the bit should be 1 */
wr_bits(offset, VDIN_VSC_INI_CTRL, 1,
VSC_PHASE0_ALWAYS_EN_BIT, VSC_PHASE0_ALWAYS_EN_WID);
/* scale phase is 0 */
wr_bits(offset, VDIN_VSC_INI_CTRL, 0,
VSCALER_INI_PHASE_BIT, VSCALER_INI_PHASE_WID);
} else {
wr_bits(offset, VDIN_VSC_INI_CTRL, 0,
VSC_PHASE0_ALWAYS_EN_BIT, VSC_PHASE0_ALWAYS_EN_WID);
/* scale phase is 0x8000 */
wr_bits(offset, VDIN_VSC_INI_CTRL, 0x8000,
VSCALER_INI_PHASE_BIT, VSCALER_INI_PHASE_WID);
}
/* skip 0 line in the beginning */
wr_bits(offset, VDIN_VSC_INI_CTRL, 0,
INI_SKIP_LINE_NUM_BIT, INI_SKIP_LINE_NUM_WID);
wr_bits(offset, VDIN_SCIN_HEIGHTM1, src_h - 1,
SCALER_INPUT_HEIGHT_BIT, SCALER_INPUT_HEIGHT_WID);
wr(offset, VDIN_DUMMY_DATA, 0x008080);
/* enable vscale */
wr_bits(offset, VDIN_VSC_INI_CTRL, 1, VSC_EN_BIT, VSC_EN_WID);
}
/* new add pre_hscale module
*do hscaler down when scaling4w is smaller than half of h_avtive
*which is closed by default
*/
static void vdin_set_prehscale(unsigned int offset)
{
wr_bits(offset, VDIN_SC_MISC_CTRL, 0, PRE_HSCL_MODE_BIT,
PRE_HSCL_MODE_WID);
wr_bits(offset, VDIN_SC_MISC_CTRL, 1, PRE_HSCL_EN_BIT, PRE_HSCL_EN_WID);
pr_info("set_prehsc done!\n");
}
/*new add vshrink module
*do vscaler down,when scaling4h is smaller than half of v_avtive
*which is closed by default
*vshrk_mode:0-->1:2; 1-->1:4; 2-->1:8
*attention:only vdin1 have this module!!
*/
static void vdin_set_vshrink(unsigned int offset, unsigned int src_h,
unsigned int vshrk_mode)
{
wr_bits(offset, VDIN_SCIN_HEIGHTM1, src_h - 1,
VSHRK_INPUT_HEIGHT_BIT, VSHRK_INPUT_HEIGHT_WID);
wr_bits(offset, VDIN_VSHRK_CTRL, 1,
VDIN_VSHRK_LPF_MODE_BIT, VDIN_VSHRK_LPF_MODE_WID);
wr_bits(offset, VDIN_VSHRK_CTRL, vshrk_mode,
VDIN_VSHRK_MODE_BIT, VDIN_VSHRK_MODE_WID);
wr_bits(offset, VDIN_VSHRK_CTRL, 1,
VDIN_VSHRK_EN_BIT, VDIN_VSHRK_EN_WID);
pr_info("set_vshrink done!\n");
}
/*function:set horizontal and veritical scale
*vdin scaler path:
* vdin0:prehsc-->hscaler-->vscaler;
* vdin1:prehsc-->hscaler-->vshrink-->vscaler
*/
void vdin_set_hvscale(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
unsigned int vshrk_mode = 0;
if ((devp->prop.scaling4w < devp->h_active) &&
(devp->prop.scaling4w > 0)) {
if (devp->prehsc_en && (devp->prop.scaling4w <=
(devp->h_active >> 1))) {
vdin_set_prehscale(offset);
devp->h_active = devp->h_active >> 1;
}
if (devp->prop.scaling4w < devp->h_active)
vdin_set_hscale(offset, devp->h_active,
devp->prop.scaling4w);
devp->h_active = devp->prop.scaling4w;
} else if (devp->h_active > VDIN_MAX_HACTIVE) {
vdin_set_hscale(offset, devp->h_active, VDIN_MAX_HACTIVE);
devp->h_active = VDIN_MAX_HACTIVE;
}
if (vdin_ctl_dbg)
pr_info("[vdin.%d] dst hactive:%u,",
devp->index, devp->h_active);
if ((devp->prop.scaling4h < devp->v_active) &&
(devp->prop.scaling4h > 0)) {
if (devp->vshrk_en && (devp->h_active <= VDIN_VSHRINK_HLIMIT) &&
(devp->index == 1) && (devp->prop.scaling4h <=
(devp->v_active >> 1))) {
vshrk_mode = devp->v_active/devp->prop.scaling4h;
if (vshrk_mode >= 8)
vshrk_mode = 2;
else if (vshrk_mode >= 4)
vshrk_mode = 1;
else if (vshrk_mode >= 2)
vshrk_mode = 0;
vdin_set_vshrink(offset, devp->v_active, vshrk_mode);
devp->v_active = devp->v_active >> (vshrk_mode + 1);
}
if (devp->prop.scaling4h < devp->v_active)
vdin_set_vscale(offset, devp->v_active,
devp->prop.scaling4h);
devp->v_active = devp->prop.scaling4h;
}
if (vdin_ctl_dbg)
pr_info(" dst vactive:%u.\n", devp->v_active);
}
/*set source_bitdepth
* base on color_depth_config:
* 10, 8, 0, other
*/
void vdin_set_bitdepth(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
unsigned int set_width = 0;
if ((devp->output_color_depth) &&
((devp->prop.fps == 50) || (devp->prop.fps == 60)) &&
((devp->parm.info.fmt == TVIN_SIG_FMT_HDMI_3840_2160_00HZ) ||
(devp->parm.info.fmt == TVIN_SIG_FMT_HDMI_4096_2160_00HZ)) &&
(devp->prop.colordepth == 10)) {
set_width = devp->output_color_depth;
pr_info("set output color depth %d bit from dts\n", set_width);
}
switch (devp->color_depth_config) {
case 8:
devp->source_bitdepth = 8;
wr_bits(offset, VDIN_WR_CTRL2, 0,
VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID);
break;
case 10:
devp->source_bitdepth = 10;
wr_bits(offset, VDIN_WR_CTRL2, 1,
VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID);
break;
case 0:
/* vdin_bit_depth is set to 0 by defaut, in this case,
devp->source_bitdepth is controlled by colordepth
change default to 10bit for 8in8out detail maybe lost
*/
if ((devp->prop.color_format == TVIN_RGB444) ||
(devp->prop.color_format == TVIN_YUV444) ||
(devp->prop.color_format == TVIN_BGGR) ||
(devp->prop.color_format == TVIN_RGGB) ||
(devp->prop.color_format == TVIN_GBRG) ||
(devp->prop.color_format == TVIN_GRBG)) {
devp->source_bitdepth = 8;
wr_bits(offset, VDIN_WR_CTRL2, 0,
VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID);
} else if (devp->prop.colordepth == 8) {
devp->source_bitdepth = 8;
wr_bits(offset, VDIN_WR_CTRL2, 0,
VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID);
} else if ((devp->color_depth_support &
VDIN_WR_COLOR_DEPTH_10BIT) &&
(devp->prop.colordepth == 10)) {
if (set_width == 8) {
devp->source_bitdepth = 8;
wr_bits(offset, VDIN_WR_CTRL2, 0,
VDIN_WR_10BIT_MODE_BIT,
VDIN_WR_10BIT_MODE_WID);
} else {
devp->source_bitdepth = 10;
wr_bits(offset, VDIN_WR_CTRL2, 1,
VDIN_WR_10BIT_MODE_BIT,
VDIN_WR_10BIT_MODE_WID);
}
} else {
devp->source_bitdepth = 8;
wr_bits(offset, VDIN_WR_CTRL2, 0,
VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID);
}
break;
default:
devp->source_bitdepth = 8;
wr_bits(offset, VDIN_WR_CTRL2, 0,
VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID);
break;
}
}
/*do horizontal reverse and veritical reverse
*hreverse:
*VDIN_WR_H_START_END
*Bit29: 1.reverse 0.do not reverse
*
*vreverse:
*VDIN_WR_V_START_END
*Bit29: 1.reverse 0.do not reverse
*/
void vdin_wr_reverse(unsigned int offset, bool hreverse, bool vreverse)
{
if (hreverse)
wr_bits(offset, VDIN_WR_H_START_END, 1,
HORIZONTAL_REVERSE_BIT, HORIZONTAL_REVERSE_WID);
else
wr_bits(offset, VDIN_WR_H_START_END, 0,
HORIZONTAL_REVERSE_BIT, HORIZONTAL_REVERSE_WID);
if (vreverse)
wr_bits(offset, VDIN_WR_V_START_END, 1,
VERTICAL_REVERSE_BIT, VERTICAL_REVERSE_WID);
else
wr_bits(offset, VDIN_WR_V_START_END, 0,
VERTICAL_REVERSE_BIT, VERTICAL_REVERSE_WID);
}
void vdin_bypass_isp(unsigned int offset)
{
wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 0, CM_TOP_EN_BIT, CM_TOP_EN_WID);
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID);
wr_bits(offset, VDIN_MATRIX_CTRL, 0,
VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID);
}
void vdin_set_cm2(unsigned int offset, unsigned int w,
unsigned int h, unsigned int *cm2)
{
unsigned int i = 0, j = 0, start_addr = 0x100;
if (!cm_enable)
return;
wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 0, CM_TOP_EN_BIT, CM_TOP_EN_WID);
for (i = 0; i < 160; i++) {
j = i/5;
wr(offset, VDIN_CHROMA_ADDR_PORT, start_addr+(j<<3)+(i%5));
wr(offset, VDIN_CHROMA_DATA_PORT, cm2[i]);
}
for (i = 0; i < 28; i++) {
wr(offset, VDIN_CHROMA_ADDR_PORT, 0x200+i);
wr(offset, VDIN_CHROMA_DATA_PORT, cm2[160+i]);
}
/*config cm2 frame size*/
wr(offset, VDIN_CHROMA_ADDR_PORT, 0x205);
wr(offset, VDIN_CHROMA_DATA_PORT, h<<16|w);
wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 1, CM_TOP_EN_BIT, CM_TOP_EN_WID);
}
/*vdin0 output ctrl
* Bit 26 vcp_nr_en. Only used in VDIN0. NOT used in VDIN1.
* Bit 25 vcp_wr_en. Only used in VDIN0. NOT used in VDIN1.
* Bit 24 vcp_in_en. Only used in VDIN0. NOT used in VDIN1.
*/
static void vdin_output_ctl(unsigned int offset, unsigned int output_nr_flag)
{
wr_bits(offset, VDIN_WR_CTRL, 1, VCP_IN_EN_BIT, VCP_IN_EN_WID);
if (output_nr_flag) {
wr_bits(offset, VDIN_WR_CTRL, 0, VCP_WR_EN_BIT, VCP_WR_EN_WID);
wr_bits(offset, VDIN_WR_CTRL, 1, VCP_NR_EN_BIT, VCP_NR_EN_WID);
} else {
wr_bits(offset, VDIN_WR_CTRL, 1, VCP_WR_EN_BIT, VCP_WR_EN_WID);
wr_bits(offset, VDIN_WR_CTRL, 0, VCP_NR_EN_BIT, VCP_NR_EN_WID);
}
}
/* set mpegin
*VDIN_COM_CTRL0
*Bit 31, mpeg_to_vdin_sel,
*0: mpeg source to NR directly,
*1: mpeg source pass through here
*/
void vdin_set_mpegin(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
/* set VDIN_MEAS_CLK_CNTL, select XTAL clock */
/* if (is_meson_gxbb_cpu()) */
/* ; */
/* else */
/* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000100); */
wr(offset, VDIN_COM_CTRL0, 0x80000911);
vdin_delay_line(delay_line_num, offset);
wr(offset, VDIN_COM_GCLK_CTRL, 0x0);
wr(offset, VDIN_INTF_WIDTHM1, devp->h_active-1);
wr(offset, VDIN_WR_CTRL2, 0x0);
wr(offset, VDIN_HIST_CTRL, 0x3);
wr(offset, VDIN_HIST_H_START_END, devp->h_active-1);
wr(offset, VDIN_HIST_V_START_END, devp->v_active-1);
vdin_output_ctl(offset, 1);
}
void vdin_force_gofiled(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
wr_bits(offset, VDIN_COM_CTRL0, 1, 28, 1);
wr_bits(offset, VDIN_COM_CTRL0, 0, 28, 1);
}
void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size)
{
unsigned int index, alloc_size;
int highmem_flag;
alloc_size = dolby_size_byte*size;
devp->dv.dv_dma_vaddr = dma_alloc_coherent(&devp->this_pdev->dev,
alloc_size, &devp->dv.dv_dma_paddr, GFP_KERNEL);
if (!devp->dv.dv_dma_vaddr) {
pr_info("%s:dmaalloc_coherent fail!!\n", __func__);
return;
}
memset(devp->dv.dv_dma_vaddr, 0, alloc_size);
if (devp->cma_config_flag & 0x100)
highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0]));
else
highmem_flag = PageHighMem(phys_to_page(devp->mem_start));
for (index = 0; index < size; index++) {
devp->vfp->dv_buf_mem[index] = devp->dv.dv_dma_paddr +
dolby_size_byte * index;
devp->vfp->dv_buf_vmem[index] = devp->dv.dv_dma_vaddr +
dolby_size_byte * index;
if (highmem_flag == 0) {
if ((devp->cma_config_flag & 0x100)
&& devp->cma_config_en)
devp->vfp->dv_buf_ori[index] =
phys_to_virt(devp->vfmem_start[index] +
devp->vfmem_size -
dolby_size_byte);
else
devp->vfp->dv_buf_ori[index] =
phys_to_virt(devp->mem_start +
devp->mem_size -
dolby_size_byte *
(devp->canvas_max_num - index));
} else {
if ((devp->cma_config_flag & 0x100)
&& devp->cma_config_en)
devp->vfp->dv_buf_ori[index] =
codec_mm_vmap(devp->vfmem_start[index] +
devp->vfmem_size-dolby_size_byte,
dolby_size_byte);
else
devp->vfp->dv_buf_ori[index] =
codec_mm_vmap(devp->mem_start +
devp->mem_size -
dolby_size_byte *
(devp->canvas_max_num - index),
dolby_size_byte);
}
pr_info("%s:dv_buf[%d]=0x%p(0x%x,0x%p)\n", __func__, index,
devp->vfp->dv_buf_ori[index],
devp->vfp->dv_buf_mem[index],
devp->vfp->dv_buf_vmem[index]);
}
pr_info("%s:dv_dma_vaddr=0x%p,dv_dma_paddr=0x%lx\n", __func__,
devp->dv.dv_dma_vaddr, (ulong)devp->dv.dv_dma_paddr);
}
void vdin_dolby_addr_release(struct vdin_dev_s *devp, unsigned int size)
{
unsigned int alloc_size;
alloc_size = dolby_size_byte*size;
if (devp->dv.dv_dma_vaddr)
dma_free_coherent(&devp->this_pdev->dev, alloc_size,
devp->dv.dv_dma_vaddr, devp->dv.dv_dma_paddr);
devp->dv.dv_dma_vaddr = NULL;
}
static void vdin_dolby_metadata_swap(char *buf)
{
char ext;
unsigned int i, j;
for (i = 0; (i*16) < dolby_size_byte; i++) {
for (j = 0; j < 8; j++) {
ext = buf[i*16+j];
buf[i*16+j] = buf[i*16+15-j];
buf[i*16+15-j] = ext;
}
}
}
#define swap32(num) \
(((num>>24)&0xff) | \
((num<<8)&0xff0000) | \
((num>>8)&0xff00) | \
((num<<24)&0xff000000))
static uint32_t crc32_lut[256] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
static uint32_t crc32(uint32_t crc, const void *buf, size_t size)
{
const uint8_t *p = (const uint8_t *)buf;
crc = ~crc;
while (size) {
crc = (crc << 8) ^ crc32_lut[((crc >> 24) ^ *p) & 0xff];
p++;
size--;
}
return crc;
}
void vdin_dolby_buffer_update(struct vdin_dev_s *devp, unsigned int index)
{
uint32_t *p;
char *c;
uint32_t meta32, meta_size;
int i;
int count;
unsigned int offset = devp->addr_offset;
uint32_t crc_result, crc;
bool multimeta_flag = 0;
bool multimetatail_flag = 0;
uint32_t crc_result1 = 0;
uint32_t crc1 = 0;
int j, k;
char tmpmeta[1024];
uint32_t extmetasize;
uint32_t metapayloadsize;
metapayloadsize = DV_META_PACKET_SIZE -
DV_META_PACKET_TYPE_SIZE -
DV_META_HEADER_LEN -
DV_META_TAIL_CRC_SIZE;
if (index >= devp->canvas_max_num)
return;
c = devp->vfp->dv_buf_ori[index];
p = (uint32_t *)c;
for (count = 0; count < META_RETRY_MAX; count++) {
if (dv_dbg_mask & DV_READ_MODE_AXI) {
memcpy(p, devp->vfp->dv_buf_vmem[index], 128);
vdin_dolby_metadata_swap(c);
} else {
wr(offset, VDIN_DOLBY_DSC_CTRL3, 0);
wr(offset, VDIN_DOLBY_DSC_CTRL2, 0xd180c0d5);
for (i = 0; i < 128; i++) {
meta32 = rd(offset, VDIN_DOLBY_DSC_STATUS1);
p[i] = swap32(meta32);
if (((c[0] & (1 << 7)) == 0) &&
((c[0] & (1 << 6)) != 0))
multimeta_flag = 1;
if ((i == 31) && (multimeta_flag == 0))
break;
}
}
meta_size = (c[3] << 8) | c[4];
crc = p[31];
crc_result = crc32(0, p, 124);
crc_result = swap32(crc_result);
for (j = 128; j < 128 * 4; j += 128) {
if ((meta_size > metapayloadsize) &&
((c[j] & (1 << 7)) != 0) &&
((c[j] & (1 << 6)) != 0))
multimetatail_flag = 1;
}
if (dv_dbg_log&(1<<0))
pr_info("multimeta_flag=%d multimetatail_flag=%d\n",
multimeta_flag, multimetatail_flag);
if ((multimeta_flag == 1) && (multimetatail_flag == 1)) {
crc1 = p[127];
crc_result1 = crc32(0, p + 32 * 3, 124);
crc_result1 = swap32(crc_result1);
}
if (crc == crc_result) {
if ((multimeta_flag == 1) &&
(multimetatail_flag == 1)) {
if (crc1 == crc_result1)
break;
} else
break;
}
}
if ((crc != crc_result) || ((multimeta_flag == 1)
&& (multimetatail_flag == 1)
&& (crc1 != crc_result1))) {
/* set small size to make control path return -1
* to use previous setting
*/
devp->vfp->dv_buf[index] = &c[5];
devp->vfp->dv_buf_size[index] = 4;
if (dv_dbg_log&(1<<3)) {
pr_err("%s:hdmi dovi meta crc error:%08x!=%08x\n",
__func__, crc, crc_result);
pr_info("%s:index:%d dma:%x vaddr:%p size:%d\n",
__func__, index,
devp->vfp->dv_buf_mem[index],
devp->vfp->dv_buf_vmem[index],
meta_size);
for (i = 0; i < 128; i += 4)
pr_info("\t%08x %08x %08x %08x\n",
p[i], p[i+1], p[i+2], p[i+3]);
}
devp->dv.dv_crc_check = false;
} else {
devp->dv.dv_crc_check = true;
devp->vfp->dv_buf[index] = &c[5];
devp->vfp->dv_buf_size[index] = meta_size;
if ((multimeta_flag == 1) && (multimetatail_flag == 1)) {
memcpy(tmpmeta, c + 5, metapayloadsize);
extmetasize = meta_size - metapayloadsize;
for (k = 0; k < extmetasize; k++)
tmpmeta[119 + k] = c[128 * 3 + 3 + k];
memcpy(devp->vfp->dv_buf[index], tmpmeta, meta_size);
} else if (meta_size > metapayloadsize)
devp->dv.dv_crc_check = false;
if (dv_dbg_log&(1<<0))
pr_info("%s:index:%d dma:%x vaddr:%p size:%d crc:%x crc1:%x\n",
__func__, index,
devp->vfp->dv_buf_mem[index],
devp->vfp->dv_buf_vmem[index],
meta_size, crc, crc1);
if (dv_dbg_log&(1<<2))
for (i = 0; i < 128; i += 4)
pr_info("\t%08x %08x %08x %08x\n",
p[i], p[i+1], p[i+2], p[i+3]);
}
}
void vdin_dolby_addr_update(struct vdin_dev_s *devp, unsigned int index)
{
unsigned int offset = devp->addr_offset;
uint32_t *p;
if (index >= devp->canvas_max_num)
return;
devp->vfp->dv_buf[index] = NULL;
devp->vfp->dv_buf_size[index] = 0;
p = (uint32_t *)devp->vfp->dv_buf_vmem[index];
p[0] = p[1] = 0;
if (dv_dbg_mask & DV_READ_MODE_AXI) {
wr(offset, VDIN_DOLBY_AXI_CTRL1,
devp->vfp->dv_buf_mem[index]);
wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 4, 1);
wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 4, 1);
if (dv_dbg_log&(1<<0))
pr_info("%s:index:%d dma:%x\n", __func__,
index, devp->vfp->dv_buf_mem[index]);
} else {
wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5);
wr(offset, VDIN_DOLBY_DSC_CTRL3, 0);
if (dv_dbg_log&(1<<0))
pr_info("%s:index:%d\n", __func__, index);
}
if (dv_dbg_log&(1<<2))
pr_info("%s:index:%d,paddr:0x%x\n", __func__, index,
devp->vfp->dv_buf_mem[index]);
}
void vdin_dolby_config(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
devp->dv.dv_config = 1;
wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 1, 30, 1);
wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 1, 26, 1);
wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 0, 26, 1);
if (dv_dbg_mask & DV_READ_MODE_AXI) {
wr(offset, VDIN_DOLBY_AXI_CTRL1,
devp->vfp->dv_buf_mem[0]);
/* hold line = 0 */
wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 8, 8);
wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 4, 1);
wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 5, 1);
wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 5, 1);
wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 4, 1);
} else {
wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5);
wr(offset, VDIN_DOLBY_DSC_CTRL3, 0x0);
}
}
int vdin_event_cb(int type, void *data, void *op_arg)
{
unsigned long flags;
struct vf_pool *p;
if (!op_arg) {
if (vdin_ctl_dbg&(1<<3))
pr_info("%s:op_arg is NULL!\n", __func__);
return -1;
}
if (!data) {
if (vdin_ctl_dbg&(1<<4))
pr_info("%s:data is NULL!\n", __func__);
return -1;
}
p = (struct vf_pool *)op_arg;
if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
struct provider_aux_req_s *req =
(struct provider_aux_req_s *)data;
unsigned char index;
if (!req->vf) {
pr_info("%s:req->vf is NULL!\n", __func__);
return -1;
}
spin_lock_irqsave(&p->dv_lock, flags);
index = req->vf->index & 0xff;
req->aux_buf = NULL;
req->aux_size = 0;
req->dv_enhance_exist = 0;
/* TODO: need change the low latency flag when LL mode */
req->low_latency = 0;
if (req->bot_flag)
index = (req->vf->index >> 8) & 0xff;
if (index != 0xff
&& index < p->size
&& p->dv_buf[index]) {
req->aux_buf = p->dv_buf[index];
req->aux_size = p->dv_buf_size[index];
}
spin_unlock_irqrestore(&p->dv_lock, flags);
if (dv_dbg_log&(1<<1))
pr_info("%s(type 0x%x vf index 0x%x)=>size 0x%x\n",
__func__, type, index, req->aux_size);
} else if (type & VFRAME_EVENT_RECEIVER_DISP_MODE) {
struct provider_disp_mode_req_s *req =
(struct provider_disp_mode_req_s *)data;
unsigned int index_disp;
if (!req->vf) {
pr_info("%s:req->vf is NULL!\n", __func__);
return -1;
}
index_disp = req->vf->index_disp & 0xff;
if (index_disp >= VFRAME_DISP_MAX_NUM) {
if (vdin_ctl_dbg&(1<<2))
pr_info("%s:req->vf->index_disp(%d) is overflow!\n",
__func__, index_disp);
return -1;
}
if (game_mode)
req->disp_mode = VFRAME_DISP_MODE_NULL;
else
req->disp_mode = p->disp_mode[index_disp];
if ((req->req_mode == 1) && (p->skip_vf_num))
p->disp_mode[index_disp] = VFRAME_DISP_MODE_UNKNOWN;
if (vdin_ctl_dbg&(1<<1))
pr_info("%s(type 0x%x vf index 0x%x)=>disp_mode %d,req_mode:%d\n",
__func__, type, index_disp, req->disp_mode,
req->req_mode);
}
return 0;
}
void set_invert_top_bot(bool invert_flag)
{
invert_top_bot = invert_flag;
}
static int vdin_hdr_sei_error_check(struct vdin_dev_s *devp)
{
int primary_data[3][2];
int i;
/*GBR compare with standard 709 primary*/
for (i = 0; i < 3; i++) {
primary_data[i][0] =
devp->prop.hdr_info.hdr_data.primaries[i].x;
primary_data[i][1] =
devp->prop.hdr_info.hdr_data.primaries[i].y;
}
if (((primary_data[0][0] + 250) / 500 == 30) &&
((primary_data[0][1] + 250) / 500 == 60) &&
((primary_data[1][0] + 250) / 500 == 15) &&
((primary_data[1][1] + 250) / 500 == 6) &&
((primary_data[2][0] + 250) / 500 == 64) &&
((primary_data[2][1] + 250) / 500 == 33))
return 1;
/*RGB compare with standard 709 primary*/
for (i = 0; i < 3; i++) {
primary_data[(i + 2) % 3][0] =
devp->prop.hdr_info.hdr_data.primaries[i].x;
primary_data[(i + 2) % 3][1] =
devp->prop.hdr_info.hdr_data.primaries[i].y;
}
if (((primary_data[0][0] + 250) / 500 == 30) &&
((primary_data[0][1] + 250) / 500 == 60) &&
((primary_data[1][0] + 250) / 500 == 15) &&
((primary_data[1][1] + 250) / 500 == 6) &&
((primary_data[2][0] + 250) / 500 == 64) &&
((primary_data[2][1] + 250) / 500 == 33))
return 1;
/*GxBxRxGyByRy compare with standard 709 primary*/
primary_data[0][0] = devp->prop.hdr_info.hdr_data.primaries[0].x;
primary_data[0][1] = devp->prop.hdr_info.hdr_data.primaries[1].y;
primary_data[1][0] = devp->prop.hdr_info.hdr_data.primaries[0].y;
primary_data[1][1] = devp->prop.hdr_info.hdr_data.primaries[2].x;
primary_data[2][0] = devp->prop.hdr_info.hdr_data.primaries[1].x;
primary_data[2][1] = devp->prop.hdr_info.hdr_data.primaries[2].y;
if (((primary_data[0][0] + 250) / 500 == 30) &&
((primary_data[0][1] + 250) / 500 == 60) &&
((primary_data[1][0] + 250) / 500 == 15) &&
((primary_data[1][1] + 250) / 500 == 6) &&
((primary_data[2][0] + 250) / 500 == 64) &&
((primary_data[2][1] + 250) / 500 == 33))
return 1;
else
return 0;
}
void vdin_set_drm_data(struct vdin_dev_s *devp,
struct vframe_s *vf)
{
struct vframe_master_display_colour_s *vf_dp
= &vf->prop.master_display_colour;
if (devp->prop.hdr_info.hdr_state == HDR_STATE_GET) {
if (vdin_hdr_sei_error_check(devp) == 1) {
devp->prop.vdin_hdr_Flag = false;
vf_dp->present_flag = false;
vf->signal_type &= ~(1 << 29);
vf->signal_type &= ~(1 << 25);
/*todo;default is bt709,if change need sync*/
vf->signal_type = ((1 << 16) |
(vf->signal_type & (~0xFF0000)));
vf->signal_type = ((1 << 8) |
(vf->signal_type & (~0xFF00)));
} else {
memcpy(vf_dp->primaries,
devp->prop.hdr_info.hdr_data.primaries,
sizeof(u32)*6);
memcpy(vf_dp->white_point,
&devp->prop.hdr_info.hdr_data.white_points,
sizeof(u32)*2);
memcpy(vf_dp->luminance,
&devp->prop.hdr_info.hdr_data.master_lum,
sizeof(u32)*2);
/* content_light_level */
vf_dp->content_light_level.max_content =
devp->prop.hdr_info.hdr_data.mcll;
vf_dp->content_light_level.max_pic_average =
devp->prop.hdr_info.hdr_data.mfall;
vf_dp->present_flag = true;
if ((devp->prop.hdr_info.hdr_data.mcll != 0) &&
(devp->prop.hdr_info.hdr_data.mfall != 0))
vf_dp->content_light_level.present_flag = 1;
else
vf_dp->content_light_level.present_flag = 0;
if ((devp->prop.hdr_info.hdr_data.eotf ==
EOTF_SMPTE_ST_2048) ||
(devp->prop.hdr_info.hdr_data.eotf ==
EOTF_HDR)) {
vf->signal_type |= (1 << 29);
vf->signal_type |= (0 << 25);/*0:limit*/
vf->signal_type = ((9 << 16) |
(vf->signal_type & (~0xFF0000)));
vf->signal_type = ((16 << 8) |
(vf->signal_type & (~0xFF00)));
vf->signal_type = ((9 << 0) |
(vf->signal_type & (~0xFF)));
} else if (devp->prop.hdr_info.hdr_data.eotf ==
EOTF_HLG) {
vf->signal_type |= (1 << 29);
vf->signal_type |= (0 << 25);/*0:limit*/
vf->signal_type = ((9 << 16) |
(vf->signal_type & (~0xFF0000)));
vf->signal_type = ((14 << 8) |
(vf->signal_type & (~0xFF00)));
vf->signal_type = ((9 << 0) |
(vf->signal_type & (~0xFF)));
} else {
vf->signal_type &= ~(1 << 29);
vf->signal_type &= ~(1 << 25);
/*todo;default is bt709,if change need sync*/
vf->signal_type = ((1 << 16) |
(vf->signal_type & (~0xFF0000)));
vf->signal_type = ((1 << 8) |
(vf->signal_type & (~0xFF00)));
}
devp->prop.vdin_hdr_Flag = true;
}
devp->prop.hdr_info.hdr_state = HDR_STATE_SET;
} else if (devp->prop.hdr_info.hdr_state == HDR_STATE_NULL) {
devp->prop.vdin_hdr_Flag = false;
vf_dp->present_flag = false;
vf->signal_type &= ~(1 << 29);
vf->signal_type &= ~(1 << 25);
/*todo;default is bt709,if change need sync*/
vf->signal_type = ((1 << 16) |
(vf->signal_type & (~0xFF0000)));
vf->signal_type = ((1 << 8) |
(vf->signal_type & (~0xFF00)));
}
}
u32 vdin_get_curr_field_type(struct vdin_dev_s *devp)
{
u32 field_status;
u32 type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_FIELD;
enum vdin_format_convert_e format_convert;
/* struct tvin_parm_s *parm = &devp->parm; */
const struct tvin_format_s *fmt_info = devp->fmt_info_p;
if (fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) {
type |= VIDTYPE_PROGRESSIVE;
} else {
field_status = vdin_get_field_type(devp->addr_offset);
/*tvafe FIELD POLARITY 0 TOP,vdin must invert for correct*/
if (invert_top_bot ||
(devp->parm.port >= TVIN_PORT_CVBS0 &&
devp->parm.port <= TVIN_PORT_CVBS3))
type |= field_status ?
VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM;
else
type |= field_status ?
VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP;
}
format_convert = devp->format_convert;
if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) ||
(format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444)) {
type |= VIDTYPE_VIU_444;
if (devp->afbce_mode == 1)
type |= VIDTYPE_COMB_MODE;
} else if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) ||
(format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422))
type |= VIDTYPE_VIU_422;
else if (devp->prop.dest_cfmt == TVIN_NV21) {
type |= VIDTYPE_VIU_NV21;
type &= (~VIDTYPE_VIU_SINGLE_PLANE);
} else if (devp->prop.dest_cfmt == TVIN_NV12) {
/* type |= VIDTYPE_VIU_NV12; */
type &= (~VIDTYPE_VIU_SINGLE_PLANE);
}
if (devp->afbce_mode == 1) {
type |= VIDTYPE_COMPRESS;
type |= VIDTYPE_SCATTER;
if (devp->afbce_lossy_en == 1)
type |= VIDTYPE_COMPRESS_LOSS;
}
return type;
}
/* function: set vf source type
* source type list:
* a.VFRAME_SOURCE_TYPE_TUNER (TVIN_PORT CVBS3/CVBS0)
* b.VFRAME_SOURCE_TYPE_CVBS (TVIN_PORT CVBS1/
* CVBS2/CVBS4/CVBS5/CVBS6/CVBS7)
* c.VFRAME_SOURCE_TYPE_COMP (TVIN_PORT COMP0~COMP7)
* d.VFRAME_SOURCE_TYPE_HDMI (TVIN_PORT HDMI0~HDMI7/DVIN0)
* e.others
*/
inline void vdin_set_source_type(struct vdin_dev_s *devp,
struct vframe_s *vf)
{
switch (devp->parm.port) {
case TVIN_PORT_CVBS3:
case TVIN_PORT_CVBS0:
vf->source_type = VFRAME_SOURCE_TYPE_TUNER;
break;
case TVIN_PORT_CVBS1:
case TVIN_PORT_CVBS2:
vf->source_type = VFRAME_SOURCE_TYPE_CVBS;
break;
case TVIN_PORT_HDMI0:
case TVIN_PORT_HDMI1:
case TVIN_PORT_HDMI2:
case TVIN_PORT_HDMI3:
case TVIN_PORT_HDMI4:
case TVIN_PORT_HDMI5:
case TVIN_PORT_HDMI6:
case TVIN_PORT_HDMI7:
case TVIN_PORT_DVIN0:/* external hdmiin used default */
vf->source_type = VFRAME_SOURCE_TYPE_HDMI;
break;
default:
vf->source_type = VFRAME_SOURCE_TYPE_OTHERS;
break;
}
}
/**function:set
*main source modes:
*a.NTSC b.PAL
*c.SECAM d.others
*/
inline void vdin_set_source_mode(struct vdin_dev_s *devp,
struct vframe_s *vf)
{
switch (devp->parm.info.fmt) {
case TVIN_SIG_FMT_CVBS_NTSC_M:
case TVIN_SIG_FMT_CVBS_NTSC_443:
vf->source_mode = VFRAME_SOURCE_MODE_NTSC;
break;
case TVIN_SIG_FMT_CVBS_PAL_I:
case TVIN_SIG_FMT_CVBS_PAL_M:
case TVIN_SIG_FMT_CVBS_PAL_60:
case TVIN_SIG_FMT_CVBS_PAL_CN:
vf->source_mode = VFRAME_SOURCE_MODE_PAL;
break;
case TVIN_SIG_FMT_CVBS_SECAM:
vf->source_mode = VFRAME_SOURCE_MODE_SECAM;
break;
default:
vf->source_mode = VFRAME_SOURCE_MODE_OTHERS;
break;
}
}
/*
* 480p/i = 9:8
* 576p/i = 16:15
* 720p and 1080p/i = 1:1
* All VGA format = 1:1
*/
void vdin_set_pixel_aspect_ratio(struct vdin_dev_s *devp,
struct vframe_s *vf)
{
switch (devp->parm.info.fmt) {
/* 480P */
case TVIN_SIG_FMT_HDMI_640X480P_60HZ:
case TVIN_SIG_FMT_HDMI_640X480P_72HZ:
case TVIN_SIG_FMT_HDMI_640X480P_75HZ:
case TVIN_SIG_FMT_HDMI_720X480P_60HZ:
case TVIN_SIG_FMT_HDMI_1440X480P_60HZ:
case TVIN_SIG_FMT_HDMI_2880X480P_60HZ:
case TVIN_SIG_FMT_HDMI_720X480P_120HZ:
case TVIN_SIG_FMT_HDMI_720X480P_240HZ:
case TVIN_SIG_FMT_HDMI_720X480P_60HZ_FRAME_PACKING:
case TVIN_SIG_FMT_CAMERA_640X480P_30HZ:
/* 480I */
case TVIN_SIG_FMT_CVBS_NTSC_M:
case TVIN_SIG_FMT_CVBS_NTSC_443:
case TVIN_SIG_FMT_CVBS_PAL_M:
case TVIN_SIG_FMT_CVBS_PAL_60:
case TVIN_SIG_FMT_HDMI_1440X480I_60HZ:
case TVIN_SIG_FMT_HDMI_2880X480I_60HZ:
case TVIN_SIG_FMT_HDMI_1440X480I_120HZ:
case TVIN_SIG_FMT_HDMI_1440X480I_240HZ:
case TVIN_SIG_FMT_BT656IN_480I_60HZ:
case TVIN_SIG_FMT_BT601IN_480I_60HZ:
vf->pixel_ratio = PIXEL_ASPECT_RATIO_8_9;
break;
/* 576P */
case TVIN_SIG_FMT_HDMI_720X576P_50HZ:
case TVIN_SIG_FMT_HDMI_1440X576P_50HZ:
case TVIN_SIG_FMT_HDMI_2880X576P_50HZ:
case TVIN_SIG_FMT_HDMI_720X576P_100HZ:
case TVIN_SIG_FMT_HDMI_720X576P_200HZ:
case TVIN_SIG_FMT_HDMI_720X576P_50HZ_FRAME_PACKING:
/* 576I */
case TVIN_SIG_FMT_CVBS_PAL_I:
case TVIN_SIG_FMT_CVBS_PAL_CN:
case TVIN_SIG_FMT_CVBS_SECAM:
case TVIN_SIG_FMT_HDMI_1440X576I_50HZ:
case TVIN_SIG_FMT_HDMI_2880X576I_50HZ:
case TVIN_SIG_FMT_HDMI_1440X576I_100HZ:
case TVIN_SIG_FMT_HDMI_1440X576I_200HZ:
case TVIN_SIG_FMT_BT656IN_576I_50HZ:
case TVIN_SIG_FMT_BT601IN_576I_50HZ:
vf->pixel_ratio = PIXEL_ASPECT_RATIO_16_15;
break;
default:
vf->pixel_ratio = PIXEL_ASPECT_RATIO_1_1;
break;
}
}
/*
* based on the bellow parameters:
*1.h_active
*2.v_active
*/
void vdin_set_display_ratio(struct vdin_dev_s *devp,
struct vframe_s *vf)
{
unsigned int re = 0;
enum tvin_aspect_ratio_e aspect_ratio = devp->prop.aspect_ratio;
if (vf->width == 0 || vf->height == 0)
return;
re = (vf->width * 36)/vf->height;
if ((re > 36 && re <= 56) || (re == 90) || (re == 108))
vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT;
else if (re > 56)
vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT;
else
vf->ratio_control = 0x0 << DISP_RATIO_ASPECT_RATIO_BIT;
switch (aspect_ratio) {
case TVIN_ASPECT_4x3_FULL:
vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM;
vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS;
vf->pic_mode.hs = 0;
vf->pic_mode.he = 0;
vf->pic_mode.vs = 0;
vf->pic_mode.ve = 0;
/* 3*256/4=0xc0 */
vf->pic_mode.custom_ar = 0xc0;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
break;
case TVIN_ASPECT_14x9_FULL:
vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM;
vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS;
vf->pic_mode.hs = 0;
vf->pic_mode.he = 0;
vf->pic_mode.vs = 0;
vf->pic_mode.ve = 0;
/* 9*256/14=0xc0 */
vf->pic_mode.custom_ar = 0xa4;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
break;
case TVIN_ASPECT_16x9_FULL:
vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM;
vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS;
vf->pic_mode.hs = 0;
vf->pic_mode.he = 0;
vf->pic_mode.vs = 0;
vf->pic_mode.ve = 0;
/* 9*256/16=0xc0 */
vf->pic_mode.custom_ar = 0x90;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
break;
case TVIN_ASPECT_14x9_LB_CENTER:
/**720/462=14/9;(576-462)/2=57;57/2=28**/
/**need cut more**/
vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM;
vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS;
vf->pic_mode.hs = 0;
vf->pic_mode.he = 0;
vf->pic_mode.vs = 36;
vf->pic_mode.ve = 36;
vf->pic_mode.custom_ar = 0xa4;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
break;
case TVIN_ASPECT_14x9_LB_TOP:
/**720/462=14/9;(576-462)/2=57**/
vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM;
vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS;
vf->pic_mode.hs = 0;
vf->pic_mode.he = 0;
vf->pic_mode.vs = 0;
vf->pic_mode.ve = 57;
vf->pic_mode.custom_ar = 0xa4;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
break;
case TVIN_ASPECT_16x9_LB_CENTER:
/**720/405=16/9;(576-405)/2=85;85/2=42**/
/**need cut more**/
vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM;
vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS;
vf->pic_mode.hs = 0;
vf->pic_mode.he = 0;
vf->pic_mode.vs = 70;
vf->pic_mode.ve = 70;
vf->pic_mode.custom_ar = 0x90;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
break;
case TVIN_ASPECT_16x9_LB_TOP:
/**720/405=16/9;(576-405)/2=85**/
vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM;
vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS;
vf->pic_mode.hs = 0;
vf->pic_mode.he = 0;
vf->pic_mode.vs = 0;
vf->pic_mode.ve = 85;
vf->pic_mode.custom_ar = 0x90;
vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
break;
default:
break;
}
}
/*function:set source bitdepth
* based on parameter:
* devp->source_bitdepth: 8/9/10
*/
inline void vdin_set_source_bitdepth(struct vdin_dev_s *devp,
struct vframe_s *vf)
{
switch (devp->source_bitdepth) {
case 10:
vf->bitdepth = BITDEPTH_Y10 | BITDEPTH_U10 | BITDEPTH_V10;
break;
case 9:
vf->bitdepth = BITDEPTH_Y9 | BITDEPTH_U9 | BITDEPTH_V9;
break;
case 8:
vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
break;
default:
vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
break;
}
if (devp->color_depth_mode && (devp->source_bitdepth > 8) &&
((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) ||
(devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)))
vf->bitdepth |= FULL_PACK_422_MODE;
}
/*@20170905new add for support dynamic adj dest_format yuv422/yuv444,
*not support nv21 dynamic adj!!!
*/
void vdin_source_bitdepth_reinit(struct vdin_dev_s *devp)
{
int i = 0;
struct vf_entry *master;
struct vframe_s *vf;
struct vf_pool *p = devp->vfp;
for (i = 0; i < p->size; ++i) {
master = vf_get_master(p, i);
vf = &master->vf;
vdin_set_source_bitdepth(devp, vf);
}
}
void vdin_clk_onoff(struct vdin_dev_s *devp, bool onoff)
{
unsigned int offset = devp->addr_offset;
if (onoff) {
wr(offset, VDIN_COM_GCLK_CTRL, 0);
wr(offset, VDIN_COM_GCLK_CTRL2, 0);
} else {
wr(offset, VDIN_COM_GCLK_CTRL, 0x55555555);
wr(offset, VDIN_COM_GCLK_CTRL2, 0x55555555);
}
}