mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
Merge commit '866b86dd10b13dfe38eeb440c20d3dfa0e7c1397'
* commit '866b86dd10b13dfe38eeb440c20d3dfa0e7c1397': arm64: configs: rockchip_linux_defconfig: Add GPIO based HP for PCIe PCI: rockchip: dw: Add gpio based hotplug ARM: rk3506_defconfig: Enable CONFIG_LD_DEAD_CODE_DATA_ELIMINATION BACKPORT: ARM: 9404/1: arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION media: rockchip: vpss: support suspend and resume media: rockchip: vpss: offline add some debug info drm/rockchip: fix some csc parameters error ARM: rk3506_defconfig: Disable more unused NET_VENDOR media: i2c: rk628: reduce power consumption when there is no hdmi in Change-Id: I1c6686c648dda72859b325ea426e5bcbc949d49b
This commit is contained in:
@@ -108,6 +108,7 @@ config ARM
|
||||
select HAVE_KERNEL_XZ
|
||||
select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
|
||||
select HAVE_KRETPROBES if HAVE_KPROBES
|
||||
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select HAVE_NMI
|
||||
select HAVE_OPTPROBES if !THUMB2_KERNEL
|
||||
|
||||
@@ -125,7 +125,7 @@ SECTIONS
|
||||
|
||||
. = BSS_START;
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
.bss : { *(.bss .bss.*) }
|
||||
_end = .;
|
||||
|
||||
. = ALIGN(8); /* the stack must be 64-bit aligned */
|
||||
|
||||
@@ -16,6 +16,7 @@ CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_LZ4 is not set
|
||||
# CONFIG_RD_ZSTD is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
|
||||
# CONFIG_BUG is not set
|
||||
# CONFIG_ELF_CORE is not set
|
||||
# CONFIG_BASE_FULL is not set
|
||||
@@ -102,17 +103,23 @@ CONFIG_NETDEVICES=y
|
||||
# CONFIG_NET_VENDOR_AMAZON is not set
|
||||
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_ASIX is not set
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CADENCE is not set
|
||||
# CONFIG_NET_VENDOR_CAVIUM is not set
|
||||
# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
# CONFIG_NET_VENDOR_CORTINA is not set
|
||||
# CONFIG_NET_VENDOR_DAVICOM is not set
|
||||
# CONFIG_NET_VENDOR_ENGLEDER is not set
|
||||
# CONFIG_NET_VENDOR_EZCHIP is not set
|
||||
# CONFIG_NET_VENDOR_FARADAY is not set
|
||||
# CONFIG_NET_VENDOR_FUNGIBLE is not set
|
||||
# CONFIG_NET_VENDOR_GOOGLE is not set
|
||||
# CONFIG_NET_VENDOR_HISILICON is not set
|
||||
# CONFIG_NET_VENDOR_HUAWEI is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_ADI is not set
|
||||
# CONFIG_NET_VENDOR_LITEX is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MELLANOX is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
@@ -136,7 +143,9 @@ CONFIG_STMMAC_FULL=y
|
||||
# CONFIG_DWMAC_GENERIC is not set
|
||||
CONFIG_DWMAC_ROCKCHIP_TOOL=y
|
||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
|
||||
# CONFIG_NET_VENDOR_VERTEXCOM is not set
|
||||
# CONFIG_NET_VENDOR_VIA is not set
|
||||
# CONFIG_NET_VENDOR_WANGXUN is not set
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
# CONFIG_NET_VENDOR_XILINX is not set
|
||||
CONFIG_MOTORCOMM_PHY=y
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#define PROC_INFO \
|
||||
. = ALIGN(4); \
|
||||
__proc_info_begin = .; \
|
||||
*(.proc.info.init) \
|
||||
KEEP(*(.proc.info.init)) \
|
||||
__proc_info_end = .;
|
||||
|
||||
#define IDMAP_TEXT \
|
||||
|
||||
@@ -1297,6 +1297,7 @@ vector_addrexcptn:
|
||||
.globl vector_fiq
|
||||
|
||||
.section .vectors, "ax", %progbits
|
||||
.reloc .text, R_ARM_NONE, .
|
||||
W(b) vector_rst
|
||||
W(b) vector_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_swi )
|
||||
@@ -1310,6 +1311,7 @@ THUMB( .reloc ., R_ARM_THM_PC12, .L__vector_swi )
|
||||
|
||||
#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
||||
.section .vectors.bhb.loop8, "ax", %progbits
|
||||
.reloc .text, R_ARM_NONE, .
|
||||
W(b) vector_rst
|
||||
W(b) vector_bhb_loop8_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_loop8_swi )
|
||||
@@ -1322,6 +1324,7 @@ THUMB( .reloc ., R_ARM_THM_PC12, .L__vector_bhb_loop8_swi )
|
||||
W(b) vector_bhb_loop8_fiq
|
||||
|
||||
.section .vectors.bhb.bpiall, "ax", %progbits
|
||||
.reloc .text, R_ARM_NONE, .
|
||||
W(b) vector_rst
|
||||
W(b) vector_bhb_bpiall_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_bpiall_swi )
|
||||
|
||||
@@ -64,7 +64,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||
__start___ex_table = .;
|
||||
ARM_MMU_KEEP(*(__ex_table))
|
||||
ARM_MMU_KEEP(KEEP(*(__ex_table)))
|
||||
__stop___ex_table = .;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ SECTIONS
|
||||
}
|
||||
.init.arch.info : {
|
||||
__arch_info_begin = .;
|
||||
*(.arch.info.init)
|
||||
KEEP(*(.arch.info.init))
|
||||
__arch_info_end = .;
|
||||
}
|
||||
.init.tagtable : {
|
||||
|
||||
@@ -75,7 +75,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||
__start___ex_table = .;
|
||||
ARM_MMU_KEEP(*(__ex_table))
|
||||
ARM_MMU_KEEP(KEEP(*(__ex_table)))
|
||||
__stop___ex_table = .;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ SECTIONS
|
||||
}
|
||||
.init.arch.info : {
|
||||
__arch_info_begin = .;
|
||||
*(.arch.info.init)
|
||||
KEEP(*(.arch.info.init))
|
||||
__arch_info_end = .;
|
||||
}
|
||||
.init.tagtable : {
|
||||
@@ -117,7 +117,7 @@ SECTIONS
|
||||
#endif
|
||||
.init.pv_table : {
|
||||
__pv_table_begin = .;
|
||||
*(.pv_table)
|
||||
KEEP(*(.pv_table))
|
||||
__pv_table_end = .;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,8 @@ CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCIEASPM_POWERSAVE=y
|
||||
CONFIG_PCIEASPM_EXT=y
|
||||
# CONFIG_VGA_ARB is not set
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_GPIO=y
|
||||
CONFIG_PCIE_ROCKCHIP_HOST=y
|
||||
CONFIG_PCIE_DW_ROCKCHIP=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
|
||||
@@ -54,6 +54,10 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_CFI), $(KBUILD_CFLAGS))
|
||||
# disable LTO
|
||||
KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
|
||||
|
||||
# The .data section would be renamed to .data.efistub, therefore, remove
|
||||
# `-fdata-sections` flag from KBUILD_CFLAGS_KERNEL
|
||||
KBUILD_CFLAGS_KERNEL := $(filter-out -fdata-sections, $(KBUILD_CFLAGS_KERNEL))
|
||||
|
||||
GCOV_PROFILE := n
|
||||
# Sanitizer runtimes are unavailable and cannot be linked here.
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
@@ -207,6 +207,13 @@ static const struct rk_pq_csc_dc_coef rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsd
|
||||
|
||||
/* xv_ycc BT.601 (i.e. SD) -> to BT.709 (i.e. HD) */
|
||||
static const struct rk_pq_csc_coef rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr = {
|
||||
1024, -118, -213,
|
||||
0, 1043, 117,
|
||||
0, 77, 1050
|
||||
};
|
||||
|
||||
/* xv_ycc BT.601 full(i.e. SD) -> to BT.709 full(i.e. HD) */
|
||||
static const struct rk_pq_csc_coef rk_csc_table_xv_yccsdy_cb_cr_full_to_hdy_cb_cr_full = {
|
||||
1024, -121, -218,
|
||||
0, 1043, 117,
|
||||
0, 77, 1050
|
||||
@@ -642,7 +649,7 @@ static const struct rk_csc_mode_coef g_mode_csc_coef[] = {
|
||||
},
|
||||
{
|
||||
RK_PQ_CSC_YUV2YUV, "YUV L->YUV L",
|
||||
&rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr,
|
||||
&rk_csc_table_identity_y_cb_cr_to_y_cb_cr,
|
||||
&rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr,
|
||||
{
|
||||
OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_ITU_R_BT_709, false, false
|
||||
@@ -690,7 +697,7 @@ static const struct rk_csc_mode_coef g_mode_csc_coef[] = {
|
||||
},
|
||||
{
|
||||
RK_PQ_CSC_YUV2YUV_601_709_FULL, "YUV601 F->YUV709 F",
|
||||
&rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr,
|
||||
&rk_csc_table_xv_yccsdy_cb_cr_full_to_hdy_cb_cr_full,
|
||||
&rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsdy_cb_cr_full,
|
||||
{
|
||||
OPTM_CS_E_XV_YCC_601, OPTM_CS_E_ITU_R_BT_709, true, true
|
||||
@@ -890,7 +897,7 @@ static const struct rk_csc_mode_coef g_mode_csc_coef[] = {
|
||||
},
|
||||
{
|
||||
RK_PQ_CSC_YUV2YUV, "YUV 601 L->YUV 601 L",
|
||||
&rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr,
|
||||
&rk_csc_table_identity_y_cb_cr_to_y_cb_cr,
|
||||
&rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr,
|
||||
{
|
||||
OPTM_CS_E_XV_YCC_601, OPTM_CS_E_XV_YCC_601, false, false
|
||||
@@ -922,7 +929,7 @@ static const struct rk_csc_mode_coef g_mode_csc_coef[] = {
|
||||
},
|
||||
{
|
||||
RK_PQ_CSC_YUV2YUV, "YUV 2020 L->YUV 2020 L",
|
||||
&rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr,
|
||||
&rk_csc_table_identity_y_cb_cr_to_y_cb_cr,
|
||||
&rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr,
|
||||
{
|
||||
OPTM_CS_E_XV_YCC_2020, OPTM_CS_E_XV_YCC_2020, false, false
|
||||
@@ -988,14 +995,26 @@ static const struct rk_csc_mode_coef g_mode_csc_coef[] = {
|
||||
|
||||
static const struct rk_pq_csc_coef r2y_for_y2y = {
|
||||
306, 601, 117,
|
||||
-151, -296, 446,
|
||||
630, -527, -102,
|
||||
-173, -339, 512,
|
||||
512, -429, -83,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef y2r_for_y2y = {
|
||||
1024, -0, 1167,
|
||||
1024, -404, -594,
|
||||
1024, 2081, -1,
|
||||
1024, -1, 1436,
|
||||
1024, -353, -731,
|
||||
1024, 1814, 1,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef r2y_for_r2r = {
|
||||
1024, 0, 1612,
|
||||
1024, -192, -480,
|
||||
1024, 1900, -2,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef y2r_for_r2r = {
|
||||
218, 732, 74,
|
||||
-117, -395, 512,
|
||||
512, -465, -47,
|
||||
};
|
||||
|
||||
static const struct rk_pq_csc_coef rgb_input_swap_matrix = {
|
||||
@@ -1124,7 +1143,7 @@ static void csc_matrix_ventor_multiply(struct rk_pq_csc_ventor *dst,
|
||||
m0->csc_coef22 * v0->csc_offset2;
|
||||
}
|
||||
|
||||
static void csc_matrix_element_left_shift(struct rk_pq_csc_coef *m, int n)
|
||||
static void csc_matrix_element_right_shift(struct rk_pq_csc_coef *m, int n)
|
||||
{
|
||||
m->csc_coef00 = m->csc_coef00 >> n;
|
||||
m->csc_coef01 = m->csc_coef01 >> n;
|
||||
@@ -1137,6 +1156,30 @@ static void csc_matrix_element_left_shift(struct rk_pq_csc_coef *m, int n)
|
||||
m->csc_coef22 = m->csc_coef22 >> n;
|
||||
}
|
||||
|
||||
static inline s32 csc_simple_round(s32 x, s32 n)
|
||||
{
|
||||
s32 value = 0;
|
||||
|
||||
if (n == 0)
|
||||
return x;
|
||||
|
||||
value = (abs(x) + (1 << (n - 1))) >> (n);
|
||||
return (((x) >= 0) ? value : -value);
|
||||
}
|
||||
|
||||
static void csc_matrix_element_right_shift_with_simple_round(struct rk_pq_csc_coef *m, int n)
|
||||
{
|
||||
m->csc_coef00 = csc_simple_round(m->csc_coef00, n);
|
||||
m->csc_coef01 = csc_simple_round(m->csc_coef01, n);
|
||||
m->csc_coef02 = csc_simple_round(m->csc_coef02, n);
|
||||
m->csc_coef10 = csc_simple_round(m->csc_coef10, n);
|
||||
m->csc_coef11 = csc_simple_round(m->csc_coef11, n);
|
||||
m->csc_coef12 = csc_simple_round(m->csc_coef12, n);
|
||||
m->csc_coef20 = csc_simple_round(m->csc_coef20, n);
|
||||
m->csc_coef21 = csc_simple_round(m->csc_coef21, n);
|
||||
m->csc_coef22 = csc_simple_round(m->csc_coef22, n);
|
||||
}
|
||||
|
||||
static struct rk_pq_csc_coef create_rgb_gain_matrix(s32 r_gain, s32 g_gain, s32 b_gain)
|
||||
{
|
||||
struct rk_pq_csc_coef m;
|
||||
@@ -1280,23 +1323,23 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
csc_matrix_multiply(&temp0, csc_mode_cfg->pst_csc_coef, &hue_matrix);
|
||||
/*
|
||||
* The value bits width is 32 bit, so every time 2 matirx multifly,
|
||||
* left shift is necessary to avoid overflow. For enhancing the
|
||||
* right shift is necessary to avoid overflow. For enhancing the
|
||||
* calculator precision, PQ_CALC_ENHANCE_BIT bits is reserved and
|
||||
* left shift before get the final result.
|
||||
* right shift before get the final result.
|
||||
*/
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_multiply(&temp1, &temp0, &saturation_matrix);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &temp1, r2y_matrix);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp1, &temp0, &gain_matrix);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &temp1, &contrast_matrix);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(out_matrix, &temp0, y2r_matrix);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_element_right_shift_with_simple_round(out_matrix,
|
||||
PQ_CSC_PARAM_FIX_BIT_WIDTH + PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
dc_in_ventor.csc_offset1 = -PQ_CSC_DC_IN_OUT_DEFAULT;
|
||||
@@ -1311,15 +1354,15 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
* hue_matrix * saturation_matrix
|
||||
*/
|
||||
csc_matrix_multiply(&temp0, csc_mode_cfg->pst_csc_coef, &hue_matrix);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_multiply(&temp1, &temp0, &saturation_matrix);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &contrast_matrix, &temp1);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(out_matrix, &gain_matrix, &temp0);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_element_right_shift(out_matrix, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
dc_in_ventor.csc_offset1 = -PQ_CSC_DC_IN_OUT_DEFAULT;
|
||||
@@ -1334,15 +1377,15 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
* gain_matrix * contrast_matrix
|
||||
*/
|
||||
csc_matrix_multiply(&temp0, csc_mode_cfg->pst_csc_coef, &gain_matrix);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_multiply(&temp1, &temp0, &contrast_matrix);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &saturation_matrix, &temp1);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(out_matrix, &hue_matrix, &temp0);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_element_right_shift(out_matrix, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
dc_in_ventor.csc_offset1 = dc_in_offset;
|
||||
@@ -1356,35 +1399,21 @@ static int csc_calc_adjust_output_coef(bool is_input_yuv, bool is_output_yuv,
|
||||
* so output = T * gain_matrix * contrast_matrix *
|
||||
* N_y2r * hue_matrix * saturation_matrix * N_r2y
|
||||
*/
|
||||
if (!color_info->in_full_range && color_info->out_full_range) {
|
||||
r2y_matrix = &rk_csc_table_rgb_limit_to_hdy_cb_cr;
|
||||
y2r_matrix = &rk_csc_table_hdy_cb_cr_limit_to_rgb_full;
|
||||
} else if (color_info->in_full_range && !color_info->out_full_range) {
|
||||
r2y_matrix = &rk_csc_table_rgb_to_hdy_cb_cr;
|
||||
y2r_matrix = &rk_csc_table_hdy_cb_cr_limit_to_rgb_limit;
|
||||
} else if (color_info->in_full_range && color_info->out_full_range) {
|
||||
r2y_matrix = &rk_csc_table_rgb_to_hdy_cb_cr_full;
|
||||
y2r_matrix = &rk_csc_table_hdy_cb_cr_to_rgb_full;
|
||||
} else {
|
||||
r2y_matrix = &rk_csc_table_rgb_limit_to_hdy_cb_cr;
|
||||
y2r_matrix = &rk_csc_table_hdy_cb_cr_limit_to_rgb_limit;
|
||||
}
|
||||
r2y_matrix = &r2y_for_r2r;
|
||||
y2r_matrix = &y2r_for_r2r;
|
||||
|
||||
csc_matrix_multiply(&temp0, &contrast_matrix, y2r_matrix);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH -
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
csc_matrix_multiply(&temp1, &gain_matrix, &temp0);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp0, &temp1, &hue_matrix);
|
||||
csc_matrix_element_left_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp0, PQ_CSC_PARAM_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(&temp1, &temp0, &saturation_matrix);
|
||||
csc_matrix_element_left_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_element_right_shift(&temp1, PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH);
|
||||
csc_matrix_multiply(out_matrix, &temp1, r2y_matrix);
|
||||
csc_matrix_element_left_shift(out_matrix, PQ_CSC_PARAM_FIX_BIT_WIDTH +
|
||||
PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
if (color_info->in_full_range && color_info->out_full_range)
|
||||
out_matrix->csc_coef00 += 1;
|
||||
csc_matrix_element_right_shift_with_simple_round(out_matrix,
|
||||
PQ_CSC_PARAM_FIX_BIT_WIDTH + PQ_CALC_ENHANCE_BIT);
|
||||
|
||||
dc_in_ventor.csc_offset0 = dc_in_offset;
|
||||
dc_in_ventor.csc_offset1 = dc_in_offset;
|
||||
@@ -1522,9 +1551,9 @@ int rockchip_calc_post_csc(struct post_csc *csc_cfg, struct post_csc_coef *csc_s
|
||||
rockchip_swap_color_channel(convert_mode->is_input_yuv, convert_mode->is_output_yuv,
|
||||
csc_simple_coef, &out_matrix, &out_dc);
|
||||
|
||||
csc_simple_coef->csc_dc0 = pq_csc_simple_round(csc_simple_coef->csc_dc0, bit_num);
|
||||
csc_simple_coef->csc_dc1 = pq_csc_simple_round(csc_simple_coef->csc_dc1, bit_num);
|
||||
csc_simple_coef->csc_dc2 = pq_csc_simple_round(csc_simple_coef->csc_dc2, bit_num);
|
||||
csc_simple_coef->csc_dc0 = csc_simple_round(csc_simple_coef->csc_dc0, bit_num);
|
||||
csc_simple_coef->csc_dc1 = csc_simple_round(csc_simple_coef->csc_dc1, bit_num);
|
||||
csc_simple_coef->csc_dc2 = csc_simple_round(csc_simple_coef->csc_dc2, bit_num);
|
||||
csc_simple_coef->range_type = csc_mode_cfg->st_csc_color_info.out_full_range;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -246,10 +246,10 @@ EXPORT_SYMBOL(rk628_txphy_power_on);
|
||||
|
||||
void rk628_txphy_power_off(struct rk628 *rk628)
|
||||
{
|
||||
rk628_i2c_update_bits(rk628, COMBTXPHY_CON0, SW_TX_IDLE_MASK | SW_TX_PD_MASK |
|
||||
SW_PD_PLL_MASK | SW_MODULEB_EN_MASK |
|
||||
SW_MODULEA_EN_MASK, SW_TX_IDLE(0x3ff) |
|
||||
SW_TX_PD(0x3ff) | SW_PD_PLL);
|
||||
rk628_i2c_update_bits(rk628, COMBTXPHY_CON0, SW_TX_IDLE_MASK | SW_TX_PD_MASK |
|
||||
SW_PD_PLL_MASK | SW_MODULEB_EN_MASK | SW_MODULEA_EN_MASK |
|
||||
SW_GVI_LVDS_EN_MASK | SW_MIPI_DSI_EN_MASK,
|
||||
SW_TX_IDLE(0x3ff) | SW_TX_PD(0x3ff) | SW_PD_PLL);
|
||||
}
|
||||
EXPORT_SYMBOL(rk628_txphy_power_off);
|
||||
|
||||
|
||||
@@ -494,6 +494,7 @@ static void rk628_hdmirx_plugout(struct v4l2_subdev *sd)
|
||||
rk628_hdmirx_hpd_ctrl(sd, false);
|
||||
rk628_hdmirx_inno_phy_power_off(sd);
|
||||
rk628_hdmirx_verisyno_phy_power_off(csi->rk628);
|
||||
mipi_dphy_power_off(csi);
|
||||
}
|
||||
|
||||
static void rk628_hdmirx_config_all(struct v4l2_subdev *sd)
|
||||
@@ -1458,9 +1459,6 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
|
||||
}
|
||||
|
||||
csi->rk628->dphy_lane_en = 0x1f;
|
||||
if (csi->plat_data->tx_mode == CSI_MODE)
|
||||
mipi_dphy_power_on(csi);
|
||||
|
||||
csi->txphy_pwron = true;
|
||||
if (tx_5v_power_present(sd))
|
||||
schedule_delayed_work(&csi->delayed_work_enable_hotplug, msecs_to_jiffies(4000));
|
||||
|
||||
@@ -90,6 +90,7 @@ static inline struct vb2_queue *to_vb2_queue(struct file *file)
|
||||
|
||||
extern int rkvpss_debug;
|
||||
extern struct platform_driver rkvpss_plat_drv;
|
||||
extern int rkvpss_cfginfo_num;
|
||||
|
||||
void rkvpss_idx_write(struct rkvpss_device *dev, u32 reg, u32 val, int idx);
|
||||
void rkvpss_unite_write(struct rkvpss_device *dev, u32 reg, u32 val);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
int rkvpss_debug;
|
||||
module_param_named(debug, rkvpss_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Debug level (0-3)");
|
||||
MODULE_PARM_DESC(debug, "Debug level (0-6)");
|
||||
|
||||
static bool rkvpss_clk_dbg;
|
||||
module_param_named(clk_dbg, rkvpss_clk_dbg, bool, 0644);
|
||||
@@ -34,6 +34,30 @@ static char rkvpss_version[RKVPSS_VERNO_LEN];
|
||||
module_param_string(version, rkvpss_version, RKVPSS_VERNO_LEN, 0444);
|
||||
MODULE_PARM_DESC(version, "version number");
|
||||
|
||||
int rkvpss_cfginfo_num = 5;
|
||||
|
||||
static int rkvpss_get_cfginfo_num(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int num, ret;
|
||||
|
||||
ret = kstrtoint(val, 10, &num);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (num < 0 || num > 50) {
|
||||
pr_info("rkvpss_cfginfo_num must be range of 0 to 50");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return param_set_int(val, kp);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops cfginfo_num_ops = {
|
||||
.set = rkvpss_get_cfginfo_num,
|
||||
.get = param_get_int,
|
||||
};
|
||||
module_param_cb(cfginfo_num, &cfginfo_num_ops, &rkvpss_cfginfo_num, 0644);
|
||||
MODULE_PARM_DESC(cfginfo_num, "rkvpss offline cfginfo number");
|
||||
|
||||
void rkvpss_set_clk_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (rkvpss_clk_dbg)
|
||||
@@ -323,6 +347,8 @@ static int rkvpss_plat_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
vpss_dev->is_probe_end = true;
|
||||
init_waitqueue_head(&vpss_dev->stop_done);
|
||||
vpss_dev->is_suspend = false;
|
||||
vpss_dev->is_idle = true;
|
||||
return 0;
|
||||
|
||||
err_unreg_media_dev:
|
||||
@@ -351,7 +377,7 @@ static int rkvpss_plat_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rkvpss_runtime_suspend(struct device *dev)
|
||||
static int __maybe_unused rkvpss_dev_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct rkvpss_device *vpss_dev = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
@@ -362,7 +388,7 @@ static int __maybe_unused rkvpss_runtime_suspend(struct device *dev)
|
||||
return (ret > 0) ? 0 : ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused rkvpss_runtime_resume(struct device *dev)
|
||||
static int __maybe_unused rkvpss_dev_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct rkvpss_device *vpss_dev = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
@@ -373,9 +399,46 @@ static int __maybe_unused rkvpss_runtime_resume(struct device *dev)
|
||||
return (ret > 0) ? 0 : ret;
|
||||
}
|
||||
|
||||
static int rkvpss_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct rkvpss_device *vpss_dev = dev_get_drvdata(dev);
|
||||
u32 ret;
|
||||
|
||||
v4l2_dbg(4, rkvpss_debug, &vpss_dev->v4l2_dev, "%s enter\n", __func__);
|
||||
if (vpss_dev->vpss_sdev.state == VPSS_STOP)
|
||||
return 0;
|
||||
|
||||
vpss_dev->is_suspend = true;
|
||||
/* wait fe*/
|
||||
if (!vpss_dev->is_idle) {
|
||||
ret = wait_for_completion_timeout(&vpss_dev->pm_suspend_wait_fe,
|
||||
msecs_to_jiffies(200));
|
||||
if (!ret)
|
||||
v4l2_info(&vpss_dev->v4l2_dev, "%s wait fe timeout\n", __func__);
|
||||
}
|
||||
v4l2_dbg(4, rkvpss_debug, &vpss_dev->v4l2_dev, "%s exit\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkvpss_pm_resume(struct device *dev)
|
||||
{
|
||||
struct rkvpss_device *vpss_dev = dev_get_drvdata(dev);
|
||||
|
||||
v4l2_dbg(4, rkvpss_debug, &vpss_dev->v4l2_dev, "%s enter\n", __func__);
|
||||
if (vpss_dev->vpss_sdev.state == VPSS_STOP)
|
||||
return 0;
|
||||
|
||||
vpss_dev->is_suspend = false;
|
||||
v4l2_dbg(4, rkvpss_debug, &vpss_dev->v4l2_dev, "%s exit\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rkvpss_plat_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(rkvpss_runtime_suspend,
|
||||
rkvpss_runtime_resume, NULL)
|
||||
.suspend = rkvpss_pm_suspend,
|
||||
.resume = rkvpss_pm_resume,
|
||||
SET_RUNTIME_PM_OPS(rkvpss_dev_runtime_suspend,
|
||||
rkvpss_dev_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
struct platform_driver rkvpss_plat_drv = {
|
||||
|
||||
@@ -79,6 +79,9 @@ struct rkvpss_device {
|
||||
unsigned int irq_ends_mask;
|
||||
|
||||
bool is_probe_end;
|
||||
bool is_suspend;
|
||||
bool is_idle;
|
||||
struct completion pm_suspend_wait_fe;
|
||||
};
|
||||
|
||||
void rkvpss_pipeline_default_fmt(struct rkvpss_device *dev);
|
||||
|
||||
@@ -702,6 +702,107 @@ static const struct of_device_id rkvpss_hw_of_match[] = {
|
||||
{},
|
||||
};
|
||||
|
||||
void rkvpss_hw_reg_save(struct rkvpss_hw_dev *dev)
|
||||
{
|
||||
void *buf = dev->sw_reg;
|
||||
|
||||
dev_info(dev->dev, "%s\n", __func__);
|
||||
memcpy_fromio(buf, dev->base_addr, RKVPSS_SW_REG_SIZE);
|
||||
}
|
||||
|
||||
void rkvpss_hw_reg_restore(struct rkvpss_hw_dev *dev)
|
||||
{
|
||||
void __iomem *base = dev->base_addr;
|
||||
void *reg_buf = dev->sw_reg;
|
||||
u32 val, *reg, i;
|
||||
|
||||
dev_info(dev->dev, "%s\n", __func__);
|
||||
|
||||
/* cmsc */
|
||||
for (i = RKVPSS_CMSC_BASE; i <= RKVPSS_CMSC_WIN7_L3_SLP; i += 4) {
|
||||
if (i == RKVPSS_CMSC_UPDATE)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_CMSC_GEN_UPD | RKVPSS_CMSC_UPDATE;
|
||||
writel(val, base + RKVPSS_CMSC_UPDATE);
|
||||
|
||||
/* crop1 */
|
||||
for (i = RKVPSS_CROP1_CTRL; i <= RKVPSS_CROP1_3_V_SIZE; i += 4) {
|
||||
if (i == RKVPSS_CROP1_UPDATE)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_CROP_GEN_UPD | RKVPSS_CROP_FORCE_UPD;
|
||||
writel(val, base + RKVPSS_CROP1_UPDATE);
|
||||
writel(val, base + RKVPSS_CROP1_UPDATE);
|
||||
|
||||
/* scale */
|
||||
for (i = RKVPSS_ZME_BASE; i <= RKVPSS_ZME_UV_YSCL_FACTOR; i += 4) {
|
||||
if (i == RKVPSS_ZME_UPDATE)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_ZME_GEN_UPD | RKVPSS_ZME_FORCE_UPD;
|
||||
writel(val, base + RKVPSS_ZME_UPDATE);
|
||||
|
||||
for (i = RKVPSS_SCALE1_BASE; i <= RKVPSS_SCALE1_IN_CROP_OFFSET; i += 4) {
|
||||
if (i == RKVPSS_SCALE1_UPDATE)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_SCL_GEN_UPD | RKVPSS_SCL_FORCE_UPD;
|
||||
writel(val, base + RKVPSS_SCALE1_UPDATE);
|
||||
|
||||
for (i = RKVPSS_SCALE2_BASE; i <= RKVPSS_SCALE2_IN_CROP_OFFSET; i += 4) {
|
||||
if (i == RKVPSS_SCALE2_UPDATE)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_SCL_GEN_UPD | RKVPSS_SCL_FORCE_UPD;
|
||||
writel(val, base + RKVPSS_SCALE2_UPDATE);
|
||||
|
||||
for (i = RKVPSS_SCALE3_BASE; i <= RKVPSS_SCALE3_IN_CROP_OFFSET; i += 4) {
|
||||
if (i == RKVPSS_SCALE3_UPDATE)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_SCL_GEN_UPD | RKVPSS_SCL_FORCE_UPD;
|
||||
writel(val, base + RKVPSS_SCALE3_UPDATE);
|
||||
|
||||
/* mi */
|
||||
for (i = RKVPSS_MI_BASE; i <= RKVPSS_MI_CHN3_WR_LINE_CNT; i += 4) {
|
||||
if (i >= RKVPSS_MI_RD_CTRL && i <= RKVPSS_MI_RD_Y_HEIGHT_SHD)
|
||||
continue;
|
||||
if (i == RKVPSS_MI_WR_INIT)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_MI_FORCE_UPD;
|
||||
writel(val, base + RKVPSS_MI_WR_INIT);
|
||||
writel(val, base + RKVPSS_MI_WR_INIT);
|
||||
|
||||
/* vpss ctrl */
|
||||
for (i = RKVPSS_VPSS_BASE; i <= RKVPSS_VPSS_Y2R_OFF2; i += 4) {
|
||||
if (i == RKVPSS_VPSS_UPDATE || i == RKVPSS_VPSS_RESET)
|
||||
continue;
|
||||
reg = reg_buf + i;
|
||||
writel(*reg, base + i);
|
||||
}
|
||||
val = RKVPSS_CFG_FORCE_UPD | RKVPSS_CFG_GEN_UPD | RKVPSS_MIR_GEN_UPD |
|
||||
RKVPSS_ONLINE2_CHN_FORCE_UPD;
|
||||
if (!dev->is_ofl_cmsc)
|
||||
val |= RKVPSS_MIR_FORCE_UPD;
|
||||
writel(val, base + RKVPSS_VPSS_UPDATE);
|
||||
}
|
||||
|
||||
static int rkvpss_hw_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
@@ -721,6 +822,9 @@ static int rkvpss_hw_probe(struct platform_device *pdev)
|
||||
if (!hw_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
hw_dev->sw_reg = devm_kzalloc(dev, RKVPSS_SW_REG_SIZE, GFP_KERNEL);
|
||||
if (!hw_dev->sw_reg)
|
||||
return -ENOMEM;
|
||||
dev_set_drvdata(dev, hw_dev);
|
||||
hw_dev->dev = dev;
|
||||
match_data = match->data;
|
||||
@@ -749,8 +853,8 @@ static int rkvpss_hw_probe(struct platform_device *pdev)
|
||||
irq = platform_get_irq_byname(pdev, match_data->irqs[i].name);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "no irq %s in dts\n", match_data->irqs[i].name);
|
||||
ret = irq;
|
||||
goto err;
|
||||
ret = irq;
|
||||
goto err;
|
||||
}
|
||||
ret = devm_request_irq(dev, irq,
|
||||
match_data->irqs[i].irq_hdl,
|
||||
@@ -798,6 +902,7 @@ static int rkvpss_hw_probe(struct platform_device *pdev)
|
||||
hw_dev->is_dma_contig = true;
|
||||
hw_dev->is_shutdown = false;
|
||||
hw_dev->is_mmu = is_iommu_enable(dev);
|
||||
hw_dev->is_suspend = false;
|
||||
ret = of_reserved_mem_device_init(dev);
|
||||
if (ret) {
|
||||
is_mem_reserved = false;
|
||||
@@ -839,40 +944,72 @@ static void rkvpss_hw_shutdown(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
static int __maybe_unused rkvpss_runtime_suspend(struct device *dev)
|
||||
static int __maybe_unused rkvpss_hw_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct rkvpss_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
u32 ret;
|
||||
|
||||
if (rkvpss_debug >= 4)
|
||||
dev_info(dev, "%s enter\n", __func__);
|
||||
|
||||
if (dev->power.runtime_status) {
|
||||
rkvpss_hw_write(hw_dev, RKVPSS_MI_IMSC, 0);
|
||||
rkvpss_hw_write(hw_dev, RKVPSS_VPSS_IMSC, 0);
|
||||
hw_dev->ofl_dev.mode_sel_en = true;
|
||||
} else {
|
||||
rkvpss_hw_reg_save(hw_dev);
|
||||
hw_dev->is_suspend = true;
|
||||
if (hw_dev->ofl_dev.pm_need_wait) {
|
||||
ret = wait_for_completion_timeout(&hw_dev->ofl_dev.pm_cmpl,
|
||||
msecs_to_jiffies(200));
|
||||
if (!ret)
|
||||
dev_info(dev, "%s pm wait offline timeout\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
rkvpss_hw_write(hw_dev, RKVPSS_MI_IMSC, 0);
|
||||
rkvpss_hw_write(hw_dev, RKVPSS_VPSS_IMSC, 0);
|
||||
disable_sys_clk(hw_dev);
|
||||
hw_dev->ofl_dev.mode_sel_en = true;
|
||||
|
||||
if (rkvpss_debug >= 4)
|
||||
dev_info(dev, "%s exit\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rkvpss_runtime_resume(struct device *dev)
|
||||
static int __maybe_unused rkvpss_hw_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct rkvpss_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
void __iomem *base = hw_dev->base_addr;
|
||||
int i;
|
||||
|
||||
if (rkvpss_debug >= 4)
|
||||
dev_info(dev, "%s enter\n", __func__);
|
||||
|
||||
enable_sys_clk(hw_dev);
|
||||
rkvpss_soft_reset(hw_dev);
|
||||
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
void *buf = hw_dev->vpss[i]->sw_base_addr;
|
||||
if (dev->power.runtime_status) {
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
void *buf = hw_dev->vpss[i]->sw_base_addr;
|
||||
|
||||
memset(buf, 0, RKVPSS_SW_REG_SIZE_MAX);
|
||||
memcpy_fromio(buf, base, RKVPSS_SW_REG_SIZE);
|
||||
memset(buf, 0, RKVPSS_SW_REG_SIZE_MAX);
|
||||
memcpy_fromio(buf, base, RKVPSS_SW_REG_SIZE);
|
||||
}
|
||||
} else {
|
||||
rkvpss_hw_reg_restore(hw_dev);
|
||||
hw_dev->is_suspend = false;
|
||||
}
|
||||
|
||||
if (rkvpss_debug >= 4)
|
||||
dev_info(dev, "%s exit\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rkvpss_hw_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
pm_runtime_force_resume)
|
||||
SET_RUNTIME_PM_OPS(rkvpss_runtime_suspend,
|
||||
rkvpss_runtime_resume, NULL)
|
||||
SET_RUNTIME_PM_OPS(rkvpss_hw_runtime_suspend,
|
||||
rkvpss_hw_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver rkvpss_hw_drv = {
|
||||
|
||||
@@ -33,6 +33,7 @@ struct rkvpss_hw_dev {
|
||||
struct rkvpss_device *vpss[VPSS_MAX_DEV];
|
||||
struct rkvpss_offline_dev ofl_dev;
|
||||
struct list_head list;
|
||||
void *sw_reg;
|
||||
int clk_rate_tbl_num;
|
||||
int clks_num;
|
||||
int dev_num;
|
||||
@@ -52,6 +53,7 @@ struct rkvpss_hw_dev {
|
||||
bool is_single;
|
||||
bool is_dma_contig;
|
||||
bool is_shutdown;
|
||||
bool is_suspend;
|
||||
};
|
||||
|
||||
#define RKVPSS_ZME_TAP_COE(x, y) (((x) & 0x3ff) | (((y) & 0x3ff) << 16))
|
||||
@@ -67,4 +69,6 @@ void rkvpss_hw_write(struct rkvpss_hw_dev *hw_dev, u32 reg, u32 val);
|
||||
u32 rkvpss_hw_read(struct rkvpss_hw_dev *hw_dev, u32 reg);
|
||||
void rkvpss_hw_set_bits(struct rkvpss_hw_dev *hw, u32 reg, u32 mask, u32 val);
|
||||
void rkvpss_hw_clear_bits(struct rkvpss_hw_dev *hw, u32 reg, u32 mask);
|
||||
void rkvpss_hw_reg_save(struct rkvpss_hw_dev *dev);
|
||||
void rkvpss_hw_reg_restore(struct rkvpss_hw_dev *dev);
|
||||
#endif
|
||||
|
||||
@@ -779,8 +779,9 @@ static void rkvpss_buf_done_task(unsigned long arg)
|
||||
buf = list_first_entry(&local_list, struct rkvpss_buffer, queue);
|
||||
list_del(&buf->queue);
|
||||
v4l2_dbg(2, rkvpss_debug, &stream->dev->v4l2_dev,
|
||||
"%s id:%d seq:%d buf:0x%x done\n",
|
||||
node->vdev.name, stream->id, buf->vb.sequence, buf->dma[0]);
|
||||
"%s stream:%d index:%d seq:%d buf:0x%x done\n",
|
||||
node->vdev.name, stream->id, buf->vb.vb2_buf.index,
|
||||
buf->vb.sequence, buf->dma[0]);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf,
|
||||
stream->streaming ? VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
@@ -794,6 +795,9 @@ static void rkvpss_stream_buf_done(struct rkvpss_stream *stream,
|
||||
if (!stream || !buf)
|
||||
return;
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &stream->dev->v4l2_dev,
|
||||
"stream:%d\n", stream->id);
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
list_add_tail(&buf->queue, &stream->buf_done_list);
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
|
||||
@@ -807,6 +811,8 @@ static void rkvpss_frame_end(struct rkvpss_stream *stream)
|
||||
struct rkvpss_buffer *buf = NULL;
|
||||
unsigned long lock_flags = 0;
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &dev->v4l2_dev,
|
||||
"stream:%d\n", stream->id);
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
if (stream->curr_buf) {
|
||||
buf = stream->curr_buf;
|
||||
@@ -906,8 +912,8 @@ static void rkvpss_buf_queue(struct vb2_buffer *vb)
|
||||
}
|
||||
|
||||
v4l2_dbg(2, rkvpss_debug, &dev->v4l2_dev,
|
||||
"%s stream:%d buf:0x%x\n", __func__,
|
||||
stream->id, vpssbuf->dma[0]);
|
||||
"%s stream:%d index:%d buf:0x%x\n", __func__,
|
||||
stream->id, vb->index, vpssbuf->dma[0]);
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
list_add_tail(&vpssbuf->queue, &stream->buf_queue);
|
||||
|
||||
@@ -246,10 +246,11 @@ static int rkvpss_sof(struct rkvpss_subdev *sdev, struct rkisp_vpss_sof *info)
|
||||
sdev->frame_seq = info->seq;
|
||||
sdev->frame_timestamp = info->timestamp;
|
||||
dev->unite_index = info->unite_index;
|
||||
dev->is_idle = false;
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &dev->v4l2_dev,
|
||||
"%s unite_mode:%u, unite_indev:%u\n", __func__,
|
||||
dev->unite_mode, dev->unite_index);
|
||||
"%s unite_mode:%u, unite_indev:%u seq:%d\n", __func__,
|
||||
dev->unite_mode, dev->unite_index, info->seq);
|
||||
|
||||
rkvpss_cmsc_config(dev, !info->irq);
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
@@ -418,6 +419,10 @@ void rkvpss_check_idle(struct rkvpss_device *dev, u32 irq)
|
||||
|
||||
dev->irq_ends = 0;
|
||||
rkvpss_end_notify_isp(dev);
|
||||
dev->is_idle = true;
|
||||
|
||||
if (dev->is_suspend)
|
||||
complete(&dev->pm_suspend_wait_fe);
|
||||
}
|
||||
|
||||
int rkvpss_register_subdev(struct rkvpss_device *dev,
|
||||
@@ -451,6 +456,7 @@ int rkvpss_register_subdev(struct rkvpss_device *dev,
|
||||
if (ret < 0)
|
||||
goto free_media;
|
||||
rkvpss_subdev_default_fmt(vpss_sdev);
|
||||
init_completion(&dev->pm_suspend_wait_fe);
|
||||
return ret;
|
||||
free_media:
|
||||
media_entity_cleanup(&sd->entity);
|
||||
|
||||
@@ -148,7 +148,8 @@ static struct rkvpss_offline_buf *buf_add(struct file *file, int id, int fd, int
|
||||
buf->alloc = false;
|
||||
list_add_tail(&buf->list, &ofl->list);
|
||||
v4l2_dbg(1, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s file:%p dev_id:%d fd:%d dbuf:%p\n", __func__, file, id, fd, dbuf);
|
||||
"%s file:%p dev_id:%d fd:%d dbuf:%p size:%d\n", __func__,
|
||||
file, id, fd, dbuf, size);
|
||||
} else {
|
||||
dma_buf_put(dbuf);
|
||||
}
|
||||
@@ -417,6 +418,13 @@ static void poly_phase_scale(struct rkvpss_frame_cfg *frame_cfg,
|
||||
end:
|
||||
val = RKVPSS_ZME_GEN_UPD | RKVPSS_ZME_FORCE_UPD;
|
||||
rkvpss_hw_write(hw, RKVPSS_ZME_UPDATE, val);
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s unite:%d left:%d hw ctrl:0x%x y_src_size:0x%x y_dst_size:0x%x\n",
|
||||
__func__, unite, left,
|
||||
rkvpss_hw_read(hw, RKVPSS_ZME_CTRL),
|
||||
rkvpss_hw_read(hw, RKVPSS_ZME_Y_SRC_SIZE),
|
||||
rkvpss_hw_read(hw, RKVPSS_ZME_Y_DST_SIZE));
|
||||
}
|
||||
|
||||
static void bilinear_scale(struct rkvpss_frame_cfg *frame_cfg,
|
||||
@@ -537,6 +545,13 @@ end:
|
||||
rkvpss_hw_write(hw, reg_base, ctrl);
|
||||
val = RKVPSS_SCL_GEN_UPD | RKVPSS_SCL_FORCE_UPD;
|
||||
rkvpss_hw_write(hw, reg_base + 0x4, val);
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s unite:%d left:%d hw ch:%d ctrl:0x%x y_src_size:0x%x y_dst_size:0x%x\n",
|
||||
__func__, unite, left, idx,
|
||||
rkvpss_hw_read(hw, reg_base),
|
||||
rkvpss_hw_read(hw, reg_base + 0x8),
|
||||
rkvpss_hw_read(hw, reg_base + 0xc));
|
||||
}
|
||||
|
||||
static void scale_config(struct file *file,
|
||||
@@ -556,7 +571,7 @@ static void scale_config(struct file *file,
|
||||
}
|
||||
}
|
||||
|
||||
static void cmsc_config(struct rkvpss_offline_dev *ofl,
|
||||
static int cmsc_config(struct rkvpss_offline_dev *ofl,
|
||||
struct rkvpss_frame_cfg *cfg, bool unite, bool left)
|
||||
{
|
||||
struct rkvpss_hw_dev *hw = ofl->hw;
|
||||
@@ -568,9 +583,10 @@ static void cmsc_config(struct rkvpss_offline_dev *ofl,
|
||||
u32 ch_win_mode[RKVPSS_OUTPUT_MAX];
|
||||
u32 win_color[RKVPSS_CMSC_WIN_MAX];
|
||||
u32 val, slope, hor, mask, mosaic_block = 0, ctrl = 0;
|
||||
u32 hw_in_w, hw_in_h;
|
||||
|
||||
if (!hw->is_ofl_cmsc)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
if (!cfg->output[i].enable)
|
||||
@@ -597,14 +613,8 @@ static void cmsc_config(struct rkvpss_offline_dev *ofl,
|
||||
cfg->output[i].cmsc.win[j].cover_color_a = 15;
|
||||
win_color[j] |= RKVPSS_CMSC_WIN_ALPHA(cfg->output[i].cmsc.win[j].cover_color_a);
|
||||
}
|
||||
for (k = 0; k < RKVPSS_CMSC_POINT_MAX; k++) {
|
||||
for (k = 0; k < RKVPSS_CMSC_POINT_MAX; k++)
|
||||
tmp_cfg.win[j].point[k] = cmsc_cfg->win[j].point[k];
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s input params dev_id:%d, unite:%d left:%d ch:%d win:%d point:%d x:%u y:%u",
|
||||
__func__, cfg->dev_id, unite, left, i, j, k,
|
||||
tmp_cfg.win[j].point[k].x,
|
||||
tmp_cfg.win[j].point[k].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,10 +715,23 @@ static void cmsc_config(struct rkvpss_offline_dev *ofl,
|
||||
}
|
||||
rkvpss_hw_write(hw, RKVPSS_CMSC_CHN0_WIN + i * 4, ch_win_en[i]);
|
||||
rkvpss_hw_write(hw, RKVPSS_CMSC_CHN0_MODE + i * 4, ch_win_mode[i]);
|
||||
hw_in_w = rkvpss_hw_read(hw, RKVPSS_MI_RD_Y_WIDTH);
|
||||
hw_in_h = rkvpss_hw_read(hw, RKVPSS_MI_RD_Y_HEIGHT);
|
||||
for (j = 0; j < RKVPSS_CMSC_WIN_MAX; j++) {
|
||||
if (!(ch_win_en[i] & BIT(j)))
|
||||
continue;
|
||||
for (k = 0; k < RKVPSS_CMSC_POINT_MAX; k++) {
|
||||
if (tmp_cfg.win[j].point[k].x > hw_in_w ||
|
||||
tmp_cfg.win[j].point[k].y > hw_in_h) {
|
||||
v4l2_err(&ofl->v4l2_dev,
|
||||
"%s cmsc coordinate error dev_id:%d unite:%u left:%u ch:%d win:%d point:%d x:%u y:%u hw_in_w:%u hw_in_h:%u\n",
|
||||
__func__, cfg->dev_id, unite, left,
|
||||
i, j, k,
|
||||
tmp_cfg.win[j].point[k].x,
|
||||
tmp_cfg.win[j].point[k].y,
|
||||
hw_in_w, hw_in_w);
|
||||
return -EINVAL;
|
||||
}
|
||||
val = RKVPSS_CMSC_WIN_VTX(tmp_cfg.win[j].point[k].x,
|
||||
tmp_cfg.win[j].point[k].y);
|
||||
rkvpss_hw_write(hw, RKVPSS_CMSC_WIN0_L0_VTX + k * 8 + j * 32, val);
|
||||
@@ -718,7 +741,7 @@ static void cmsc_config(struct rkvpss_offline_dev *ofl,
|
||||
&slope, &hor);
|
||||
val = RKVPSS_CMSC_WIN_SLP(slope, hor);
|
||||
rkvpss_hw_write(hw, RKVPSS_CMSC_WIN0_L0_SLP + k * 8 + j * 32, val);
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
v4l2_dbg(4, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s dev_id:%d, unite:%d left:%d ch:%d win:%d point:%d x:%u y:%u",
|
||||
__func__, cfg->dev_id, unite, left, i, j, k,
|
||||
tmp_cfg.win[j].point[k].x,
|
||||
@@ -736,9 +759,11 @@ static void cmsc_config(struct rkvpss_offline_dev *ofl,
|
||||
val = RKVPSS_CMSC_GEN_UPD | RKVPSS_CMSC_FORCE_UPD;
|
||||
rkvpss_hw_write(hw, RKVPSS_CMSC_UPDATE, val);
|
||||
|
||||
v4l2_dbg(4, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s dev_id:%d, unite:%d left:%d ctrl:0x%x update_val:0x%x",
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s dev_id:%d, unite:%d left:%d hw ctrl:0x%x update_val:0x%x",
|
||||
__func__, cfg->dev_id, unite, left, ctrl, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aspt_config(struct file *file,
|
||||
@@ -789,6 +814,14 @@ static void aspt_config(struct file *file,
|
||||
rkvpss_hw_write(hw, reg_base, RKVPSS_RATIO_EN);
|
||||
val = RKVPSS_RATIO_FORCE_UPD | RKVPSS_RATIO_GEN_UPD;
|
||||
rkvpss_hw_write(hw, reg_base + 0x4, val);
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s hw ch:%d ctrl:0x%x in_size:0x%x out_size:0x%x offset:0x%x\n",
|
||||
__func__, i,
|
||||
rkvpss_hw_read(hw, reg_base),
|
||||
rkvpss_hw_read(hw, reg_base + 0x10),
|
||||
rkvpss_hw_read(hw, reg_base + 0x14),
|
||||
rkvpss_hw_read(hw, reg_base + 0x18));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -821,14 +854,16 @@ static void add_cfginfo(struct rkvpss_offline_dev *ofl, struct rkvpss_frame_cfg
|
||||
list_for_each_entry(cfginfo, &ofl->cfginfo_list, list) {
|
||||
count++;
|
||||
}
|
||||
if (count >= 5) {
|
||||
while (count >= rkvpss_cfginfo_num && count != 0) {
|
||||
first_cfg = list_first_entry(&ofl->cfginfo_list, struct rkvpss_ofl_cfginfo, list);
|
||||
list_del_init(&first_cfg->list);
|
||||
kfree(first_cfg);
|
||||
list_add_tail(&new_cfg->list, &ofl->cfginfo_list);
|
||||
} else {
|
||||
list_add_tail(&new_cfg->list, &ofl->cfginfo_list);
|
||||
count--;
|
||||
}
|
||||
if (rkvpss_cfginfo_num)
|
||||
list_add_tail(&new_cfg->list, &ofl->cfginfo_list);
|
||||
else
|
||||
kfree(new_cfg);
|
||||
mutex_unlock(&ofl->ofl_lock);
|
||||
}
|
||||
|
||||
@@ -1028,7 +1063,7 @@ static int read_config(struct file *file, struct rkvpss_frame_cfg *cfg, bool uni
|
||||
}
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s unite:%d left:%d width:%d height:%d y_base:0x%x\n",
|
||||
"%s unite:%d left:%d hw width:%d height:%d y_base:0x%x\n",
|
||||
__func__, unite, left,
|
||||
rkvpss_hw_read(hw, RKVPSS_MI_RD_Y_WIDTH),
|
||||
rkvpss_hw_read(hw, RKVPSS_MI_RD_Y_HEIGHT),
|
||||
@@ -1144,13 +1179,17 @@ static void crop_config(struct file *file, struct rkvpss_frame_cfg *cfg, bool un
|
||||
rkvpss_hw_write(hw, RKVPSS_CROP0_CTRL, crop_en);
|
||||
rkvpss_hw_write(hw, RKVPSS_CROP0_UPDATE, RKVPSS_CROP_FORCE_UPD);
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s unite:%d left:%d h_offs:%d v_offs:%d width:%d height:%d\n",
|
||||
__func__, unite, left,
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_H_OFFS),
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_V_OFFS),
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_H_SIZE),
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_V_SIZE));
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
if (!cfg->output[i].enable)
|
||||
continue;
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s unite:%d left:%d hw ch:%d h_offs:%d v_offs:%d width:%d height:%d\n",
|
||||
__func__, unite, left, i,
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_H_OFFS + i * 0x10),
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_V_OFFS + i * 0x10),
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_H_SIZE + i * 0x10),
|
||||
rkvpss_hw_read(hw, RKVPSS_CROP0_0_V_SIZE + i * 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
static int write_config(struct file *file, struct rkvpss_frame_cfg *cfg, bool unite, bool left)
|
||||
@@ -1375,7 +1414,7 @@ static int write_config(struct file *file, struct rkvpss_frame_cfg *cfg, bool un
|
||||
mi_update |= (RKVPSS_MI_CHN0_FORCE_UPD << i);
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s unite:%d left:%d ch:%d y_size:%d y_stride:%d y_pic_size:%d y_base:0x%x",
|
||||
"%s unite:%d left:%d hw ch:%d y_size:%d y_stride:%d y_pic_size:%d y_base:0x%x",
|
||||
__func__, unite, left, i,
|
||||
rkvpss_hw_read(hw, RKVPSS_MI_CHN0_WR_Y_SIZE + i * 100),
|
||||
rkvpss_hw_read(hw, RKVPSS_MI_CHN0_WR_Y_STRIDE + i * 100),
|
||||
@@ -1505,22 +1544,22 @@ static void calc_unite_scl_params(struct file *file, struct rkvpss_frame_cfg *cf
|
||||
params->scl_in_crop_w_y = right_y_crop_total - params->quad_crop_w;
|
||||
params->scl_in_crop_w_c = right_c_crop_total - params->quad_crop_w;
|
||||
|
||||
if (rkvpss_debug >= 2) {
|
||||
if (rkvpss_debug >= 4) {
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"%s dev_id:%d seq:%d ch:%d y_w_fac:%u c_w_fac:%u y_h_fac:%u c_h_fac:%u\n",
|
||||
__func__, cfg->dev_id, cfg->sequence, i, params->y_w_fac,
|
||||
params->c_w_fac, params->y_h_fac, params->c_h_fac);
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t%s unite_right_enlarge:%u",
|
||||
__func__, ofl->unite_right_enlarge);
|
||||
"\t\t\t\t\t\t unite_right_enlarge:%u",
|
||||
ofl->unite_right_enlarge);
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t%s y_w_phase:%u c_w_phase:%u quad_crop_w:%u scl_in_crop_w_y:%u scl_in_crop_w_c:%u\n",
|
||||
__func__, params->y_w_phase, params->c_w_phase,
|
||||
"\t\t\t\t\t\t y_w_phase:%u c_w_phase:%u quad_crop_w:%u scl_in_crop_w_y:%u scl_in_crop_w_c:%u\n",
|
||||
params->y_w_phase, params->c_w_phase,
|
||||
params->quad_crop_w,
|
||||
params->scl_in_crop_w_y, params->scl_in_crop_w_c);
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t%s right_scl_need_size_y:%u right_scl_need_size_c:%u\n",
|
||||
__func__, params->right_scl_need_size_y,
|
||||
"\t\t\t\t\t\t right_scl_need_size_y:%u right_scl_need_size_c:%u\n",
|
||||
params->right_scl_need_size_y,
|
||||
params->right_scl_need_size_c);
|
||||
}
|
||||
}
|
||||
@@ -1531,41 +1570,12 @@ static int rkvpss_ofl_run(struct file *file, struct rkvpss_frame_cfg *cfg, bool
|
||||
struct rkvpss_offline_dev *ofl = video_drvdata(file);
|
||||
struct rkvpss_hw_dev *hw = ofl->hw;
|
||||
u32 update, val, mask;
|
||||
ktime_t t = 0;
|
||||
s64 us = 0;
|
||||
int ret, i;
|
||||
u64 ns;
|
||||
bool left_tmp;
|
||||
|
||||
if (rkvpss_debug >= 2) {
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"%s dev_id:%d seq:%d mirror:%d input:%dx%d buffd:%d format:%c%c%c%c\n",
|
||||
__func__, cfg->dev_id, cfg->sequence, cfg->mirror,
|
||||
cfg->input.width, cfg->input.height, cfg->input.buf_fd,
|
||||
cfg->input.format, cfg->input.format >> 8,
|
||||
cfg->input.format >> 16, cfg->input.format >> 24);
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
if (!cfg->output[i].enable)
|
||||
continue;
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t\t\tch%d crop:(%d,%d)/%dx%d scl:%dx%d flip:%d buffd:%d format:%c%c%c%c\n",
|
||||
i, cfg->output[i].crop_h_offs, cfg->output[i].crop_v_offs,
|
||||
cfg->output[i].crop_width, cfg->output[i].crop_height,
|
||||
cfg->output[i].scl_width, cfg->output[i].scl_height,
|
||||
cfg->output[i].flip, cfg->output[i].buf_fd,
|
||||
cfg->output[i].format, cfg->output[i].format >> 8,
|
||||
cfg->output[i].format >> 16, cfg->output[i].format >> 24);
|
||||
}
|
||||
t = ktime_get();
|
||||
}
|
||||
|
||||
if (!unite || left)
|
||||
add_cfginfo(ofl, cfg);
|
||||
|
||||
ns = ktime_get_ns();
|
||||
ofl->dev_rate[cfg->dev_id].in_rate = ns - ofl->dev_rate[cfg->dev_id].in_timestamp;
|
||||
ofl->dev_rate[cfg->dev_id].in_timestamp = ns;
|
||||
|
||||
init_completion(&ofl->cmpl);
|
||||
ofl->mode_sel_en = false;
|
||||
|
||||
@@ -1581,7 +1591,9 @@ static int rkvpss_ofl_run(struct file *file, struct rkvpss_frame_cfg *cfg, bool
|
||||
else
|
||||
left_tmp = left;
|
||||
|
||||
cmsc_config(ofl, cfg, unite, left_tmp);
|
||||
ret = cmsc_config(ofl, cfg, unite, left_tmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
crop_config(file, cfg, unite, left_tmp);
|
||||
scale_config(file, cfg, unite, left_tmp);
|
||||
if (!unite)
|
||||
@@ -1614,20 +1626,6 @@ static int rkvpss_ofl_run(struct file *file, struct rkvpss_frame_cfg *cfg, bool
|
||||
rkvpss_hw_write(hw, RKVPSS_VPSS_UPDATE, update);
|
||||
rkvpss_hw_set_bits(hw, RKVPSS_VPSS_IMSC, 0, RKVPSS_ALL_FRM_END);
|
||||
|
||||
if (rkvpss_debug >=5) {
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"%s dev_id%d unite:%d left:%d\n",
|
||||
__func__, cfg->dev_id, unite, left);
|
||||
for (i = 0; i < 16128; i += 16) {
|
||||
printk("%04x: %08x %08x %08x %08x\n",
|
||||
i,
|
||||
rkvpss_hw_read(hw, i),
|
||||
rkvpss_hw_read(hw, i + 4),
|
||||
rkvpss_hw_read(hw, i + 8),
|
||||
rkvpss_hw_read(hw, i + 12));
|
||||
}
|
||||
}
|
||||
|
||||
rkvpss_hw_write(hw, RKVPSS_MI_RD_START, RKVPSS_MI_RD_ST);
|
||||
|
||||
ret = wait_for_completion_timeout(&ofl->cmpl, msecs_to_jiffies(500));
|
||||
@@ -1638,19 +1636,6 @@ static int rkvpss_ofl_run(struct file *file, struct rkvpss_frame_cfg *cfg, bool
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (rkvpss_debug >= 2) {
|
||||
us = ktime_us_delta(ktime_get(), t);
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"%s end, time:%lldus\n", __func__, us);
|
||||
}
|
||||
|
||||
ns = ktime_get_ns();
|
||||
ofl->dev_rate[cfg->dev_id].out_rate = ns - ofl->dev_rate[cfg->dev_id].out_timestamp;
|
||||
ofl->dev_rate[cfg->dev_id].out_timestamp = ns;
|
||||
ofl->dev_rate[cfg->dev_id].sequence = cfg->sequence;
|
||||
ofl->dev_rate[cfg->dev_id].delay = ofl->dev_rate[cfg->dev_id].out_timestamp -
|
||||
ofl->dev_rate[cfg->dev_id].in_timestamp;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1970,11 +1955,83 @@ static int rkvpss_prepare_run(struct file *file, struct rkvpss_frame_cfg *cfg)
|
||||
struct rkvpss_offline_dev *ofl = video_drvdata(file);
|
||||
int ret = 0;
|
||||
bool unite;
|
||||
int i, j, k;
|
||||
s64 us = 0;
|
||||
u64 ns;
|
||||
ktime_t t = 0;
|
||||
|
||||
ns = ktime_get_ns();
|
||||
ofl->dev_rate[cfg->dev_id].in_rate = ns - ofl->dev_rate[cfg->dev_id].in_timestamp;
|
||||
ofl->dev_rate[cfg->dev_id].in_timestamp = ns;
|
||||
|
||||
ret = rkvpss_check_params(file, cfg, &unite);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
/******** show cfg info ********/
|
||||
if (rkvpss_debug >= 2) {
|
||||
t = ktime_get();
|
||||
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"%s dev_id:%d seq:%d mirror:%d input:%dx%d buffd:%d format:%c%c%c%c stride:%d rotate:%d\n",
|
||||
__func__, cfg->dev_id, cfg->sequence, cfg->mirror,
|
||||
cfg->input.width, cfg->input.height, cfg->input.buf_fd,
|
||||
cfg->input.format, cfg->input.format >> 8,
|
||||
cfg->input.format >> 16, cfg->input.format >> 24,
|
||||
cfg->input.stride, cfg->input.rotate);
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t\t\tch%d enable:%d crop:(%d,%d)/%dx%d scl:%dx%d flip:%d buffd:%d format:%c%c%c%c stride:%d\n",
|
||||
i, cfg->output[i].enable,
|
||||
cfg->output[i].crop_h_offs, cfg->output[i].crop_v_offs,
|
||||
cfg->output[i].crop_width, cfg->output[i].crop_height,
|
||||
cfg->output[i].scl_width, cfg->output[i].scl_height,
|
||||
cfg->output[i].flip, cfg->output[i].buf_fd,
|
||||
cfg->output[i].format, cfg->output[i].format >> 8,
|
||||
cfg->output[i].format >> 16, cfg->output[i].format >> 24,
|
||||
cfg->output[i].stride);
|
||||
if (rkvpss_debug < 4)
|
||||
break;
|
||||
if (!cfg->output[i].enable)
|
||||
continue;
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t\t\tcmsc mosaic_block:%d width_ro:%d height_ro:%d\n",
|
||||
cfg->output[i].cmsc.mosaic_block,
|
||||
cfg->output[i].cmsc.width_ro,
|
||||
cfg->output[i].cmsc.height_ro);
|
||||
for (j = 0; j < RKVPSS_CMSC_WIN_MAX; j++) {
|
||||
if (!cfg->output[i].cmsc.win[j].win_en)
|
||||
continue;
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t\t\t\twin:%d win_en:%u mode:%u color_y:%u color_u:%u color_v:%u color_a:%u\n",
|
||||
j,
|
||||
cfg->output[i].cmsc.win[j].win_en,
|
||||
cfg->output[i].cmsc.win[j].mode,
|
||||
cfg->output[i].cmsc.win[j].cover_color_y,
|
||||
cfg->output[i].cmsc.win[j].cover_color_u,
|
||||
cfg->output[i].cmsc.win[j].cover_color_v,
|
||||
cfg->output[i].cmsc.win[j].cover_color_a);
|
||||
for (k = 0; k < RKVPSS_CMSC_POINT_MAX; k++) {
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t\t\t\t\tpoint:%d x:%d y:%d\n",
|
||||
k,
|
||||
cfg->output[i].cmsc.win[j].point[k].x,
|
||||
cfg->output[i].cmsc.win[j].point[k].y);
|
||||
}
|
||||
}
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"\t\t\taspt_en:%d w:%d h:%d h_offs:%d v_offs:%d color_y:%d color_u:%d color_v:%d\n",
|
||||
cfg->output[i].aspt.enable,
|
||||
cfg->output[i].aspt.width,
|
||||
cfg->output[i].aspt.height,
|
||||
cfg->output[i].aspt.h_offs,
|
||||
cfg->output[i].aspt.v_offs,
|
||||
cfg->output[i].aspt.color_y,
|
||||
cfg->output[i].aspt.color_u,
|
||||
cfg->output[i].aspt.color_v);
|
||||
}
|
||||
}
|
||||
|
||||
if (!unite) {
|
||||
ret = rkvpss_ofl_run(file, cfg, false, false);
|
||||
if (ret < 0)
|
||||
@@ -1992,6 +2049,19 @@ static int rkvpss_prepare_run(struct file *file, struct rkvpss_frame_cfg *cfg)
|
||||
}
|
||||
}
|
||||
|
||||
if (rkvpss_debug >= 2) {
|
||||
us = ktime_us_delta(ktime_get(), t);
|
||||
v4l2_info(&ofl->v4l2_dev,
|
||||
"%s end, time:%lldus\n", __func__, us);
|
||||
}
|
||||
|
||||
ns = ktime_get_ns();
|
||||
ofl->dev_rate[cfg->dev_id].out_rate = ns - ofl->dev_rate[cfg->dev_id].out_timestamp;
|
||||
ofl->dev_rate[cfg->dev_id].out_timestamp = ns;
|
||||
ofl->dev_rate[cfg->dev_id].sequence = cfg->sequence;
|
||||
ofl->dev_rate[cfg->dev_id].delay = ofl->dev_rate[cfg->dev_id].out_timestamp -
|
||||
ofl->dev_rate[cfg->dev_id].in_timestamp;
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
@@ -1999,11 +2069,16 @@ end:
|
||||
static long rkvpss_ofl_ioctl(struct file *file, void *fh,
|
||||
bool valid_prio, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct rkvpss_offline_dev *ofl = video_drvdata(file);
|
||||
long ret = 0;
|
||||
bool unite;
|
||||
|
||||
if (!arg)
|
||||
return -EINVAL;
|
||||
ofl->pm_need_wait = true;
|
||||
|
||||
if (!arg) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case RKVPSS_CMD_MODULE_SEL:
|
||||
@@ -2028,6 +2103,12 @@ static long rkvpss_ofl_ioctl(struct file *file, void *fh,
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
out:
|
||||
/* notify hw suspend */
|
||||
if (ofl->hw->is_suspend)
|
||||
complete(&ofl->pm_cmpl);
|
||||
|
||||
ofl->pm_need_wait = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2131,6 +2212,8 @@ int rkvpss_register_offline(struct rkvpss_hw_dev *hw)
|
||||
INIT_LIST_HEAD(&ofl->cfginfo_list);
|
||||
mutex_init(&ofl->ofl_lock);
|
||||
rkvpss_offline_proc_init(ofl);
|
||||
ofl->pm_need_wait = false;
|
||||
init_completion(&ofl->pm_cmpl);
|
||||
return 0;
|
||||
unreg_v4l2:
|
||||
mutex_destroy(&ofl->apilock);
|
||||
|
||||
@@ -73,8 +73,10 @@ struct rkvpss_offline_dev {
|
||||
struct mutex ofl_lock;
|
||||
struct rkvpss_dev_rate dev_rate[DEV_NUM_MAX];
|
||||
struct rkvpss_unite_scl_params unite_params[RKVPSS_OUTPUT_MAX];
|
||||
struct completion pm_cmpl;
|
||||
u32 unite_right_enlarge;
|
||||
bool mode_sel_en;
|
||||
bool pm_need_wait;
|
||||
};
|
||||
|
||||
int rkvpss_register_offline(struct rkvpss_hw_dev *hw);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "pcie-designware.h"
|
||||
#include "../rockchip-pcie-dma.h"
|
||||
#include "pcie-dw-dmatest.h"
|
||||
#include "../../hotplug/gpiophp.h"
|
||||
|
||||
#define RK_PCIE_DBG 0
|
||||
|
||||
@@ -131,6 +132,9 @@ struct rk_pcie {
|
||||
bool is_signal_test;
|
||||
bool bifurcation;
|
||||
bool supports_clkreq;
|
||||
bool slot_pluggable;
|
||||
struct gpio_hotplug_slot hp_slot;
|
||||
bool hp_no_link;
|
||||
struct regulator *vpcie3v3;
|
||||
struct irq_domain *irq_domain;
|
||||
raw_spinlock_t intx_lock;
|
||||
@@ -280,7 +284,7 @@ static int rk_pcie_establish_link(struct dw_pcie *pci)
|
||||
* we still need to reset link as we need to remove all resource info
|
||||
* from devices, for instance BAR, as it wasn't assigned by kernel.
|
||||
*/
|
||||
if (dw_pcie_link_up(pci)) {
|
||||
if (dw_pcie_link_up(pci) && !rk_pcie->hp_no_link) {
|
||||
dev_err(pci->dev, "link is already up\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -346,6 +350,8 @@ static int rk_pcie_establish_link(struct dw_pcie *pci)
|
||||
dev_info(pci->dev, "PCIe Link up, LTSSM is 0x%x\n",
|
||||
rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS));
|
||||
rk_pcie_debug_dump(rk_pcie);
|
||||
if (rk_pcie->slot_pluggable)
|
||||
rk_pcie->hp_no_link = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -372,7 +378,12 @@ static int rk_pcie_establish_link(struct dw_pcie *pci)
|
||||
}
|
||||
}
|
||||
|
||||
return rk_pcie->is_signal_test == true ? 0 : -EINVAL;
|
||||
if (rk_pcie->slot_pluggable) {
|
||||
rk_pcie->hp_no_link = true;
|
||||
return 0;
|
||||
} else {
|
||||
return rk_pcie->is_signal_test == true ? 0 : -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rk_pcie_udma_enabled(struct rk_pcie *rk_pcie)
|
||||
@@ -1070,6 +1081,40 @@ remove:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int rk_pcie_slot_enable(struct gpio_hotplug_slot *slot)
|
||||
{
|
||||
struct rk_pcie *rk_pcie = container_of(slot, struct rk_pcie, hp_slot);
|
||||
int ret;
|
||||
|
||||
dev_info(rk_pcie->pci->dev, "%s\n", __func__);
|
||||
rk_pcie->hp_no_link = true;
|
||||
rk_pcie_enable_power(rk_pcie);
|
||||
rk_pcie_fast_link_setup(rk_pcie);
|
||||
ret = rk_pcie_establish_link(rk_pcie->pci);
|
||||
if (ret)
|
||||
dev_err(rk_pcie->pci->dev, "fail to enable slot\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_pcie_slot_disable(struct gpio_hotplug_slot *slot)
|
||||
{
|
||||
struct rk_pcie *rk_pcie = container_of(slot, struct rk_pcie, hp_slot);
|
||||
|
||||
dev_info(rk_pcie->pci->dev, "%s\n", __func__);
|
||||
rk_pcie->hp_no_link = true;
|
||||
rk_pcie_disable_ltssm(rk_pcie);
|
||||
gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0);
|
||||
rk_pcie_disable_power(rk_pcie);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct gpio_hotplug_slot_plat_ops rk_pcie_gpio_hp_plat_ops = {
|
||||
.enable = rk_pcie_slot_enable,
|
||||
.disable = rk_pcie_slot_disable,
|
||||
};
|
||||
|
||||
static int rk_pcie_really_probe(void *p)
|
||||
{
|
||||
struct platform_device *pdev = p;
|
||||
@@ -1128,6 +1173,12 @@ static int rk_pcie_really_probe(void *p)
|
||||
|
||||
rk_pcie->supports_clkreq = device_property_read_bool(dev, "supports-clkreq");
|
||||
|
||||
if (device_property_read_bool(dev, "hotplug-gpios") ||
|
||||
device_property_read_bool(dev, "hotplug-gpio")) {
|
||||
rk_pcie->slot_pluggable = true;
|
||||
dev_info(dev, "support hotplug-gpios!\n");
|
||||
}
|
||||
|
||||
retry_regulator:
|
||||
/* DON'T MOVE ME: must be enable before phy init */
|
||||
rk_pcie->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
|
||||
@@ -1257,9 +1308,23 @@ retry_regulator:
|
||||
if (rk_pcie->is_signal_test == true)
|
||||
return 0;
|
||||
|
||||
if (ret)
|
||||
if (ret && !rk_pcie->slot_pluggable)
|
||||
goto remove_rst_wq;
|
||||
|
||||
if (rk_pcie->slot_pluggable) {
|
||||
rk_pcie->hp_slot.plat_ops = &rk_pcie_gpio_hp_plat_ops;
|
||||
rk_pcie->hp_slot.np = rk_pcie->pci->dev->of_node;
|
||||
rk_pcie->hp_slot.slot_nr = rk_pcie->pci->pp.bridge->busnr;
|
||||
rk_pcie->hp_slot.pdev = pci_get_slot(rk_pcie->pci->pp.bridge->bus, PCI_DEVFN(0, 0));
|
||||
|
||||
ret = register_gpio_hotplug_slot(&rk_pcie->hp_slot);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "Failed to register ops for GPIO Hot-Plug controller: %d\n",
|
||||
ret);
|
||||
/* Set debounce to 200ms for safe if possible */
|
||||
gpiod_set_debounce(rk_pcie->hp_slot.gpiod, 200);
|
||||
}
|
||||
|
||||
ret = rk_pcie_init_dma_trx(rk_pcie);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add dma extension\n");
|
||||
|
||||
Reference in New Issue
Block a user