soc/mediatek/mt8196: Refactor mt8196 eDP driver for better code sharing

Refactor the MT8196 eDP driver to improve code reusability:
- Move common parts of dp_intf.h to dp_intf_v2.h
- Move common parts of dptx_hal.h to dptx_hal_v2.h
- Move common parts of dptx_reg.h to dptx_v2.h
- Extract shared code from dptx.c to dptx_v2.c
- Extract shared code from dptx_hal.c to dptx_hal_v2.c
- Rename dp_intf.c to dp_intf_v2.c

SoC-specific parts remain in its respective .c and .h files.

BUG=b:400886838
BRANCH=none
TEST=Check the display function on Navi

Signed-off-by: Vince Liu <vince-wl.liu@mediatek.corp-partner.google.com>
Change-Id: Ia41f62c0f5f7b5a38d7c5650e6f3a06963cc84a7
Reviewed-on: https://review.coreboot.org/c/coreboot/+/88149
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yidi Lin <yidilin@google.com>
This commit is contained in:
Vince Liu 2025-06-10 10:14:46 +08:00 committed by Yidi Lin
commit df91698b11
27 changed files with 1271 additions and 1184 deletions

View file

@ -0,0 +1,358 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#include <assert.h>
#include <console/console.h>
#include <device/mmio.h>
#include <delay.h>
#include <edid.h>
#include <soc/dptx.h>
#include <soc/dptx_hal.h>
#include <soc/dptx_reg.h>
#include <types.h>
const int dptx_hal_driving_offset[] = {
PHYD_DIG_LAN0_OFFSET + DRIVING_FORCE,
PHYD_DIG_LAN1_OFFSET + DRIVING_FORCE,
PHYD_DIG_LAN2_OFFSET + DRIVING_FORCE,
PHYD_DIG_LAN3_OFFSET + DRIVING_FORCE,
};
const int dptx_hal_driving_offset_size = ARRAY_SIZE(dptx_hal_driving_offset);
void dptx_hal_init_setting(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, 0x2000, GENMASK(1, 0), GENMASK(1, 0));
mtk_dp_mask(mtk_dp, REG_3540_DP_TRANS_P0, BIT(3), BIT(3));
mtk_dp_mask(mtk_dp, REG_342C_DP_TRANS_P0, 0x68, 0xFF);
mtk_dp_mask(mtk_dp, REG_31EC_DP_ENCODER0_P0, BIT(4), BIT(4));
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, 0, BIT(8));
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, BIT(3), BIT(3));
/* default marker */
mtk_dp_mask(mtk_dp, REG_3F04_DP_ENC_4P_3, 0, 0xFFFF);
mtk_dp_mask(mtk_dp, REG_3F08_DP_ENC_4P_3, BIT(3), BIT(3));
mtk_dp_mask(mtk_dp, REG_3F0C_DP_ENC_4P_3, BIT(1), BIT(1));
mtk_dp_mask(mtk_dp, REG_3F10_DP_ENC_4P_3, BIT(3), BIT(3));
mtk_dp_mask(mtk_dp, REG_33C0_DP_ENCODER1_P0, 0, 0xF000);
mtk_dp_mask(mtk_dp, REG_33C0_DP_ENCODER1_P0, 0x80, 0x80);
mtk_dp_mask(mtk_dp, REG_33C4_DP_ENCODER1_P0, BIT(5), BIT(6) | BIT(5));
mtk_dp_mask(mtk_dp, REG_3F28_DP_ENC_4P_3, 0xA << 2, GENMASK(5, 2));
mtk_dp_mask(mtk_dp, DP_TX_TOP_RESET_AND_PROBE, 0x9100FF, 0x9100FF);
mtk_dp_mask(mtk_dp, MTK_DP_TOP_IRQ_MASK, ENCODER_IRQ_MSK | TRANS_IRQ_MSK,
ENCODER_IRQ_MSK | TRANS_IRQ_MSK);
}
void dptx_hal_set_color_format(struct mtk_dp *mtk_dp, u8 out_format)
{
u32 val;
/* MISC0 */
mtk_dp_mask(mtk_dp, REG_3034_DP_ENCODER0_P0, out_format << DP_TEST_COLOR_FORMAT_SHIFT,
DP_TEST_COLOR_FORMAT_MASK);
mtk_dp_mask(mtk_dp, REG_3034_DP_ENCODER0_P0, BIT(3), BIT(3));
switch (out_format) {
case DP_COLOR_FORMAT_RGB_444:
case DP_COLOR_FORMAT_YUV_444:
val = 0;
break;
case DP_COLOR_FORMAT_YUV_422:
val = 0x1;
break;
case DP_COLOR_FORMAT_YUV_420:
val = 0x2;
break;
default:
printk(BIOS_ERR, "Unsupported color format: %u\n", out_format);
return;
}
mtk_dp_mask(mtk_dp, REG_303C_DP_ENCODER0_P0, val << 12, 0x7 << 12);
}
void dptx_hal_settu_setencoder(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_303C_DP_ENCODER0_P0, BIT(15), BIT(15));
DP_WRITE2BYTE(mtk_dp, REG_3040_DP_ENCODER0_P0, 0x2020);
DP_WRITE2BYTE(mtk_dp, REG_3364_DP_ENCODER1_P0, 0x2020);
mtk_dp_mask(mtk_dp, REG_3300_DP_ENCODER1_P0, 0x2 << 8, 0x3 << 8);
mtk_dp_mask(mtk_dp, REG_3364_DP_ENCODER1_P0, 0x40 << 8, 0x70 << 8);
}
bool dptx_hal_hpd_high(struct mtk_dp *mtk_dp)
{
return mtk_dp_read(mtk_dp, REG_364C_AUX_TX_P0) & BIT(15);
}
bool dptx_hal_setswing_preemphasis(struct mtk_dp *mtk_dp, int lane_num, u8 swing_value,
u8 preemphasis)
{
assert(lane_num <= DPTX_LANE_MAX);
for (int i = 0; i < lane_num; ++i) {
mtk_dp_phy_mask(mtk_dp, dptx_hal_driving_offset[i],
swing_value << EDP_TX_LN_VOLT_SWING_VAL_SHIFT |
preemphasis << EDP_TX_LN_PRE_EMPH_VAL_SHIFT,
EDP_TX_LN_VOLT_SWING_VAL_MASK | EDP_TX_LN_PRE_EMPH_VAL_MASK);
printk(BIOS_DEBUG, "lane(%d), set swing(%u), emp(%u)\n",
i, swing_value, preemphasis);
}
mtk_dp_mask(mtk_dp, 0x2000, GENMASK(1, 0), GENMASK(1, 0));
return true;
}
void dptx_hal_hpd_detect_setting(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_364C_AUX_TX_P0, HPD_INT_THD_FLDMASK_VAL << 4,
HPD_INT_THD_FLDMASK);
}
void dptx_hal_phy_init(struct mtk_dp *mtk_dp)
{
mtk_dp_phy_mask(mtk_dp, IPMUX_CONTROL, 0 << EDPTX_DSI_PHYD_SEL_FLDMASK_POS,
EDPTX_DSI_PHYD_SEL_FLDMASK);
mtk_dp_phy_mask(mtk_dp, PHYD_DIG_GLB_OFFSET + 0x10, GENMASK(2, 0), GENMASK(2, 0));
dptx_hal_ssc_en(mtk_dp, false);
}
void dptx_hal_set_txrate(struct mtk_dp *mtk_dp, u8 value)
{
printk(BIOS_INFO, "Link rate = 0x%x\n", value);
switch (value) {
case DP_LINKRATE_RBR:
mtk_dp_phy_write(mtk_dp, 0x143C, DP_LINKRATE_RBR_VAL);
break;
case DP_LINKRATE_HBR:
mtk_dp_phy_write(mtk_dp, 0x143C, DP_LINKRATE_HBR_VAL);
break;
case DP_LINKRATE_HBR2:
mtk_dp_phy_write(mtk_dp, 0x143C, DP_LINKRATE_HBR2_VAL);
break;
case DP_LINKRATE_HBR3:
mtk_dp_phy_write(mtk_dp, 0x143C, DP_LINKRATE_HBR3_VAL);
break;
default:
printk(BIOS_ERR, "Link rate not support(%d)\n", value);
return;
}
}
void dptx_hal_phy_setting(struct mtk_dp *mtk_dp)
{
u8 link_rate = mtk_dp->train_info.linkrate;
u8 lane_count = mtk_dp->train_info.linklane_count;
dptx_hal_phy_set_lanes(mtk_dp, lane_count);
dptx_hal_set_txrate(mtk_dp, link_rate);
/* Turn on phy power after phy configure */
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, PHY_STATE_W_1_DP_ENC_4P_3,
PHY_STATE_W_1_DP_ENC_4P_3_MASK);
mtk_dp_mask(mtk_dp, 0x2000, GENMASK(1, 0), GENMASK(1, 0));
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_PLL_CTL_1:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_PLL_CTL_1));
}
void dptx_hal_ssc_en(struct mtk_dp *mtk_dp, bool enable)
{
if (enable) {
printk(BIOS_DEBUG, "[eDPTX] enable ssc\n");
mtk_dp_phy_mask(mtk_dp, DP_PHY_DIG_PLL_CTL_1, BIT(8), BIT(8));
} else {
printk(BIOS_DEBUG, "[eDPTX] disable ssc\n");
mtk_dp_phy_mask(mtk_dp, DP_PHY_DIG_PLL_CTL_1, 0x0, BIT(8));
}
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_PLL_CTL_1:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_PLL_CTL_1));
mdelay(1);
}
void dptx_hal_aux_setting(struct mtk_dp *mtk_dp)
{
/* Modify timeout threshold = 1595 [12 : 8] */
mtk_dp_mask(mtk_dp, REG_360C_AUX_TX_P0, 0x1D0C, 0x1FFF);
mtk_dp_mask(mtk_dp, REG_3658_AUX_TX_P0, 0, BIT(0));
/* [0]mtk_dp, REG_aux_tx_ov_en */
mtk_dp_mask(mtk_dp, REG_36A0_AUX_TX_4P, 0xFFFC, 0xFFFC);
/* 26M */
mtk_dp_mask(mtk_dp, REG_3634_AUX_TX_P0, AUX_TX_OVER_SAMPLE_RATE_FOR_26M << 8,
0xff << 8);
mtk_dp_mask(mtk_dp, REG_3614_AUX_TX_P0, AUX_RX_UI_CNT_THR_AUX_FOR_26M, 0x7f);
/* Modify, 13 for 26M */
mtk_dp_mask(mtk_dp, REG_37C8_AUX_TX_P0, MTK_ATOP_EN_AUX_TX_4P, MTK_ATOP_EN_AUX_TX_4P);
/* Disable aux sync_stop detect function */
mtk_dp_mask(mtk_dp, REG_3690_AUX_TX_P0, RX_REPLY_COMPLETE_MODE_AUX_TX_4P,
RX_REPLY_COMPLETE_MODE_AUX_TX_4P);
mtk_dp_mask(mtk_dp, REG_367C_AUX_TX_P0, HPD_CONN_THD_AUX_TX_P0_FLDMASK_POS << 6,
HPD_CONN_THD_AUX_TX_P0_FLDMASK);
mtk_dp_mask(mtk_dp, REG_37A0_AUX_TX_P0, HPD_DISC_THD_AUX_TX_P0_FLDMASK_POS << 4,
HPD_DISC_THD_AUX_TX_P0_FLDMASK);
mtk_dp_mask(mtk_dp, REG_3690_AUX_TX_P0, RX_REPLY_COMPLETE_MODE_AUX_TX_4P,
RX_REPLY_COMPLETE_MODE_AUX_TX_4P);
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_VALUE << 9,
XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_MASK);
mtk_dp_mask(mtk_dp, REG_366C_AUX_TX_P0, XTAL_FREQ_DP_TX_AUX_366C_VALUE << 8,
XTAL_FREQ_DP_TX_AUX_366C_MASK);
}
void dptx_hal_digital_setting(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, 0, VBID_VIDEO_MUTE_DP_ENC0_4P_MASK);
mtk_dp_mask(mtk_dp, REG_3368_DP_ENCODER1_P0, BS2BS_MODE_DP_ENC1_4P_VAL << 12,
0x3 << 12);
mtk_dp_mask(mtk_dp, REG_3030_DP_ENCODER0_P0, BIT(11), BIT(11));
/* dp I-mode enable */
mtk_dp_mask(mtk_dp, BS2BS_MODE_DP_ENCODER1_P0_FLDMASK, DP_I_MODE_ENABLE,
DP_I_MODE_ENABLE);
mtk_dp_mask(mtk_dp, REG_3030_DP_ENCODER0_P0, 0x3ff, 0x3ff);
mtk_dp_mask(mtk_dp, REG_3028_DP_ENCODER0_P0, 0, BIT(15));
mtk_dp_mask(mtk_dp, REG_302C_DP_ENCODER0_P0, 0, BIT(15));
/* set color format */
dptx_hal_set_color_format(mtk_dp, DP_COLOR_FORMAT_RGB_444);
/* set color depth */
dptx_hal_set_color_depth(mtk_dp, DP_COLOR_DEPTH_8BIT);
/* reg_bs)symbol_cnt_reset */
mtk_dp_mask(mtk_dp, REG_3000_DP_ENCODER0_P0, REG_BS_SYMBOL_CNT_RESET,
REG_BS_SYMBOL_CNT_RESET);
mtk_dp_mask(mtk_dp, REG_3004_DP_ENCODER0_P0, BIT(14), BIT(14));
printk(BIOS_DEBUG, "[eDPTX] REG_3004_DP_ENCODER0_P0:%#x\n",
mtk_dp_read(mtk_dp, REG_3004_DP_ENCODER0_P0));
mtk_dp_mask(mtk_dp, REG_3368_DP_ENCODER1_P0, 0x2, BIT(1) | BIT(2));
mtk_dp_mask(mtk_dp, REG_3368_DP_ENCODER1_P0, BIT(15), BIT(15));
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, 0, BIT(8));
/* [5:0]video sram start address */
mtk_dp_mask(mtk_dp, REG_303C_DP_ENCODER0_P0, 0x8, 0x3F);
/* reg_psr_patgen_avt_en patch */
mtk_dp_mask(mtk_dp, REG_3F80_DP_ENC_4P_3, 0, PSR_PATGEN_AVT_EN_FLDMASK);
/* phy D enable */
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, PHY_STATE_W_1_DP_ENC_4P_3,
PHY_STATE_W_1_DP_ENC_4P_3_MASK);
/* reg_dvo_on_ow_en */
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, DVO_ON_W_1_FLDMASK, DVO_ON_W_1_FLDMASK);
/* dp tx encoder reset all sw */
mtk_dp_mask(mtk_dp, REG_3004_DP_ENCODER0_P0, DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0,
DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
printk(BIOS_DEBUG, "[eDPTX] REG_3004_DP_ENCODER0_P0:%#x\n",
mtk_dp_read(mtk_dp, REG_3004_DP_ENCODER0_P0));
mtk_dp_mask(mtk_dp, REG_3004_DP_ENCODER0_P0, 0, BIT(9));
printk(BIOS_DEBUG, "[eDPTX] REG_3004_DP_ENCODER0_P0:%#x\n",
mtk_dp_read(mtk_dp, REG_3004_DP_ENCODER0_P0));
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, 0xff, 0xff);
/* Wait for sw reset to complete */
mdelay(1);
}
void dptx_hal_digital_swreset(struct mtk_dp *mtk_dp)
{
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_TX_CTL_0:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_TX_CTL_0));
mtk_dp_mask(mtk_dp, REG_340C_DP_TRANS_P0, BIT(13), BIT(13));
mdelay(1);
mtk_dp_mask(mtk_dp, REG_340C_DP_TRANS_P0, 0, BIT(13));
mtk_dp_mask(mtk_dp, EDP_TX_TOP_CLKGEN_0, 0xF, 0xF);
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_TX_CTL_0:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_TX_CTL_0));
}
void dptx_hal_swing_emp_reset(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_2004_TOP_SWING_EMP, 0,
DP_TX0_VOLT_SWING_MASK | DP_TX1_VOLT_SWING_MASK | DP_TX2_VOLT_SWING_MASK |
DP_TX3_VOLT_SWING_MASK | DP_TX0_PRE_EMPH_MASK | DP_TX1_PRE_EMPH_MASK |
DP_TX2_PRE_EMPH_MASK | DP_TX3_PRE_EMPH_MASK);
}
void dptx_hal_phy_wait_aux_ldo_ready(struct mtk_dp *mtk_dp)
{
u32 mask = RGS_BG_CORE_EN_READY_MASK | RGS_AUX_LDO_EN_READY_MASK;
if (!retry(WAIT_AUX_READY_RETRY_TIMES,
(mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_GLB_STATUS_02_OFSSET) & mask) == mask,
mdelay(2))) {
printk(BIOS_ERR, "Wait AUX LDO ready timeout!\n");
}
}
void dptx_hal_set_txlane(struct mtk_dp *mtk_dp, u8 value)
{
/* Turn off phy power before phy configure */
mtk_dp_mask(mtk_dp, REG_3F44_DP_ENC_4P_3, PHY_PWR_STATE_OW_EN_DP_ENC_4P_3,
PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK);
mtk_dp_mask(mtk_dp, REG_3F44_DP_ENC_4P_3, BIAS_POWER_ON,
PHY_PWR_STATE_OW_VALUE_DP_ENC_4P_3_MASK);
dptx_hal_phy_wait_aux_ldo_ready(mtk_dp);
mtk_dp_mask(mtk_dp, REG_3F44_DP_ENC_4P_3, 0 << 2, PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK);
if (value == 0)
mtk_dp_mask(mtk_dp, REG_35F0_DP_TRANS_P0, 0, BIT(3) | BIT(2));
else
mtk_dp_mask(mtk_dp, REG_35F0_DP_TRANS_P0, BIT(3), BIT(3) | BIT(2));
assert((value << 2) <= UINT8_MAX);
mtk_dp_mask(mtk_dp, REG_3000_DP_ENCODER0_P0, value, BIT(1) | BIT(0));
mtk_dp_mask(mtk_dp, REG_34A4_DP_TRANS_P0, value << 2, BIT(3) | BIT(2));
}
void dptx_hal_phy_set_swing_preemphasis(struct mtk_dp *mtk_dp, u8 lane_count, u8 *swing_val,
u8 *preemphasis)
{
assert(lane_count <= DPTX_LANE_MAX);
for (int i = 0; i < lane_count; ++i) {
mtk_dp_phy_mask(mtk_dp, dptx_hal_driving_offset[i],
swing_val[i] << EDP_TX_LN_VOLT_SWING_VAL_SHIFT |
preemphasis[i] << EDP_TX_LN_PRE_EMPH_VAL_SHIFT,
EDP_TX_LN_VOLT_SWING_VAL_MASK | EDP_TX_LN_PRE_EMPH_VAL_MASK);
printk(BIOS_DEBUG, "lane(%d), set swing(%u), emp(%u)\n",
i, swing_val[i], preemphasis[i]);
}
}
void dptx_hal_phy_set_idle_pattern(struct mtk_dp *mtk_dp, u8 lane_count, bool enable)
{
u32 val = 0x0;
printk(BIOS_INFO, "lane_count: %x idle pattern enable: %d\n", lane_count, enable);
switch (lane_count) {
case 1:
val = POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK;
break;
case 2:
val = POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE1_OV_DP_TRANS_4P_MASK;
break;
case 4:
val = POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE1_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE2_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE3_OV_DP_TRANS_4P_MASK;
break;
default:
printk(BIOS_ERR, "%s: Unexpected lane count %d\n", __func__, lane_count);
return;
}
mtk_dp_mask(mtk_dp, REG_3580_DP_TRANS_P0, (enable ? val : 0x0) << 8,
POST_MISC_DATA_LANE_OV_DP_TRANS_4P_MASK);
}

View file

@ -0,0 +1,412 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#include <assert.h>
#include <commonlib/bsd/helpers.h>
#include <console/console.h>
#include <delay.h>
#include <device/mmio.h>
#include <edid.h>
#include <soc/addressmap.h>
#include <soc/dp_intf.h>
#include <soc/dptx.h>
#include <soc/dptx_hal.h>
#include <soc/dptx_reg.h>
static void mtk_edp_pattern(struct mtk_dp *mtk_dp, u8 lane_count, u8 pattern)
{
u8 aux_offset;
switch (pattern) {
case DPTX_PATTERN_TPS1:
aux_offset = DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE;
dptx_hal_phy_set_idle_pattern(mtk_dp, lane_count, false);
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN1_EN_DP_TRANS_4P_TPS1,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_TPS2:
aux_offset = DP_TRAINING_PATTERN_2 | DP_LINK_SCRAMBLING_DISABLE;
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN2_EN_DP_TRANS_4P_TPS2,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_TPS3:
aux_offset = DP_TRAINING_PATTERN_3 | DP_LINK_SCRAMBLING_DISABLE;
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN3_EN_DP_TRANS_4P_TPS3,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_TPS4:
aux_offset = DP_TRAINING_PATTERN_4;
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN4_EN_DP_TRANS_4P_TPS4,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_UNKNOWN:
default:
printk(BIOS_ERR, "Set default or unknown pattern\n");
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, 0x0, PATTERN_EN_DP_TRANS_4P_MASK);
return;
}
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &aux_offset);
}
static void update_swing_preemphasis(struct mtk_dp *mtk_dp, u8 lane_count,
u8 dpcd_adjust_req[DP_LANSE_ADJUST_SIZE])
{
u8 swing_val[MAX_LANECOUNT];
u8 preemphasis[MAX_LANECOUNT];
for (int lane = 0; lane < lane_count; lane++) {
u8 val;
int index = lane / 2;
assert(index < DP_LANSE_ADJUST_SIZE);
int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
u8 swing_value = dpcd_adjust_req[index] >> shift;
if (mtk_dp->force_max_swing) {
swing_val[lane] = DPTX_SWING3;
printk(BIOS_INFO, "%s: Force swing setting to %u (500 mV)\n",
__func__, swing_val[lane]);
} else {
swing_val[lane] = swing_value & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
}
preemphasis[lane] = swing_value & DP_ADJUST_PRE_EMPHASIS_LANE0_MASK;
preemphasis[lane] >>= DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
val = swing_val[lane] << DP_TRAIN_VOLTAGE_SWING_SHIFT |
preemphasis[lane] << DP_TRAIN_PRE_EMPHASIS_SHIFT;
if (swing_val[lane] == DPTX_SWING3)
val |= DP_TRAIN_MAX_SWING_REACHED;
if (preemphasis[lane] == DPTX_PREEMPHASIS3)
val |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00103 + lane, 0x1, &val);
}
dptx_hal_phy_set_swing_preemphasis(mtk_dp, lane_count, swing_val, preemphasis);
}
static void dptx_training_changemode(struct mtk_dp *mtk_dp)
{
dptx_hal_phyd_reset(mtk_dp);
dptx_hal_swing_emp_reset(mtk_dp);
mdelay(2);
}
static void mtk_edp_train_setting(struct mtk_dp *mtk_dp,
u8 linkrate, u8 lanecount)
{
u8 lanecount_enhanced_frame;
u8 dpcd_data;
lanecount_enhanced_frame = lanecount | DP_LANE_COUNT_ENHANCED_FRAME_EN;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00100, 0x1, &linkrate);
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00101, 0x1,
&lanecount_enhanced_frame);
if (mtk_dp->train_info.sink_ssc_en) {
dpcd_data = DP_SPREAD_AMP_0_5;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00107, 0x1, &dpcd_data);
dptx_hal_ssc_en(mtk_dp, true);
} else {
dpcd_data = 0x0;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00107, 0x1, &dpcd_data);
dptx_hal_ssc_en(mtk_dp, false);
}
dptx_hal_set_txlane(mtk_dp, lanecount / 2);
dptx_hal_phy_setting(mtk_dp);
printk(BIOS_INFO, "Link train linkrate = %#x, lanecount = %#x\n",
linkrate, lanecount);
}
static void drm_dp_dpcd_read_link_status(struct mtk_dp *mtk_dp, u8 status[DP_LINK_STATUS_SIZE])
{
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00202, DP_LINK_STATUS_SIZE, status);
}
static int mtk_edp_train_cr(struct mtk_dp *mtk_dp, u8 lane_count)
{
u8 lane_adjust[DP_LANSE_ADJUST_SIZE];
u8 link_status[DP_LINK_STATUS_SIZE];
u8 prev_lane_adjust = 0xff;
int train_retries = 0;
int voltage_retries = 0;
u8 buff;
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS1);
/* In DP spec 1.4, the retry count of CR is defined as 10. */
do {
train_retries++;
if (!dptx_hal_hpd_high(mtk_dp)) {
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TRANING_FAIL;
}
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00206, sizeof(lane_adjust),
lane_adjust);
printk(BIOS_DEBUG, "[aux_read] dpcd206 lane_adjust[0]=%#x\n", lane_adjust[0]);
printk(BIOS_DEBUG, "[aux_read] dpcd207 lane_adjust[1]=%#x\n", lane_adjust[1]);
update_swing_preemphasis(mtk_dp, lane_count, lane_adjust);
dptx_link_train_clock_recovery_delay(mtk_dp->rx_cap);
/* Check link status from sink device */
drm_dp_dpcd_read_link_status(mtk_dp, link_status);
if (dptx_clock_recovery_ok(link_status, lane_count)) {
printk(BIOS_INFO, "Link train CR pass\n");
return 0;
}
/*
* In DP spec 1.4, if current voltage level is the same
* with previous voltage level, we need to retry 5 times.
*/
if (prev_lane_adjust == link_status[4]) {
voltage_retries++;
/*
* Condition of CR fail:
* 1. Failed to pass CR using the same voltage
* level over five times.
* 2. Failed to pass CR when the current voltage
* level is the same with previous voltage
* level and reach max voltage level (3).
*/
if (voltage_retries > MTK_DP_TRAIN_VOLTAGE_LEVEL_RETRY ||
(prev_lane_adjust & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) == 3) {
printk(BIOS_ERR, "Link train CR fail\n");
break;
}
} else {
/*
* If the voltage level is changed, we need to
* re-calculate this retry count.
*/
voltage_retries = 0;
}
prev_lane_adjust = link_status[4];
printk(BIOS_INFO, "CR training retries %d\n", voltage_retries);
} while (train_retries < MTK_DP_TRAIN_DOWNSCALE_RETRY);
/* Failed to train CR, and disable pattern. */
buff = DP_TRAINING_PATTERN_DISABLE;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &buff);
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TRANING_FAIL;
}
static int mtk_edp_train_eq(struct mtk_dp *mtk_dp, u8 lane_count)
{
u8 lane_adjust[2];
u8 link_status[DP_LINK_STATUS_SIZE];
int train_retries = 0;
u8 buff;
if (mtk_dp->train_info.tps4)
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS4);
else if (mtk_dp->train_info.tps3)
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS3);
else
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS2);
do {
train_retries++;
if (!dptx_hal_hpd_high(mtk_dp)) {
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TRANING_FAIL;
}
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00206, sizeof(lane_adjust),
lane_adjust);
printk(BIOS_DEBUG, "[aux_read] dpcd206 lane_adjust[0]=%#x\n", lane_adjust[0]);
printk(BIOS_DEBUG, "[aux_read] dpcd207 lane_adjust[1]=%#x\n", lane_adjust[1]);
update_swing_preemphasis(mtk_dp, lane_count, lane_adjust);
dptx_link_train_channel_eq_delay(mtk_dp->rx_cap);
/* check link status from sink device */
drm_dp_dpcd_read_link_status(mtk_dp, link_status);
if (dptx_channel_eq_ok(link_status, lane_count)) {
printk(BIOS_DEBUG, "Link train EQ pass\n");
/* Training done, and disable pattern. */
buff = DP_TRAINING_PATTERN_DISABLE;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &buff);
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return 0;
}
printk(BIOS_INFO, "Link train EQ fail retry:%d\n", train_retries);
} while (train_retries < MTK_DP_TRAIN_DOWNSCALE_RETRY);
/* Failed to train EQ, and disable pattern. */
buff = DP_TRAINING_PATTERN_DISABLE;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &buff);
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TIMEOUT;
}
static int dptx_set_trainingstart(struct mtk_dp *mtk_dp)
{
u8 lanecount;
u8 linkrate;
u8 buffer;
u8 train_limit;
u8 max_linkrate;
int ret;
buffer = 0x1;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00600, 0x1, &buffer);
linkrate = mtk_dp->rx_cap[1];
lanecount = mtk_dp->rx_cap[2] & 0x1F;
printk(BIOS_INFO, "RX support linkrate = %#x, lanecount = %#x\n", linkrate, lanecount);
if (mtk_dp->train_info.sink_extcap_en)
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_02002, 0x1, &buffer);
else
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00200, 0x1, &buffer);
if ((buffer & 0xBF) != 0)
mtk_dp->train_info.sink_count_num = buffer & 0xBF;
dptx_hal_setscramble(mtk_dp, false);
switch (linkrate) {
case DP_LINKRATE_RBR:
case DP_LINKRATE_HBR:
case DP_LINKRATE_HBR2:
case DP_LINKRATE_HBR25:
case DP_LINKRATE_HBR3:
break;
default:
mtk_dp->train_info.linkrate = DP_LINKRATE_HBR3;
break;
};
max_linkrate = linkrate;
printk(BIOS_INFO, "[eDPTX] linkrate = %#x, lanecount = %#x\n", linkrate, lanecount);
for (train_limit = 6; train_limit > 0; train_limit--) {
dptx_training_changemode(mtk_dp);
mtk_edp_train_setting(mtk_dp, linkrate, lanecount);
ret = mtk_edp_train_cr(mtk_dp, lanecount);
if (ret == DPTX_TRANING_FAIL) {
return ret;
} else if (ret) {
/* Reduce link rate */
switch (linkrate) {
case DP_LINKRATE_RBR:
lanecount = lanecount / 2;
linkrate = max_linkrate;
if (lanecount == 0)
return DPTX_TRANING_FAIL;
break;
case DP_LINKRATE_HBR:
linkrate = DP_LINKRATE_RBR;
break;
case DP_LINKRATE_HBR2:
linkrate = DP_LINKRATE_HBR;
break;
case DP_LINKRATE_HBR3:
linkrate = DP_LINKRATE_HBR2;
break;
default:
return DPTX_TRANING_FAIL;
}
continue;
}
ret = mtk_edp_train_eq(mtk_dp, lanecount);
if (ret == DPTX_TIMEOUT) {
return DPTX_TIMEOUT;
} else if (ret) {
/* Reduce lane count */
if (lanecount == DP_LANECOUNT_4)
lanecount = DP_LANECOUNT_2;
else if (lanecount == DP_LANECOUNT_2)
lanecount = DP_LANECOUNT_1;
else
return DPTX_TRANING_FAIL;
continue;
}
printk(BIOS_INFO, "[eDPTX] EQ training pass\n");
/* If we reach here, training is done. */
break;
}
if (train_limit == 0)
return DPTX_TRANING_FAIL;
mtk_dp->train_info.linkrate = linkrate;
mtk_dp->train_info.linklane_count = lanecount;
/*
* After training done, we need to output normal stream instead of TPS,
* so we need to enable scramble.
*/
dptx_hal_setscramble(mtk_dp, true);
dptx_hal_set_ef_mode(mtk_dp, ENABLE_DPTX_EF_MODE);
printk(BIOS_INFO, "%s: done\n", __func__);
return DPTX_PASS;
}
static void dptx_init_port(struct mtk_dp *mtk_dp)
{
dptx_hal_phy_setidlepattern(mtk_dp, true);
dptx_hal_init_setting(mtk_dp);
dptx_hal_aux_setting(mtk_dp);
dptx_hal_digital_setting(mtk_dp);
dptx_hal_phy_init(mtk_dp);
dptx_hal_phy_setting(mtk_dp);
dptx_hal_hpd_detect_setting(mtk_dp);
dptx_hal_digital_swreset(mtk_dp);
dptx_hal_analog_power_en(mtk_dp, true);
dptx_hal_hpd_int_en(mtk_dp, true);
}
int mtk_edp_init(struct mtk_dp *mtk_dp, struct edid *edid)
{
dptx_set_tx_power_con();
dptx_set_26mhz_clock();
udelay(50);
dptx_init_variable(mtk_dp);
dptx_init_port(mtk_dp);
if (!dptx_hal_hpd_high(mtk_dp)) {
printk(BIOS_ERR, "HPD is low\n");
return -1;
}
dptx_check_sinkcap(mtk_dp);
if (dptx_get_edid(mtk_dp, edid) != 0) {
printk(BIOS_ERR, "Failed to get EDID\n");
return -1;
}
if (dptx_set_trainingstart(mtk_dp) != DPTX_PASS) {
printk(BIOS_ERR, "%s: Failed to set training start\n", __func__);
return -1;
}
dp_intf_config(edid);
dptx_video_config(mtk_dp);
return 0;
}
int mtk_edp_enable(struct mtk_dp *mtk_dp)
{
if (!mtk_dp) {
printk(BIOS_ERR, "%s: eDP is not initialized\n", __func__);
return -1;
}
dptx_video_enable(mtk_dp, true);
return 0;
}

View file

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SOC_MEDIATEK_COMMON_DP_DP_INTF_COMMON_H
#define SOC_MEDIATEK_COMMON_DP_DP_INTF_COMMON_H
#ifndef SOC_MEDIATEK_COMMON_DP_DP_INTF_V1_H
#define SOC_MEDIATEK_COMMON_DP_DP_INTF_V1_H
#include <edid.h>
#include <types.h>
@ -264,4 +264,4 @@ extern const struct mtk_dpintf dpintf_data;
void dp_intf_config(const struct edid *edid);
#endif /* SOC_MEDIATEK_COMMON_DP_DP_INTF_COMMON_H */
#endif /* SOC_MEDIATEK_COMMON_DP_DP_INTF_V1_H */

View file

@ -0,0 +1,208 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#ifndef SOC_MEDIATEK_COMMON_DP_DP_INTF_V2_H
#define SOC_MEDIATEK_COMMON_DP_DP_INTF_V2_H
#include <edid.h>
#include <soc/addressmap.h>
#include <types.h>
#define DVO_EN 0x00
#define EN BIT(0)
#define DVO_FORCE_ON BIT(4)
#define LINK_OFF BIT(8)
#define MMSYS1_CG_CLR0 0x108
#define MMSYS1_CG_CLR1 0x118
#define DISP_EDPTX_PWR_CON 0x74
#define DVO_RET 0x04
#define SWRST BIT(0)
#define SWRST_SEL BIT(4)
#define DVO_INTEN 0x08
#define INT_VFP_START_EN BIT(0)
#define INT_VSYNC_START_EN BIT(1)
#define INT_VSYNC_END_EN BIT(2)
#define INT_VDE_START_EN BIT(3)
#define INT_VDE_END_EN BIT(4)
#define INT_WR_INFOQ_REG_EN BIT(5)
#define INT_TARGET_LINE0_EN BIT(6)
#define INT_TARGET_LINE1_EN BIT(7)
#define INT_TARGET_LINE2_EN BIT(8)
#define INT_TARGET_LINE3_EN BIT(9)
#define INT_WR_INFOQ_START_EN BIT(10)
#define INT_WR_INFOQ_END_EN BIT(11)
#define EXT_VSYNC_START_EN BIT(12)
#define EXT_VSYNC_END_EN BIT(13)
#define EXT_VDE_START_EN BIT(14)
#define EXT_VDE_END_EN BIT(15)
#define EXT_VBLANK_END_EN BIT(16)
#define UNDERFLOW_EN BIT(17)
#define INFOQ_ABORT_EN BIT(18)
#define DVO_INTSTA 0x0C
#define INT_VFP_START_STA BIT(0)
#define INT_VSYNC_START_STA BIT(1)
#define INT_VSYNC_END_STA BIT(2)
#define INT_VDE_START_STA BIT(3)
#define INT_VDE_END_STA BIT(4)
#define INT_WR_INFOQ_REG_STA BIT(5)
#define INT_TARGET_LINE0_STA BIT(6)
#define INT_TARGET_LINE1_STA BIT(7)
#define INT_TARGET_LINE2_STA BIT(8)
#define INT_TARGET_LINE3_STA BIT(9)
#define INT_WR_INFOQ_START_STA BIT(10)
#define INT_WR_INFOQ_END_STA BIT(11)
#define EXT_VSYNC_START_STA BIT(12)
#define EXT_VSYNC_END_STA BIT(13)
#define EXT_VDE_START_STA BIT(14)
#define EXT_VDE_END_STA BIT(15)
#define EXT_VBLANK_END_STA BIT(16)
#define INT_UNDERFLOW_STA BIT(17)
#define INFOQ_ABORT_STA BIT(18)
#define DVO_CON 0x10
#define INTL_EN BIT(0)
#define DVO_OUTPUT_SET 0x18
#define OUT_NP_SEL (0x3 << 0)
#define BIT_SWAP BIT(4)
#define CH_SWAP_MASK (0x7 << 5)
#define SWAP_RGB 0x00
#define SWAP_GBR 0x01
#define SWAP_BRG 0x02
#define SWAP_RBG 0x03
#define SWAP_GRB 0x04
#define SWAP_BGR 0x05
#define PXL_SWAP BIT(8)
#define R_MASK BIT(12)
#define G_MASK BIT(13)
#define B_MASK BIT(14)
#define DE_MASK BIT(16)
#define HS_MASK BIT(17)
#define VS_MASK BIT(18)
#define HS_INV BIT(19)
#define VS_INV BIT(20)
#define DVO_SRC_SIZE 0x20
#define SRC_HSIZE_SHIFT 0
#define SRC_HSIZE_MASK (0xFFFF << 0)
#define SRC_VSIZE_SHIFT 16
#define SRC_VSIZE_MASK (0xFFFF << 16)
#define DVO_PIC_SIZE 0x24
#define PIC_HSIZE_SHIFT 0
#define PIC_HSIZE_MASK (0xFFFF << 0)
#define PIC_VSIZE_SHIFT 16
#define PIC_VSIZE_MASK (0xFFFF << 16)
#define DVO_TGEN_H0 0x50
#define HFP_SHIFT 0
#define HFP_MASK (0xFFFF << 0)
#define HSYNC_SHIFT 16
#define HSYNC_MASK (0xFFFF << 16)
#define DVO_TGEN_H1 0x54
#define HSYNC2ACT_SHIFT 0
#define HSYNC2ACT_MASK (0xFFFF << 0)
#define HACT_SHIFT 16
#define HACT_MASK (0xFFFF << 16)
#define DVO_TGEN_V0 0x58
#define VFP_SHIFT 0
#define VFP_MASK (0xFFFF << 0)
#define VSYNC_SHIFT 16
#define VSYNC_MASK (0xFFFF << 16)
#define DVO_TGEN_V1 0x5C
#define VSYNC2ACT_SHIFT 0
#define VSYNC2ACT_MASK (0xFFFF << 0)
#define VACT_SHIFT 16
#define VACT_MASK (0xFFFF << 16)
#define DVO_TGEN_INFOQ_LATENCY 0x80
#define INFOQ_START_LATENCY 0
#define INFOQ_START_LATENCY_MASK (0xFFFF << 0)
#define INFOQ_END_LATENCY 16
#define INFOQ_END_LATENCY_MASK (0xFFFF << 16)
#define DVO_BUF_CON0 0x220
#define DISP_BUF_EN BIT(0)
#define FIFO_UNDERFLOW_DONE_BLOCK BIT(4)
#define DVO_TGEN_V_LAST_TRAILING_BLANK 0x6C
#define V_LAST_TRAILING_BLANK 0
#define V_LAST_TRAILING_BLANK_MASK (0xFFFF << 0)
#define DVO_TGEN_OUTPUT_DELAY_LINE 0x7C
#define EXT_TG_DLY_LINE 0
#define EXT_TG_DLY_LINE_MASK (0xFFFF << 0)
#define DVO_PATTERN_CTRL 0x100
#define PRE_PAT_EN BIT(0)
#define PRE_PAT_SEL_MASK (0x7 << 4)
#define COLOR_BAR (0x4 << 4)
#define PRE_PAT_FORCE_ON BIT(8)
#define DVO_PATTERN_COLOR 0x104
#define PAT_R (0x3FF << 0)
#define PAT_G (0x3FF << 10)
#define PAT_B (0x3FF << 20)
#define DVO_SHADOW_CTRL 0x190
#define FORCE_COMMIT BIT(0)
#define BYPASS_SHADOW BIT(1)
#define READ_WRK_REG BIT(2)
#define DVO_SIZE 0x18
#define DVO_TGEN_VWIDTH 0x28
#define DVO_TGEN_VPORCH 0x2C
#define DVO_TGEN_HPORCH 0x24
#define DVO_TGEN_HWIDTH 0x20
#define DVO_BUF_SODI_HIGHT 0x230
#define DVO_BUF_SODI_LOW 0x234
enum mtk_dvo_golden_setting_level {
MTK_DVO_FHD_60FPS_1920 = 0,
MTK_DVO_FHD_60FPS_2180,
MTK_DVO_FHD_60FPS_2400,
MTK_DVO_FHD_60FPS_2520,
MTK_DVO_FHD_90FPS,
MTK_DVO_FHD_120FPS,
MTK_DVO_WQHD_60FPS,
MTK_DVO_WQHD_120FPS,
MTK_DVO_8K_30FPS,
MTK_DVO_GSL_MAX,
};
struct mtk_dvo_gs_info {
u32 dvo_buf_sodi_high;
u32 dvo_buf_sodi_low;
};
enum TVDPLL_CLK {
TVDPLL_PLL = 0,
TVDPLL_D16 = 1,
TVDPLL_D8 = 2,
TVDPLL_D4 = 3,
};
struct mtk_dvo {
void *regs;
void *regs_ck;
void *regs_mm;
enum mtk_dvo_golden_setting_level gs_level;
};
struct mtk_dvo_sync_param {
u32 sync_width;
u32 front_porch;
u32 back_porch;
};
void dp_intf_config(const struct edid *edid);
#endif /* SOC_MEDIATEK_COMMON_DP_DP_INTF__V2_H */

View file

@ -3,6 +3,8 @@
#ifndef SOC_MEDIATEK_COMMON_DP_DPTX_COMMON_H
#define SOC_MEDIATEK_COMMON_DP_DPTX_COMMON_H
#include <types.h>
#define DP_LANSE_ADJUST_SIZE 2
#define DPTX_TBC_BUF_READSTARTADRTHRD 0x08
#define ENABLE_DPTX_EF_MODE 0x1
@ -218,6 +220,8 @@ struct mtk_dp {
int mtk_edp_init(struct mtk_dp *mtk_dp, struct edid *edid);
int mtk_edp_enable(struct mtk_dp *mtk_dp);
void dptx_set_tx_power_con(void);
void dptx_set_26mhz_clock(void);
bool dptx_auxread_dpcd(struct mtk_dp *mtk_dp, u8 cmd, u32 dpcd_addr,
size_t length, u8 *rxbuf);
bool dptx_auxwrite_dpcd(struct mtk_dp *mtk_dp, u8 cmd, u32 dpcd_addr,

View file

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SOC_MEDIATEK_COMMON_DP_DPTX_HAL_V1_H
#define SOC_MEDIATEK_COMMON_DP_DPTX_HAL_V1_H
#include <soc/dptx_hal_common.h>
#endif /* SOC_MEDIATEK_COMMON_DP_DPTX_HAL_V1_H */

View file

@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#ifndef SOC_MEDIATEK_COMMON_DP_DPTX_HAL_V2_H
#define SOC_MEDIATEK_COMMON_DP_DPTX_HAL_V2_H
#include <soc/dptx_hal_common.h>
#define MTK_DP_TRAIN_VOLTAGE_LEVEL_RETRY 5
#define MTK_DP_TRAIN_DOWNSCALE_RETRY 10
enum {
DPTX_PATTERN_TPS1 = 1,
DPTX_PATTERN_TPS2,
DPTX_PATTERN_TPS3,
DPTX_PATTERN_TPS4,
DPTX_PATTERN_UNKNOWN,
};
extern const int dptx_hal_driving_offset[];
extern const int dptx_hal_driving_offset_size;
void dptx_hal_swing_emp_reset(struct mtk_dp *mtk_dp);
void dptx_hal_phy_init(struct mtk_dp *mtk_dp);
void dptx_hal_phy_wait_aux_ldo_ready(struct mtk_dp *mtk_dp);
void dptx_hal_phy_set_idle_pattern(struct mtk_dp *mtk_dp, u8 lane_count, bool enable);
void dptx_hal_phy_set_lanes(struct mtk_dp *mtk_dp, u8 lane_count);
void dptx_hal_phy_set_swing_preemphasis(struct mtk_dp *mtk_dp, u8 lane_count, u8 *swing_val,
u8 *preemphasis);
#endif /* SOC_MEDIATEK_COMMON_DP_DPTX_HAL_V2_H */

View file

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SOC_MEDIATEK_COMMON_DP_DPTX_REG_V1_H
#define SOC_MEDIATEK_COMMON_DP_DPTX_REG_V1_H
#include <soc/dptx_reg_common.h>
#endif /* SOC_MEDIATEK_COMMON_DP_DPTX_REG_V1_H */

View file

@ -0,0 +1,210 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#ifndef SOC_MEDIATEK_COMMON_DP_DPTX_REG_V2_H
#define SOC_MEDIATEK_COMMON_DP_DPTX_REG_V2_H
#include <soc/dptx_reg_common.h>
#define WAIT_AUX_READY_RETRY_TIMES 5
#define PHYD_DIG_GLB_OFFSET 0x1400
#define SEC_OFFSET 0x4000
#define IPMUX_CONTROL (PHYD_DIG_GLB_OFFSET + 0x98)
#define EDPTX_DSI_PHYD_SEL_FLDMASK 0x1
#define EDPTX_DSI_PHYD_SEL_FLDMASK_POS 0
#define TOP_OFFSET 0x2000
#define MTK_DP_TOP_IRQ_MASK 0x202C
#define ENCODER_IRQ_MSK BIT(0)
#define TRANS_IRQ_MSK BIT(1)
#define EDP_TX_TOP_CLKGEN_0 0x2074
#define DP_PHY_DIG_PLL_CTL_1 0x1414
#define DP_PHY_DIG_SW_RST 0x1438
#define RGS_BG_CORE_EN_READY_MASK BIT(0)
#define REG_2004_TOP_SWING_EMP 0x2004
#define DP_TX0_VOLT_SWING_MASK GENMASK(1, 0)
#define DP_TX0_PRE_EMPH_MASK GENMASK(3, 2)
#define DP_TX1_VOLT_SWING_MASK GENMASK(9, 8)
#define DP_TX1_PRE_EMPH_MASK GENMASK(11, 10)
#define DP_TX2_VOLT_SWING_MASK GENMASK(17, 16)
#define DP_TX2_PRE_EMPH_MASK GENMASK(19, 18)
#define DP_TX3_VOLT_SWING_MASK GENMASK(25, 24)
#define DP_TX3_PRE_EMPH_MASK GENMASK(27, 26)
#define REG_3000_DP_ENCODER0_P0 0x3000
#define REG_BS_SYMBOL_CNT_RESET BIT(7)
#define REG_3004_DP_ENCODER0_P0 0x3004
#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0 BIT(9)
#define REG_3008_DP_ENCODER0_P0 0x3008
#define REG_300C_DP_ENCODER0_P0 0x300C
#define REG_3010_DP_ENCODER0_P0 0x3010
#define REG_3014_DP_ENCODER0_P0 0x3014
#define REG_3018_DP_ENCODER0_P0 0x3018
#define REG_301C_DP_ENCODER0_P0 0x301C
#define REG_3020_DP_ENCODER0_P0 0x3020
#define REG_3024_DP_ENCODER0_P0 0x3024
#define REG_3028_DP_ENCODER0_P0 0x3028
#define HSP_SW_DP_ENCODER0_P0_FLDMASK 0x8000
#define HSP_SW_DP_ENCODER0_P0_FLDMASK_POS 15
#define REG_302C_DP_ENCODER0_P0 0x302C
#define REG_3030_DP_ENCODER0_P0 0x3030
#define REG_3034_DP_ENCODER0_P0 0x3034
#define DP_TEST_COLOR_FORMAT_MASK (3 << 1)
#define DP_TEST_COLOR_FORMAT_SHIFT 1
#define REG_303C_DP_ENCODER0_P0 0x303C
#define REG_3040_DP_ENCODER0_P0 0x3040
#define REG_3044_DP_ENCODER0_P0 0x3044
#define REG_3048_DP_ENCODER0_P0 0x3048
#define REG_304C_DP_ENCODER0_P0 0x304C
#define VBID_VIDEO_MUTE_DP_ENC0_4P_MASK BIT(2)
#define REG_3050_DP_ENCODER0_P0 0x3050
#define REG_3054_DP_ENCODER0_P0 0x3054
#define REG_3064_DP_ENCODER0_P0 0x3064
#define REG_3154_DP_ENCODER0_P0 0x3154
#define REG_3158_DP_ENCODER0_P0 0x3158
#define REG_315C_DP_ENCODER0_P0 0x315C
#define REG_3160_DP_ENCODER0_P0 0x3160
#define REG_3164_DP_ENCODER0_P0 0x3164
#define REG_3168_DP_ENCODER0_P0 0x3168
#define REG_316C_DP_ENCODER0_P0 0x316C
#define REG_3170_DP_ENCODER0_P0 0x3170
#define REG_3174_DP_ENCODER0_P0 0x3174
#define REG_3178_DP_ENCODER0_P0 0x3178
#define REG_31EC_DP_ENCODER0_P0 0x31EC
#define REG_3300_DP_ENCODER1_P0 0x3300
#define REG_3364_DP_ENCODER1_P0 0x3364
#define REG_3368_DP_ENCODER1_P0 0x3368
#define BS2BS_MODE_DP_ENC1_4P_VAL 1
#define BS2BS_MODE_DP_ENCODER1_P0_FLDMASK 0x3000
#define DP_I_MODE_ENABLE BIT(6)
#define REG_33C0_DP_ENCODER1_P0 0x33C0
#define REG_33C4_DP_ENCODER1_P0 0x33C4
#define REG_33C8_DP_ENCODER1_P0 0x33C8
#define REG_3400_DP_TRANS_P0 0x3400
#define PATTERN1_EN_DP_TRANS_4P_TPS1 BIT(12)
#define PATTERN2_EN_DP_TRANS_4P_TPS2 BIT(13)
#define PATTERN3_EN_DP_TRANS_4P_TPS3 BIT(14)
#define PATTERN4_EN_DP_TRANS_4P_TPS4 BIT(15)
#define PATTERN_EN_DP_TRANS_4P_MASK GENMASK(15, 12)
#define REG_3404_DP_TRANS_P0 0x3404
#define REG_340C_DP_TRANS_P0 0x340C
#define REG_3418_DP_TRANS_P0 0x3418
#define REG_342C_DP_TRANS_P0 0x342C
#define REG_34A4_DP_TRANS_P0 0x34A4
#define REG_3540_DP_TRANS_P0 0x3540
#define REG_3580_DP_TRANS_P0 0x3580
#define POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK BIT(8)
#define POST_MISC_DATA_LANE1_OV_DP_TRANS_4P_MASK BIT(9)
#define POST_MISC_DATA_LANE2_OV_DP_TRANS_4P_MASK BIT(10)
#define POST_MISC_DATA_LANE3_OV_DP_TRANS_4P_MASK BIT(11)
#define POST_MISC_DATA_LANE_OV_DP_TRANS_4P_MASK GENMASK(11, 8)
#define REG_35F0_DP_TRANS_P0 0x35F0
#define REG_360C_AUX_TX_P0 0x360C
#define REG_3614_AUX_TX_P0 0x3614
#define AUX_RX_UI_CNT_THR_AUX_FOR_26M 13
#define REG_3618_AUX_TX_P0 0x3618
#define AUX_RX_FIFO_FULL_AUX_TX_P0_FLDMASK 0x200
#define REG_3620_AUX_TX_P0 0x3620
#define AUX_RD_MODE_AUX_TX_P0_FLDMASK 0x200
#define AUX_RD_MODE_AUX_TX_P0_FLDMASK_POS 9
#define AUX_RX_FIFO_READ_PULSE_TX_P0_FLDMASK 0x100
#define AUX_RX_FIFO_R_PULSE_TX_P0_FLDMASK_POS 8
#define REG_3624_AUX_TX_P0 0x3624
#define REG_3628_AUX_TX_P0 0x3628
#define REG_362C_AUX_TX_P0 0x362C
#define AUX_NO_LENGTH_AUX_TX_P0_FLDMASK 0x1
#define AUX_NO_LENGTH_AUX_TX_P0_FLDMASK_POS 0
#define REG_3630_AUX_TX_P0 0x3630
#define AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK 0x8
#define AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK_POS 3
#define REG_3634_AUX_TX_P0 0x3634
#define AUX_TX_OVER_SAMPLE_RATE_FOR_26M 25
#define REG_3640_AUX_TX_P0 0x3640
#define AUX_RX_RECV_COMPLETE_IRQ_TX_P0_FLDMASK 0x40
#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_FLDMASK 0x1
#define REG_3644_AUX_TX_P0 0x3644
#define REG_3648_AUX_TX_P0 0x3648
#define REG_364C_AUX_TX_P0 0x364C
#define HPD_INT_THD_FLDMASK_VAL 0x32
#define HPD_INT_THD_FLDMASK 0x3F0
#define REG_3650_AUX_TX_P0 0x3650
#define MCU_REQUEST_DATA_NUM_AUX_TX_P0_FLDMASK 0xf000
#define MCU_REQ_DATA_NUM_AUX_TX_P0_FLDMASK_POS 12
#define MCU_ACK_TRANSACTION_COMPLETE_AUX_TX_P0_FLDMASK 0x100
#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_FLDMASK_POS 8
#define REG_3658_AUX_TX_P0 0x3658
#define REG_366C_AUX_TX_P0 0x366C
#define XTAL_FREQ_DP_TX_AUX_366C_VALUE 0x68
#define XTAL_FREQ_DP_TX_AUX_366C_MASK 0xFF00
#define REG_367C_AUX_TX_P0 0x367C
#define HPD_CONN_THD_AUX_TX_P0_FLDMASK_POS 5
#define HPD_CONN_THD_AUX_TX_P0_FLDMASK 0x3c0
#define REG_3690_AUX_TX_P0 0x3690
#define RX_REPLY_COMPLETE_MODE_AUX_TX_4P BIT(8)
#define REG_36A0_AUX_TX_4P 0x36A0
#define REG_3704_AUX_TX_P0 0x3704
#define AUX_TX_FIFO_WRITE_DATA_TOGGLE_AUX_TX_P0_FLDMASK 0x2
#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK 0x4
#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK_POS 2
#define REG_3708_AUX_TX_P0 0x3708
#define REG_37A0_AUX_TX_P0 0x37A0
#define HPD_DISC_THD_AUX_TX_P0_FLDMASK_POS 5
#define HPD_DISC_THD_AUX_TX_P0_FLDMASK 0xF0
#define REG_37C8_AUX_TX_P0 0x37C8
#define MTK_ATOP_EN_AUX_TX_4P BIT(0)
#define REG_3F04_DP_ENC_4P_3 0x3F04
#define REG_3F08_DP_ENC_4P_3 0x3F08
#define REG_3F0C_DP_ENC_4P_3 0x3F0C
#define REG_3F10_DP_ENC_4P_3 0x3F10
#define REG_3F28_DP_ENC_4P_3 0x3F28
#define REG_3F44_DP_ENC_4P_3 0x3F44
#define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3 BIT(2)
#define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK BIT(2)
#define BIAS_POWER_ON (0x01 << 3)
#define PHY_PWR_STATE_OW_VALUE_DP_ENC_4P_3_MASK GENMASK(4, 3)
#define REG_3F80_DP_ENC_4P_3 0x3F80
#define PSR_PATGEN_AVT_EN_FLDMASK 0x20
#define REG_3FF8_DP_ENC_4P_3 0x3FF8
#define PHY_STATE_W_1_DP_ENC_4P_3 BIT(6)
#define PHY_STATE_W_1_DP_ENC_4P_3_MASK BIT(6)
#define DVO_ON_W_1_FLDMASK 0x20
#define XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_VALUE 25
#define XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_MASK 0x3E00
#define PHYD_DIG_LAN0_OFFSET 0x1000
#define PHYD_DIG_LAN1_OFFSET 0x1100
#define PHYD_DIG_LAN2_OFFSET 0x1200
#define PHYD_DIG_LAN3_OFFSET 0x1300
#define EDP_TX_LN_VOLT_SWING_VAL_MASK GENMASK(2, 1)
#define EDP_TX_LN_VOLT_SWING_VAL_SHIFT 1
#define DP_TX_TOP_APB_WSTRB (TOP_OFFSET + 0x10)
#define DP_TX_TOP_RESET_AND_PROBE (TOP_OFFSET + 0x20)
#define DP_TX_SECURE_REG11 (SEC_OFFSET + 0x2C)
#define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7)
#define DPCD_00000 0x00000
#define DPCD_0000E 0x0000E
#define DPCD_00021 0x00021
#define DPCD_00100 0x00100
#define DPCD_00101 0x00101
#define DPCD_00102 0x00102
#define DP_TRAINING_PATTERN_DISABLE 0
#define DP_TRAINING_PATTERN_1 1
#define DP_TRAINING_PATTERN_2 2
#define DP_TRAINING_PATTERN_3 3 /* 1.2 */
#define DP_TRAINING_PATTERN_4 7 /* 1.4 */
#define DP_LINK_SCRAMBLING_DISABLE BIT(5)
#define DPCD_00103 0x00103
#define DP_TRAIN_VOLTAGE_SWING_SHIFT 0
#define DP_TRAIN_MAX_SWING_REACHED BIT(2)
#define DP_TRAIN_PRE_EMPHASIS_SHIFT 3
#define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED BIT(5)
#define DPCD_00107 0x00107
#define DP_SPREAD_AMP_0_5 BIT(4)
#define DPCD_00200 0x00200
#define DPCD_00202 0x00202
#define DPCD_00206 0x00206
#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03
#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0C
#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2
#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
#define DPCD_00600 0x00600
#define DPCD_02002 0x02002
#define DPCD_02003 0x02003
#endif /* SOC_MEDIATEK_COMMON_DP_DPTX_REG_V2_H */

View file

@ -39,8 +39,9 @@ ramstage-y += ../common/ddp.c ddp.c
ramstage-y += ../common/devapc.c devapc.c
ramstage-y += ../common/dfd.c
ramstage-y += ../common/display.c
ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_hal_common.c
ramstage-y += ../common/dp/dp_intf.c ../common/dp/dptx.c ../common/dp/dptx_hal.c dp_intf.c
ramstage-y += ../common/dp/dp_intf_v1.c dp_intf.c
ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_v1.c
ramstage-y += ../common/dp/dptx_hal_common.c ../common/dp/dptx_hal_v1.c
ramstage-y += ../common/dpm.c
ramstage-y += ../common/dpm_v1.c
ramstage-$(CONFIG_DPM_FOUR_CHANNEL) += ../common/dpm_4ch.c

View file

@ -3,6 +3,6 @@
#ifndef __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DP_INTF_H__
#define __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DP_INTF_H__
#include <soc/dp_intf_common.h>
#include <soc/dp_intf_v1.h>
#endif /* __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DP_INTF_H__ */

View file

@ -3,6 +3,6 @@
#ifndef __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DPTX_HAL_H__
#define __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DPTX_HAL_H__
#include <soc/dptx_hal_common.h>
#include <soc/dptx_hal_v1.h>
#endif /* __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DPTX_HAL_H__ */

View file

@ -3,6 +3,6 @@
#ifndef __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DPTX_REG_H__
#define __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DPTX_REG_H__
#include <soc/dptx_reg_common.h>
#include <soc/dptx_reg_v1.h>
#endif /* __SOC_MEDIATEK_MT8188_INCLUDE_SOC_DPTX_REG_H__ */

View file

@ -51,8 +51,9 @@ ramstage-y += ../common/display.c
ramstage-y += ../common/dpm.c
ramstage-y += ../common/dpm_v1.c
ramstage-$(CONFIG_DPM_FOUR_CHANNEL) += ../common/dpm_4ch.c
ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_hal_common.c
ramstage-y += ../common/dp/dp_intf.c ../common/dp/dptx.c ../common/dp/dptx_hal.c dp_intf.c
ramstage-y += ../common/dp/dp_intf_v1.c dp_intf.c
ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_v1.c
ramstage-y += ../common/dp/dptx_hal_common.c ../common/dp/dptx_hal_v1.c
ramstage-y += emi.c
ramstage-y += hdmi.c
ramstage-y += ../common/l2c_ops.c

View file

@ -3,6 +3,6 @@
#ifndef __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DP_INTF_H__
#define __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DP_INTF_H__
#include <soc/dp_intf_common.h>
#include <soc/dp_intf_v1.h>
#endif /* __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DP_INTF_H__ */

View file

@ -3,6 +3,6 @@
#ifndef __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DPTX_HAL_H__
#define __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DPTX_HAL_H__
#include <soc/dptx_hal_common.h>
#include <soc/dptx_hal_v1.h>
#endif /* __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DPTX_HAL_H__ */

View file

@ -3,6 +3,6 @@
#ifndef __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DPTX_REG_H__
#define __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DPTX_REG_H__
#include <soc/dptx_reg_common.h>
#include <soc/dptx_reg_v1.h>
#endif /* __SOC_MEDIATEK_MT8195_INCLUDE_SOC_DPTX_REG_H__ */

View file

@ -60,8 +60,9 @@ ramstage-y += ddp.c
ramstage-y += ../common/display.c
ramstage-y += ../common/dpm.c
ramstage-y += ../common/dpm_v2.c
ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_hal_common.c
ramstage-y += dptx.c dptx_hal.c dp_intf.c
ramstage-y += ../common/dp/dp_intf_v2.c
ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_v2.c dptx.c
ramstage-y += ../common/dp/dptx_hal_common.c ../common/dp/dptx_hal_v2.c dptx_hal.c
ramstage-y += ../common/dramc_info.c
ramstage-y += ../common/early_init.c
ramstage-y += ../common/emi.c

View file

@ -1,415 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#include <assert.h>
#include <commonlib/bsd/helpers.h>
#include <console/console.h>
#include <delay.h>
#include <device/mmio.h>
#include <edid.h>
#include <soc/addressmap.h>
#include <soc/dp_intf.h>
#include <soc/dptx.h>
#include <soc/dptx_hal.h>
#include <soc/dptx_reg.h>
#include <soc/dp_intf.h>
static void mtk_edp_pattern(struct mtk_dp *mtk_dp, u8 lane_count, u8 pattern)
{
u8 aux_offset;
switch (pattern) {
case DPTX_PATTERN_TPS1:
aux_offset = DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE;
dptx_hal_phy_set_idle_pattern(mtk_dp, lane_count, false);
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN1_EN_DP_TRANS_4P_TPS1,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_TPS2:
aux_offset = DP_TRAINING_PATTERN_2 | DP_LINK_SCRAMBLING_DISABLE;
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN2_EN_DP_TRANS_4P_TPS2,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_TPS3:
aux_offset = DP_TRAINING_PATTERN_3 | DP_LINK_SCRAMBLING_DISABLE;
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN3_EN_DP_TRANS_4P_TPS3,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_TPS4:
aux_offset = DP_TRAINING_PATTERN_4;
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, PATTERN4_EN_DP_TRANS_4P_TPS4,
PATTERN_EN_DP_TRANS_4P_MASK);
break;
case DPTX_PATTERN_UNKNOWN:
default:
printk(BIOS_ERR, "Set default or unknown pattern\n");
mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, 0x0, PATTERN_EN_DP_TRANS_4P_MASK);
return;
}
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &aux_offset);
}
static void update_swing_preemphasis(struct mtk_dp *mtk_dp, u8 lane_count,
u8 dpcd_adjust_req[DP_LANSE_ADJUST_SIZE])
{
u8 swing_val[MAX_LANECOUNT];
u8 preemphasis[MAX_LANECOUNT];
for (int lane = 0; lane < lane_count; lane++) {
u8 val;
int index = lane / 2;
assert(index < DP_LANSE_ADJUST_SIZE);
int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
u8 swing_value = dpcd_adjust_req[index] >> shift;
if (mtk_dp->force_max_swing) {
swing_val[lane] = DPTX_SWING3;
printk(BIOS_INFO, "%s: Force swing setting to %u (500 mV)\n",
__func__, swing_val[lane]);
} else {
swing_val[lane] = swing_value & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
}
preemphasis[lane] = swing_value & DP_ADJUST_PRE_EMPHASIS_LANE0_MASK;
preemphasis[lane] >>= DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
val = swing_val[lane] << DP_TRAIN_VOLTAGE_SWING_SHIFT |
preemphasis[lane] << DP_TRAIN_PRE_EMPHASIS_SHIFT;
if (swing_val[lane] == DPTX_SWING3)
val |= DP_TRAIN_MAX_SWING_REACHED;
if (preemphasis[lane] == DPTX_PREEMPHASIS3)
val |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00103 + lane, 0x1, &val);
}
dptx_hal_phy_set_swing_preemphasis(mtk_dp, lane_count, swing_val, preemphasis);
}
static void dptx_training_changemode(struct mtk_dp *mtk_dp)
{
dptx_hal_phyd_reset(mtk_dp);
dptx_hal_swing_emp_reset(mtk_dp);
mdelay(2);
}
static void mtk_edp_train_setting(struct mtk_dp *mtk_dp,
u8 linkrate, u8 lanecount)
{
u8 lanecount_enhanced_frame;
u8 dpcd_data;
lanecount_enhanced_frame = lanecount | DP_LANE_COUNT_ENHANCED_FRAME_EN;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00100, 0x1, &linkrate);
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00101, 0x1,
&lanecount_enhanced_frame);
if (mtk_dp->train_info.sink_ssc_en) {
dpcd_data = DP_SPREAD_AMP_0_5;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00107, 0x1, &dpcd_data);
dptx_hal_ssc_en(mtk_dp, true);
} else {
dpcd_data = 0x0;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00107, 0x1, &dpcd_data);
dptx_hal_ssc_en(mtk_dp, false);
}
dptx_hal_set_txlane(mtk_dp, lanecount / 2);
dptx_hal_phy_setting(mtk_dp);
printk(BIOS_INFO, "Link train linkrate = %#x, lanecount = %#x\n",
linkrate, lanecount);
}
static void drm_dp_dpcd_read_link_status(struct mtk_dp *mtk_dp, u8 status[DP_LINK_STATUS_SIZE])
{
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00202, DP_LINK_STATUS_SIZE, status);
}
static int mtk_edp_train_cr(struct mtk_dp *mtk_dp, u8 lane_count)
{
u8 lane_adjust[DP_LANSE_ADJUST_SIZE];
u8 link_status[DP_LINK_STATUS_SIZE];
u8 prev_lane_adjust = 0xff;
int train_retries = 0;
int voltage_retries = 0;
u8 buff;
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS1);
/* In DP spec 1.4, the retry count of CR is defined as 10. */
do {
train_retries++;
if (!dptx_hal_hpd_high(mtk_dp)) {
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TRANING_FAIL;
}
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00206, sizeof(lane_adjust),
lane_adjust);
printk(BIOS_DEBUG, "[aux_read] dpcd206 lane_adjust[0]=%#x\n", lane_adjust[0]);
printk(BIOS_DEBUG, "[aux_read] dpcd207 lane_adjust[1]=%#x\n", lane_adjust[1]);
update_swing_preemphasis(mtk_dp, lane_count, lane_adjust);
dptx_link_train_clock_recovery_delay(mtk_dp->rx_cap);
/* Check link status from sink device */
drm_dp_dpcd_read_link_status(mtk_dp, link_status);
if (dptx_clock_recovery_ok(link_status, lane_count)) {
printk(BIOS_INFO, "Link train CR pass\n");
return 0;
}
/*
* In DP spec 1.4, if current voltage level is the same
* with previous voltage level, we need to retry 5 times.
*/
if (prev_lane_adjust == link_status[4]) {
voltage_retries++;
/*
* Condition of CR fail:
* 1. Failed to pass CR using the same voltage
* level over five times.
* 2. Failed to pass CR when the current voltage
* level is the same with previous voltage
* level and reach max voltage level (3).
*/
if (voltage_retries > MTK_DP_TRAIN_VOLTAGE_LEVEL_RETRY ||
(prev_lane_adjust & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) == 3) {
printk(BIOS_ERR, "Link train CR fail\n");
break;
}
} else {
/*
* If the voltage level is changed, we need to
* re-calculate this retry count.
*/
voltage_retries = 0;
}
prev_lane_adjust = link_status[4];
printk(BIOS_INFO, "CR training retries %d\n", voltage_retries);
} while (train_retries < MTK_DP_TRAIN_DOWNSCALE_RETRY);
/* Failed to train CR, and disable pattern. */
buff = DP_TRAINING_PATTERN_DISABLE;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &buff);
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TRANING_FAIL;
}
static int mtk_edp_train_eq(struct mtk_dp *mtk_dp, u8 lane_count)
{
u8 lane_adjust[2];
u8 link_status[DP_LINK_STATUS_SIZE];
int train_retries = 0;
u8 buff;
if (mtk_dp->train_info.tps4)
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS4);
else if (mtk_dp->train_info.tps3)
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS3);
else
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_TPS2);
do {
train_retries++;
if (!dptx_hal_hpd_high(mtk_dp)) {
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TRANING_FAIL;
}
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00206, sizeof(lane_adjust),
lane_adjust);
printk(BIOS_DEBUG, "[aux_read] dpcd206 lane_adjust[0]=%#x\n", lane_adjust[0]);
printk(BIOS_DEBUG, "[aux_read] dpcd207 lane_adjust[1]=%#x\n", lane_adjust[1]);
update_swing_preemphasis(mtk_dp, lane_count, lane_adjust);
dptx_link_train_channel_eq_delay(mtk_dp->rx_cap);
/* check link status from sink device */
drm_dp_dpcd_read_link_status(mtk_dp, link_status);
if (dptx_channel_eq_ok(link_status, lane_count)) {
printk(BIOS_DEBUG, "Link train EQ pass\n");
/* Training done, and disable pattern. */
buff = DP_TRAINING_PATTERN_DISABLE;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &buff);
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return 0;
}
printk(BIOS_INFO, "Link train EQ fail retry:%d\n", train_retries);
} while (train_retries < MTK_DP_TRAIN_DOWNSCALE_RETRY);
/* Failed to train EQ, and disable pattern. */
buff = DP_TRAINING_PATTERN_DISABLE;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00102, 0x1, &buff);
mtk_edp_pattern(mtk_dp, lane_count, DPTX_PATTERN_UNKNOWN);
return DPTX_TIMEOUT;
}
static int dptx_set_trainingstart(struct mtk_dp *mtk_dp)
{
u8 lanecount;
u8 linkrate;
u8 buffer;
u8 train_limit;
u8 max_linkrate;
int ret;
buffer = 0x1;
dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00600, 0x1, &buffer);
linkrate = mtk_dp->rx_cap[1];
lanecount = mtk_dp->rx_cap[2] & 0x1F;
printk(BIOS_INFO, "RX support linkrate = %#x, lanecount = %#x\n", linkrate, lanecount);
if (mtk_dp->train_info.sink_extcap_en)
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_02002, 0x1, &buffer);
else
dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, DPCD_00200, 0x1, &buffer);
if ((buffer & 0xBF) != 0)
mtk_dp->train_info.sink_count_num = buffer & 0xBF;
dptx_hal_setscramble(mtk_dp, false);
switch (linkrate) {
case DP_LINKRATE_RBR:
case DP_LINKRATE_HBR:
case DP_LINKRATE_HBR2:
case DP_LINKRATE_HBR25:
case DP_LINKRATE_HBR3:
break;
default:
mtk_dp->train_info.linkrate = DP_LINKRATE_HBR3;
break;
};
max_linkrate = linkrate;
printk(BIOS_INFO, "[eDPTX] linkrate = %#x, lanecount = %#x\n", linkrate, lanecount);
for (train_limit = 6; train_limit > 0; train_limit--) {
dptx_training_changemode(mtk_dp);
mtk_edp_train_setting(mtk_dp, linkrate, lanecount);
ret = mtk_edp_train_cr(mtk_dp, lanecount);
if (ret == DPTX_TRANING_FAIL) {
return ret;
} else if (ret) {
/* Reduce link rate */
switch (linkrate) {
case DP_LINKRATE_RBR:
lanecount = lanecount / 2;
linkrate = max_linkrate;
if (lanecount == 0)
return DPTX_TRANING_FAIL;
break;
case DP_LINKRATE_HBR:
linkrate = DP_LINKRATE_RBR;
break;
case DP_LINKRATE_HBR2:
linkrate = DP_LINKRATE_HBR;
break;
case DP_LINKRATE_HBR3:
linkrate = DP_LINKRATE_HBR2;
break;
default:
return DPTX_TRANING_FAIL;
}
continue;
}
ret = mtk_edp_train_eq(mtk_dp, lanecount);
if (ret == DPTX_TIMEOUT) {
return DPTX_TIMEOUT;
} else if (ret) {
/* Reduce lane count */
if (lanecount == DP_LANECOUNT_4)
lanecount = DP_LANECOUNT_2;
else if (lanecount == DP_LANECOUNT_2)
lanecount = DP_LANECOUNT_1;
else
return DPTX_TRANING_FAIL;
continue;
}
printk(BIOS_INFO, "[eDPTX] EQ training pass\n");
/* If we reach here, training is done. */
break;
}
if (train_limit == 0)
return DPTX_TRANING_FAIL;
mtk_dp->train_info.linkrate = linkrate;
mtk_dp->train_info.linklane_count = lanecount;
/*
* After training done, we need to output normal stream instead of TPS,
* so we need to enable scramble.
*/
dptx_hal_setscramble(mtk_dp, true);
dptx_hal_set_ef_mode(mtk_dp, ENABLE_DPTX_EF_MODE);
printk(BIOS_INFO, "%s: done\n", __func__);
return DPTX_PASS;
}
static void dptx_init_port(struct mtk_dp *mtk_dp)
{
dptx_hal_phy_setidlepattern(mtk_dp, true);
dptx_hal_init_setting(mtk_dp);
dptx_hal_aux_setting(mtk_dp);
dptx_hal_digital_setting(mtk_dp);
dptx_hal_phy_init(mtk_dp);
dptx_hal_phy_setting(mtk_dp);
dptx_hal_hpd_detect_setting(mtk_dp);
dptx_hal_digital_swreset(mtk_dp);
dptx_hal_analog_power_en(mtk_dp, true);
dptx_hal_hpd_int_en(mtk_dp, true);
}
int mtk_edp_init(struct mtk_dp *mtk_dp, struct edid *edid)
void dptx_set_tx_power_con(void)
{
write32p(EDP_CLK_BASE + DISP_EDPTX_PWR_CON, 0xC2FC224D);
/* Add 26Mhz clock */
}
void dptx_set_26mhz_clock(void)
{
write32p(CKSYS_GP2_BASE + CKSYS2_CLK_CFG_3_CLR, 0xFF000000);
write32p(CKSYS_GP2_BASE + CKSYS2_CLK_CFG_UPDATE, 0x00008000);
udelay(50);
dptx_init_variable(mtk_dp);
dptx_init_port(mtk_dp);
if (!dptx_hal_hpd_high(mtk_dp)) {
printk(BIOS_ERR, "HPD is low\n");
return -1;
}
dptx_check_sinkcap(mtk_dp);
if (dptx_get_edid(mtk_dp, edid) != 0) {
printk(BIOS_ERR, "Failed to get EDID\n");
return -1;
}
if (dptx_set_trainingstart(mtk_dp) != DPTX_PASS) {
printk(BIOS_ERR, "%s: Failed to set training start\n", __func__);
return -1;
}
dp_intf_config(edid);
dptx_video_config(mtk_dp);
return 0;
}
int mtk_edp_enable(struct mtk_dp *mtk_dp)
{
if (!mtk_dp) {
printk(BIOS_ERR, "%s: eDP is not initialized\n", __func__);
return -1;
}
dptx_video_enable(mtk_dp, true);
return 0;
}

View file

@ -1,299 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#include <assert.h>
#include <console/console.h>
#include <device/mmio.h>
#include <delay.h>
#include <edid.h>
#include <soc/dptx.h>
#include <soc/dptx_hal.h>
#include <soc/dptx_reg.h>
#include <types.h>
static const int driving_offset[] = {
PHYD_DIG_LAN0_OFFSET + DRIVING_FORCE,
PHYD_DIG_LAN1_OFFSET + DRIVING_FORCE,
PHYD_DIG_LAN2_OFFSET + DRIVING_FORCE,
PHYD_DIG_LAN3_OFFSET + DRIVING_FORCE,
};
void dptx_hal_init_setting(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, 0x2000, GENMASK(1, 0), GENMASK(1, 0));
mtk_dp_mask(mtk_dp, REG_3540_DP_TRANS_P0, BIT(3), BIT(3));
mtk_dp_mask(mtk_dp, REG_342C_DP_TRANS_P0, 0x68, 0xFF);
mtk_dp_mask(mtk_dp, REG_31EC_DP_ENCODER0_P0, BIT(4), BIT(4));
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, 0, BIT(8));
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, BIT(3), BIT(3));
/* default marker */
mtk_dp_mask(mtk_dp, REG_3F04_DP_ENC_4P_3, 0, 0xFFFF);
mtk_dp_mask(mtk_dp, REG_3F08_DP_ENC_4P_3, BIT(3), BIT(3));
mtk_dp_mask(mtk_dp, REG_3F0C_DP_ENC_4P_3, BIT(1), BIT(1));
mtk_dp_mask(mtk_dp, REG_3F10_DP_ENC_4P_3, BIT(3), BIT(3));
mtk_dp_mask(mtk_dp, REG_33C0_DP_ENCODER1_P0, 0, 0xF000);
mtk_dp_mask(mtk_dp, REG_33C0_DP_ENCODER1_P0, 0x80, 0x80);
mtk_dp_mask(mtk_dp, REG_33C4_DP_ENCODER1_P0, BIT(5), BIT(6) | BIT(5));
mtk_dp_mask(mtk_dp, REG_3F28_DP_ENC_4P_3, 0xA << 2, GENMASK(5, 2));
mtk_dp_mask(mtk_dp, DP_TX_TOP_RESET_AND_PROBE, 0x9100FF, 0x9100FF);
mtk_dp_mask(mtk_dp, MTK_DP_TOP_IRQ_MASK, ENCODER_IRQ_MSK | TRANS_IRQ_MSK,
ENCODER_IRQ_MSK | TRANS_IRQ_MSK);
}
void dptx_hal_set_color_format(struct mtk_dp *mtk_dp, u8 out_format)
{
u32 val;
/* MISC0 */
mtk_dp_mask(mtk_dp, REG_3034_DP_ENCODER0_P0, out_format << DP_TEST_COLOR_FORMAT_SHIFT,
DP_TEST_COLOR_FORMAT_MASK);
mtk_dp_mask(mtk_dp, REG_3034_DP_ENCODER0_P0, BIT(3), BIT(3));
switch (out_format) {
case DP_COLOR_FORMAT_RGB_444:
case DP_COLOR_FORMAT_YUV_444:
val = 0;
break;
case DP_COLOR_FORMAT_YUV_422:
val = 0x1;
break;
case DP_COLOR_FORMAT_YUV_420:
val = 0x2;
break;
default:
printk(BIOS_ERR, "Unsupported color format: %u\n", out_format);
return;
}
mtk_dp_mask(mtk_dp, REG_303C_DP_ENCODER0_P0, val << 12, 0x7 << 12);
}
void dptx_hal_settu_setencoder(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_303C_DP_ENCODER0_P0, BIT(15), BIT(15));
DP_WRITE2BYTE(mtk_dp, REG_3040_DP_ENCODER0_P0, 0x2020);
DP_WRITE2BYTE(mtk_dp, REG_3364_DP_ENCODER1_P0, 0x2020);
mtk_dp_mask(mtk_dp, REG_3300_DP_ENCODER1_P0, 0x2 << 8, 0x3 << 8);
mtk_dp_mask(mtk_dp, REG_3364_DP_ENCODER1_P0, 0x40 << 8, 0x70 << 8);
}
bool dptx_hal_hpd_high(struct mtk_dp *mtk_dp)
{
return mtk_dp_read(mtk_dp, REG_364C_AUX_TX_P0) & BIT(15);
}
bool dptx_hal_setswing_preemphasis(struct mtk_dp *mtk_dp, int lane_num, u8 swing_value,
u8 preemphasis)
{
assert(lane_num <= DPTX_LANE_MAX);
for (int i = 0; i < lane_num; ++i) {
mtk_dp_phy_mask(mtk_dp, driving_offset[i],
swing_value << 1 | preemphasis << 3,
EDP_TX_LN_VOLT_SWING_VAL_MASK | EDP_TX_LN_PRE_EMPH_VAL_MASK);
printk(BIOS_DEBUG, "lane(%d), set swing(%u), emp(%u)\n",
i, swing_value, preemphasis);
}
mtk_dp_mask(mtk_dp, 0x2000, GENMASK(1, 0), GENMASK(1, 0));
return true;
}
static void dptx_hal_phy_reset_swing_preemphasis(struct mtk_dp *mtk_dp)
{
for (int i = 0; i < ARRAY_SIZE(driving_offset); i++)
mtk_dp_phy_mask(mtk_dp, driving_offset[i], 0,
for (int i = 0; i < dptx_hal_driving_offset_size; i++)
mtk_dp_phy_mask(mtk_dp, dptx_hal_driving_offset[i], 0,
EDP_TX_LN_VOLT_SWING_VAL_MASK | EDP_TX_LN_PRE_EMPH_VAL_MASK);
}
void dptx_hal_hpd_detect_setting(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_364C_AUX_TX_P0, HPD_INT_THD_FLDMASK_VAL << 4,
HPD_INT_THD_FLDMASK);
}
void dptx_hal_phy_init(struct mtk_dp *mtk_dp)
{
mtk_dp_phy_mask(mtk_dp, IPMUX_CONTROL, 0 << EDPTX_DSI_PHYD_SEL_FLDMASK_POS,
EDPTX_DSI_PHYD_SEL_FLDMASK);
mtk_dp_phy_mask(mtk_dp, PHYD_DIG_GLB_OFFSET + 0x10, GENMASK(2, 0), GENMASK(2, 0));
dptx_hal_ssc_en(mtk_dp, false);
}
void dptx_hal_set_txrate(struct mtk_dp *mtk_dp, u8 value)
{
printk(BIOS_INFO, "Link rate = 0x%x\n", value);
switch (value) {
case DP_LINKRATE_RBR:
mtk_dp_phy_write(mtk_dp, 0x143C, 0x1);
break;
case DP_LINKRATE_HBR:
mtk_dp_phy_write(mtk_dp, 0x143C, 0x4);
break;
case DP_LINKRATE_HBR2:
mtk_dp_phy_write(mtk_dp, 0x143C, 0x7);
break;
case DP_LINKRATE_HBR3:
mtk_dp_phy_write(mtk_dp, 0x143C, 0x9);
break;
default:
printk(BIOS_ERR, "Link rate not support(%d)\n", value);
return;
}
}
void dptx_hal_phy_set_lanes(struct mtk_dp *mtk_dp, u8 lane_count)
{
for (int i = 0; i < lane_count; i++)
mtk_dp_phy_mask(mtk_dp, PHYD_DIG_GLB_OFFSET + 0x74, BIT(i), BIT(i));
}
void dptx_hal_phy_setting(struct mtk_dp *mtk_dp)
{
u8 link_rate = mtk_dp->train_info.linkrate;
u8 lane_count = mtk_dp->train_info.linklane_count;
dptx_hal_phy_set_lanes(mtk_dp, lane_count);
dptx_hal_set_txrate(mtk_dp, link_rate);
/* Turn on phy power after phy configure */
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, PHY_STATE_W_1_DP_ENC_4P_3,
PHY_STATE_W_1_DP_ENC_4P_3_MASK);
mtk_dp_mask(mtk_dp, 0x2000, GENMASK(1, 0), GENMASK(1, 0));
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_PLL_CTL_1:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_PLL_CTL_1));
}
void dptx_hal_ssc_en(struct mtk_dp *mtk_dp, bool enable)
{
if (enable) {
printk(BIOS_DEBUG, "[eDPTX] enable ssc\n");
mtk_dp_phy_mask(mtk_dp, DP_PHY_DIG_PLL_CTL_1, BIT(8), BIT(8));
} else {
printk(BIOS_DEBUG, "[eDPTX] disable ssc\n");
mtk_dp_phy_mask(mtk_dp, DP_PHY_DIG_PLL_CTL_1, 0x0, BIT(8));
}
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_PLL_CTL_1:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_PLL_CTL_1));
mdelay(1);
}
void dptx_hal_aux_setting(struct mtk_dp *mtk_dp)
{
/* Modify timeout threshold = 1595 [12 : 8] */
mtk_dp_mask(mtk_dp, REG_360C_AUX_TX_P0, 0x1D0C, 0x1FFF);
mtk_dp_mask(mtk_dp, REG_3658_AUX_TX_P0, 0, BIT(0));
/* [0]mtk_dp, REG_aux_tx_ov_en */
mtk_dp_mask(mtk_dp, REG_36A0_AUX_TX_4P, 0xFFFC, 0xFFFC);
/* 26M */
mtk_dp_mask(mtk_dp, REG_3634_AUX_TX_P0, AUX_TX_OVER_SAMPLE_RATE_FOR_26M << 8,
0xff << 8);
mtk_dp_mask(mtk_dp, REG_3614_AUX_TX_P0, AUX_RX_UI_CNT_THR_AUX_FOR_26M, 0x7f);
/* Modify, 13 for 26M */
mtk_dp_mask(mtk_dp, REG_37C8_AUX_TX_P0, MTK_ATOP_EN_AUX_TX_4P, MTK_ATOP_EN_AUX_TX_4P);
/* Disable aux sync_stop detect function */
mtk_dp_mask(mtk_dp, REG_3690_AUX_TX_P0, RX_REPLY_COMPLETE_MODE_AUX_TX_4P,
RX_REPLY_COMPLETE_MODE_AUX_TX_4P);
mtk_dp_mask(mtk_dp, REG_367C_AUX_TX_P0, HPD_CONN_THD_AUX_TX_P0_FLDMASK_POS << 6,
HPD_CONN_THD_AUX_TX_P0_FLDMASK);
mtk_dp_mask(mtk_dp, REG_37A0_AUX_TX_P0, HPD_DISC_THD_AUX_TX_P0_FLDMASK_POS << 4,
HPD_DISC_THD_AUX_TX_P0_FLDMASK);
mtk_dp_mask(mtk_dp, REG_3690_AUX_TX_P0, RX_REPLY_COMPLETE_MODE_AUX_TX_4P,
RX_REPLY_COMPLETE_MODE_AUX_TX_4P);
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_VALUE << 9,
XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_MASK);
mtk_dp_mask(mtk_dp, REG_366C_AUX_TX_P0, XTAL_FREQ_DP_TX_AUX_366C_VALUE << 8,
XTAL_FREQ_DP_TX_AUX_366C_MASK);
}
void dptx_hal_digital_setting(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, 0, VBID_VIDEO_MUTE_DP_ENC0_4P_MASK);
mtk_dp_mask(mtk_dp, REG_3368_DP_ENCODER1_P0, BS2BS_MODE_DP_ENC1_4P_VAL << 12,
0x3 << 12);
mtk_dp_mask(mtk_dp, REG_3030_DP_ENCODER0_P0, BIT(11), BIT(11));
/* dp I-mode enable */
mtk_dp_mask(mtk_dp, BS2BS_MODE_DP_ENCODER1_P0_FLDMASK, DP_I_MODE_ENABLE,
DP_I_MODE_ENABLE);
mtk_dp_mask(mtk_dp, REG_3030_DP_ENCODER0_P0, 0x3ff, 0x3ff);
mtk_dp_mask(mtk_dp, REG_3028_DP_ENCODER0_P0, 0, BIT(15));
mtk_dp_mask(mtk_dp, REG_302C_DP_ENCODER0_P0, 0, BIT(15));
/* set color format */
dptx_hal_set_color_format(mtk_dp, DP_COLOR_FORMAT_RGB_444);
/* set color depth */
dptx_hal_set_color_depth(mtk_dp, DP_COLOR_DEPTH_8BIT);
/* reg_bs)symbol_cnt_reset */
mtk_dp_mask(mtk_dp, REG_3000_DP_ENCODER0_P0, REG_BS_SYMBOL_CNT_RESET,
REG_BS_SYMBOL_CNT_RESET);
mtk_dp_mask(mtk_dp, REG_3004_DP_ENCODER0_P0, BIT(14), BIT(14));
printk(BIOS_DEBUG, "[eDPTX] REG_3004_DP_ENCODER0_P0:%#x\n",
mtk_dp_read(mtk_dp, REG_3004_DP_ENCODER0_P0));
mtk_dp_mask(mtk_dp, REG_3368_DP_ENCODER1_P0, 0x2, BIT(1) | BIT(2));
mtk_dp_mask(mtk_dp, REG_3368_DP_ENCODER1_P0, BIT(15), BIT(15));
mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, 0, BIT(8));
/* [5:0]video sram start address */
mtk_dp_mask(mtk_dp, REG_303C_DP_ENCODER0_P0, 0x8, 0x3F);
/* reg_psr_patgen_avt_en patch */
mtk_dp_mask(mtk_dp, REG_3F80_DP_ENC_4P_3, 0, PSR_PATGEN_AVT_EN_FLDMASK);
/* phy D enable */
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, PHY_STATE_W_1_DP_ENC_4P_3,
PHY_STATE_W_1_DP_ENC_4P_3_MASK);
/* reg_dvo_on_ow_en */
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, DVO_ON_W_1_FLDMASK, DVO_ON_W_1_FLDMASK);
/* dp tx encoder reset all sw */
mtk_dp_mask(mtk_dp, REG_3004_DP_ENCODER0_P0, DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0,
DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
printk(BIOS_DEBUG, "[eDPTX] REG_3004_DP_ENCODER0_P0:%#x\n",
mtk_dp_read(mtk_dp, REG_3004_DP_ENCODER0_P0));
mtk_dp_mask(mtk_dp, REG_3004_DP_ENCODER0_P0, 0, BIT(9));
printk(BIOS_DEBUG, "[eDPTX] REG_3004_DP_ENCODER0_P0:%#x\n",
mtk_dp_read(mtk_dp, REG_3004_DP_ENCODER0_P0));
mtk_dp_mask(mtk_dp, REG_3FF8_DP_ENC_4P_3, 0xff, 0xff);
/* Wait for sw reset to complete */
mdelay(1);
}
void dptx_hal_digital_swreset(struct mtk_dp *mtk_dp)
{
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_TX_CTL_0:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_TX_CTL_0));
mtk_dp_mask(mtk_dp, REG_340C_DP_TRANS_P0, BIT(13), BIT(13));
mdelay(1);
mtk_dp_mask(mtk_dp, REG_340C_DP_TRANS_P0, 0, BIT(13));
mtk_dp_mask(mtk_dp, EDP_TX_TOP_CLKGEN_0, 0xF, 0xF);
printk(BIOS_DEBUG, "[eDPTX] DP_PHY_DIG_TX_CTL_0:%#x\n",
mtk_dp_phy_read(mtk_dp, DP_PHY_DIG_TX_CTL_0));
}
void dptx_hal_swing_emp_reset(struct mtk_dp *mtk_dp)
{
mtk_dp_mask(mtk_dp, REG_2004_TOP_SWING_EMP, 0,
DP_TX0_VOLT_SWING_MASK | DP_TX1_VOLT_SWING_MASK | DP_TX2_VOLT_SWING_MASK |
DP_TX3_VOLT_SWING_MASK | DP_TX0_PRE_EMPH_MASK | DP_TX1_PRE_EMPH_MASK |
DP_TX2_PRE_EMPH_MASK | DP_TX3_PRE_EMPH_MASK);
}
void dptx_hal_phyd_reset(struct mtk_dp *mtk_dp)
{
u32 val;
@ -314,74 +39,3 @@ void dptx_hal_phyd_reset(struct mtk_dp *mtk_dp)
dptx_hal_phy_reset_swing_preemphasis(mtk_dp);
}
void dptx_hal_phy_wait_aux_ldo_ready(struct mtk_dp *mtk_dp)
{
u32 mask = RGS_BG_CORE_EN_READY_MASK | RGS_AUX_LDO_EN_READY_MASK;
if (!retry(WAIT_AUX_READY_RETRY_TIMES, (mtk_dp_phy_read(mtk_dp, 0x146C) & mask) == mask,
mdelay(2))) {
printk(BIOS_ERR, "Wait AUX LDO ready timeout!\n");
}
}
void dptx_hal_set_txlane(struct mtk_dp *mtk_dp, u8 value)
{
/* Turn off phy power before phy configure */
mtk_dp_mask(mtk_dp, REG_3F44_DP_ENC_4P_3, PHY_PWR_STATE_OW_EN_DP_ENC_4P_3,
PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK);
mtk_dp_mask(mtk_dp, REG_3F44_DP_ENC_4P_3, BIAS_POWER_ON,
PHY_PWR_STATE_OW_VALUE_DP_ENC_4P_3_MASK);
dptx_hal_phy_wait_aux_ldo_ready(mtk_dp);
mtk_dp_mask(mtk_dp, REG_3F44_DP_ENC_4P_3, 0 << 2, PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK);
if (value == 0)
mtk_dp_mask(mtk_dp, REG_35F0_DP_TRANS_P0, 0, BIT(3) | BIT(2));
else
mtk_dp_mask(mtk_dp, REG_35F0_DP_TRANS_P0, BIT(3), BIT(3) | BIT(2));
assert((value << 2) <= UINT8_MAX);
mtk_dp_mask(mtk_dp, REG_3000_DP_ENCODER0_P0, value, BIT(1) | BIT(0));
mtk_dp_mask(mtk_dp, REG_34A4_DP_TRANS_P0, value << 2, BIT(3) | BIT(2));
}
void dptx_hal_phy_set_swing_preemphasis(struct mtk_dp *mtk_dp, u8 lane_count, u8 *swing_val,
u8 *preemphasis)
{
assert(lane_count <= DPTX_LANE_MAX);
for (int i = 0; i < lane_count; ++i) {
mtk_dp_phy_mask(mtk_dp, driving_offset[i],
swing_val[i] << 1 | preemphasis[i] << 3,
EDP_TX_LN_VOLT_SWING_VAL_MASK | EDP_TX_LN_PRE_EMPH_VAL_MASK);
printk(BIOS_DEBUG, "lane(%d), set swing(%u), emp(%u)\n",
i, swing_val[i], preemphasis[i]);
}
}
void dptx_hal_phy_set_idle_pattern(struct mtk_dp *mtk_dp, u8 lane_count, bool enable)
{
u32 val = 0x0;
printk(BIOS_INFO, "lane_count: %x idle pattern enable: %d\n", lane_count, enable);
switch (lane_count) {
case 1:
val = POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK;
break;
case 2:
val = POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE1_OV_DP_TRANS_4P_MASK;
break;
case 4:
val = POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE1_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE2_OV_DP_TRANS_4P_MASK |
POST_MISC_DATA_LANE3_OV_DP_TRANS_4P_MASK;
break;
default:
printk(BIOS_ERR, "%s: Unexpected lane count %d\n", __func__, lane_count);
return;
}
mtk_dp_mask(mtk_dp, REG_3580_DP_TRANS_P0, (enable ? val : 0x0) << 8,
POST_MISC_DATA_LANE_OV_DP_TRANS_4P_MASK);
}

View file

@ -3,208 +3,9 @@
#ifndef __SOC_MEDIATEK_MT8196_DP_DP_INTF_H__
#define __SOC_MEDIATEK_MT8196_DP_DP_INTF_H__
#include <edid.h>
#include <soc/addressmap.h>
#include <types.h>
#include <soc/dp_intf_v2.h>
#define DVO_EN 0x00
#define EN BIT(0)
#define DVO_FORCE_ON BIT(4)
#define LINK_OFF BIT(8)
#define MMSYS1_CG_CLR0 0x108
#define MMSYS1_CG_CLR1 0x118
#define CKSYS2_CLK_CFG_3_CLR 0x48
#define CKSYS2_CLK_CFG_UPDATE 0x4
#define DISP_EDPTX_PWR_CON 0x74
#define DVO_RET 0x04
#define SWRST BIT(0)
#define SWRST_SEL BIT(4)
#define DVO_INTEN 0x08
#define INT_VFP_START_EN BIT(0)
#define INT_VSYNC_START_EN BIT(1)
#define INT_VSYNC_END_EN BIT(2)
#define INT_VDE_START_EN BIT(3)
#define INT_VDE_END_EN BIT(4)
#define INT_WR_INFOQ_REG_EN BIT(5)
#define INT_TARGET_LINE0_EN BIT(6)
#define INT_TARGET_LINE1_EN BIT(7)
#define INT_TARGET_LINE2_EN BIT(8)
#define INT_TARGET_LINE3_EN BIT(9)
#define INT_WR_INFOQ_START_EN BIT(10)
#define INT_WR_INFOQ_END_EN BIT(11)
#define EXT_VSYNC_START_EN BIT(12)
#define EXT_VSYNC_END_EN BIT(13)
#define EXT_VDE_START_EN BIT(14)
#define EXT_VDE_END_EN BIT(15)
#define EXT_VBLANK_END_EN BIT(16)
#define UNDERFLOW_EN BIT(17)
#define INFOQ_ABORT_EN BIT(18)
#define DVO_INTSTA 0x0C
#define INT_VFP_START_STA BIT(0)
#define INT_VSYNC_START_STA BIT(1)
#define INT_VSYNC_END_STA BIT(2)
#define INT_VDE_START_STA BIT(3)
#define INT_VDE_END_STA BIT(4)
#define INT_WR_INFOQ_REG_STA BIT(5)
#define INT_TARGET_LINE0_STA BIT(6)
#define INT_TARGET_LINE1_STA BIT(7)
#define INT_TARGET_LINE2_STA BIT(8)
#define INT_TARGET_LINE3_STA BIT(9)
#define INT_WR_INFOQ_START_STA BIT(10)
#define INT_WR_INFOQ_END_STA BIT(11)
#define EXT_VSYNC_START_STA BIT(12)
#define EXT_VSYNC_END_STA BIT(13)
#define EXT_VDE_START_STA BIT(14)
#define EXT_VDE_END_STA BIT(15)
#define EXT_VBLANK_END_STA BIT(16)
#define INT_UNDERFLOW_STA BIT(17)
#define INFOQ_ABORT_STA BIT(18)
#define DVO_CON 0x10
#define INTL_EN BIT(0)
#define DVO_OUTPUT_SET 0x18
#define OUT_NP_SEL (0x3 << 0)
#define BIT_SWAP BIT(4)
#define CH_SWAP_MASK (0x7 << 5)
#define SWAP_RGB 0x00
#define SWAP_GBR 0x01
#define SWAP_BRG 0x02
#define SWAP_RBG 0x03
#define SWAP_GRB 0x04
#define SWAP_BGR 0x05
#define PXL_SWAP BIT(8)
#define R_MASK BIT(12)
#define G_MASK BIT(13)
#define B_MASK BIT(14)
#define DE_MASK BIT(16)
#define HS_MASK BIT(17)
#define VS_MASK BIT(18)
#define HS_INV BIT(19)
#define VS_INV BIT(20)
#define DVO_SRC_SIZE 0x20
#define SRC_HSIZE_SHIFT 0
#define SRC_HSIZE_MASK (0xFFFF << 0)
#define SRC_VSIZE_SHIFT 16
#define SRC_VSIZE_MASK (0xFFFF << 16)
#define DVO_PIC_SIZE 0x24
#define PIC_HSIZE_SHIFT 0
#define PIC_HSIZE_MASK (0xFFFF << 0)
#define PIC_VSIZE_SHIFT 16
#define PIC_VSIZE_MASK (0xFFFF << 16)
#define DVO_TGEN_H0 0x50
#define HFP_SHIFT 0
#define HFP_MASK (0xFFFF << 0)
#define HSYNC_SHIFT 16
#define HSYNC_MASK (0xFFFF << 16)
#define DVO_TGEN_H1 0x54
#define HSYNC2ACT_SHIFT 0
#define HSYNC2ACT_MASK (0xFFFF << 0)
#define HACT_SHIFT 16
#define HACT_MASK (0xFFFF << 16)
#define DVO_TGEN_V0 0x58
#define VFP_SHIFT 0
#define VFP_MASK (0xFFFF << 0)
#define VSYNC_SHIFT 16
#define VSYNC_MASK (0xFFFF << 16)
#define DVO_TGEN_V1 0x5C
#define VSYNC2ACT_SHIFT 0
#define VSYNC2ACT_MASK (0xFFFF << 0)
#define VACT_SHIFT 16
#define VACT_MASK (0xFFFF << 16)
#define DVO_TGEN_INFOQ_LATENCY 0x80
#define INFOQ_START_LATENCY 0
#define INFOQ_START_LATENCY_MASK (0xFFFF << 0)
#define INFOQ_END_LATENCY 16
#define INFOQ_END_LATENCY_MASK (0xFFFF << 16)
#define DVO_BUF_CON0 0x220
#define DISP_BUF_EN BIT(0)
#define FIFO_UNDERFLOW_DONE_BLOCK BIT(4)
#define DVO_TGEN_V_LAST_TRAILING_BLANK 0x6C
#define V_LAST_TRAILING_BLANK 0
#define V_LAST_TRAILING_BLANK_MASK (0xFFFF << 0)
#define DVO_TGEN_OUTPUT_DELAY_LINE 0x7C
#define EXT_TG_DLY_LINE 0
#define EXT_TG_DLY_LINE_MASK (0xFFFF << 0)
#define DVO_PATTERN_CTRL 0x100
#define PRE_PAT_EN BIT(0)
#define PRE_PAT_SEL_MASK (0x7 << 4)
#define COLOR_BAR (0x4 << 4)
#define PRE_PAT_FORCE_ON BIT(8)
#define DVO_PATTERN_COLOR 0x104
#define PAT_R (0x3FF << 0)
#define PAT_G (0x3FF << 10)
#define PAT_B (0x3FF << 20)
#define DVO_SHADOW_CTRL 0x190
#define FORCE_COMMIT BIT(0)
#define BYPASS_SHADOW BIT(1)
#define READ_WRK_REG BIT(2)
#define DVO_SIZE 0x18
#define DVO_TGEN_VWIDTH 0x28
#define DVO_TGEN_VPORCH 0x2C
#define DVO_TGEN_HPORCH 0x24
#define DVO_TGEN_HWIDTH 0x20
#define DVO_BUF_SODI_HIGHT 0x230
#define DVO_BUF_SODI_LOW 0x234
enum mtk_dvo_golden_setting_level {
MTK_DVO_FHD_60FPS_1920 = 0,
MTK_DVO_FHD_60FPS_2180,
MTK_DVO_FHD_60FPS_2400,
MTK_DVO_FHD_60FPS_2520,
MTK_DVO_FHD_90FPS,
MTK_DVO_FHD_120FPS,
MTK_DVO_WQHD_60FPS,
MTK_DVO_WQHD_120FPS,
MTK_DVO_8K_30FPS,
MTK_DVO_GSL_MAX,
};
struct mtk_dvo_gs_info {
u32 dvo_buf_sodi_high;
u32 dvo_buf_sodi_low;
};
enum TVDPLL_CLK {
TVDPLL_PLL = 0,
TVDPLL_D16 = 1,
TVDPLL_D8 = 2,
TVDPLL_D4 = 3,
};
struct mtk_dvo {
void *regs;
void *regs_ck;
void *regs_mm;
enum mtk_dvo_golden_setting_level gs_level;
};
struct mtk_dvo_sync_param {
u32 sync_width;
u32 front_porch;
u32 back_porch;
};
void dp_intf_config(const struct edid *edid);
#endif /* __SOC_MEDIATEK_MT8196_DP_DP_INTF_H__ */

View file

@ -3,25 +3,13 @@
#ifndef __SOC_MEDIATEK_MT8196_DP_DPTX_HAL_H__
#define __SOC_MEDIATEK_MT8196_DP_DPTX_HAL_H__
#include <soc/dptx_hal_common.h>
#include <soc/dptx_hal_v2.h>
#define MTK_DP_TRAIN_VOLTAGE_LEVEL_RETRY 5
#define MTK_DP_TRAIN_DOWNSCALE_RETRY 10
#define DP_LINKRATE_RBR_VAL 0x1
#define DP_LINKRATE_HBR_VAL 0x4
#define DP_LINKRATE_HBR2_VAL 0x7
#define DP_LINKRATE_HBR3_VAL 0x9
enum {
DPTX_PATTERN_TPS1 = 1,
DPTX_PATTERN_TPS2,
DPTX_PATTERN_TPS3,
DPTX_PATTERN_TPS4,
DPTX_PATTERN_UNKNOWN,
};
void dptx_hal_swing_emp_reset(struct mtk_dp *mtk_dp);
void dptx_hal_phy_init(struct mtk_dp *mtk_dp);
void dptx_hal_phy_set_lanes(struct mtk_dp *mtk_dp, u8 lane_count);
void dptx_hal_phy_wait_aux_ldo_ready(struct mtk_dp *mtk_dp);
void dptx_hal_phy_set_idle_pattern(struct mtk_dp *mtk_dp, u8 lane_count, bool enable);
void dptx_hal_phy_set_swing_preemphasis(struct mtk_dp *mtk_dp, u8 lane_count, u8 *swing_val,
u8 *preemphasis);
#define DP_PHY_DIG_GLB_STATUS_02_OFSSET 0x146C
#endif /* __SOC_MEDIATEK_MT8196_DP_DPTX_HAL_H__ */

View file

@ -3,211 +3,12 @@
#ifndef __SOC_MEDIATEK_MT8196_DP_DPTX_REG_H__
#define __SOC_MEDIATEK_MT8196_DP_DPTX_REG_H__
#include <soc/dptx_reg_common.h>
#include <soc/dptx_reg_v2.h>
#define WAIT_AUX_READY_RETRY_TIMES 5
#define PHYD_DIG_GLB_OFFSET 0x1400
#define SEC_OFFSET 0x4000
#define IPMUX_CONTROL (PHYD_DIG_GLB_OFFSET + 0x98)
#define EDPTX_DSI_PHYD_SEL_FLDMASK 0x1
#define EDPTX_DSI_PHYD_SEL_FLDMASK_POS 0
#define TOP_OFFSET 0x2000
#define MTK_DP_TOP_IRQ_MASK 0x202C
#define ENCODER_IRQ_MSK BIT(0)
#define TRANS_IRQ_MSK BIT(1)
#define EDP_TX_TOP_CLKGEN_0 0x2074
#define DP_PHY_DIG_PLL_CTL_1 0x1414
#define DP_PHY_DIG_SW_RST 0x1438
#define DP_PHY_DIG_TX_CTL_0 0x1474
#define RGS_BG_CORE_EN_READY_MASK BIT(0)
#define RGS_AUX_LDO_EN_READY_MASK BIT(1)
#define REG_2004_TOP_SWING_EMP 0x2004
#define DP_TX0_VOLT_SWING_MASK GENMASK(1, 0)
#define DP_TX0_PRE_EMPH_MASK GENMASK(3, 2)
#define DP_TX1_VOLT_SWING_MASK GENMASK(9, 8)
#define DP_TX1_PRE_EMPH_MASK GENMASK(11, 10)
#define DP_TX2_VOLT_SWING_MASK GENMASK(17, 16)
#define DP_TX2_PRE_EMPH_MASK GENMASK(19, 18)
#define DP_TX3_VOLT_SWING_MASK GENMASK(25, 24)
#define DP_TX3_PRE_EMPH_MASK GENMASK(27, 26)
#define REG_3000_DP_ENCODER0_P0 0x3000
#define REG_BS_SYMBOL_CNT_RESET BIT(7)
#define REG_3004_DP_ENCODER0_P0 0x3004
#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0 BIT(9)
#define REG_3008_DP_ENCODER0_P0 0x3008
#define REG_300C_DP_ENCODER0_P0 0x300C
#define REG_3010_DP_ENCODER0_P0 0x3010
#define REG_3014_DP_ENCODER0_P0 0x3014
#define REG_3018_DP_ENCODER0_P0 0x3018
#define REG_301C_DP_ENCODER0_P0 0x301C
#define REG_3020_DP_ENCODER0_P0 0x3020
#define REG_3024_DP_ENCODER0_P0 0x3024
#define REG_3028_DP_ENCODER0_P0 0x3028
#define HSP_SW_DP_ENCODER0_P0_FLDMASK 0x8000
#define HSP_SW_DP_ENCODER0_P0_FLDMASK_POS 15
#define REG_302C_DP_ENCODER0_P0 0x302C
#define REG_3030_DP_ENCODER0_P0 0x3030
#define REG_3034_DP_ENCODER0_P0 0x3034
#define DP_TEST_COLOR_FORMAT_MASK (3 << 1)
#define DP_TEST_COLOR_FORMAT_SHIFT 1
#define REG_303C_DP_ENCODER0_P0 0x303C
#define REG_3040_DP_ENCODER0_P0 0x3040
#define REG_3044_DP_ENCODER0_P0 0x3044
#define REG_3048_DP_ENCODER0_P0 0x3048
#define REG_304C_DP_ENCODER0_P0 0x304C
#define VBID_VIDEO_MUTE_DP_ENC0_4P_MASK BIT(2)
#define REG_3050_DP_ENCODER0_P0 0x3050
#define REG_3054_DP_ENCODER0_P0 0x3054
#define REG_3064_DP_ENCODER0_P0 0x3064
#define REG_3154_DP_ENCODER0_P0 0x3154
#define REG_3158_DP_ENCODER0_P0 0x3158
#define REG_315C_DP_ENCODER0_P0 0x315C
#define REG_3160_DP_ENCODER0_P0 0x3160
#define REG_3164_DP_ENCODER0_P0 0x3164
#define REG_3168_DP_ENCODER0_P0 0x3168
#define REG_316C_DP_ENCODER0_P0 0x316C
#define REG_3170_DP_ENCODER0_P0 0x3170
#define REG_3174_DP_ENCODER0_P0 0x3174
#define REG_3178_DP_ENCODER0_P0 0x3178
#define REG_31EC_DP_ENCODER0_P0 0x31EC
#define REG_3300_DP_ENCODER1_P0 0x3300
#define REG_3364_DP_ENCODER1_P0 0x3364
#define REG_3368_DP_ENCODER1_P0 0x3368
#define BS2BS_MODE_DP_ENC1_4P_VAL 1
#define BS2BS_MODE_DP_ENCODER1_P0_FLDMASK 0x3000
#define DP_I_MODE_ENABLE BIT(6)
#define REG_33C0_DP_ENCODER1_P0 0x33C0
#define REG_33C4_DP_ENCODER1_P0 0x33C4
#define REG_33C8_DP_ENCODER1_P0 0x33C8
#define REG_3400_DP_TRANS_P0 0x3400
#define PATTERN1_EN_DP_TRANS_4P_TPS1 BIT(12)
#define PATTERN2_EN_DP_TRANS_4P_TPS2 BIT(13)
#define PATTERN3_EN_DP_TRANS_4P_TPS3 BIT(14)
#define PATTERN4_EN_DP_TRANS_4P_TPS4 BIT(15)
#define PATTERN_EN_DP_TRANS_4P_MASK GENMASK(15, 12)
#define REG_3404_DP_TRANS_P0 0x3404
#define REG_340C_DP_TRANS_P0 0x340C
#define REG_3418_DP_TRANS_P0 0x3418
#define REG_342C_DP_TRANS_P0 0x342C
#define REG_34A4_DP_TRANS_P0 0x34A4
#define REG_3540_DP_TRANS_P0 0x3540
#define REG_3580_DP_TRANS_P0 0x3580
#define POST_MISC_DATA_LANE0_OV_DP_TRANS_4P_MASK BIT(8)
#define POST_MISC_DATA_LANE1_OV_DP_TRANS_4P_MASK BIT(9)
#define POST_MISC_DATA_LANE2_OV_DP_TRANS_4P_MASK BIT(10)
#define POST_MISC_DATA_LANE3_OV_DP_TRANS_4P_MASK BIT(11)
#define POST_MISC_DATA_LANE_OV_DP_TRANS_4P_MASK GENMASK(11, 8)
#define REG_35F0_DP_TRANS_P0 0x35F0
#define REG_360C_AUX_TX_P0 0x360C
#define REG_3614_AUX_TX_P0 0x3614
#define AUX_RX_UI_CNT_THR_AUX_FOR_26M 13
#define REG_3618_AUX_TX_P0 0x3618
#define AUX_RX_FIFO_FULL_AUX_TX_P0_FLDMASK 0x200
#define REG_3620_AUX_TX_P0 0x3620
#define AUX_RD_MODE_AUX_TX_P0_FLDMASK 0x200
#define AUX_RD_MODE_AUX_TX_P0_FLDMASK_POS 9
#define AUX_RX_FIFO_READ_PULSE_TX_P0_FLDMASK 0x100
#define AUX_RX_FIFO_R_PULSE_TX_P0_FLDMASK_POS 8
#define REG_3624_AUX_TX_P0 0x3624
#define REG_3628_AUX_TX_P0 0x3628
#define REG_362C_AUX_TX_P0 0x362C
#define AUX_NO_LENGTH_AUX_TX_P0_FLDMASK 0x1
#define AUX_NO_LENGTH_AUX_TX_P0_FLDMASK_POS 0
#define REG_3630_AUX_TX_P0 0x3630
#define AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK 0x8
#define AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK_POS 3
#define REG_3634_AUX_TX_P0 0x3634
#define AUX_TX_OVER_SAMPLE_RATE_FOR_26M 25
#define REG_3640_AUX_TX_P0 0x3640
#define AUX_RX_RECV_COMPLETE_IRQ_TX_P0_FLDMASK 0x40
#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_FLDMASK 0x1
#define REG_3644_AUX_TX_P0 0x3644
#define REG_3648_AUX_TX_P0 0x3648
#define REG_364C_AUX_TX_P0 0x364C
#define HPD_INT_THD_FLDMASK_VAL 0x32
#define HPD_INT_THD_FLDMASK 0x3F0
#define REG_3650_AUX_TX_P0 0x3650
#define MCU_REQUEST_DATA_NUM_AUX_TX_P0_FLDMASK 0xf000
#define MCU_REQ_DATA_NUM_AUX_TX_P0_FLDMASK_POS 12
#define MCU_ACK_TRANSACTION_COMPLETE_AUX_TX_P0_FLDMASK 0x100
#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_FLDMASK_POS 8
#define REG_3658_AUX_TX_P0 0x3658
#define REG_366C_AUX_TX_P0 0x366C
#define XTAL_FREQ_DP_TX_AUX_366C_VALUE 0x68
#define XTAL_FREQ_DP_TX_AUX_366C_MASK 0xFF00
#define REG_367C_AUX_TX_P0 0x367C
#define HPD_CONN_THD_AUX_TX_P0_FLDMASK_POS 5
#define HPD_CONN_THD_AUX_TX_P0_FLDMASK 0x3c0
#define REG_3690_AUX_TX_P0 0x3690
#define RX_REPLY_COMPLETE_MODE_AUX_TX_4P BIT(8)
#define REG_36A0_AUX_TX_4P 0x36A0
#define REG_3704_AUX_TX_P0 0x3704
#define AUX_TX_FIFO_WRITE_DATA_TOGGLE_AUX_TX_P0_FLDMASK 0x2
#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK 0x4
#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK_POS 2
#define REG_3708_AUX_TX_P0 0x3708
#define REG_37A0_AUX_TX_P0 0x37A0
#define HPD_DISC_THD_AUX_TX_P0_FLDMASK_POS 5
#define HPD_DISC_THD_AUX_TX_P0_FLDMASK 0xF0
#define REG_37C8_AUX_TX_P0 0x37C8
#define MTK_ATOP_EN_AUX_TX_4P BIT(0)
#define REG_3F04_DP_ENC_4P_3 0x3F04
#define REG_3F08_DP_ENC_4P_3 0x3F08
#define REG_3F0C_DP_ENC_4P_3 0x3F0C
#define REG_3F10_DP_ENC_4P_3 0x3F10
#define REG_3F28_DP_ENC_4P_3 0x3F28
#define REG_3F44_DP_ENC_4P_3 0x3F44
#define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3 BIT(2)
#define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK BIT(2)
#define BIAS_POWER_ON (0x01 << 3)
#define PHY_PWR_STATE_OW_VALUE_DP_ENC_4P_3_MASK GENMASK(4, 3)
#define REG_3F80_DP_ENC_4P_3 0x3F80
#define PSR_PATGEN_AVT_EN_FLDMASK 0x20
#define REG_3FF8_DP_ENC_4P_3 0x3FF8
#define PHY_STATE_W_1_DP_ENC_4P_3 BIT(6)
#define PHY_STATE_W_1_DP_ENC_4P_3_MASK BIT(6)
#define DVO_ON_W_1_FLDMASK 0x20
#define XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_VALUE 25
#define XTAL_FREQ_FOR_PSR_DP_ENC_4P_3_MASK 0x3E00
#define PHYD_DIG_LAN0_OFFSET 0x1000
#define PHYD_DIG_LAN1_OFFSET 0x1100
#define PHYD_DIG_LAN2_OFFSET 0x1200
#define PHYD_DIG_LAN3_OFFSET 0x1300
#define DRIVING_FORCE 0x30
#define EDP_TX_LN_VOLT_SWING_VAL_MASK GENMASK(2, 1)
#define EDP_TX_LN_PRE_EMPH_VAL_MASK GENMASK(4, 3)
#define DP_TX_TOP_APB_WSTRB (TOP_OFFSET + 0x10)
#define DP_TX_TOP_RESET_AND_PROBE (TOP_OFFSET + 0x20)
#define DP_TX_SECURE_REG11 (SEC_OFFSET + 0x2C)
#define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7)
#define DPCD_00000 0x00000
#define DPCD_0000E 0x0000E
#define DPCD_00021 0x00021
#define DPCD_00100 0x00100
#define DPCD_00101 0x00101
#define DPCD_00102 0x00102
#define DP_TRAINING_PATTERN_DISABLE 0
#define DP_TRAINING_PATTERN_1 1
#define DP_TRAINING_PATTERN_2 2
#define DP_TRAINING_PATTERN_3 3 /* 1.2 */
#define DP_TRAINING_PATTERN_4 7 /* 1.4 */
#define DP_LINK_SCRAMBLING_DISABLE BIT(5)
#define DPCD_00103 0x00103
#define DP_TRAIN_VOLTAGE_SWING_SHIFT 0
#define DP_TRAIN_MAX_SWING_REACHED BIT(2)
#define DP_TRAIN_PRE_EMPHASIS_SHIFT 3
#define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED BIT(5)
#define DPCD_00107 0x00107
#define DP_SPREAD_AMP_0_5 BIT(4)
#define DPCD_00200 0x00200
#define DPCD_00202 0x00202
#define DPCD_00206 0x00206
#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03
#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0C
#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2
#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
#define DPCD_00600 0x00600
#define DPCD_02002 0x02002
#define DPCD_02003 0x02003
#define EDP_TX_LN_PRE_EMPH_VAL_SHIFT 3
#endif /* __SOC_MEDIATEK_MT8196_DP_DPTX_REG_H__ */