soc/mediatek/mt8195: add eDP support
BUG=b:189985956 Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> Signed-off-by: Rex-BC Chen <rex-bc.chen@mediatek.com> Change-Id: I37326ad053295aa4944c8291e4e7a7d69c8f3f63 Reviewed-on: https://review.coreboot.org/c/coreboot/+/55573 Reviewed-by: Yu-Ping Wu <yupingso@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
@@ -49,6 +49,7 @@ romstage-y += ../common/rtc.c ../common/rtc_osc_init.c ../common/rtc_mt6359p.c
|
||||
|
||||
ramstage-y += ../common/auxadc.c
|
||||
ramstage-y += ../common/ddp.c ddp.c
|
||||
ramstage-y += dp_intf.c dptx.c dptx_hal.c
|
||||
ramstage-y += emi.c
|
||||
ramstage-y += ../common/flash_controller.c
|
||||
ramstage-y += ../common/gpio.c gpio.c
|
||||
|
309
src/soc/mediatek/mt8195/dp_intf.c
Normal file
309
src/soc/mediatek/mt8195/dp_intf.c
Normal file
@@ -0,0 +1,309 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/mmio.h>
|
||||
#include <delay.h>
|
||||
#include <edid.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/dp_intf.h>
|
||||
#include <soc/mcucfg.h>
|
||||
#include <soc/pll.h>
|
||||
#include <soc/pll_common.h>
|
||||
#include <soc/spm.h>
|
||||
#include <string.h>
|
||||
#include <timer.h>
|
||||
|
||||
static void mtk_dpintf_mask(struct mtk_dpintf *dpintf, u32 offset, u32 val, u32 mask)
|
||||
{
|
||||
clrsetbits32(dpintf->regs + offset, mask, val);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_sw_reset(struct mtk_dpintf *dpintf, bool reset)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_RET, reset ? RST : 0, RST);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_enable(struct mtk_dpintf *dpintf)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_EN, EN, EN);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_hsync(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_sync_param *sync)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_TGEN_HWIDTH,
|
||||
sync->sync_width << HPW, HPW_MASK);
|
||||
mtk_dpintf_mask(dpintf, DPINTF_TGEN_HPORCH,
|
||||
sync->back_porch << HBP, HBP_MASK);
|
||||
mtk_dpintf_mask(dpintf, DPINTF_TGEN_HPORCH,
|
||||
sync->front_porch << HFP, HFP_MASK);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_vsync(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_sync_param *sync,
|
||||
u32 width_addr, u32 porch_addr)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, width_addr,
|
||||
sync->sync_width << VSYNC_WIDTH_SHIFT,
|
||||
VSYNC_WIDTH_MASK);
|
||||
mtk_dpintf_mask(dpintf, width_addr,
|
||||
sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
|
||||
VSYNC_HALF_LINE_MASK);
|
||||
mtk_dpintf_mask(dpintf, porch_addr,
|
||||
sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
|
||||
VSYNC_BACK_PORCH_MASK);
|
||||
mtk_dpintf_mask(dpintf, porch_addr,
|
||||
sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
|
||||
VSYNC_FRONT_PORCH_MASK);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_vsync_lodd(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_sync_param *sync)
|
||||
{
|
||||
mtk_dpintf_config_vsync(dpintf, sync, DPINTF_TGEN_VWIDTH,
|
||||
DPINTF_TGEN_VPORCH);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_vsync_leven(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_sync_param *sync)
|
||||
{
|
||||
mtk_dpintf_config_vsync(dpintf, sync, DPINTF_TGEN_VWIDTH_LEVEN,
|
||||
DPINTF_TGEN_VPORCH_LEVEN);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_vsync_rodd(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_sync_param *sync)
|
||||
{
|
||||
mtk_dpintf_config_vsync(dpintf, sync, DPINTF_TGEN_VWIDTH_RODD,
|
||||
DPINTF_TGEN_VPORCH_RODD);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_vsync_reven(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_sync_param *sync)
|
||||
{
|
||||
mtk_dpintf_config_vsync(dpintf, sync, DPINTF_TGEN_VWIDTH_REVEN,
|
||||
DPINTF_TGEN_VPORCH_REVEN);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_pol(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_polarities *dpintf_pol)
|
||||
{
|
||||
u32 pol;
|
||||
|
||||
pol = (dpintf_pol->hsync_pol == MTK_DPINTF_POLARITY_RISING ? 0 : HSYNC_POL) |
|
||||
(dpintf_pol->vsync_pol == MTK_DPINTF_POLARITY_RISING ? 0 : VSYNC_POL);
|
||||
mtk_dpintf_mask(dpintf, DPINTF_OUTPUT_SETTING, pol, HSYNC_POL | VSYNC_POL);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_3d(struct mtk_dpintf *dpintf, bool en_3d)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_CON, en_3d ? TDFP_EN : 0, TDFP_EN);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_interface(struct mtk_dpintf *dpintf, bool inter)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_CON, inter ? INTL_EN : 0, INTL_EN);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_fb_size(struct mtk_dpintf *dpintf,
|
||||
u32 width, u32 height)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_SIZE, width << HSIZE, HSIZE_MASK);
|
||||
mtk_dpintf_mask(dpintf, DPINTF_SIZE, height << VSIZE, VSIZE_MASK);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_channel_limit(struct mtk_dpintf *dpintf,
|
||||
struct mtk_dpintf_yc_limit *limit)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_Y_LIMIT,
|
||||
limit->y_bottom << Y_LIMINT_BOT, Y_LIMINT_BOT_MASK);
|
||||
mtk_dpintf_mask(dpintf, DPINTF_Y_LIMIT,
|
||||
limit->y_top << Y_LIMINT_TOP, Y_LIMINT_TOP_MASK);
|
||||
mtk_dpintf_mask(dpintf, DPINTF_C_LIMIT,
|
||||
limit->c_bottom << C_LIMIT_BOT, C_LIMIT_BOT_MASK);
|
||||
mtk_dpintf_mask(dpintf, DPINTF_C_LIMIT,
|
||||
limit->c_top << C_LIMIT_TOP, C_LIMIT_TOP_MASK);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_bit_num(struct mtk_dpintf *dpintf,
|
||||
enum mtk_dpintf_out_bit_num num)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
switch (num) {
|
||||
case MTK_DPINTF_OUT_BIT_NUM_8BITS:
|
||||
val = OUT_BIT_8;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_BIT_NUM_10BITS:
|
||||
val = OUT_BIT_10;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_BIT_NUM_12BITS:
|
||||
val = OUT_BIT_12;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_BIT_NUM_16BITS:
|
||||
val = OUT_BIT_16;
|
||||
break;
|
||||
default:
|
||||
val = OUT_BIT_8;
|
||||
break;
|
||||
}
|
||||
mtk_dpintf_mask(dpintf, DPINTF_OUTPUT_SETTING, val, OUT_BIT_MASK);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_channel_swap(struct mtk_dpintf *dpintf,
|
||||
enum mtk_dpintf_out_channel_swap swap)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
switch (swap) {
|
||||
case MTK_DPINTF_OUT_CHANNEL_SWAP_RGB:
|
||||
val = SWAP_RGB;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_CHANNEL_SWAP_GBR:
|
||||
val = SWAP_GBR;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_CHANNEL_SWAP_BRG:
|
||||
val = SWAP_BRG;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_CHANNEL_SWAP_RBG:
|
||||
val = SWAP_RBG;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_CHANNEL_SWAP_GRB:
|
||||
val = SWAP_GRB;
|
||||
break;
|
||||
case MTK_DPINTF_OUT_CHANNEL_SWAP_BGR:
|
||||
val = SWAP_BGR;
|
||||
break;
|
||||
default:
|
||||
val = SWAP_RGB;
|
||||
break;
|
||||
}
|
||||
|
||||
mtk_dpintf_mask(dpintf, DPINTF_OUTPUT_SETTING, val, CH_SWAP_MASK);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_yuv422_enable(struct mtk_dpintf *dpintf, bool enable)
|
||||
{
|
||||
mtk_dpintf_mask(dpintf, DPINTF_CON, enable ? YUV422_EN : 0, YUV422_EN);
|
||||
}
|
||||
|
||||
static void mtk_dpintf_config_color_format(struct mtk_dpintf *dpintf,
|
||||
enum mtk_dpintf_out_color_format format)
|
||||
{
|
||||
bool enable;
|
||||
int channel_swap;
|
||||
|
||||
if (format == MTK_DPINTF_COLOR_FORMAT_YCBCR_444 ||
|
||||
format == MTK_DPINTF_COLOR_FORMAT_YCBCR_444_FULL) {
|
||||
enable = false;
|
||||
channel_swap = MTK_DPINTF_OUT_CHANNEL_SWAP_BGR;
|
||||
} else if (format == MTK_DPINTF_COLOR_FORMAT_YCBCR_422 ||
|
||||
format == MTK_DPINTF_COLOR_FORMAT_YCBCR_422_FULL) {
|
||||
enable = true;
|
||||
channel_swap = MTK_DPINTF_OUT_CHANNEL_SWAP_RGB;
|
||||
} else {
|
||||
enable = false;
|
||||
channel_swap = MTK_DPINTF_OUT_CHANNEL_SWAP_RGB;
|
||||
}
|
||||
|
||||
mtk_dpintf_config_yuv422_enable(dpintf, enable);
|
||||
mtk_dpintf_config_channel_swap(dpintf, channel_swap);
|
||||
}
|
||||
|
||||
static int mtk_dpintf_power_on(struct mtk_dpintf *dpintf, const struct edid *edid)
|
||||
{
|
||||
u32 clksrc;
|
||||
u32 pll_rate;
|
||||
|
||||
if (edid->mode.pixel_clock < 70000)
|
||||
clksrc = TVDPLL_D16;
|
||||
else if (edid->mode.pixel_clock < 200000)
|
||||
clksrc = TVDPLL_D8;
|
||||
else
|
||||
clksrc = TVDPLL_D4;
|
||||
|
||||
pll_rate = edid->mode.pixel_clock * 1000 * (1 << ((clksrc + 1) / 2));
|
||||
|
||||
mt_pll_set_tvd_pll1_freq(pll_rate / 4);
|
||||
edp_mux_set_sel(clksrc);
|
||||
|
||||
mtk_dpintf_enable(dpintf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_dpintf_set_display_mode(struct mtk_dpintf *dpintf,
|
||||
const struct edid *edid)
|
||||
{
|
||||
struct mtk_dpintf_yc_limit limit;
|
||||
struct mtk_dpintf_polarities dpintf_pol;
|
||||
struct mtk_dpintf_sync_param hsync;
|
||||
struct mtk_dpintf_sync_param vsync_lodd = { 0 };
|
||||
struct mtk_dpintf_sync_param vsync_leven = { 0 };
|
||||
struct mtk_dpintf_sync_param vsync_rodd = { 0 };
|
||||
struct mtk_dpintf_sync_param vsync_reven = { 0 };
|
||||
|
||||
vsync_lodd.back_porch = edid->mode.vbl - edid->mode.vso -
|
||||
edid->mode.vspw - edid->mode.vborder;
|
||||
vsync_lodd.front_porch = edid->mode.vso - edid->mode.vborder;
|
||||
vsync_lodd.sync_width = edid->mode.vspw;
|
||||
vsync_lodd.shift_half_line = false;
|
||||
|
||||
hsync.sync_width = edid->mode.hspw / 4;
|
||||
hsync.back_porch = (edid->mode.hbl - edid->mode.hso -
|
||||
edid->mode.hspw - edid->mode.hborder) / 4;
|
||||
hsync.front_porch = (edid->mode.hso - edid->mode.hborder) / 4;
|
||||
hsync.shift_half_line = false;
|
||||
|
||||
/* Let pll_rate be able to fix the valid range of tvdpll (1G~2GHz) */
|
||||
limit.c_bottom = 0x0000;
|
||||
limit.c_top = 0xfff;
|
||||
limit.y_bottom = 0x0000;
|
||||
limit.y_top = 0xfff;
|
||||
|
||||
dpintf_pol.ck_pol = MTK_DPINTF_POLARITY_FALLING;
|
||||
dpintf_pol.de_pol = MTK_DPINTF_POLARITY_RISING;
|
||||
dpintf_pol.hsync_pol = (edid->mode.phsync == '+') ?
|
||||
MTK_DPINTF_POLARITY_FALLING :
|
||||
MTK_DPINTF_POLARITY_RISING;
|
||||
dpintf_pol.vsync_pol = (edid->mode.pvsync == '+') ?
|
||||
MTK_DPINTF_POLARITY_FALLING :
|
||||
MTK_DPINTF_POLARITY_RISING;
|
||||
|
||||
mtk_dpintf_sw_reset(dpintf, true);
|
||||
mtk_dpintf_config_pol(dpintf, &dpintf_pol);
|
||||
|
||||
mtk_dpintf_config_hsync(dpintf, &hsync);
|
||||
mtk_dpintf_config_vsync_lodd(dpintf, &vsync_lodd);
|
||||
mtk_dpintf_config_vsync_rodd(dpintf, &vsync_rodd);
|
||||
mtk_dpintf_config_vsync_leven(dpintf, &vsync_leven);
|
||||
mtk_dpintf_config_vsync_reven(dpintf, &vsync_reven);
|
||||
|
||||
mtk_dpintf_config_3d(dpintf, false);
|
||||
mtk_dpintf_config_interface(dpintf, false);
|
||||
mtk_dpintf_config_fb_size(dpintf, edid->mode.ha, edid->mode.va);
|
||||
|
||||
mtk_dpintf_config_channel_limit(dpintf, &limit);
|
||||
mtk_dpintf_config_bit_num(dpintf, dpintf->bit_num);
|
||||
mtk_dpintf_config_channel_swap(dpintf, dpintf->channel_swap);
|
||||
mtk_dpintf_config_color_format(dpintf, dpintf->color_format);
|
||||
|
||||
mtk_dpintf_mask(dpintf, DPINTF_CON, INPUT_2P_EN, INPUT_2P_EN);
|
||||
mtk_dpintf_sw_reset(dpintf, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dp_intf_config(const struct edid *edid)
|
||||
{
|
||||
struct mtk_dpintf dpintf = {
|
||||
.regs = (void *)(DP_INTF0_BASE),
|
||||
.color_format = MTK_DPINTF_COLOR_FORMAT_RGB,
|
||||
.yc_map = MTK_DPINTF_OUT_YC_MAP_RGB,
|
||||
.bit_num = MTK_DPINTF_OUT_BIT_NUM_8BITS,
|
||||
.channel_swap = MTK_DPINTF_OUT_CHANNEL_SWAP_RGB,
|
||||
};
|
||||
|
||||
mtk_dpintf_power_on(&dpintf, edid);
|
||||
mtk_dpintf_set_display_mode(&dpintf, edid);
|
||||
}
|
1134
src/soc/mediatek/mt8195/dptx.c
Normal file
1134
src/soc/mediatek/mt8195/dptx.c
Normal file
File diff suppressed because it is too large
Load Diff
826
src/soc/mediatek/mt8195/dptx_hal.c
Normal file
826
src/soc/mediatek/mt8195/dptx_hal.c
Normal file
@@ -0,0 +1,826 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#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 <string.h>
|
||||
#include <timer.h>
|
||||
|
||||
#define REG_OFFSET_LIMIT 0x8000
|
||||
|
||||
struct shift_mask {
|
||||
u32 shift;
|
||||
u32 mask;
|
||||
};
|
||||
static const struct shift_mask volt_swing[DPTX_LANE_MAX] = {
|
||||
[DPTX_LANE0] = { DP_TX0_VOLT_SWING_FLDMASK_POS, DP_TX0_VOLT_SWING_FLDMASK },
|
||||
[DPTX_LANE1] = { DP_TX1_VOLT_SWING_FLDMASK_POS, DP_TX1_VOLT_SWING_FLDMASK },
|
||||
[DPTX_LANE2] = { DP_TX2_VOLT_SWING_FLDMASK_POS, DP_TX2_VOLT_SWING_FLDMASK },
|
||||
[DPTX_LANE3] = { DP_TX3_VOLT_SWING_FLDMASK_POS, DP_TX3_VOLT_SWING_FLDMASK },
|
||||
};
|
||||
static const struct shift_mask volt_preemphasis[DPTX_LANE_MAX] = {
|
||||
[DPTX_LANE0] = { DP_TX0_PRE_EMPH_FLDMASK_POS, DP_TX0_PRE_EMPH_FLDMASK },
|
||||
[DPTX_LANE1] = { DP_TX1_PRE_EMPH_FLDMASK_POS, DP_TX1_PRE_EMPH_FLDMASK },
|
||||
[DPTX_LANE2] = { DP_TX2_PRE_EMPH_FLDMASK_POS, DP_TX2_PRE_EMPH_FLDMASK },
|
||||
[DPTX_LANE3] = { DP_TX3_PRE_EMPH_FLDMASK_POS, DP_TX3_PRE_EMPH_FLDMASK },
|
||||
};
|
||||
|
||||
u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
|
||||
{
|
||||
void *addr = mtk_dp->regs + offset;
|
||||
|
||||
if (offset % 4 != 0 || offset > REG_OFFSET_LIMIT) {
|
||||
printk(BIOS_ERR, "[%s] invalid offset %#x for reg %p\n",
|
||||
__func__, offset, mtk_dp->regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return read32(addr);
|
||||
}
|
||||
|
||||
void mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
|
||||
{
|
||||
void *addr = mtk_dp->regs + offset;
|
||||
|
||||
if (offset % 4 != 0 || offset > REG_OFFSET_LIMIT) {
|
||||
printk(BIOS_ERR, "[%s] invalid offset %#x for reg %p\n",
|
||||
__func__, offset, mtk_dp->regs);
|
||||
return;
|
||||
}
|
||||
|
||||
write32(addr, val);
|
||||
}
|
||||
|
||||
void mtk_dp_mask(struct mtk_dp *mtk_dp, u32 offset, u32 val, u32 mask)
|
||||
{
|
||||
void *addr = mtk_dp->regs + offset;
|
||||
|
||||
if (offset % 4 != 0 || offset > REG_OFFSET_LIMIT) {
|
||||
printk(BIOS_ERR, "[%s] invalid offset %#x for reg %p\n",
|
||||
__func__, offset, mtk_dp->regs);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: modify to clrsetbits32(addr, mask, val);
|
||||
* There is asserion error when testing assert((val & mask) == val).
|
||||
*/
|
||||
clrsetbits32(addr, mask, val & mask);
|
||||
}
|
||||
|
||||
void mtk_dp_write_byte(struct mtk_dp *mtk_dp, u32 addr, u8 val, u32 mask)
|
||||
{
|
||||
if (addr % 2) {
|
||||
mtk_dp_write(mtk_dp, DP_TX_TOP_APB_WSTRB, 0x12);
|
||||
mtk_dp_mask(mtk_dp, addr - 1, val << 8, mask << 8);
|
||||
} else {
|
||||
mtk_dp_write(mtk_dp, DP_TX_TOP_APB_WSTRB, 0x11);
|
||||
mtk_dp_mask(mtk_dp, addr, val, mask);
|
||||
}
|
||||
|
||||
mtk_dp_write(mtk_dp, DP_TX_TOP_APB_WSTRB, 0x0);
|
||||
}
|
||||
|
||||
void dptx_hal_verify_clock(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
u32 m, n, ls_clk, pix_clk;
|
||||
|
||||
m = mtk_dp_read(mtk_dp, REG_33C8_DP_ENCODER1_P0);
|
||||
n = 0x8000;
|
||||
ls_clk = mtk_dp->train_info.linkrate;
|
||||
ls_clk *= 27;
|
||||
|
||||
pix_clk = m * ls_clk / n;
|
||||
printk(BIOS_DEBUG, "DPTX calc pixel clock = %d MHz, dp_intf clock = %dMHz\n",
|
||||
pix_clk, pix_clk / 4);
|
||||
}
|
||||
|
||||
void dptx_hal_init_setting(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
DP_WRITE1BYTE(mtk_dp, REG_342C_DP_TRANS_P0, 0x69);
|
||||
mtk_dp_mask(mtk_dp, REG_3540_DP_TRANS_P0, BIT(3), BIT(3));
|
||||
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, DP_TX_TOP_IRQ_MASK, BIT(2), BIT(2));
|
||||
}
|
||||
|
||||
void dptx_hal_bypassmsa_en(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
mtk_dp_mask(mtk_dp, REG_3030_DP_ENCODER0_P0,
|
||||
enable ? 0 : 0x3ff, 0x3ff);
|
||||
}
|
||||
|
||||
void dptx_hal_set_msa(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
u32 va, vsync, vbp, vfp, vtotal, ha, hsync, hbp, hfp, htotal;
|
||||
struct edid *edid = mtk_dp->edid;
|
||||
|
||||
va = edid->mode.va;
|
||||
vsync = edid->mode.vspw;
|
||||
vbp = edid->mode.vbl - edid->mode.vso -
|
||||
edid->mode.vspw - edid->mode.vborder;
|
||||
vfp = edid->mode.vso - edid->mode.vborder;
|
||||
|
||||
ha = edid->mode.ha;
|
||||
hsync = edid->mode.hspw;
|
||||
hbp = edid->mode.hbl - edid->mode.hso -
|
||||
edid->mode.hspw - edid->mode.hborder;
|
||||
hfp = edid->mode.hso - edid->mode.hborder;
|
||||
|
||||
htotal = ha + hsync + hbp + hfp;
|
||||
vtotal = va + vsync + vbp + vfp;
|
||||
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3010_DP_ENCODER0_P0, htotal);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3018_DP_ENCODER0_P0, hsync + hbp);
|
||||
mtk_dp_mask(mtk_dp, REG_3028_DP_ENCODER0_P0,
|
||||
hsync << HSW_SW_DP_ENCODER0_P0_FLDMASK_POS,
|
||||
HSW_SW_DP_ENCODER0_P0_FLDMASK);
|
||||
mtk_dp_mask(mtk_dp, REG_3028_DP_ENCODER0_P0,
|
||||
0 << HSP_SW_DP_ENCODER0_P0_FLDMASK_POS,
|
||||
HSP_SW_DP_ENCODER0_P0_FLDMASK);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3020_DP_ENCODER0_P0, ha);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3014_DP_ENCODER0_P0, va);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_301C_DP_ENCODER0_P0, vsync + vbp);
|
||||
mtk_dp_mask(mtk_dp, REG_302C_DP_ENCODER0_P0,
|
||||
vsync << VSW_SW_DP_ENCODER0_P0_FLDMASK_POS,
|
||||
VSW_SW_DP_ENCODER0_P0_FLDMASK);
|
||||
mtk_dp_mask(mtk_dp, REG_302C_DP_ENCODER0_P0,
|
||||
0 << VSP_SW_DP_ENCODER0_P0_FLDMASK_POS,
|
||||
VSP_SW_DP_ENCODER0_P0_FLDMASK);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3024_DP_ENCODER0_P0, va);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3064_DP_ENCODER0_P0, ha);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3154_DP_ENCODER0_P0, htotal);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3158_DP_ENCODER0_P0, hfp);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_315C_DP_ENCODER0_P0, vsync);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3160_DP_ENCODER0_P0, hsync + hbp);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3164_DP_ENCODER0_P0, ha);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3168_DP_ENCODER0_P0, vtotal);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_316C_DP_ENCODER0_P0, hfp);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3170_DP_ENCODER0_P0, vsync);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3174_DP_ENCODER0_P0, vsync + vbp);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3178_DP_ENCODER0_P0, va);
|
||||
|
||||
printk(BIOS_INFO, "MSA:Htt(%d), Vtt(%d), Hact(%d), Vact(%d), FPS(%d)\n",
|
||||
htotal, vtotal, ha, va,
|
||||
edid->mode.pixel_clock * 1000 / htotal / vtotal);
|
||||
}
|
||||
|
||||
void dptx_hal_set_color_format(struct mtk_dp *mtk_dp, u8 out_format)
|
||||
{
|
||||
/* MISC0 */
|
||||
mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0,
|
||||
out_format << 0x1, MASKBIT(2, 1));
|
||||
|
||||
switch (out_format) {
|
||||
case DP_COLOR_FORMAT_RGB_444:
|
||||
case DP_COLOR_FORMAT_YUV_444:
|
||||
mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1,
|
||||
0, MASKBIT(6, 4));
|
||||
break;
|
||||
case DP_COLOR_FORMAT_YUV_422:
|
||||
mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1,
|
||||
BIT(4), MASKBIT(6, 4));
|
||||
break;
|
||||
case DP_COLOR_FORMAT_YUV_420:
|
||||
mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1, BIT(5),
|
||||
MASKBIT(6, 4));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dptx_hal_set_color_depth(struct mtk_dp *mtk_dp, u8 color_depth)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0,
|
||||
color_depth << 0x5, 0xe0);
|
||||
|
||||
switch (color_depth) {
|
||||
case DP_COLOR_DEPTH_6BIT:
|
||||
val = 4;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_8BIT:
|
||||
val = 3;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_10BIT:
|
||||
val = 2;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_12BIT:
|
||||
val = 1;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_16BIT:
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1, val, 0x7);
|
||||
}
|
||||
|
||||
void dptx_hal_setmisc(struct mtk_dp *mtk_dp, u8 cmisc[2])
|
||||
{
|
||||
mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0, cmisc[0], 0xfe);
|
||||
mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0 + 1, cmisc[1], 0xff);
|
||||
}
|
||||
|
||||
void dptx_hal_overwrite_mn(struct mtk_dp *mtk_dp,
|
||||
bool enable, u32 video_m, u32 video_n)
|
||||
{
|
||||
if (enable) {
|
||||
/* Turn on overwrite MN */
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3008_DP_ENCODER0_P0,
|
||||
video_m & 0xffff);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_300C_DP_ENCODER0_P0,
|
||||
(video_m >> 16) & 0xff);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3044_DP_ENCODER0_P0,
|
||||
video_n & 0xffff);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3048_DP_ENCODER0_P0,
|
||||
(video_n >> 16) & 0xff);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3050_DP_ENCODER0_P0,
|
||||
video_n & 0xffff);
|
||||
|
||||
/* Add legerII. */
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3054_DP_ENCODER0_P0,
|
||||
(video_n >> 16) & 0xff);
|
||||
mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1,
|
||||
BIT(0), BIT(0));
|
||||
} else {
|
||||
/* Turn off overwrite MN */
|
||||
mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1,
|
||||
0, BIT(0));
|
||||
}
|
||||
}
|
||||
|
||||
u8 dptx_hal_get_colorbpp(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
u8 color_bpp;
|
||||
u8 color_depth = mtk_dp->info.depth;
|
||||
u8 color_format = mtk_dp->info.format;
|
||||
|
||||
switch (color_depth) {
|
||||
case DP_COLOR_DEPTH_6BIT:
|
||||
if (color_format == DP_COLOR_FORMAT_YUV_422)
|
||||
color_bpp = 16;
|
||||
else if (color_format == DP_COLOR_FORMAT_YUV_420)
|
||||
color_bpp = 12;
|
||||
else
|
||||
color_bpp = 18;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_8BIT:
|
||||
if (color_format == DP_COLOR_FORMAT_YUV_422)
|
||||
color_bpp = 16;
|
||||
else if (color_format == DP_COLOR_FORMAT_YUV_420)
|
||||
color_bpp = 12;
|
||||
else
|
||||
color_bpp = 24;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_10BIT:
|
||||
if (color_format == DP_COLOR_FORMAT_YUV_422)
|
||||
color_bpp = 20;
|
||||
else if (color_format == DP_COLOR_FORMAT_YUV_420)
|
||||
color_bpp = 15;
|
||||
else
|
||||
color_bpp = 30;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_12BIT:
|
||||
if (color_format == DP_COLOR_FORMAT_YUV_422)
|
||||
color_bpp = 24;
|
||||
else if (color_format == DP_COLOR_FORMAT_YUV_420)
|
||||
color_bpp = 18;
|
||||
else
|
||||
color_bpp = 36;
|
||||
break;
|
||||
case DP_COLOR_DEPTH_16BIT:
|
||||
if (color_format == DP_COLOR_FORMAT_YUV_422)
|
||||
color_bpp = 32;
|
||||
else if (color_format == DP_COLOR_FORMAT_YUV_420)
|
||||
color_bpp = 24;
|
||||
else
|
||||
color_bpp = 48;
|
||||
break;
|
||||
default:
|
||||
color_bpp = 24;
|
||||
printk(BIOS_ERR, "Set wrong bpp = %d\n", color_bpp);
|
||||
break;
|
||||
}
|
||||
|
||||
return color_bpp;
|
||||
}
|
||||
|
||||
void dptx_hal_settu_sramrd_start(struct mtk_dp *mtk_dp, u16 value)
|
||||
{
|
||||
/*
|
||||
* [5:0] video sram start address
|
||||
* modify in 480P case only, default=0x1f
|
||||
*/
|
||||
mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0, (u8)value, 0x3f);
|
||||
}
|
||||
|
||||
void dptx_hal_setsdp_downcnt_init_inhblanking(struct mtk_dp *mtk_dp, u16 value)
|
||||
{
|
||||
mtk_dp_mask(mtk_dp, REG_3364_DP_ENCODER1_P0, value, 0xfff);
|
||||
|
||||
}
|
||||
|
||||
void dptx_hal_setsdp_downcnt_init(struct mtk_dp *mtk_dp, u16 value)
|
||||
{
|
||||
mtk_dp_mask(mtk_dp, REG_3040_DP_ENCODER0_P0, value, 0xfff);
|
||||
}
|
||||
|
||||
void dptx_hal_settu_setencoder(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1,
|
||||
BIT(7), BIT(7));
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3040_DP_ENCODER0_P0, 0x2020);
|
||||
mtk_dp_mask(mtk_dp, REG_3364_DP_ENCODER1_P0, 0x2020, 0xfff);
|
||||
mtk_dp_write_byte(mtk_dp, REG_3300_DP_ENCODER1_P0 + 1,
|
||||
0x2, BIT(1) | BIT(0));
|
||||
mtk_dp_write_byte(mtk_dp, REG_3364_DP_ENCODER1_P0 + 1,
|
||||
0x40, 0x70);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3368_DP_ENCODER1_P0, 0x1111);
|
||||
}
|
||||
|
||||
bool dptx_hal_hpd_high(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
return mtk_dp_read(mtk_dp, REG_3414_DP_TRANS_P0) & BIT(2);
|
||||
}
|
||||
|
||||
bool dptx_hal_auxread_bytes(struct mtk_dp *mtk_dp, u8 cmd,
|
||||
u32 dpcd_addr, size_t length, u8 *rx_buf)
|
||||
{
|
||||
bool valid_cmd = false;
|
||||
u8 reply_cmd, aux_irq_status;
|
||||
int rd_count;
|
||||
u32 wait_reply_count = AUX_WAITREPLY_LPNUM;
|
||||
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
|
||||
mdelay(1);
|
||||
|
||||
if (length > 16 || (cmd == AUX_CMD_NATIVE_R && length == 0x0))
|
||||
return false;
|
||||
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3644_AUX_TX_P0, cmd);
|
||||
DP_WRITE2BYTE(mtk_dp, REG_3648_AUX_TX_P0, dpcd_addr & 0xffff);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_364C_AUX_TX_P0, (dpcd_addr >> 16) & 0xf);
|
||||
|
||||
if (length > 0) {
|
||||
mtk_dp_mask(mtk_dp, REG_3650_AUX_TX_P0,
|
||||
(length - 1) << MCU_REQ_DATA_NUM_AUX_TX_P0_FLDMASK_POS,
|
||||
MCU_REQUEST_DATA_NUM_AUX_TX_P0_FLDMASK);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
|
||||
}
|
||||
|
||||
if (cmd == AUX_CMD_I2C_R || cmd == AUX_CMD_I2C_R_MOT0)
|
||||
if (length == 0x0)
|
||||
mtk_dp_mask(mtk_dp, REG_362C_AUX_TX_P0,
|
||||
0x1 << AUX_NO_LENGTH_AUX_TX_P0_FLDMASK_POS,
|
||||
AUX_NO_LENGTH_AUX_TX_P0_FLDMASK);
|
||||
|
||||
mtk_dp_mask(mtk_dp, REG_3630_AUX_TX_P0,
|
||||
0x1 << AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK_POS,
|
||||
AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK);
|
||||
|
||||
while (--wait_reply_count) {
|
||||
if (mtk_dp_read(mtk_dp, REG_3618_AUX_TX_P0) &
|
||||
AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_FLDMASK) {
|
||||
valid_cmd = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtk_dp_read(mtk_dp, REG_3618_AUX_TX_P0) &
|
||||
AUX_RX_FIFO_FULL_AUX_TX_P0_FLDMASK) {
|
||||
valid_cmd = true;
|
||||
break;
|
||||
}
|
||||
|
||||
aux_irq_status = mtk_dp_read(mtk_dp, REG_3640_AUX_TX_P0) & 0xff;
|
||||
|
||||
if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_FLDMASK) {
|
||||
valid_cmd = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_FLDMASK) {
|
||||
printk(BIOS_ERR, "(AUX Read)HW Timeout 400us irq\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reply_cmd = mtk_dp_read(mtk_dp, REG_3624_AUX_TX_P0) & 0xf;
|
||||
if (reply_cmd)
|
||||
printk(BIOS_ERR, "reply_cmd(%#x), NACK or Defer\n", reply_cmd);
|
||||
|
||||
if (wait_reply_count == 0x0 || reply_cmd) {
|
||||
u8 phy_status = 0x0;
|
||||
|
||||
phy_status = mtk_dp_read(mtk_dp, REG_3628_AUX_TX_P0);
|
||||
if (phy_status != 0x1)
|
||||
printk(BIOS_ERR, "Aux read: aux hang, need sw reset\n");
|
||||
|
||||
mtk_dp_mask(mtk_dp, REG_3650_AUX_TX_P0,
|
||||
0x1 << MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_FLDMASK_POS,
|
||||
MCU_ACK_TRANSACTION_COMPLETE_AUX_TX_P0_FLDMASK);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
|
||||
|
||||
mdelay(1);
|
||||
printk(BIOS_ERR, "wait_reply_count(%#x), TimeOut\n",
|
||||
wait_reply_count);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
|
||||
} else {
|
||||
if (valid_cmd) {
|
||||
mtk_dp_mask(mtk_dp, REG_3620_AUX_TX_P0,
|
||||
0x0 << AUX_RD_MODE_AUX_TX_P0_FLDMASK_POS,
|
||||
AUX_RD_MODE_AUX_TX_P0_FLDMASK);
|
||||
|
||||
for (rd_count = 0; rd_count < length; rd_count++) {
|
||||
mtk_dp_mask(mtk_dp, REG_3620_AUX_TX_P0,
|
||||
0x1 << AUX_RX_FIFO_R_PULSE_TX_P0_FLDMASK_POS,
|
||||
AUX_RX_FIFO_READ_PULSE_TX_P0_FLDMASK);
|
||||
mdelay(1);
|
||||
*(rx_buf + rd_count) = mtk_dp_read(mtk_dp,
|
||||
REG_3620_AUX_TX_P0);
|
||||
}
|
||||
} else {
|
||||
printk(BIOS_INFO, "Read TimeOut %#x\n", dpcd_addr);
|
||||
}
|
||||
}
|
||||
|
||||
mtk_dp_mask(mtk_dp, REG_3650_AUX_TX_P0,
|
||||
0x1 << MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_FLDMASK_POS,
|
||||
MCU_ACK_TRANSACTION_COMPLETE_AUX_TX_P0_FLDMASK);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
|
||||
|
||||
mdelay(1);
|
||||
return valid_cmd;
|
||||
}
|
||||
|
||||
bool dptx_hal_auxwrite_bytes(struct mtk_dp *mtk_dp, u8 cmd,
|
||||
u32 dpcd_addr, size_t length, u8 *data)
|
||||
{
|
||||
bool valid_cmd = false;
|
||||
u8 reply_cmd;
|
||||
int i;
|
||||
u16 wait_reply_count = AUX_WAITREPLY_LPNUM;
|
||||
int reg_idx;
|
||||
|
||||
mtk_dp_write_byte(mtk_dp, REG_3704_AUX_TX_P0,
|
||||
1 << AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK_POS,
|
||||
AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
|
||||
mdelay(1);
|
||||
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3644_AUX_TX_P0, cmd);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3648_AUX_TX_P0, dpcd_addr & 0xff);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3648_AUX_TX_P0 + 1,
|
||||
(dpcd_addr >> 8) & 0xff);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_364C_AUX_TX_P0,
|
||||
(dpcd_addr >> 16) & 0xf);
|
||||
|
||||
if (length > 0) {
|
||||
DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
|
||||
for (i = 0; i < (length + 1) / 2; i++)
|
||||
for (reg_idx = 0; reg_idx < 2; reg_idx++)
|
||||
if ((i * 2 + reg_idx) < length)
|
||||
DP_WRITE1BYTE(mtk_dp,
|
||||
REG_3708_AUX_TX_P0 + i * 4 + reg_idx,
|
||||
data[i * 2 + reg_idx]);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1,
|
||||
((length - 1) & 0xf) << 4);
|
||||
} else {
|
||||
DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x1);
|
||||
}
|
||||
|
||||
mtk_dp_write_byte(mtk_dp, REG_3704_AUX_TX_P0,
|
||||
AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_FLDMASK,
|
||||
AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_FLDMASK);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3630_AUX_TX_P0, 0x8);
|
||||
|
||||
while (--wait_reply_count) {
|
||||
u8 aux_irq_status;
|
||||
|
||||
aux_irq_status = mtk_dp_read(mtk_dp, REG_3640_AUX_TX_P0) & 0xff;
|
||||
mdelay(1);
|
||||
if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_FLDMASK) {
|
||||
valid_cmd = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_FLDMASK)
|
||||
break;
|
||||
}
|
||||
|
||||
reply_cmd = mtk_dp_read(mtk_dp, REG_3624_AUX_TX_P0) & 0xf;
|
||||
if (reply_cmd)
|
||||
printk(BIOS_ERR, "reply_cmd(%#x), NACK or Defer\n", reply_cmd);
|
||||
|
||||
if (wait_reply_count == 0x0 || reply_cmd) {
|
||||
u8 phy_status = 0x0;
|
||||
|
||||
phy_status = mtk_dp_read(mtk_dp, REG_3628_AUX_TX_P0);
|
||||
if (phy_status != 0x1)
|
||||
printk(BIOS_ERR,
|
||||
"Aux write: aux hang, need SW reset!\n");
|
||||
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
|
||||
|
||||
mdelay(1);
|
||||
|
||||
printk(BIOS_INFO, "reply_cmd(%#x), wait_reply_count(%d)\n",
|
||||
reply_cmd, wait_reply_count);
|
||||
return false;
|
||||
}
|
||||
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
|
||||
|
||||
if (length == 0)
|
||||
DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
|
||||
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
|
||||
|
||||
mdelay(1);
|
||||
|
||||
return valid_cmd;
|
||||
}
|
||||
|
||||
bool dptx_hal_setswing_preemphasis(struct mtk_dp *mtk_dp, int lane_num,
|
||||
int swing_value, int preemphasis)
|
||||
{
|
||||
printk(BIOS_DEBUG, "lane(%d), set swing(%#x), emp(%#x)\n",
|
||||
lane_num, swing_value, preemphasis);
|
||||
|
||||
if (lane_num >= DPTX_LANE_MAX) {
|
||||
printk(BIOS_ERR, "invalid lane number: %d\n", lane_num);
|
||||
return false;
|
||||
}
|
||||
|
||||
mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
|
||||
swing_value << volt_swing[lane_num].shift,
|
||||
volt_swing[lane_num].mask);
|
||||
mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
|
||||
preemphasis << volt_preemphasis[lane_num].shift,
|
||||
volt_preemphasis[lane_num].mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
void dptx_hal_reset_swing_preemphasis(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
int lane;
|
||||
|
||||
for (lane = 0; lane < DPTX_LANE_MAX; lane++)
|
||||
mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
|
||||
0, volt_swing[lane].mask);
|
||||
for (lane = 0; lane < DPTX_LANE_MAX; lane++)
|
||||
mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
|
||||
0, volt_preemphasis[lane].mask);
|
||||
}
|
||||
|
||||
void dptx_hal_hpd_int_en(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
/* [7]:int, [6]:Con, [5]DisCon, [4]No-Use: UnMASK HPD Port */
|
||||
mtk_dp_write_byte(mtk_dp, REG_3418_DP_TRANS_P0,
|
||||
enable ? 0 : MASKBIT(7, 5), MASKBIT(7, 5));
|
||||
}
|
||||
|
||||
void dptx_hal_hpd_detect_setting(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
mtk_dp_write_byte(mtk_dp, REG_3410_DP_TRANS_P0,
|
||||
0x8, MASKBIT(3, 0));
|
||||
mtk_dp_write_byte(mtk_dp, REG_3410_DP_TRANS_P0,
|
||||
0xa << 4, MASKBIT(7, 4));
|
||||
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3410_DP_TRANS_P0 + 1, 0x55);
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3430_DP_TRANS_P0, 0x2);
|
||||
}
|
||||
|
||||
void dptx_hal_phy_setting(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
mtk_dp_mask(mtk_dp, DP_TX_TOP_PWR_STATE,
|
||||
0x3 << DP_PWR_STATE_FLDMASK_POS, DP_PWR_STATE_FLDMASK);
|
||||
|
||||
mtk_dp_write(mtk_dp, 0x2000, 0x00000001);
|
||||
mtk_dp_write(mtk_dp, 0x103c, 0x00000000);
|
||||
mtk_dp_write(mtk_dp, 0x2000, 0x00000003);
|
||||
mtk_dp_write(mtk_dp, 0x1138, 0x20181410);
|
||||
mtk_dp_write(mtk_dp, 0x1238, 0x20181410);
|
||||
mtk_dp_write(mtk_dp, 0x1338, 0x20181410);
|
||||
mtk_dp_write(mtk_dp, 0x1438, 0x20181410);
|
||||
mtk_dp_write(mtk_dp, 0x113C, 0x20241e18);
|
||||
mtk_dp_write(mtk_dp, 0x123C, 0x20241e18);
|
||||
mtk_dp_write(mtk_dp, 0x133C, 0x20241e18);
|
||||
mtk_dp_write(mtk_dp, 0x143C, 0x20241e18);
|
||||
mtk_dp_write(mtk_dp, 0x1140, 0x00003028);
|
||||
mtk_dp_write(mtk_dp, 0x1240, 0x00003028);
|
||||
mtk_dp_write(mtk_dp, 0x1340, 0x00003028);
|
||||
mtk_dp_write(mtk_dp, 0x1440, 0x00003028);
|
||||
mtk_dp_write(mtk_dp, 0x1144, 0x10080400);
|
||||
mtk_dp_write(mtk_dp, 0x1244, 0x10080400);
|
||||
mtk_dp_write(mtk_dp, 0x1344, 0x10080400);
|
||||
mtk_dp_write(mtk_dp, 0x1444, 0x10080400);
|
||||
mtk_dp_write(mtk_dp, 0x1148, 0x000c0600);
|
||||
mtk_dp_write(mtk_dp, 0x1248, 0x000c0600);
|
||||
mtk_dp_write(mtk_dp, 0x1348, 0x000c0600);
|
||||
mtk_dp_write(mtk_dp, 0x1448, 0x000c0600);
|
||||
mtk_dp_write(mtk_dp, 0x114C, 0x00000008);
|
||||
mtk_dp_write(mtk_dp, 0x124C, 0x00000008);
|
||||
mtk_dp_write(mtk_dp, 0x134C, 0x00000008);
|
||||
mtk_dp_write(mtk_dp, 0x144C, 0x00000008);
|
||||
mtk_dp_mask(mtk_dp, 0x3690, BIT(8), BIT(8));
|
||||
}
|
||||
|
||||
void dptx_hal_ssc_en(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
mtk_dp_mask(mtk_dp, 0x2000, BIT(0), MASKBIT(1, 0));
|
||||
|
||||
if (enable)
|
||||
mtk_dp_mask(mtk_dp, 0x1014, BIT(3), BIT(3));
|
||||
else
|
||||
mtk_dp_mask(mtk_dp, 0x1014, 0x0, BIT(3));
|
||||
|
||||
mtk_dp_mask(mtk_dp, 0x2000, MASKBIT(1, 0), MASKBIT(1, 0));
|
||||
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
void dptx_hal_aux_setting(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
/* [12 : 8]: modify timeout threshold = 1595 */
|
||||
mtk_dp_mask(mtk_dp, REG_360C_AUX_TX_P0,
|
||||
0x1595, AUX_TIMEOUT_THR_AUX_TX_P0_FLDMASK);
|
||||
mtk_dp_write_byte(mtk_dp, REG_3658_AUX_TX_P0, 0, BIT(0));
|
||||
|
||||
/* 0x19 for 26M */
|
||||
DP_WRITE1BYTE(mtk_dp, REG_3634_AUX_TX_P0 + 1, 0x19);
|
||||
/* 0xd for 26M */
|
||||
mtk_dp_write_byte(mtk_dp, REG_3614_AUX_TX_P0,
|
||||
0xd, MASKBIT(6, 0));
|
||||
mtk_dp_mask(mtk_dp, REG_37C8_AUX_TX_P0,
|
||||
0x01 << MTK_ATOP_EN_AUX_TX_P0_FLDMASK_POS,
|
||||
MTK_ATOP_EN_AUX_TX_P0_FLDMASK);
|
||||
}
|
||||
|
||||
void dptx_hal_digital_setting(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
mtk_dp_write_byte(mtk_dp, REG_304C_DP_ENCODER0_P0,
|
||||
0, VBID_VIDEO_MUTE_DP_ENCODER0_P0_FLDMASK);
|
||||
/* MISC0 */
|
||||
dptx_hal_set_color_format(mtk_dp, DP_COLOR_FORMAT_RGB_444);
|
||||
|
||||
dptx_hal_set_color_depth(mtk_dp, DP_COLOR_DEPTH_8BIT);
|
||||
mtk_dp_write_byte(mtk_dp, REG_3368_DP_ENCODER1_P0 + 1,
|
||||
BIT(4), MASKBIT(5, 4));
|
||||
/* DPtx encoder reset all sw. */
|
||||
mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1, BIT(1), BIT(1));
|
||||
|
||||
mdelay(1);
|
||||
|
||||
/* DPtx encoder reset all sw. */
|
||||
mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1, 0, BIT(1));
|
||||
}
|
||||
|
||||
void dptx_hal_digital_swreset(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
mtk_dp_write_byte(mtk_dp, REG_340C_DP_TRANS_P0 + 1, BIT(5), BIT(5));
|
||||
mdelay(1);
|
||||
mtk_dp_write_byte(mtk_dp, REG_340C_DP_TRANS_P0 + 1, 0, BIT(5));
|
||||
}
|
||||
|
||||
void dptx_hal_phyd_reset(struct mtk_dp *mtk_dp)
|
||||
{
|
||||
mtk_dp_write_byte(mtk_dp, 0x1038, 0, BIT(0));
|
||||
mdelay(1);
|
||||
mtk_dp_write_byte(mtk_dp, 0x1038, BIT(0), BIT(0));
|
||||
}
|
||||
|
||||
void dptx_hal_set_txlane(struct mtk_dp *mtk_dp, int value)
|
||||
{
|
||||
if (value == 0)
|
||||
mtk_dp_write_byte(mtk_dp, REG_35F0_DP_TRANS_P0,
|
||||
0, BIT(3) | BIT(2));
|
||||
else
|
||||
mtk_dp_write_byte(mtk_dp, REG_35F0_DP_TRANS_P0,
|
||||
BIT(3), BIT(3) | BIT(2));
|
||||
|
||||
if ((value << 2) <= UINT8_MAX) {
|
||||
mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
|
||||
value, BIT(1) | BIT(0));
|
||||
mtk_dp_write_byte(mtk_dp, REG_34A4_DP_TRANS_P0,
|
||||
value << 2, BIT(3) | BIT(2));
|
||||
} else {
|
||||
printk(BIOS_ERR, "ERROR: [%s]value << 2 > 0xff\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void dptx_hal_set_txrate(struct mtk_dp *mtk_dp, int value)
|
||||
{
|
||||
/* Power off TPLL and lane */
|
||||
mtk_dp_write(mtk_dp, 0x2000, 0x00000001);
|
||||
/* Set gear : 0x0 : RBR, 0x1 : HBR, 0x2 : HBR2, 0x3 : HBR3 */
|
||||
switch (value) {
|
||||
case DP_LINKRATE_RBR:
|
||||
mtk_dp_write(mtk_dp, 0x103C, 0x0);
|
||||
break;
|
||||
case DP_LINKRATE_HBR:
|
||||
mtk_dp_write(mtk_dp, 0x103C, 0x1);
|
||||
break;
|
||||
case DP_LINKRATE_HBR2:
|
||||
mtk_dp_write(mtk_dp, 0x103C, 0x2);
|
||||
break;
|
||||
case DP_LINKRATE_HBR3:
|
||||
mtk_dp_write(mtk_dp, 0x103C, 0x3);
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR, "ERROR: Link rate not support(%d)\n", value);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Power on BandGap, TPLL and Lane */
|
||||
mtk_dp_write(mtk_dp, 0x2000, 0x3);
|
||||
}
|
||||
|
||||
void dptx_hal_set_txtrainingpattern(struct mtk_dp *mtk_dp, int value)
|
||||
{
|
||||
/* if Set TPS1. */
|
||||
if (value == BIT(4))
|
||||
dptx_hal_phy_setidlepattern(mtk_dp, false);
|
||||
|
||||
mtk_dp_write_byte(mtk_dp, REG_3400_DP_TRANS_P0 + 1,
|
||||
value, MASKBIT(7, 4));
|
||||
}
|
||||
|
||||
void dptx_hal_phy_setidlepattern(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
mtk_dp_write_byte(mtk_dp, REG_3580_DP_TRANS_P0 + 1,
|
||||
enable ? 0xf : 0x0, 0xf);
|
||||
}
|
||||
|
||||
void dptx_hal_set_ef_mode(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
/*
|
||||
* [4]: REG_enhanced_frame_mode
|
||||
* [1 : 0]: REG_lane_num
|
||||
*/
|
||||
if (enable)
|
||||
mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
|
||||
BIT(4), BIT(4));
|
||||
else
|
||||
mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
|
||||
0, BIT(4));
|
||||
}
|
||||
|
||||
void dptx_hal_setscramble(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
/* [0]: dp tx transmitter scramble enable. */
|
||||
if (enable)
|
||||
mtk_dp_write_byte(mtk_dp, REG_3404_DP_TRANS_P0,
|
||||
BIT(0), BIT(0));
|
||||
else
|
||||
mtk_dp_write_byte(mtk_dp, REG_3404_DP_TRANS_P0,
|
||||
0, BIT(0));
|
||||
}
|
||||
|
||||
void dptx_hal_videomute(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
|
||||
BIT(3) | BIT(2), BIT(3) | BIT(2));
|
||||
mtk_dp_write_byte(mtk_dp, DP_TX_SECURE_REG11,
|
||||
BIT(3) | BIT(4), BIT(3) | BIT(4));
|
||||
} else {
|
||||
mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
|
||||
BIT(3), BIT(3) | BIT(2));
|
||||
mtk_dp_write_byte(mtk_dp, DP_TX_SECURE_REG11,
|
||||
BIT(4), BIT(3) | BIT(4));
|
||||
}
|
||||
printk(BIOS_DEBUG, "mute = %#x\n", read32(mtk_dp->regs + 0x402c));
|
||||
}
|
||||
|
||||
void dptx_hal_analog_power_en(struct mtk_dp *mtk_dp, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
mtk_dp_write_byte(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
|
||||
0, BIT(4));
|
||||
mdelay(1);
|
||||
mtk_dp_write_byte(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
|
||||
BIT(4), BIT(4));
|
||||
} else {
|
||||
DP_WRITE2BYTE(mtk_dp, TOP_OFFSET, 0x0);
|
||||
mdelay(1);
|
||||
DP_WRITE2BYTE(mtk_dp, 0x0034, 0x4aa);
|
||||
DP_WRITE2BYTE(mtk_dp, 0x1040, 0x0);
|
||||
DP_WRITE2BYTE(mtk_dp, 0x0038, 0x555);
|
||||
}
|
||||
}
|
258
src/soc/mediatek/mt8195/include/soc/dp_intf.h
Normal file
258
src/soc/mediatek/mt8195/include/soc/dp_intf.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef SOC_MEDIATEK_MT8195_DP_INTF_H
|
||||
#define SOC_MEDIATEK_MT8195_DP_INTF_H
|
||||
|
||||
#include <edid.h>
|
||||
|
||||
#define DPINTF_EN 0x00
|
||||
#define EN BIT(0)
|
||||
|
||||
#define DPINTF_RET 0x04
|
||||
#define RST BIT(0)
|
||||
#define RST_SEL BIT(16)
|
||||
|
||||
#define DPINTF_INTEN 0x08
|
||||
#define INT_VSYNC_EN BIT(0)
|
||||
#define INT_VDE_EN BIT(1)
|
||||
#define INT_UNDERFLOW_EN BIT(2)
|
||||
#define INT_TARGET_LINE_EN BIT(3)
|
||||
|
||||
#define DPINTF_INTSTA 0x0C
|
||||
#define INT_VSYNC_STA BIT(0)
|
||||
#define INT_VDE_STA BIT(1)
|
||||
#define INT_UNDERFLOW_STA BIT(2)
|
||||
#define INT_TARGET_LINE_STA BIT(3)
|
||||
|
||||
#define DPINTF_CON 0x10
|
||||
#define BG_ENABLE BIT(0)
|
||||
#define INTL_EN BIT(2)
|
||||
#define TDFP_EN BIT(3)
|
||||
#define VS_LODD_EN BIT(16)
|
||||
#define VS_LEVEN_EN BIT(17)
|
||||
#define VS_RODD_EN BIT(18)
|
||||
#define VS_REVEN BIT(19)
|
||||
#define FAKE_DE_LODD BIT(20)
|
||||
#define FAKE_DE_LEVEN BIT(21)
|
||||
#define FAKE_DE_RODD BIT(22)
|
||||
#define FAKE_DE_REVEN BIT(23)
|
||||
#define YUV422_EN BIT(24)
|
||||
#define CLPF_EN BIT(25)
|
||||
#define MATRIX_EN BIT(26)
|
||||
#define INTERNAL_CG_EN BIT(27)
|
||||
#define LOWPOWER_EN BIT(28)
|
||||
#define INPUT_2P_EN BIT(29)
|
||||
#define EXT_VSYNC_EN BIT(30)
|
||||
|
||||
#define DPINTF_OUTPUT_SETTING 0x14
|
||||
#define PIXEL_SWAP BIT(0)
|
||||
#define CH_SWAP BIT(1)
|
||||
#define CH_SWAP_MASK (0x7 << 1)
|
||||
#define SWAP_RGB (0x00 << 1)
|
||||
#define SWAP_GBR (0x01 << 1)
|
||||
#define SWAP_BRG (0x02 << 1)
|
||||
#define SWAP_RBG (0x03 << 1)
|
||||
#define SWAP_GRB (0x04 << 1)
|
||||
#define SWAP_BGR (0x05 << 1)
|
||||
#define B_MASK BIT(4)
|
||||
#define G_MASK BIT(5)
|
||||
#define R_MASK BIT(6)
|
||||
#define DE_MASK BIT(8)
|
||||
#define HS_MASK BIT(9)
|
||||
#define VS_MASK BIT(10)
|
||||
#define HSYNC_POL BIT(13)
|
||||
#define VSYNC_POL BIT(14)
|
||||
#define OUT_BIT BIT(16)
|
||||
#define OUT_BIT_MASK (0x3 << 18)
|
||||
#define OUT_BIT_8 (0x00 << 18)
|
||||
#define OUT_BIT_10 (0x01 << 18)
|
||||
#define OUT_BIT_12 (0x02 << 18)
|
||||
#define OUT_BIT_16 (0x03 << 18)
|
||||
|
||||
#define DPINTF_SIZE 0x18
|
||||
#define HSIZE 0
|
||||
#define HSIZE_MASK (0xffff << 0)
|
||||
#define VSIZE 16
|
||||
#define VSIZE_MASK (0xffff << 16)
|
||||
|
||||
#define DPINTF_TGEN_HWIDTH 0x20
|
||||
#define HPW 0
|
||||
#define HPW_MASK (0xffff << 0)
|
||||
|
||||
#define DPINTF_TGEN_HPORCH 0x24
|
||||
#define HBP 0
|
||||
#define HBP_MASK (0xffff << 0)
|
||||
#define HFP 16
|
||||
#define HFP_MASK (0xffff << 16)
|
||||
|
||||
#define DPINTF_TGEN_VWIDTH 0x28
|
||||
#define VSYNC_WIDTH_SHIFT 0
|
||||
#define VSYNC_WIDTH_MASK (0xffff << 0)
|
||||
#define VSYNC_HALF_LINE_SHIFT 16
|
||||
#define VSYNC_HALF_LINE_MASK BIT(16)
|
||||
|
||||
|
||||
#define DPINTF_TGEN_VPORCH 0x2C
|
||||
#define VSYNC_BACK_PORCH_SHIFT 0
|
||||
#define VSYNC_BACK_PORCH_MASK (0xffff << 0)
|
||||
#define VSYNC_FRONT_PORCH_SHIFT 16
|
||||
#define VSYNC_FRONT_PORCH_MASK (0xffff << 16)
|
||||
|
||||
#define DPINTF_BG_HCNTL 0x30
|
||||
#define BG_RIGHT (0xffff << 0)
|
||||
#define BG_LEFT (0xffff << 16)
|
||||
|
||||
#define DPINTF_BG_VCNTL 0x34
|
||||
#define BG_BOT (0xffff << 0)
|
||||
#define BG_TOP (0xffff << 16)
|
||||
|
||||
#define DPINTF_BG_COLOR 0x38
|
||||
#define BG_B (0x3ff << 0)
|
||||
#define BG_G (0x3ff << 10)
|
||||
#define BG_R (0x3ff << 20)
|
||||
|
||||
#define DPINTF_FIFO_CTL 0x3C
|
||||
#define FIFO_VALID_SET (0x1F << 0)
|
||||
#define FIFO_RST_SEL BIT(8)
|
||||
#define FIFO_RD_MASK BIT(12)
|
||||
|
||||
#define DPINTF_STATUS 0x40
|
||||
#define VCOUNTER (0x3ffff << 0)
|
||||
#define DPINTF_BUSY BIT(24)
|
||||
#define FIELD BIT(28)
|
||||
#define TDLR BIT(29)
|
||||
|
||||
#define DPINTF_TGEN_VWIDTH_LEVEN 0x68
|
||||
#define DPINTF_TGEN_VPORCH_LEVEN 0x6C
|
||||
#define DPINTF_TGEN_VWIDTH_RODD 0x70
|
||||
#define DPINTF_TGEN_VPORCH_RODD 0x74
|
||||
#define DPINTF_TGEN_VWIDTH_REVEN 0x78
|
||||
#define DPINTF_TGEN_VPORCH_REVEN 0x7C
|
||||
|
||||
#define DPINTF_CLPF_SETTING 0x94
|
||||
#define CLPF_TYPE (0x3 << 0)
|
||||
#define ROUND_EN BIT(4)
|
||||
|
||||
#define DPINTF_Y_LIMIT 0x98
|
||||
#define Y_LIMINT_BOT 0
|
||||
#define Y_LIMINT_BOT_MASK (0xFFF << 0)
|
||||
#define Y_LIMINT_TOP 16
|
||||
#define Y_LIMINT_TOP_MASK (0xFFF << 16)
|
||||
|
||||
#define DPINTF_C_LIMIT 0x9C
|
||||
#define C_LIMIT_BOT 0
|
||||
#define C_LIMIT_BOT_MASK (0xFFF << 0)
|
||||
#define C_LIMIT_TOP 16
|
||||
#define C_LIMIT_TOP_MASK (0xFFF << 16)
|
||||
|
||||
#define DPINTF_YUV422_SETTING 0xA0
|
||||
#define UV_SWAP BIT(0)
|
||||
#define CR_DELSEL BIT(4)
|
||||
#define CB_DELSEL BIT(5)
|
||||
#define Y_DELSEL BIT(6)
|
||||
#define DE_DELSEL BIT(7)
|
||||
|
||||
#define DPINTF_MATRIX_SET 0xB4
|
||||
#define INT_MATRIX_SEL_MASK 0x1f
|
||||
#define RGB_TO_JPEG 0x00
|
||||
#define RGB_TO_FULL709 0x01
|
||||
#define RGB_TO_BT601 0x02
|
||||
#define RGB_TO_BT709 0x03
|
||||
#define JPEG_TO_RGB 0x04
|
||||
#define FULL709_TO_RGB 0x05
|
||||
#define BT601_TO_RGB 0x06
|
||||
#define BT709_TO_RGB 0x07
|
||||
#define JPEG_TO_BT601 0x08
|
||||
#define JPEG_TO_BT709 0x09
|
||||
#define BT601_TO_JPEG 0xA
|
||||
#define BT709_TO_JPEG 0xB
|
||||
#define BT709_TO_BT601 0xC
|
||||
#define BT601_TO_BT709 0xD
|
||||
#define JPEG_TO_CERGB 0x14
|
||||
#define FULL709_TO_CERGB 0x15
|
||||
#define BT601_TO_CERGB 0x16
|
||||
#define BT709_TO_CERGB 0x17
|
||||
#define RGB_TO_CERGB 0x1C
|
||||
|
||||
#define MATRIX_BIT_MASK (0x3 << 8)
|
||||
#define EXT_MATRIX_EN BIT(12)
|
||||
|
||||
enum mtk_dpintf_out_bit_num {
|
||||
MTK_DPINTF_OUT_BIT_NUM_8BITS,
|
||||
MTK_DPINTF_OUT_BIT_NUM_10BITS,
|
||||
MTK_DPINTF_OUT_BIT_NUM_12BITS,
|
||||
MTK_DPINTF_OUT_BIT_NUM_16BITS,
|
||||
};
|
||||
|
||||
enum mtk_dpintf_out_yc_map {
|
||||
MTK_DPINTF_OUT_YC_MAP_RGB,
|
||||
MTK_DPINTF_OUT_YC_MAP_CYCY,
|
||||
MTK_DPINTF_OUT_YC_MAP_YCYC,
|
||||
MTK_DPINTF_OUT_YC_MAP_CY,
|
||||
MTK_DPINTF_OUT_YC_MAP_YC,
|
||||
};
|
||||
|
||||
enum mtk_dpintf_out_channel_swap {
|
||||
MTK_DPINTF_OUT_CHANNEL_SWAP_RGB,
|
||||
MTK_DPINTF_OUT_CHANNEL_SWAP_GBR,
|
||||
MTK_DPINTF_OUT_CHANNEL_SWAP_BRG,
|
||||
MTK_DPINTF_OUT_CHANNEL_SWAP_RBG,
|
||||
MTK_DPINTF_OUT_CHANNEL_SWAP_GRB,
|
||||
MTK_DPINTF_OUT_CHANNEL_SWAP_BGR,
|
||||
};
|
||||
|
||||
enum mtk_dpintf_out_color_format {
|
||||
MTK_DPINTF_COLOR_FORMAT_RGB,
|
||||
MTK_DPINTF_COLOR_FORMAT_RGB_FULL,
|
||||
MTK_DPINTF_COLOR_FORMAT_YCBCR_444,
|
||||
MTK_DPINTF_COLOR_FORMAT_YCBCR_422,
|
||||
MTK_DPINTF_COLOR_FORMAT_XV_YCC,
|
||||
MTK_DPINTF_COLOR_FORMAT_YCBCR_444_FULL,
|
||||
MTK_DPINTF_COLOR_FORMAT_YCBCR_422_FULL,
|
||||
};
|
||||
|
||||
enum TVDPLL_CLK {
|
||||
TVDPLL_PLL = 0,
|
||||
TVDPLL_D2 = 1,
|
||||
TVDPLL_D4 = 3,
|
||||
TVDPLL_D8 = 5,
|
||||
TVDPLL_D16 = 7,
|
||||
};
|
||||
|
||||
struct mtk_dpintf {
|
||||
void *regs;
|
||||
enum mtk_dpintf_out_color_format color_format;
|
||||
enum mtk_dpintf_out_yc_map yc_map;
|
||||
enum mtk_dpintf_out_bit_num bit_num;
|
||||
enum mtk_dpintf_out_channel_swap channel_swap;
|
||||
};
|
||||
|
||||
enum mtk_dpintf_polarity {
|
||||
MTK_DPINTF_POLARITY_RISING,
|
||||
MTK_DPINTF_POLARITY_FALLING,
|
||||
};
|
||||
|
||||
struct mtk_dpintf_polarities {
|
||||
enum mtk_dpintf_polarity de_pol;
|
||||
enum mtk_dpintf_polarity ck_pol;
|
||||
enum mtk_dpintf_polarity hsync_pol;
|
||||
enum mtk_dpintf_polarity vsync_pol;
|
||||
};
|
||||
|
||||
struct mtk_dpintf_sync_param {
|
||||
u32 sync_width;
|
||||
u32 front_porch;
|
||||
u32 back_porch;
|
||||
bool shift_half_line;
|
||||
};
|
||||
|
||||
struct mtk_dpintf_yc_limit {
|
||||
u16 y_top;
|
||||
u16 y_bottom;
|
||||
u16 c_top;
|
||||
u16 c_bottom;
|
||||
};
|
||||
|
||||
void dp_intf_config(const struct edid *edid);
|
||||
|
||||
#endif /* SOC_MEDIATEK_MT8195_DP_INTF_H */
|
77
src/soc/mediatek/mt8195/include/soc/dptx.h
Normal file
77
src/soc/mediatek/mt8195/include/soc/dptx.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef SOC_MEDIATEK_MT8195_DPTX_H
|
||||
#define SOC_MEDIATEK_MT8195_DPTX_H
|
||||
|
||||
#define DPTX_TBC_BUF_READSTARTADRTHRD 0x08
|
||||
#define ENABLE_DPTX_EF_MODE 0x1
|
||||
#define DPTX_AUX_SET_ENAHNCED_FRAME 0x80
|
||||
|
||||
union misc_t {
|
||||
struct {
|
||||
u8 is_sync_clock : 1;
|
||||
u8 color_format : 2;
|
||||
u8 spec_def1 : 2;
|
||||
u8 color_depth : 3;
|
||||
u8 interlaced : 1;
|
||||
u8 stereo_attr : 2;
|
||||
u8 reserved : 3;
|
||||
u8 is_vsc_sdp : 1;
|
||||
u8 spec_def2 : 1;
|
||||
} dp_misc;
|
||||
u8 cmisc[2];
|
||||
};
|
||||
|
||||
struct dptx_training_info {
|
||||
bool sink_extcap_en;
|
||||
bool tps3;
|
||||
bool tps4;
|
||||
bool sink_ssc_en;
|
||||
bool dp_mstcap;
|
||||
bool dp_mstbranch;
|
||||
bool down_stream_port_present;
|
||||
bool cr_done;
|
||||
bool eq_done;
|
||||
u8 sys_max_linkrate;
|
||||
u8 linkrate;
|
||||
u8 linklane_count;
|
||||
u8 dpcd_rev;
|
||||
u8 sink_count_num;
|
||||
};
|
||||
|
||||
struct dptx_info {
|
||||
uint8_t depth;
|
||||
uint8_t format;
|
||||
uint8_t resolution;
|
||||
};
|
||||
|
||||
struct mtk_dp {
|
||||
int id;
|
||||
struct edid *edid;
|
||||
u8 rx_cap[16];
|
||||
struct dptx_info info;
|
||||
int state;
|
||||
int state_pre;
|
||||
struct dptx_training_info train_info;
|
||||
int training_state;
|
||||
u8 irq_status;
|
||||
u32 min_clock;
|
||||
u32 max_clock;
|
||||
u32 max_hdisplay;
|
||||
u32 max_vdisplay;
|
||||
void *regs;
|
||||
int disp_status;
|
||||
bool power_on;
|
||||
bool audio_enable;
|
||||
bool video_enable;
|
||||
bool dp_ready;
|
||||
bool has_dsc;
|
||||
bool has_fec;
|
||||
bool dsc_enable;
|
||||
bool enabled;
|
||||
bool powered;
|
||||
};
|
||||
|
||||
int mtk_edp_init(struct edid *edid);
|
||||
|
||||
#endif /* SOC_MEDIATEK_MT8195_DPTX_H */
|
105
src/soc/mediatek/mt8195/include/soc/dptx_hal.h
Normal file
105
src/soc/mediatek/mt8195/include/soc/dptx_hal.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef SOC_MEDIATEK_MT8195_DPTX_HAL_H
|
||||
#define SOC_MEDIATEK_MT8195_DPTX_HAL_H
|
||||
|
||||
#define AUX_CMD_I2C_R_MOT0 0x1
|
||||
#define AUX_CMD_I2C_R 0x5
|
||||
#define AUX_CMD_NATIVE_R 0x9
|
||||
#define AUX_WAITREPLY_LPNUM 20000
|
||||
|
||||
#define DP_AUX_I2C_WRITE 0x0
|
||||
#define DP_AUX_I2C_READ 0x1
|
||||
#define DP_AUX_I2C_WRITE_STATUS_UPDATE 0x2
|
||||
#define DP_AUX_I2C_MOT 0x4
|
||||
#define DP_AUX_NATIVE_WRITE 0x8
|
||||
#define DP_AUX_NATIVE_READ 0x9
|
||||
|
||||
#define MASKBIT(a, b) ((a > b) ? (BIT(a + 1) - BIT(b)) : (BIT(b + 1) - BIT(a)))
|
||||
|
||||
#define DP_WRITE1BYTE(mtk_dp, reg, u8_val) \
|
||||
mtk_dp_write_byte(mtk_dp, reg, u8_val, 0xff)
|
||||
#define DP_WRITE2BYTE(mtk_dp, reg, u16_val) \
|
||||
mtk_dp_mask(mtk_dp, reg, u16_val, 0xffff)
|
||||
|
||||
enum {
|
||||
DPTX_LANE0 = 0x0,
|
||||
DPTX_LANE1 = 0x1,
|
||||
DPTX_LANE2 = 0x2,
|
||||
DPTX_LANE3 = 0x3,
|
||||
DPTX_LANE_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
DP_LINKRATE_RBR = 0x6,
|
||||
DP_LINKRATE_HBR = 0xa,
|
||||
DP_LINKRATE_HBR2 = 0x14,
|
||||
DP_LINKRATE_HBR25 = 0x19,
|
||||
DP_LINKRATE_HBR3 = 0x1e,
|
||||
};
|
||||
|
||||
enum {
|
||||
DP_COLOR_FORMAT_RGB_444 = 0,
|
||||
DP_COLOR_FORMAT_YUV_422 = 1,
|
||||
DP_COLOR_FORMAT_YUV_444 = 2,
|
||||
DP_COLOR_FORMAT_YUV_420 = 3,
|
||||
DP_COLOR_FORMAT_YONLY = 4,
|
||||
DP_COLOR_FORMAT_RAW = 5,
|
||||
DP_COLOR_FORMAT_RESERVED = 6,
|
||||
DP_COLOR_FORMAT_DEFAULT = DP_COLOR_FORMAT_RGB_444,
|
||||
DP_COLOR_FORMAT_UNKNOWN = 15,
|
||||
};
|
||||
|
||||
enum {
|
||||
DP_COLOR_DEPTH_6BIT = 0,
|
||||
DP_COLOR_DEPTH_8BIT = 1,
|
||||
DP_COLOR_DEPTH_10BIT = 2,
|
||||
DP_COLOR_DEPTH_12BIT = 3,
|
||||
DP_COLOR_DEPTH_16BIT = 4,
|
||||
DP_COLOR_DEPTH_UNKNOWN = 5,
|
||||
};
|
||||
|
||||
bool dptx_hal_hpd_high(struct mtk_dp *mtk_dp);
|
||||
bool dptx_hal_auxread_bytes(struct mtk_dp *mtk_dp, u8 cmd,
|
||||
u32 dpcd_addr, size_t length, u8 *rx_buf);
|
||||
bool dptx_hal_auxwrite_bytes(struct mtk_dp *mtk_dp, u8 cmd,
|
||||
u32 dpcd_addr, size_t length, u8 *data);
|
||||
bool dptx_hal_setswing_preemphasis(struct mtk_dp *mtk_dp, int lane_num,
|
||||
int swing_value, int preemphasis);
|
||||
u8 dptx_hal_get_colorbpp(struct mtk_dp *mtk_dp);
|
||||
u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset);
|
||||
void mtk_dp_write_byte(struct mtk_dp *mtk_dp, u32 addr, u8 val, u32 mask);
|
||||
void mtk_dp_mask(struct mtk_dp *mtk_dp, u32 offset, u32 val, u32 mask);
|
||||
void mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val);
|
||||
void dptx_hal_verify_clock(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_reset_swing_preemphasis(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_digital_swreset(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_ssc_en(struct mtk_dp *mtk_dp, bool enable);
|
||||
void dptx_hal_hpd_int_en(struct mtk_dp *mtk_dp, bool enable);
|
||||
void dptx_hal_hpd_detect_setting(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_phy_setting(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_aux_setting(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_digital_setting(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_set_txlane(struct mtk_dp *mtk_dp, int value);
|
||||
void dptx_hal_phy_setidlepattern(struct mtk_dp *mtk_dp, bool enable);
|
||||
void dptx_hal_phyd_reset(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_set_txtrainingpattern(struct mtk_dp *mtk_dp, int value);
|
||||
void dptx_hal_set_ef_mode(struct mtk_dp *mtk_dp, bool enable);
|
||||
void dptx_hal_setscramble(struct mtk_dp *mtk_dp, bool enable);
|
||||
void dptx_hal_init_setting(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_videomute(struct mtk_dp *mtk_dp, bool enable);
|
||||
void dptx_hal_bypassmsa_en(struct mtk_dp *mtk_dp, bool enable);
|
||||
void dptx_hal_overwrite_mn(struct mtk_dp *mtk_dp, bool enable,
|
||||
u32 video_m, u32 video_n);
|
||||
void dptx_hal_settu_sramrd_start(struct mtk_dp *mtk_dp, u16 value);
|
||||
void dptx_hal_setsdp_downcnt_init_inhblanking(struct mtk_dp *mtk_dp, u16 value);
|
||||
void dptx_hal_setsdp_downcnt_init(struct mtk_dp *mtk_dp, u16 value);
|
||||
void dptx_hal_settu_setencoder(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_set_msa(struct mtk_dp *mtk_dp);
|
||||
void dptx_hal_setmisc(struct mtk_dp *mtk_dp, u8 cmisc[2]);
|
||||
void dptx_hal_set_color_depth(struct mtk_dp *mtk_dp, u8 color_depth);
|
||||
void dptx_hal_set_color_format(struct mtk_dp *mtk_dp, u8 color_format);
|
||||
void dptx_hal_set_txrate(struct mtk_dp *mtk_dp, int value);
|
||||
void dptx_hal_analog_power_en(struct mtk_dp *mtk_dp, bool enable);
|
||||
|
||||
#endif /* SOC_MEDIATEK_MT8195_DPTX_HAL_H */
|
4740
src/soc/mediatek/mt8195/include/soc/dptx_reg.h
Normal file
4740
src/soc/mediatek/mt8195/include/soc/dptx_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user