mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
hdmitx: sync edid valid_mode check between uboot/kernel [2/2]
PD#SWPL-154107 Problem: sync edid valid_mode check between uboot/kernel Solution: sync edid valid_mode check between uboot/kernel Verify: sc2/s5 Test: DRM-TX-27, DRM-TX-29, DRM-TX-42, DRM-TX-44 DRM-TX-59, DRM-TX-70, DRM-TX-113 Change-Id: I2a708d55575e8d781380a34b397296589aa69d71 Signed-off-by: Wenjie Qiao <wenjie.qiao@amlogic.com> Signed-off-by: zongdong.jiao <zongdong.jiao@amlogic.com>
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#include "meson_hdmi.h"
|
||||
#include "meson_vpu.h"
|
||||
#include "meson_crtc.h"
|
||||
#include "../media/vout/hdmitx_common/hdmitx_check_valid.h"
|
||||
|
||||
#define HDMITX_ATTR_LEN_MAX 16
|
||||
#define HDMITX_MAX_BPC 12
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_audio.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h>
|
||||
#include "../hdmitx_common/hdmitx_compliance.h"
|
||||
#include "../hdmitx_common/hdmitx_check_valid.h"
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_DSC
|
||||
#include <linux/amlogic/media/vout/dsc.h>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "hdmi_tx_module.h"
|
||||
#include "hdmi_tx.h"
|
||||
#include "hw/enc_clk_config.h"
|
||||
#include "../hdmitx_common/hdmitx_check_valid.h"
|
||||
|
||||
/* BRR 720p60hz */
|
||||
static const struct mvrr_const_val const_hdmi720p60_6000 = {
|
||||
|
||||
@@ -593,6 +593,9 @@ bool hdmitx21_uboot_audio_en(void)
|
||||
|
||||
static bool soc_resolution_limited(const struct hdmi_timing *timing, u32 res_v)
|
||||
{
|
||||
if (!timing)
|
||||
return 0;
|
||||
|
||||
if (timing->v_active > res_v)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
@@ -15,4 +15,5 @@ $(MEDIA_MODULE_NAME)-$(CONFIG_AMLOGIC_HDMITX_COMMON) += \
|
||||
vout/hdmitx_common/hdmitx_tracer_linux.o \
|
||||
vout/hdmitx_common/hdmitx_event_mgr_linux.o \
|
||||
vout/hdmitx_common/hdmitx_log.o \
|
||||
vout/hdmitx_common/hdmitx_compliance.o
|
||||
vout/hdmitx_common/hdmitx_compliance.o \
|
||||
vout/hdmitx_common/hdmitx_check_valid.o
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hdmitx_check_valid.h"
|
||||
|
||||
/* only check vic in edid */
|
||||
bool hdmitx_edid_validate_mode(struct rx_cap *rxcap, u32 vic)
|
||||
{
|
||||
int i = 0;
|
||||
bool edid_matched = false;
|
||||
|
||||
if (!rxcap)
|
||||
return false;
|
||||
|
||||
if (vic < HDMITX_VESA_OFFSET) {
|
||||
/*check cea cap*/
|
||||
for (i = 0 ; i < rxcap->VIC_count; i++) {
|
||||
if (rxcap->VIC[i] == vic) {
|
||||
edid_matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
enum hdmi_vic *vesa_t = &rxcap->vesa_timing[0];
|
||||
/*check vesa mode.*/
|
||||
for (i = 0; i < VESA_MAX_TIMING && vesa_t[i]; i++) {
|
||||
if (vic == vesa_t[i]) {
|
||||
edid_matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return edid_matched;
|
||||
}
|
||||
|
||||
/* check if vic is supported by SOC hdmitx */
|
||||
int hdmitx_common_validate_vic(struct hdmitx_common *tx_comm, u32 vic)
|
||||
{
|
||||
const struct hdmi_timing *timing = hdmitx_mode_vic_to_hdmi_timing(vic);
|
||||
|
||||
if (!timing)
|
||||
return -EINVAL;
|
||||
|
||||
/*soc level filter*/
|
||||
/*filter 1080p max size.*/
|
||||
if (tx_comm->res_1080p) {
|
||||
/* if the vic equals to HDMI_0_UNKNOWN or VESA,
|
||||
* then create it as over limited
|
||||
*/
|
||||
if (vic == HDMI_0_UNKNOWN || vic >= HDMITX_VESA_OFFSET)
|
||||
return -ERANGE;
|
||||
/* check the resolution is over 1920x1080 or not */
|
||||
if (timing->h_active > 1920 || timing->v_active > 1080)
|
||||
return -ERANGE;
|
||||
|
||||
/* check the fresh rate is over 60hz or not */
|
||||
if (timing->v_freq > 60000)
|
||||
return -ERANGE;
|
||||
|
||||
/* test current vic is over 150MHz or not */
|
||||
if (timing->pixel_freq > 150000)
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
/* efuse ctrl all 4k mode */
|
||||
if (tx_comm->efuse_dis_output_4k)
|
||||
if (timing->v_active >= 2160)
|
||||
return -ERANGE;
|
||||
|
||||
/* efuse ctrl 4k50, 4k60 */
|
||||
if (tx_comm->efuse_dis_hdmi_4k60)
|
||||
if (timing->v_active >= 2160 && timing->v_freq >= 5000)
|
||||
return -ERANGE;
|
||||
|
||||
/*filter max refreshrate.*/
|
||||
if (timing->v_freq > (tx_comm->max_refreshrate * 1000)) {
|
||||
//HDMITX_INFO("validate refreshrate (%s)-(%d) fail\n",
|
||||
//timing->name, timing->v_freq);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/*ip level filter*/
|
||||
if (hdmitx_hw_validate_mode(tx_comm->tx_hw, vic) != 0)
|
||||
return -EPERM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_DSC
|
||||
static bool hdmitx_check_dsc_support(struct tx_cap *hdmi_tx_cap,
|
||||
struct rx_cap *rxcap, struct hdmi_format_para *para)
|
||||
{
|
||||
enum dsc_encode_mode dsc_mode = DSC_ENCODE_MAX;
|
||||
u8 dsc_slice_num = 0;
|
||||
enum frl_rate_enum dsc_frl_rate = FRL_NONE;
|
||||
u32 bytes_target = 0;
|
||||
u8 dsc_policy;
|
||||
|
||||
if (!hdmi_tx_cap || !rxcap || !para)
|
||||
return false;
|
||||
|
||||
/* step1: check if DSC mode is supported by SOC driver & policy */
|
||||
if (!hdmi_tx_cap->dsc_capable) {
|
||||
HDMITX_DEBUG_EDID("tx not capable of dsc\n");
|
||||
return false;
|
||||
}
|
||||
dsc_policy = hdmi_tx_cap->dsc_policy;
|
||||
|
||||
dsc_mode = dsc_enc_confirm_mode(para->timing.h_active,
|
||||
para->timing.v_active,
|
||||
para->timing.v_freq,
|
||||
para->cs);
|
||||
|
||||
if (dsc_mode == DSC_ENCODE_MAX) {
|
||||
HDMITX_DEBUG_EDID("dsc mode not supported!\n");
|
||||
return false;
|
||||
}
|
||||
if (dsc_policy == 0) {
|
||||
/* force not support below 12bit format temporarily */
|
||||
switch (dsc_mode) {
|
||||
/* 4k120hz */
|
||||
case DSC_RGB_3840X2160_120HZ:
|
||||
case DSC_YUV444_3840X2160_120HZ:
|
||||
/* 4k100hz */
|
||||
case DSC_RGB_3840X2160_100HZ:
|
||||
case DSC_YUV444_3840X2160_100HZ:
|
||||
/* 8k60hz */
|
||||
case DSC_RGB_7680X4320_60HZ:
|
||||
case DSC_YUV444_7680X4320_60HZ:
|
||||
/* 8k50hz */
|
||||
case DSC_RGB_7680X4320_50HZ:
|
||||
case DSC_YUV444_7680X4320_50HZ:
|
||||
/* 8k24hz */
|
||||
case DSC_RGB_7680X4320_24HZ:
|
||||
case DSC_YUV444_7680X4320_24HZ:
|
||||
/* 8k25hz */
|
||||
case DSC_RGB_7680X4320_25HZ:
|
||||
case DSC_YUV444_7680X4320_25HZ:
|
||||
/* 8k30hz */
|
||||
case DSC_RGB_7680X4320_30HZ:
|
||||
case DSC_YUV444_7680X4320_30HZ:
|
||||
if (para->cd == COLORDEPTH_36B)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* step2: check if DSC mode is supported by RX */
|
||||
if (rxcap->dsc_1p2 == 0) {
|
||||
HDMITX_DEBUG_EDID("RX not support DSC\n");
|
||||
return false;
|
||||
}
|
||||
/* check dsc color depth cap */
|
||||
if (para->cd == COLORDEPTH_30B &&
|
||||
!rxcap->dsc_10bpc) {
|
||||
HDMITX_DEBUG_EDID("RX not support 10bpc DSC\n");
|
||||
return false;
|
||||
} else if (para->cd == COLORDEPTH_36B &&
|
||||
!rxcap->dsc_12bpc) {
|
||||
HDMITX_DEBUG_EDID("RX not support 12bpc DSC\n");
|
||||
return false;
|
||||
}
|
||||
/* check dsc color space cap */
|
||||
if (para->cs == HDMI_COLORSPACE_YUV420 &&
|
||||
!rxcap->dsc_native_420) {
|
||||
HDMITX_DEBUG_EDID("RX not support Y420 DSC\n");
|
||||
return false;
|
||||
}
|
||||
dsc_slice_num = dsc_get_slice_num(dsc_mode);
|
||||
/* slice num exceed rx cap */
|
||||
if (dsc_slice_num == 0 ||
|
||||
dsc_slice_num > dsc_max_slices_num[rxcap->dsc_max_slices]) {
|
||||
HDMITX_DEBUG_EDID("current slice num %d exceed rx cap %d\n",
|
||||
dsc_slice_num, dsc_max_slices_num[rxcap->dsc_max_slices]);
|
||||
return false;
|
||||
}
|
||||
/* note: pixel clock per slice not checked, assume
|
||||
* it's always within rx cap
|
||||
*/
|
||||
/* check dsc frl rate within rx cap */
|
||||
dsc_frl_rate = get_dsc_frl_rate(dsc_mode);
|
||||
if (dsc_frl_rate == FRL_RATE_MAX ||
|
||||
dsc_frl_rate > rxcap->dsc_max_frl_rate ||
|
||||
dsc_frl_rate > rxcap->max_frl_rate) {
|
||||
HDMITX_DEBUG_EDID("current dsc frl rate %d exceed rx cap %d-%d\n",
|
||||
dsc_frl_rate, rxcap->dsc_max_frl_rate, rxcap->max_frl_rate);
|
||||
return false;
|
||||
}
|
||||
/* 2.1 spec table 6-56, if Bytes Target is greater than
|
||||
* the value indicated by DSC_TotalChunkKBytes (see Sections
|
||||
* 7.7.1 and 7.7.4.2), then the configuration is not
|
||||
* supported with Compressed Video Transport.
|
||||
*/
|
||||
bytes_target = dsc_get_bytes_target_by_mode(dsc_mode);
|
||||
if (bytes_target > (rxcap->dsc_total_chunk_bytes + 1) * 1024) {
|
||||
HDMITX_DEBUG_EDID("bytes_target %d exceed DSC_TotalChunkKBytes %d\n",
|
||||
bytes_target, (rxcap->dsc_total_chunk_bytes + 1) * 1024);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hdmitx_mode_validate_y420_vic(enum hdmi_vic vic)
|
||||
{
|
||||
const struct hdmi_timing *timing;
|
||||
|
||||
/* In Spec2.1 Table 7-34, greater than 2160p30hz will support y420 */
|
||||
timing = hdmitx_mode_vic_to_hdmi_timing(vic);
|
||||
if (!timing)
|
||||
return false;
|
||||
if (timing->v_active >= 2160 && timing->v_freq > 30000)
|
||||
return true;
|
||||
if (timing->v_active >= 4320)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_mode_validate_y420_vic);
|
||||
|
||||
//return true means support; false means not support
|
||||
bool hdmitx_edid_check_y420_support(struct rx_cap *prxcap, enum hdmi_vic vic)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
bool ret = false;
|
||||
const struct hdmi_timing *timing = hdmitx_mode_vic_to_hdmi_timing(vic);
|
||||
|
||||
if (!timing || !prxcap)
|
||||
return false;
|
||||
|
||||
if (hdmitx_mode_validate_y420_vic(vic)) {
|
||||
for (i = 0; i < Y420_VIC_MAX_NUM; i++) {
|
||||
if (prxcap->y420_vic[i]) {
|
||||
if (prxcap->y420_vic[i] == vic) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* For some TV's EDID, there maybe exist some information ambiguous.
|
||||
* Such as EDID declare support 2160p60hz(Y444 8bit), but no valid
|
||||
* Max_TMDS_Clock2 to indicate that it can support 5.94G signal.
|
||||
*/
|
||||
static int hdmitx_edid_validate_format_para(struct tx_cap *hdmi_tx_cap,
|
||||
struct rx_cap *prxcap, struct hdmi_format_para *para)
|
||||
{
|
||||
const struct dv_info *dv;
|
||||
/* needed tmds clk bandwidth for current format */
|
||||
unsigned int calc_tmds_clk = 0;
|
||||
/* max tmds clk supported by RX */
|
||||
unsigned int rx_max_tmds_clk = 0;
|
||||
/* bandwidth needed for current FRL mode */
|
||||
u32 tx_frl_bandwidth = 0;
|
||||
/* maximum supported frl bandwidth of RX */
|
||||
u32 rx_frl_bandwidth_cap = 0;
|
||||
/* maximum supported frl bandwidth of soc */
|
||||
u32 tx_frl_bandwidth_cap = 0;
|
||||
bool must_frl_flag = 0;
|
||||
int ret = 0;
|
||||
u8 dsc_policy;
|
||||
|
||||
if (!hdmi_tx_cap || !prxcap || !para)
|
||||
return -EPERM;
|
||||
|
||||
dsc_policy = hdmi_tx_cap->dsc_policy;
|
||||
dv = &prxcap->dv_info;
|
||||
/* step1: check if mode + cs/cd is supported by TX */
|
||||
switch (para->timing.vic) {
|
||||
/* Note: below check for formats which should use FRL
|
||||
* is also checked in step3, so remove
|
||||
*/
|
||||
/* case HDMI_96_3840x2160p50_16x9: */
|
||||
/* case HDMI_97_3840x2160p60_16x9: */
|
||||
/* case HDMI_101_4096x2160p50_256x135: */
|
||||
/* case HDMI_102_4096x2160p60_256x135: */
|
||||
/* case HDMI_106_3840x2160p50_64x27: */
|
||||
/* case HDMI_107_3840x2160p60_64x27: */
|
||||
/* if (para->cs == HDMI_COLORSPACE_RGB || */
|
||||
/* para->cs == HDMI_COLORSPACE_YUV444) */
|
||||
/* if (para->cd != COLORDEPTH_24B && */
|
||||
/* (prxcap->max_frl_rate == FRL_NONE || */
|
||||
/* hdmi_tx_cap->tx_max_frl_rate == FRL_NONE)) */
|
||||
/* return -EPERM; */
|
||||
/* break; */
|
||||
case HDMI_6_720x480i60_4x3:
|
||||
case HDMI_7_720x480i60_16x9:
|
||||
case HDMI_21_720x576i50_4x3:
|
||||
case HDMI_22_720x576i50_16x9:
|
||||
if (para->cs == HDMI_COLORSPACE_YUV422)
|
||||
return -EPERM;
|
||||
break;
|
||||
/* don't support 640x480p60 */
|
||||
case HDMI_1_640x480p60_4x3:
|
||||
return -EPERM;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* step2: DVI case, only rgb,8bit */
|
||||
if (prxcap->ieeeoui != HDMI_IEEE_OUI) {
|
||||
if (para->cd != COLORDEPTH_24B || para->cs != HDMI_COLORSPACE_RGB) {
|
||||
HDMITX_DEBUG_EDID("cs:%d, cd:%d not support by DVI sink\n",
|
||||
para->cs, para->cd);
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
/* step3: check TMDS/FRL bandwidth is within TX/RX cap */
|
||||
if (prxcap->Max_TMDS_Clock2) {
|
||||
rx_max_tmds_clk = prxcap->Max_TMDS_Clock2 * 5;
|
||||
} else {
|
||||
/* Default min is 74.25 / 5 */
|
||||
if (prxcap->Max_TMDS_Clock1 < 0xf)
|
||||
prxcap->Max_TMDS_Clock1 = DEFAULT_MAX_TMDS_CLK;
|
||||
rx_max_tmds_clk = prxcap->Max_TMDS_Clock1 * 5;
|
||||
}
|
||||
calc_tmds_clk = para->tmds_clk / 1000;
|
||||
|
||||
/* more > 4k60 must use frl mode */
|
||||
if (para->timing.h_active > 4096 || para->timing.v_active > 2160 ||
|
||||
para->timing.v_freq == 48000 || calc_tmds_clk > 594 ||
|
||||
para->timing.pixel_freq / 1000 > 600)
|
||||
must_frl_flag = true;
|
||||
|
||||
if (hdmi_tx_cap->tx_max_frl_rate == FRL_NONE) {
|
||||
/* output format need FRL while SOC not support FRL */
|
||||
if (must_frl_flag) {
|
||||
HDMITX_DEBUG_EDID("output format need FRL, while tx not support\n");
|
||||
return -EPERM;
|
||||
}
|
||||
/* tmds clk of the output format exceed TX/RX cap */
|
||||
if (calc_tmds_clk > hdmi_tx_cap->tx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed tx cap: %d\n",
|
||||
calc_tmds_clk, hdmi_tx_cap->tx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
if (calc_tmds_clk > rx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed rx cap: %d\n",
|
||||
calc_tmds_clk, rx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
#ifdef CONFIG_AMLOGIC_DSC
|
||||
if (dsc_policy == 1) {
|
||||
/* force enable policy */
|
||||
if (hdmitx_check_dsc_support(hdmi_tx_cap, prxcap, para))
|
||||
return 0;
|
||||
} else if (dsc_policy == 2) {
|
||||
/* for debug test */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (!must_frl_flag) {
|
||||
if (calc_tmds_clk > hdmi_tx_cap->tx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed tx cap: %d\n",
|
||||
calc_tmds_clk, hdmi_tx_cap->tx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
if (calc_tmds_clk > rx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed rx cap: %d\n",
|
||||
calc_tmds_clk, rx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
/* try to check if able to run under FRL mode */
|
||||
|
||||
/* output format need FRL while RX not support FRL
|
||||
* no need below check, it will be checked with rx_frl_bandwidth_cap
|
||||
*/
|
||||
if (prxcap->max_frl_rate == FRL_NONE) {
|
||||
HDMITX_DEBUG_EDID("output format need FRL, while rx not support\n");
|
||||
return -EPERM;
|
||||
}
|
||||
/* tx_frl_bandwidth = timing->pixel_freq / 1000 * 24 * 1.122 */
|
||||
tx_frl_bandwidth = hdmitx_calc_frl_bandwidth(para->timing.pixel_freq / 1000,
|
||||
para->cs, para->cd);
|
||||
tx_frl_bandwidth_cap =
|
||||
hdmitx_get_frl_bandwidth(hdmi_tx_cap->tx_max_frl_rate);
|
||||
rx_frl_bandwidth_cap = hdmitx_get_frl_bandwidth(prxcap->max_frl_rate);
|
||||
|
||||
if (prxcap->dsc_1p2 == 0) {
|
||||
/* RX not support DSC */
|
||||
if (tx_frl_bandwidth > tx_frl_bandwidth_cap) {
|
||||
HDMITX_DEBUG_EDID("frl bandwitch:%d exceed tx_cap:%d\n",
|
||||
tx_frl_bandwidth, tx_frl_bandwidth_cap);
|
||||
return -EPERM;
|
||||
}
|
||||
if (tx_frl_bandwidth > rx_frl_bandwidth_cap) {
|
||||
HDMITX_DEBUG_EDID("frl bandwitch:%d exceed rx_cap:%d\n",
|
||||
tx_frl_bandwidth, rx_frl_bandwidth_cap);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
if (tx_frl_bandwidth <= tx_frl_bandwidth_cap &&
|
||||
tx_frl_bandwidth <= rx_frl_bandwidth_cap)
|
||||
; // non-dsc bandwidth is within cap, continue check
|
||||
#ifdef CONFIG_AMLOGIC_DSC
|
||||
else if (dsc_policy == 3) //forcely filter out dsc mode output
|
||||
return -EPERM;
|
||||
else if (!hdmitx_check_dsc_support(hdmi_tx_cap, prxcap, para))
|
||||
return -EPERM;
|
||||
#else
|
||||
else
|
||||
return -EPERM;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* step4: check color space/depth is within RX cap */
|
||||
if (para->cs == HDMI_COLORSPACE_YUV444) {
|
||||
enum hdmi_color_depth rx_y444_max_dc = COLORDEPTH_24B;
|
||||
/* Rx may not support Y444 */
|
||||
if (!(prxcap->native_Mode & (1 << 5)))
|
||||
return -EACCES;
|
||||
if (prxcap->dc_y444 && (prxcap->dc_30bit ||
|
||||
dv->sup_10b_12b_444 == 0x1))
|
||||
rx_y444_max_dc = COLORDEPTH_30B;
|
||||
if (prxcap->dc_y444 && (prxcap->dc_36bit ||
|
||||
dv->sup_10b_12b_444 == 0x2))
|
||||
rx_y444_max_dc = COLORDEPTH_36B;
|
||||
|
||||
if (para->cd <= rx_y444_max_dc)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (para->cs == HDMI_COLORSPACE_YUV422) {
|
||||
/* Rx may not support Y422 */
|
||||
if (prxcap->native_Mode & (1 << 4))
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (para->cs == HDMI_COLORSPACE_RGB) {
|
||||
enum hdmi_color_depth rx_rgb_max_dc = COLORDEPTH_24B;
|
||||
/* Always assume RX supports RGB444 */
|
||||
if (prxcap->dc_30bit || dv->sup_10b_12b_444 == 0x1)
|
||||
rx_rgb_max_dc = COLORDEPTH_30B;
|
||||
if (prxcap->dc_36bit || dv->sup_10b_12b_444 == 0x2)
|
||||
rx_rgb_max_dc = COLORDEPTH_36B;
|
||||
|
||||
if (para->cd <= rx_rgb_max_dc)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (para->cs == HDMI_COLORSPACE_YUV420) {
|
||||
ret = 0;
|
||||
if (!hdmitx_edid_check_y420_support(prxcap, para->vic))
|
||||
ret = -EACCES;
|
||||
else if (!prxcap->dc_30bit_420 && para->cd == COLORDEPTH_30B)
|
||||
ret = -EACCES;
|
||||
else if (!prxcap->dc_36bit_420 && para->cd == COLORDEPTH_36B)
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* check fmt para is supported or not by hdmitx/edid.
|
||||
* note that vic is not checked if supported by hdmitx/edid
|
||||
* return 0 means valid, other value means invalid
|
||||
*/
|
||||
int hdmitx_common_validate_format_para(struct hdmitx_common *tx_comm,
|
||||
struct hdmi_format_para *para)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!tx_comm || !para)
|
||||
return -EPERM;
|
||||
|
||||
if (para->vic == HDMI_0_UNKNOWN)
|
||||
return -EPERM;
|
||||
|
||||
/* check if the format param is within capability of both TX/RX */
|
||||
ret = hdmitx_edid_validate_format_para(&tx_comm->tx_hw->hdmi_tx_cap,
|
||||
&tx_comm->rxcap, para);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_common_validate_format_para);
|
||||
|
||||
/* check VIC supported or not with basic cs/cd
|
||||
* compare with hdmitx_common_validate_mode_locked()
|
||||
* or valid_mode_store(), it doesn't check if vic
|
||||
* is supported by hdmitx/rx or not
|
||||
* return 0 means valid, other value means invalid
|
||||
*/
|
||||
int hdmitx_common_check_valid_para_of_vic(struct hdmitx_common *tx_comm, enum hdmi_vic vic)
|
||||
{
|
||||
struct hdmi_format_para tst_para;
|
||||
enum hdmi_color_depth cd; /* cd8, cd10 or cd12 */
|
||||
enum hdmi_colorspace cs; /* 0/1/2/3: rgb/422/444/420 */
|
||||
const enum hdmi_quantization_range cr = HDMI_QUANTIZATION_RANGE_FULL; /*default to full*/
|
||||
int i = 0;
|
||||
|
||||
if (!tx_comm || vic == HDMI_0_UNKNOWN)
|
||||
return -EINVAL;
|
||||
|
||||
if (hdmitx_mode_validate_y420_vic(vic)) {
|
||||
cs = HDMI_COLORSPACE_YUV420;
|
||||
cd = COLORDEPTH_24B;
|
||||
if (hdmitx_common_build_format_para(tx_comm,
|
||||
&tst_para, vic, false, cs, cd, cr) == 0 &&
|
||||
hdmitx_common_validate_format_para(tx_comm, &tst_para) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct {
|
||||
enum hdmi_colorspace cs;
|
||||
enum hdmi_color_depth cd;
|
||||
} test_color_attr[] = {
|
||||
{HDMI_COLORSPACE_RGB, COLORDEPTH_24B},
|
||||
{HDMI_COLORSPACE_YUV444, COLORDEPTH_24B},
|
||||
{HDMI_COLORSPACE_YUV422, COLORDEPTH_36B},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_color_attr); i++) {
|
||||
cs = test_color_attr[i].cs;
|
||||
cd = test_color_attr[i].cd;
|
||||
hdmitx_format_para_reset(&tst_para);
|
||||
if (hdmitx_common_build_format_para(tx_comm,
|
||||
&tst_para, vic, false, cs, cd, cr) == 0 &&
|
||||
hdmitx_common_validate_format_para(tx_comm, &tst_para) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_common_check_valid_para_of_vic);
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HDMITX_CHECK_VALID_H_
|
||||
#define __HDMITX_CHECK_VALID_H_
|
||||
|
||||
#include "hdmitx_check_valid_header.h"
|
||||
|
||||
/*check valid mode api*/
|
||||
|
||||
/* check if vic supported by rx */
|
||||
bool hdmitx_edid_validate_mode(struct rx_cap *rxcap, u32 vic);
|
||||
/* validate if vic can supported. return 0 if can support, return < 0 with error reason;
|
||||
* This function used by get_mode_list;
|
||||
*/
|
||||
int hdmitx_common_validate_vic(struct hdmitx_common *tx_comm, u32 vic);
|
||||
bool hdmitx_edid_check_y420_support(struct rx_cap *prxcap, enum hdmi_vic vic);
|
||||
/* validate if hdmi_format_para can support, return 0 if can support or return < 0;
|
||||
* vic should already validate by hdmitx_common_validate_mode(), will not check if vic
|
||||
* support by rx. This function used to verify hdmi setting config from userspace;
|
||||
*/
|
||||
int hdmitx_common_validate_format_para(struct hdmitx_common *tx_comm,
|
||||
struct hdmi_format_para *para);
|
||||
bool hdmitx_mode_validate_y420_vic(enum hdmi_vic vic);
|
||||
/* for some non-std TV, it declare 4k while MAX_TMDS_CLK
|
||||
* not match 4K format, so filter out mode list by
|
||||
* check if basic color space/depth is supported
|
||||
* or not under this resolution;
|
||||
* return 0 when can found valid cs/cd configs, or return < 0;
|
||||
*/
|
||||
int hdmitx_common_check_valid_para_of_vic(struct hdmitx_common *tx_comm, enum hdmi_vic vic);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HDMITX_CHECK_VALID_HEADER_H_
|
||||
#define __HDMITX_CHECK_VALID_HEADER_H_
|
||||
|
||||
#include <linux/amlogic/media/vout/vinfo.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h>
|
||||
#include <linux/types.h>
|
||||
#include "hdmitx_log.h"
|
||||
|
||||
#endif
|
||||
@@ -14,9 +14,9 @@
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h>
|
||||
#include <hdmitx_boot_parameters.h>
|
||||
#include "hdmitx_log.h"
|
||||
#include "hdmitx_check_valid.h"
|
||||
#include "../../../efuse_unifykey/efuse.h"
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/amlogic/media/vout/dsc.h>
|
||||
|
||||
int hdmitx_format_para_init(struct hdmi_format_para *para,
|
||||
enum hdmi_vic vic, u32 frac_rate_policy,
|
||||
@@ -64,6 +64,7 @@ int hdmitx_common_init(struct hdmitx_common *tx_comm, struct hdmitx_hw_common *h
|
||||
|
||||
/*mutex init*/
|
||||
mutex_init(&tx_comm->hdmimode_mutex);
|
||||
mutex_init(&tx_comm->valid_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -94,78 +95,6 @@ int hdmitx_common_destroy(struct hdmitx_common *tx_comm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if vic is supported by SOC hdmitx */
|
||||
int hdmitx_common_validate_vic(struct hdmitx_common *tx_comm, u32 vic)
|
||||
{
|
||||
const struct hdmi_timing *timing = hdmitx_mode_vic_to_hdmi_timing(vic);
|
||||
|
||||
if (!timing)
|
||||
return -EINVAL;
|
||||
|
||||
/*soc level filter*/
|
||||
/*filter 1080p max size.*/
|
||||
if (tx_comm->res_1080p) {
|
||||
/* if the vic equals to HDMI_0_UNKNOWN or VESA,
|
||||
* then create it as over limited
|
||||
*/
|
||||
if (vic == HDMI_0_UNKNOWN || vic >= HDMITX_VESA_OFFSET)
|
||||
return -ERANGE;
|
||||
/* check the resolution is over 1920x1080 or not */
|
||||
if (timing->h_active > 1920 || timing->v_active > 1080)
|
||||
return -ERANGE;
|
||||
|
||||
/* check the fresh rate is over 60hz or not */
|
||||
if (timing->v_freq > 60000)
|
||||
return -ERANGE;
|
||||
|
||||
/* test current vic is over 150MHz or not */
|
||||
if (timing->pixel_freq > 150000)
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
/* efuse ctrl all 4k mode */
|
||||
if (tx_comm->efuse_dis_output_4k)
|
||||
if (timing->v_active >= 2160)
|
||||
return -ERANGE;
|
||||
|
||||
/* efuse ctrl 4k50, 4k60 */
|
||||
if (tx_comm->efuse_dis_hdmi_4k60)
|
||||
if (timing->v_active >= 2160 && timing->v_freq >= 5000)
|
||||
return -ERANGE;
|
||||
|
||||
/*filter max refreshrate.*/
|
||||
if (timing->v_freq > (tx_comm->max_refreshrate * 1000)) {
|
||||
//HDMITX_INFO("validate refreshrate (%s)-(%d) fail\n",
|
||||
//timing->name, timing->v_freq);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/*ip level filter*/
|
||||
if (hdmitx_hw_validate_mode(tx_comm->tx_hw, vic) != 0)
|
||||
return -EPERM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check fmt para is supported or not by hdmitx/edid.
|
||||
* note that vic is not checked if supported by hdmitx/edid
|
||||
*/
|
||||
int hdmitx_common_validate_format_para(struct hdmitx_common *tx_comm,
|
||||
struct hdmi_format_para *para)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (para->vic == HDMI_0_UNKNOWN)
|
||||
return -EPERM;
|
||||
|
||||
/* check if the format param is within capability of both TX/RX */
|
||||
ret = hdmitx_edid_validate_format_para(&tx_comm->tx_hw->hdmi_tx_cap,
|
||||
&tx_comm->rxcap, para);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_common_validate_format_para);
|
||||
|
||||
/* build format para of current mode + cs/cd + frac */
|
||||
int hdmitx_common_build_format_para(struct hdmitx_common *tx_comm,
|
||||
struct hdmi_format_para *para, enum hdmi_vic vic, u32 frac_rate_policy,
|
||||
@@ -208,6 +137,7 @@ int hdmitx_common_validate_mode_locked(struct hdmitx_common *tx_comm,
|
||||
}
|
||||
|
||||
mutex_lock(&tx_comm->hdmimode_mutex);
|
||||
mutex_lock(&tx_comm->valid_mutex);
|
||||
|
||||
if (!mode || !attr) {
|
||||
ret = -EINVAL;
|
||||
@@ -243,8 +173,8 @@ int hdmitx_common_validate_mode_locked(struct hdmitx_common *tx_comm,
|
||||
HDMITX_ERROR("validate formatpara [%s,%s] return error %d\n",
|
||||
mode, attr, ret);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&tx_comm->valid_mutex);
|
||||
mutex_unlock(&tx_comm->hdmimode_mutex);
|
||||
return ret;
|
||||
}
|
||||
@@ -600,62 +530,14 @@ enum hdmi_vic hdmitx_get_prefer_vic(struct hdmitx_common *tx_comm, enum hdmi_vic
|
||||
return vic;
|
||||
}
|
||||
|
||||
/* check VIC supported or not with basic cs/cd
|
||||
* compare with hdmitx_common_validate_mode_locked()
|
||||
* or valid_mode_store(), it doesn't check if vic
|
||||
* is supported by hdmitx/rx or not
|
||||
*/
|
||||
int hdmitx_common_check_valid_para_of_vic(struct hdmitx_common *tx_comm, enum hdmi_vic vic)
|
||||
{
|
||||
struct hdmi_format_para tst_para;
|
||||
enum hdmi_color_depth cd; /* cd8, cd10 or cd12 */
|
||||
enum hdmi_colorspace cs; /* 0/1/2/3: rgb/422/444/420 */
|
||||
const enum hdmi_quantization_range cr = HDMI_QUANTIZATION_RANGE_FULL; /*default to full*/
|
||||
int i = 0;
|
||||
|
||||
if (vic == HDMI_0_UNKNOWN)
|
||||
return -EINVAL;
|
||||
|
||||
if (hdmitx_mode_validate_y420_vic(vic)) {
|
||||
cs = HDMI_COLORSPACE_YUV420;
|
||||
cd = COLORDEPTH_24B;
|
||||
if (hdmitx_common_build_format_para(tx_comm,
|
||||
&tst_para, vic, false, cs, cd, cr) == 0 &&
|
||||
hdmitx_common_validate_format_para(tx_comm, &tst_para) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct {
|
||||
enum hdmi_colorspace cs;
|
||||
enum hdmi_color_depth cd;
|
||||
} test_color_attr[] = {
|
||||
{HDMI_COLORSPACE_RGB, COLORDEPTH_24B},
|
||||
{HDMI_COLORSPACE_YUV444, COLORDEPTH_24B},
|
||||
{HDMI_COLORSPACE_YUV422, COLORDEPTH_36B},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_color_attr); i++) {
|
||||
cs = test_color_attr[i].cs;
|
||||
cd = test_color_attr[i].cd;
|
||||
hdmitx_format_para_reset(&tst_para);
|
||||
if (hdmitx_common_build_format_para(tx_comm,
|
||||
&tst_para, vic, false, cs, cd, cr) == 0 &&
|
||||
hdmitx_common_validate_format_para(tx_comm, &tst_para) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_common_check_valid_para_of_vic);
|
||||
|
||||
/* get corresponding vic of mode, and will check if it's supported in EDID */
|
||||
int hdmitx_common_parse_vic_in_edid(struct hdmitx_common *tx_comm, const char *mode)
|
||||
{
|
||||
const struct hdmi_timing *timing;
|
||||
enum hdmi_vic prefer_vic = HDMI_0_UNKNOWN;
|
||||
|
||||
if (!tx_comm || !mode)
|
||||
return HDMI_0_UNKNOWN;
|
||||
/*parse by name to find default mode*/
|
||||
timing = hdmitx_mode_match_timing_name(mode);
|
||||
if (!timing || timing->vic == HDMI_0_UNKNOWN)
|
||||
@@ -1310,63 +1192,6 @@ enum hdmi_color_depth get_hdmi_colordepth(const struct vinfo_s *vinfo)
|
||||
return cd;
|
||||
}
|
||||
|
||||
bool hdmitx_edid_check_y420_support(struct rx_cap *prxcap, enum hdmi_vic vic)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
bool ret = false;
|
||||
const struct hdmi_timing *timing = hdmitx_mode_vic_to_hdmi_timing(vic);
|
||||
|
||||
if (!timing || !prxcap)
|
||||
return false;
|
||||
|
||||
if (hdmitx_mode_validate_y420_vic(vic)) {
|
||||
for (i = 0; i < Y420_VIC_MAX_NUM; i++) {
|
||||
if (prxcap->y420_vic[i]) {
|
||||
if (prxcap->y420_vic[i] == vic) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* only check if vic is in edid */
|
||||
bool hdmitx_edid_validate_mode(struct rx_cap *rxcap, u32 vic)
|
||||
{
|
||||
int i = 0;
|
||||
bool edid_matched = false;
|
||||
|
||||
if (!rxcap)
|
||||
return false;
|
||||
|
||||
if (vic < HDMITX_VESA_OFFSET) {
|
||||
/*check cea cap*/
|
||||
for (i = 0 ; i < rxcap->VIC_count; i++) {
|
||||
if (rxcap->VIC[i] == vic) {
|
||||
edid_matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
enum hdmi_vic *vesa_t = &rxcap->vesa_timing[0];
|
||||
/*check vesa mode.*/
|
||||
for (i = 0; i < VESA_MAX_TIMING && vesa_t[i]; i++) {
|
||||
if (vic == vesa_t[i]) {
|
||||
edid_matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return edid_matched;
|
||||
}
|
||||
|
||||
bool hdmitx_edid_only_support_sd(struct rx_cap *prxcap)
|
||||
{
|
||||
enum hdmi_vic vic;
|
||||
@@ -1399,7 +1224,7 @@ bool hdmitx_edid_only_support_sd(struct rx_cap *prxcap)
|
||||
/* get the needed frl rate, refer to 2.1 spec table 7-37/38,
|
||||
* actually it may also need to check bpp
|
||||
*/
|
||||
static enum frl_rate_enum get_dsc_frl_rate(enum dsc_encode_mode dsc_mode)
|
||||
enum frl_rate_enum get_dsc_frl_rate(enum dsc_encode_mode dsc_mode)
|
||||
{
|
||||
enum frl_rate_enum frl_rate = FRL_RATE_MAX;
|
||||
|
||||
@@ -1482,350 +1307,4 @@ static enum frl_rate_enum get_dsc_frl_rate(enum dsc_encode_mode dsc_mode)
|
||||
}
|
||||
return frl_rate;
|
||||
}
|
||||
|
||||
static bool hdmitx_check_dsc_support(struct tx_cap *hdmi_tx_cap,
|
||||
struct rx_cap *rxcap, struct hdmi_format_para *para)
|
||||
{
|
||||
enum dsc_encode_mode dsc_mode = DSC_ENCODE_MAX;
|
||||
u8 dsc_slice_num = 0;
|
||||
enum frl_rate_enum dsc_frl_rate = FRL_NONE;
|
||||
u32 bytes_target = 0;
|
||||
u8 dsc_policy;
|
||||
|
||||
if (!hdmi_tx_cap || !rxcap || !para)
|
||||
return false;
|
||||
|
||||
/* step1: check if DSC mode is supported by SOC driver & policy */
|
||||
if (!hdmi_tx_cap->dsc_capable) {
|
||||
HDMITX_DEBUG_EDID("tx not capable of dsc\n");
|
||||
return false;
|
||||
}
|
||||
dsc_policy = hdmi_tx_cap->dsc_policy;
|
||||
|
||||
dsc_mode = dsc_enc_confirm_mode(para->timing.h_active,
|
||||
para->timing.v_active, para->timing.v_freq, para->cs);
|
||||
|
||||
if (dsc_mode == DSC_ENCODE_MAX) {
|
||||
HDMITX_DEBUG_EDID("dsc mode not supported!\n");
|
||||
return false;
|
||||
}
|
||||
if (dsc_policy == 0) {
|
||||
/* force not support below 12bit format temporarily */
|
||||
switch (dsc_mode) {
|
||||
/* 4k120hz */
|
||||
case DSC_RGB_3840X2160_120HZ:
|
||||
case DSC_YUV444_3840X2160_120HZ:
|
||||
/* 4k100hz */
|
||||
case DSC_RGB_3840X2160_100HZ:
|
||||
case DSC_YUV444_3840X2160_100HZ:
|
||||
/* 8k60hz */
|
||||
case DSC_RGB_7680X4320_60HZ:
|
||||
case DSC_YUV444_7680X4320_60HZ:
|
||||
/* 8k50hz */
|
||||
case DSC_RGB_7680X4320_50HZ:
|
||||
case DSC_YUV444_7680X4320_50HZ:
|
||||
/* 8k24hz */
|
||||
case DSC_RGB_7680X4320_24HZ:
|
||||
case DSC_YUV444_7680X4320_24HZ:
|
||||
/* 8k25hz */
|
||||
case DSC_RGB_7680X4320_25HZ:
|
||||
case DSC_YUV444_7680X4320_25HZ:
|
||||
/* 8k30hz */
|
||||
case DSC_RGB_7680X4320_30HZ:
|
||||
case DSC_YUV444_7680X4320_30HZ:
|
||||
if (para->cd == COLORDEPTH_36B)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* step2: check if DSC mode is supported by RX */
|
||||
if (rxcap->dsc_1p2 == 0) {
|
||||
HDMITX_DEBUG_EDID("RX not support DSC\n");
|
||||
return false;
|
||||
}
|
||||
/* check dsc color depth cap */
|
||||
if (para->cd == COLORDEPTH_30B &&
|
||||
!rxcap->dsc_10bpc) {
|
||||
HDMITX_DEBUG_EDID("RX not support 10bpc DSC\n");
|
||||
return false;
|
||||
} else if (para->cd == COLORDEPTH_36B &&
|
||||
!rxcap->dsc_12bpc) {
|
||||
HDMITX_DEBUG_EDID("RX not support 12bpc DSC\n");
|
||||
return false;
|
||||
}
|
||||
/* check dsc color space cap */
|
||||
if (para->cs == HDMI_COLORSPACE_YUV420 &&
|
||||
!rxcap->dsc_native_420) {
|
||||
HDMITX_DEBUG_EDID("RX not support Y420 DSC\n");
|
||||
return false;
|
||||
}
|
||||
dsc_slice_num = dsc_get_slice_num(dsc_mode);
|
||||
/* slice num exceed rx cap */
|
||||
if (dsc_slice_num == 0 ||
|
||||
dsc_slice_num > dsc_max_slices_num[rxcap->dsc_max_slices]) {
|
||||
HDMITX_DEBUG_EDID("current slice num %d exceed rx cap %d\n",
|
||||
dsc_slice_num, dsc_max_slices_num[rxcap->dsc_max_slices]);
|
||||
return false;
|
||||
}
|
||||
/* note: pixel clock per slice not checked, assume
|
||||
* it's always within rx cap
|
||||
*/
|
||||
/* check dsc frl rate within rx cap */
|
||||
dsc_frl_rate = get_dsc_frl_rate(dsc_mode);
|
||||
if (dsc_frl_rate == FRL_RATE_MAX ||
|
||||
dsc_frl_rate > rxcap->dsc_max_frl_rate ||
|
||||
dsc_frl_rate > rxcap->max_frl_rate) {
|
||||
HDMITX_DEBUG_EDID("current dsc frl rate %d exceed rx cap %d-%d\n",
|
||||
dsc_frl_rate, rxcap->dsc_max_frl_rate, rxcap->max_frl_rate);
|
||||
return false;
|
||||
}
|
||||
/* 2.1 spec table 6-56, if Bytes Target is greater than
|
||||
* the value indicated by DSC_TotalChunkKBytes (see Sections
|
||||
* 7.7.1 and 7.7.4.2), then the configuration is not
|
||||
* supported with Compressed Video Transport.
|
||||
*/
|
||||
bytes_target = dsc_get_bytes_target_by_mode(dsc_mode);
|
||||
if (bytes_target > (rxcap->dsc_total_chunk_bytes + 1) * 1024) {
|
||||
HDMITX_DEBUG_EDID("bytes_target %d exceed DSC_TotalChunkKBytes %d\n",
|
||||
bytes_target, (rxcap->dsc_total_chunk_bytes + 1) * 1024);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For some TV's EDID, there maybe exist some information ambiguous.
|
||||
* Such as EDID declare support 2160p60hz(Y444 8bit), but no valid
|
||||
* Max_TMDS_Clock2 to indicate that it can support 5.94G signal.
|
||||
*/
|
||||
int hdmitx_edid_validate_format_para(struct tx_cap *hdmi_tx_cap,
|
||||
struct rx_cap *prxcap, struct hdmi_format_para *para)
|
||||
{
|
||||
const struct dv_info *dv;
|
||||
/* needed tmds clk bandwidth for current format */
|
||||
unsigned int calc_tmds_clk = 0;
|
||||
/* max tmds clk supported by RX */
|
||||
unsigned int rx_max_tmds_clk = 0;
|
||||
/* bandwidth needed for current FRL mode */
|
||||
u32 tx_frl_bandwidth = 0;
|
||||
/* maximum supported frl bandwidth of RX */
|
||||
u32 rx_frl_bandwidth_cap = 0;
|
||||
/* maximum supported frl bandwidth of soc */
|
||||
u32 tx_frl_bandwidth_cap = 0;
|
||||
bool must_frl_flag = 0;
|
||||
int ret = 0;
|
||||
u8 dsc_policy;
|
||||
|
||||
if (!hdmi_tx_cap || !prxcap || !para)
|
||||
return -EPERM;
|
||||
|
||||
dsc_policy = hdmi_tx_cap->dsc_policy;
|
||||
dv = &prxcap->dv_info;
|
||||
/* step1: check if mode + cs/cd is supported by TX */
|
||||
switch (para->timing.vic) {
|
||||
/* Note: below check for formats which should use FRL
|
||||
* is also checked in step3, so remove
|
||||
*/
|
||||
/* case HDMI_96_3840x2160p50_16x9: */
|
||||
/* case HDMI_97_3840x2160p60_16x9: */
|
||||
/* case HDMI_101_4096x2160p50_256x135: */
|
||||
/* case HDMI_102_4096x2160p60_256x135: */
|
||||
/* case HDMI_106_3840x2160p50_64x27: */
|
||||
/* case HDMI_107_3840x2160p60_64x27: */
|
||||
/* if (para->cs == HDMI_COLORSPACE_RGB || */
|
||||
/* para->cs == HDMI_COLORSPACE_YUV444) */
|
||||
/* if (para->cd != COLORDEPTH_24B && */
|
||||
/* (prxcap->max_frl_rate == FRL_NONE || */
|
||||
/* hdmi_tx_cap->tx_max_frl_rate == FRL_NONE)) */
|
||||
/* return -EPERM; */
|
||||
/* break; */
|
||||
case HDMI_6_720x480i60_4x3:
|
||||
case HDMI_7_720x480i60_16x9:
|
||||
case HDMI_21_720x576i50_4x3:
|
||||
case HDMI_22_720x576i50_16x9:
|
||||
if (para->cs == HDMI_COLORSPACE_YUV422)
|
||||
return -EPERM;
|
||||
break;
|
||||
/* don't support 640x480p60 */
|
||||
case HDMI_1_640x480p60_4x3:
|
||||
return -EPERM;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* step2: DVI case, only rgb,8bit */
|
||||
if (prxcap->ieeeoui != HDMI_IEEE_OUI) {
|
||||
if (para->cd != COLORDEPTH_24B || para->cs != HDMI_COLORSPACE_RGB) {
|
||||
HDMITX_DEBUG_EDID("cs:%d, cd:%d not support by DVI sink\n",
|
||||
para->cs, para->cd);
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
/* step3: check TMDS/FRL bandwidth is within TX/RX cap */
|
||||
if (prxcap->Max_TMDS_Clock2) {
|
||||
rx_max_tmds_clk = prxcap->Max_TMDS_Clock2 * 5;
|
||||
} else {
|
||||
/* Default min is 74.25 / 5 */
|
||||
if (prxcap->Max_TMDS_Clock1 < 0xf)
|
||||
prxcap->Max_TMDS_Clock1 = DEFAULT_MAX_TMDS_CLK;
|
||||
rx_max_tmds_clk = prxcap->Max_TMDS_Clock1 * 5;
|
||||
}
|
||||
calc_tmds_clk = para->tmds_clk / 1000;
|
||||
|
||||
/* more > 4k60 must use frl mode */
|
||||
if (para->timing.h_active > 4096 || para->timing.v_active > 2160 ||
|
||||
para->timing.v_freq == 48000 || calc_tmds_clk > 594 ||
|
||||
para->timing.pixel_freq / 1000 > 600)
|
||||
must_frl_flag = true;
|
||||
|
||||
if (hdmi_tx_cap->tx_max_frl_rate == FRL_NONE) {
|
||||
/* output format need FRL while SOC not support FRL */
|
||||
if (must_frl_flag) {
|
||||
HDMITX_DEBUG_EDID("output format need FRL, while tx not support\n");
|
||||
return -EPERM;
|
||||
}
|
||||
/* tmds clk of the output format exceed TX/RX cap */
|
||||
if (calc_tmds_clk > hdmi_tx_cap->tx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed tx cap: %d\n",
|
||||
calc_tmds_clk, hdmi_tx_cap->tx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
if (calc_tmds_clk > rx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed rx cap: %d\n",
|
||||
calc_tmds_clk, rx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
#ifdef CONFIG_AMLOGIC_DSC
|
||||
if (dsc_policy == 1) {
|
||||
/* force enable policy */
|
||||
if (hdmitx_check_dsc_support(hdmi_tx_cap, prxcap, para))
|
||||
return 0;
|
||||
} else if (dsc_policy == 2) {
|
||||
/* for debug test */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (!must_frl_flag) {
|
||||
if (calc_tmds_clk > hdmi_tx_cap->tx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed tx cap: %d\n",
|
||||
calc_tmds_clk, hdmi_tx_cap->tx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
if (calc_tmds_clk > rx_max_tmds_clk) {
|
||||
HDMITX_DEBUG_EDID("output tmds clk:%d exceed rx cap: %d\n",
|
||||
calc_tmds_clk, rx_max_tmds_clk);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
/* try to check if able to run under FRL mode */
|
||||
|
||||
/* output format need FRL while RX not support FRL
|
||||
* no need below check, it will be checked with rx_frl_bandwidth_cap
|
||||
*/
|
||||
if (prxcap->max_frl_rate == FRL_NONE) {
|
||||
HDMITX_DEBUG_EDID("output format need FRL, while rx not support\n");
|
||||
return -EPERM;
|
||||
}
|
||||
/* tx_frl_bandwidth = timing->pixel_freq / 1000 * 24 * 1.122 */
|
||||
tx_frl_bandwidth = hdmitx_calc_frl_bandwidth(para->timing.pixel_freq / 1000,
|
||||
para->cs, para->cd);
|
||||
tx_frl_bandwidth_cap =
|
||||
hdmitx_get_frl_bandwidth(hdmi_tx_cap->tx_max_frl_rate);
|
||||
rx_frl_bandwidth_cap = hdmitx_get_frl_bandwidth(prxcap->max_frl_rate);
|
||||
|
||||
if (prxcap->dsc_1p2 == 0) {
|
||||
/* RX not support DSC */
|
||||
if (tx_frl_bandwidth > tx_frl_bandwidth_cap) {
|
||||
HDMITX_DEBUG_EDID("frl bandwitch:%d exceed tx_cap:%d\n",
|
||||
tx_frl_bandwidth, tx_frl_bandwidth_cap);
|
||||
return -EPERM;
|
||||
}
|
||||
if (tx_frl_bandwidth > rx_frl_bandwidth_cap) {
|
||||
HDMITX_DEBUG_EDID("frl bandwitch:%d exceed rx_cap:%d\n",
|
||||
tx_frl_bandwidth, rx_frl_bandwidth_cap);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
if (tx_frl_bandwidth <= tx_frl_bandwidth_cap &&
|
||||
tx_frl_bandwidth <= rx_frl_bandwidth_cap)
|
||||
; // non-dsc bandwidth is within cap, continue check
|
||||
#ifdef CONFIG_AMLOGIC_DSC
|
||||
else if (dsc_policy == 3) //forcely filter out dsc mode output
|
||||
return -EPERM;
|
||||
else if (!hdmitx_check_dsc_support(hdmi_tx_cap, prxcap, para))
|
||||
return -EPERM;
|
||||
#else
|
||||
else
|
||||
return -EPERM;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* step4: check color space/depth is within RX cap */
|
||||
if (para->cs == HDMI_COLORSPACE_YUV444) {
|
||||
enum hdmi_color_depth rx_y444_max_dc = COLORDEPTH_24B;
|
||||
/* Rx may not support Y444 */
|
||||
if (!(prxcap->native_Mode & (1 << 5)))
|
||||
return -EACCES;
|
||||
if (prxcap->dc_y444 && (prxcap->dc_30bit ||
|
||||
dv->sup_10b_12b_444 == 0x1))
|
||||
rx_y444_max_dc = COLORDEPTH_30B;
|
||||
if (prxcap->dc_y444 && (prxcap->dc_36bit ||
|
||||
dv->sup_10b_12b_444 == 0x2))
|
||||
rx_y444_max_dc = COLORDEPTH_36B;
|
||||
|
||||
if (para->cd <= rx_y444_max_dc)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (para->cs == HDMI_COLORSPACE_YUV422) {
|
||||
/* Rx may not support Y422 */
|
||||
if (prxcap->native_Mode & (1 << 4))
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (para->cs == HDMI_COLORSPACE_RGB) {
|
||||
enum hdmi_color_depth rx_rgb_max_dc = COLORDEPTH_24B;
|
||||
/* Always assume RX supports RGB444 */
|
||||
if (prxcap->dc_30bit || dv->sup_10b_12b_444 == 0x1)
|
||||
rx_rgb_max_dc = COLORDEPTH_30B;
|
||||
if (prxcap->dc_36bit || dv->sup_10b_12b_444 == 0x2)
|
||||
rx_rgb_max_dc = COLORDEPTH_36B;
|
||||
|
||||
if (para->cd <= rx_rgb_max_dc)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (para->cs == HDMI_COLORSPACE_YUV420) {
|
||||
ret = 0;
|
||||
if (!hdmitx_edid_check_y420_support(prxcap, para->vic))
|
||||
ret = -EACCES;
|
||||
else if (!prxcap->dc_30bit_420 && para->cd == COLORDEPTH_30B)
|
||||
ret = -EACCES;
|
||||
else if (!prxcap->dc_36bit_420 && para->cd == COLORDEPTH_36B)
|
||||
ret = -EACCES;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/component.h>
|
||||
#include "hdmitx_drm_hook.h"
|
||||
#include "hdmitx_log.h"
|
||||
#include "hdmitx_check_valid.h"
|
||||
|
||||
/*!!Only one instance supported.*/
|
||||
const struct hdmi_timing *hdmitx_mode_match_timing_name(const char *name);
|
||||
@@ -110,6 +111,7 @@ int hdmitx_common_get_vic_list(int **vics)
|
||||
int *edid_vics = 0;
|
||||
enum hdmi_vic prefer_vic = HDMI_0_UNKNOWN;
|
||||
|
||||
mutex_lock(&global_tx_base->valid_mutex);
|
||||
viclist = kcalloc(len, sizeof(int), GFP_KERNEL);
|
||||
edid_vics = vmalloc(len * sizeof(int));
|
||||
memset(edid_vics, 0, len * sizeof(int));
|
||||
@@ -158,6 +160,7 @@ int hdmitx_common_get_vic_list(int **vics)
|
||||
else
|
||||
*vics = viclist;
|
||||
|
||||
mutex_unlock(&global_tx_base->valid_mutex);
|
||||
return count;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_common_get_vic_list);
|
||||
@@ -179,15 +182,18 @@ bool hdmitx_common_chk_mode_attr_sup(char *mode, char *attr)
|
||||
if (!mode || !attr)
|
||||
return false;
|
||||
|
||||
mutex_lock(&global_tx_base->valid_mutex);
|
||||
vic = hdmitx_common_parse_vic_in_edid(global_tx_base, mode);
|
||||
if (vic == HDMI_0_UNKNOWN) {
|
||||
HDMITX_ERROR("%s: get vic from (%s) fail\n", __func__, mode);
|
||||
mutex_unlock(&global_tx_base->valid_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = hdmitx_common_validate_vic(global_tx_base, vic);
|
||||
if (ret != 0) {
|
||||
HDMITX_ERROR("validate vic [%s,%s]-%d return error %d\n", mode, attr, vic, ret);
|
||||
mutex_unlock(&global_tx_base->valid_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -198,6 +204,7 @@ bool hdmitx_common_chk_mode_attr_sup(char *mode, char *attr)
|
||||
if (ret != 0) {
|
||||
hdmitx_format_para_reset(&tst_para);
|
||||
HDMITX_ERROR("build formatpara [%s,%s] return error %d\n", mode, attr, ret);
|
||||
mutex_unlock(&global_tx_base->valid_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -211,9 +218,11 @@ bool hdmitx_common_chk_mode_attr_sup(char *mode, char *attr)
|
||||
ret = hdmitx_common_validate_format_para(global_tx_base, &tst_para);
|
||||
if (ret != 0) {
|
||||
HDMITX_ERROR("validate formatpara [%s,%s] return error %d\n", mode, attr, ret);
|
||||
mutex_unlock(&global_tx_base->valid_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
mutex_unlock(&global_tx_base->valid_mutex);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_common_chk_mode_attr_sup);
|
||||
|
||||
@@ -30,5 +30,6 @@
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h>
|
||||
#include "hdmitx_log.h"
|
||||
#include "hdmitx_check_valid.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -561,22 +561,6 @@ const struct hdmi_timing *hdmitx_mode_match_timing_name(const char *name)
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_mode_match_timing_name);
|
||||
|
||||
bool hdmitx_mode_validate_y420_vic(enum hdmi_vic vic)
|
||||
{
|
||||
const struct hdmi_timing *timing;
|
||||
|
||||
/* In Spec2.1 Table 7-34, greater than 2160p30hz will support y420 */
|
||||
timing = hdmitx_mode_vic_to_hdmi_timing(vic);
|
||||
if (!timing)
|
||||
return false;
|
||||
if (timing->v_active >= 2160 && timing->v_freq > 30000)
|
||||
return true;
|
||||
if (timing->v_active >= 4320)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(hdmitx_mode_validate_y420_vic);
|
||||
|
||||
const char *hdmitx_mode_get_timing_name(enum hdmi_vic vic)
|
||||
{
|
||||
const struct hdmi_timing *timing =
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h>
|
||||
#include "hdmitx_log.h"
|
||||
#include "hdmitx_check_valid.h"
|
||||
|
||||
const struct hdmi_timing *hdmitx_mode_match_timing_name(const char *name);
|
||||
static int hdmitx_module_disable(enum vmode_e cur_vmod, void *data);
|
||||
@@ -165,6 +166,7 @@ static void reset_vinfo(struct vinfo_s *tx_vinfo)
|
||||
static int hdmitx_common_pre_enable_mode(struct hdmitx_common *tx_comm,
|
||||
struct hdmi_format_para *para)
|
||||
{
|
||||
mutex_lock(&tx_comm->valid_mutex);
|
||||
if (tx_comm->ready)
|
||||
HDMITX_ERROR("Should run disable_mode before enable new mode.\n");
|
||||
|
||||
@@ -172,6 +174,7 @@ static int hdmitx_common_pre_enable_mode(struct hdmitx_common *tx_comm,
|
||||
HDMITX_ERROR("%s current hpd_state/suspend (%d,%d), exit\n",
|
||||
__func__, tx_comm->hpd_state, tx_comm->suspend_flag);
|
||||
hdmitx_tracer_write_event(tx_comm->tx_tracer, HDMITX_KMS_SKIP);
|
||||
mutex_unlock(&tx_comm->valid_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -181,16 +184,19 @@ static int hdmitx_common_pre_enable_mode(struct hdmitx_common *tx_comm,
|
||||
/*check if vic supported by rx*/
|
||||
if (!hdmitx_edid_validate_mode(&tx_comm->rxcap, tx_comm->fmt_para.vic)) {
|
||||
HDMITX_ERROR("edid invalid vic-%d return error\n", tx_comm->fmt_para.vic);
|
||||
mutex_unlock(&tx_comm->valid_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hdmitx_common_validate_vic(tx_comm, tx_comm->fmt_para.vic)) {
|
||||
HDMITX_ERROR("validate vic-%d return error\n", tx_comm->fmt_para.vic);
|
||||
mutex_unlock(&tx_comm->valid_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hdmitx_common_validate_format_para(tx_comm, &tx_comm->fmt_para)) {
|
||||
HDMITX_ERROR("format para check fail.\n");
|
||||
mutex_unlock(&tx_comm->valid_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -201,6 +207,7 @@ static int hdmitx_common_pre_enable_mode(struct hdmitx_common *tx_comm,
|
||||
if (tx_comm->ctrl_ops->pre_enable_mode)
|
||||
tx_comm->ctrl_ops->pre_enable_mode(tx_comm, para);
|
||||
|
||||
mutex_unlock(&tx_comm->valid_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "hdmitx_sysfs_common.h"
|
||||
#include "hdmitx_log.h"
|
||||
#include "hdmitx_compliance.h"
|
||||
#include "hdmitx_check_valid.h"
|
||||
|
||||
/*!!Only one instance supported.*/
|
||||
static struct hdmitx_common *global_tx_common;
|
||||
@@ -853,6 +854,7 @@ static ssize_t disp_cap_show(struct device *dev,
|
||||
int *edid_vics = vmalloc(vic_len * sizeof(int));
|
||||
enum hdmi_vic prefer_vic = HDMI_0_UNKNOWN;
|
||||
|
||||
mutex_lock(&global_tx_common->valid_mutex);
|
||||
memset(edid_vics, 0, vic_len * sizeof(int));
|
||||
|
||||
/* step1: only select VIC which is supported in EDID */
|
||||
@@ -905,6 +907,7 @@ static ssize_t disp_cap_show(struct device *dev,
|
||||
}
|
||||
|
||||
vfree(edid_vics);
|
||||
mutex_unlock(&global_tx_common->valid_mutex);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -1074,6 +1077,7 @@ static ssize_t valid_mode_store(struct device *dev,
|
||||
struct hdmi_format_para tst_para;
|
||||
enum hdmi_vic vic = HDMI_0_UNKNOWN;
|
||||
|
||||
mutex_lock(&global_tx_common->valid_mutex);
|
||||
memset(modename, 0, sizeof(modename));
|
||||
memset(attrstr, 0, sizeof(attrstr));
|
||||
memset(cvalid_mode, 0, sizeof(cvalid_mode));
|
||||
@@ -1125,6 +1129,7 @@ static ssize_t valid_mode_store(struct device *dev,
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
mutex_unlock(&global_tx_common->valid_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_tracer.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_event_mgr.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/amlogic/media/vout/dsc.h>
|
||||
|
||||
struct hdmitx_common_state {
|
||||
struct hdmi_format_para para;
|
||||
@@ -91,6 +92,7 @@ struct hdmitx_common {
|
||||
* handler and mode setting sequentially.
|
||||
*/
|
||||
struct mutex hdmimode_mutex;
|
||||
struct mutex valid_mutex; /* check valid mode need mutex */
|
||||
|
||||
/* save the last plug out/in work done state */
|
||||
enum hdmi_event_t last_hpd_handle_done_stat;
|
||||
@@ -193,23 +195,6 @@ int hdmitx_common_destroy(struct hdmitx_common *tx_common);
|
||||
* return the vic of mode, if failed return HDMI_0_UNKNOWN;
|
||||
*/
|
||||
int hdmitx_common_parse_vic_in_edid(struct hdmitx_common *tx_comm, const char *mode);
|
||||
/* validate if vic can supported. return 0 if can support, return < 0 with error reason;
|
||||
* This function used by get_mode_list;
|
||||
*/
|
||||
int hdmitx_common_validate_vic(struct hdmitx_common *tx_comm, u32 vic);
|
||||
/* for some non-std TV, it declare 4k while MAX_TMDS_CLK
|
||||
* not match 4K format, so filter out mode list by
|
||||
* check if basic color space/depth is supported
|
||||
* or not under this resolution;
|
||||
* return 0 when can found valid cs/cd configs, or return < 0;
|
||||
*/
|
||||
int hdmitx_common_check_valid_para_of_vic(struct hdmitx_common *tx_comm, enum hdmi_vic vic);
|
||||
/* validate if hdmi_format_para can support, return 0 if can support or return < 0;
|
||||
* vic should already validate by hdmitx_common_validate_mode(), will not check if vic
|
||||
* support by rx. This function used to verify hdmi setting config from userspace;
|
||||
*/
|
||||
int hdmitx_common_validate_format_para(struct hdmitx_common *tx_comm,
|
||||
struct hdmi_format_para *para);
|
||||
|
||||
/* create hdmi_format_para from config and also calc setting from hw; */
|
||||
int hdmitx_common_build_format_para(struct hdmitx_common *tx_comm,
|
||||
@@ -219,14 +204,7 @@ int hdmitx_common_build_format_para(struct hdmitx_common *tx_comm,
|
||||
/* For bootup init: init hdmi_format_para from hw configs.*/
|
||||
int hdmitx_common_init_bootup_format_para(struct hdmitx_common *tx_comm,
|
||||
struct hdmi_format_para *para);
|
||||
|
||||
/*edid valid api*/
|
||||
int hdmitx_edid_validate_format_para(struct tx_cap *hdmi_tx_cap,
|
||||
struct rx_cap *prxcap, struct hdmi_format_para *para);
|
||||
bool hdmitx_edid_check_y420_support(struct rx_cap *prxcap,
|
||||
enum hdmi_vic vic);
|
||||
|
||||
bool hdmitx_edid_validate_mode(struct rx_cap *rxcap, u32 vic);
|
||||
bool hdmitx_edid_only_support_sd(struct rx_cap *prxcap);
|
||||
|
||||
/* Attach platform related functions to hdmitx_common;
|
||||
@@ -359,5 +337,6 @@ void hdmitx_audio_notify_callback(struct hdmitx_common *tx_comm,
|
||||
void get_hdmi_efuse(struct hdmitx_common *tx_comm);
|
||||
enum hdmi_color_depth get_hdmi_colordepth(const struct vinfo_s *vinfo);
|
||||
enum hdmi_vic hdmitx_get_prefer_vic(struct hdmitx_common *tx_comm, enum hdmi_vic vic);
|
||||
enum frl_rate_enum get_dsc_frl_rate(enum dsc_encode_mode dsc_mode);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -279,7 +279,6 @@ bool hdmitx_edid_check_data_valid(u8 edid_check, unsigned char *buf);
|
||||
ssize_t _show_aud_cap(struct rx_cap *prxcap, char *buf);
|
||||
int hdmitx_edid_parse(struct rx_cap *prxcap, u8 *edid_buf);
|
||||
unsigned int hdmitx_edid_valid_block_num(unsigned char *edid_buf);
|
||||
bool hdmitx_mode_validate_y420_vic(enum hdmi_vic vic);
|
||||
void hdmitx_edid_print(u8 *edid_buf);
|
||||
void hdmitx_edid_buffer_clear(u8 *edid_buf, int size);
|
||||
void hdmitx_edid_rxcap_clear(struct rx_cap *prxcap);
|
||||
|
||||
Reference in New Issue
Block a user