intel_extreme: for DDI, map the ddc pin to the GPIO

add port G for Gen12

Change-Id: I70bba2d6d2ec0fbad8bdbec14412ea982690d563
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5626
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Jérôme Duval 2022-09-07 23:01:52 +02:00 committed by Adrien Destugues
parent dbc23cdfb7
commit 4a6a465c80
4 changed files with 117 additions and 14 deletions

View File

@ -249,7 +249,8 @@ enum port_index {
INTEL_PORT_C,
INTEL_PORT_D,
INTEL_PORT_E,
INTEL_PORT_F
INTEL_PORT_F,
INTEL_PORT_G
};
enum pch_info {
@ -1042,6 +1043,7 @@ struct intel_brightness_legacy {
#define DDI_BUF_CTL_D (0x4300 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_E (0x4400 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_F (0x4500 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_G (0x4600 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_ENABLE (1 << 31)
#define DDI_BUF_TRANS_SELECT(n) ((n) << 24)
#define DDI_BUF_EMP_MASK (0xf << 24)
@ -1055,16 +1057,22 @@ struct intel_brightness_legacy {
#define PIPE_DDI_FUNC_CTL_B (0x1400 | REGS_NORTH_PIPE_AND_PORT)
#define PIPE_DDI_FUNC_CTL_C (0x2400 | REGS_NORTH_PIPE_AND_PORT)
#define PIPE_DDI_FUNC_CTL_EDP (0xF400 | REGS_NORTH_PIPE_AND_PORT)
#define PIPE_DDI_FUNC_CTL_DSI0 (0xB400 | REGS_NORTH_PIPE_AND_PORT)
#define PIPE_DDI_FUNC_CTL_DSI1 (0xBC00 | REGS_NORTH_PIPE_AND_PORT)
#define PIPE_DDI_FUNC_CTL_ENABLE (1 << 31)
#define PIPE_DDI_SELECT_SHIFT 28
#define TGL_PIPE_DDI_SELECT_SHIFT 27
#define PIPE_DDI_SELECT_PORT(x) ((x) << PIPE_DDI_SELECT_SHIFT)
#define TGL_PIPE_DDI_SELECT_PORT(x) ((x) << TGL_PIPE_DDI_SELECT_SHIFT)
#define PIPE_DDI_SELECT_MASK (7 << PIPE_DDI_SELECT_SHIFT)
#define TGL_PIPE_DDI_SELECT_MASK (7 << TGL_PIPE_DDI_SELECT_SHIFT)
#define PIPE_DDI_PORT_NONE 0
#define PIPE_DDI_PORT_B 1
#define PIPE_DDI_PORT_C 2
#define PIPE_DDI_PORT_D 3
#define PIPE_DDI_PORT_E 4
#define PIPE_DDI_PORT_F 5
#define PIPE_DDI_PORT_G 6
#define PIPE_DDI_MODESEL_SHIFT 24
#define PIPE_DDI_MODESEL_MODE(x) ((x) << PIPE_DDI_MODESEL_SHIFT)
#define PIPE_DDI_MODESEL_MASK (7 << PIPE_DDI_MODESEL_SHIFT)
@ -1313,6 +1321,12 @@ struct intel_brightness_legacy {
#define INTEL_I2C_IO_F (0x5024 | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_G (0x5028 | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_H (0x502c | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_I (0x5030 | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_J (0x5034 | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_K (0x5038 | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_L (0x503c | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_M (0x5040 | REGS_SOUTH_SHARED)
#define INTEL_I2C_IO_N (0x5044 | REGS_SOUTH_SHARED)
// i2c hardware controller
#define INTEL_GMBUS0 (0x5100 | REGS_SOUTH_SHARED)
#define INTEL_GMBUS4 (0x5110 | REGS_SOUTH_SHARED)

View File

@ -446,6 +446,9 @@ Port::_IsPortInVBT(uint32* foundIndex)
case INTEL_PORT_F:
found = port == DVO_PORT_HDMIF || port == DVO_PORT_DPF;
break;
case INTEL_PORT_G:
found = port == DVO_PORT_HDMIG || port == DVO_PORT_DPG;
break;
default:
ERROR("%s: DDI port unknown\n", __func__);
break;
@ -495,6 +498,95 @@ Port::_IsEDPPort()
}
addr_t
Port::_DDCPin()
{
uint32 foundIndex = 0;
if (!_IsPortInVBT(&foundIndex))
return 0;
child_device_config& config = gInfo->shared_info->device_configs[foundIndex];
if (gInfo->shared_info->pch_info >= INTEL_PCH_ICP) {
switch (config.ddc_pin) {
case 1:
return INTEL_I2C_IO_A;
case 2:
return INTEL_I2C_IO_B;
case 3:
return INTEL_I2C_IO_C;
case 4:
return INTEL_I2C_IO_I;
case 5:
return INTEL_I2C_IO_J;
case 6:
return INTEL_I2C_IO_K;
case 7:
return INTEL_I2C_IO_L;
case 8:
return INTEL_I2C_IO_M;
case 9:
return INTEL_I2C_IO_N;
default:
return 0;
}
} else if (gInfo->shared_info->pch_info >= INTEL_PCH_CNP) {
switch (config.ddc_pin) {
case 1:
return INTEL_I2C_IO_A;
case 2:
return INTEL_I2C_IO_B;
case 3:
return INTEL_I2C_IO_D;
case 4:
return INTEL_I2C_IO_C;
default:
return 0;
}
} else if (gInfo->shared_info->device_type.Generation() == 9) {
switch (config.ddc_pin) {
case 4:
return INTEL_I2C_IO_D;
case 5:
return INTEL_I2C_IO_E;
case 6:
return INTEL_I2C_IO_F;
default:
return 0;
}
} else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_BDW)) {
switch (config.ddc_pin) {
case 2:
return INTEL_I2C_IO_A;
case 4:
return INTEL_I2C_IO_D;
case 5:
return INTEL_I2C_IO_E;
case 6:
return INTEL_I2C_IO_F;
default:
return 0;
}
} else {
switch (config.ddc_pin) {
case 1:
return INTEL_I2C_IO_B;
case 2:
return INTEL_I2C_IO_A;
case 3:
return INTEL_I2C_IO_C;
case 4:
return INTEL_I2C_IO_D;
case 5:
return INTEL_I2C_IO_E;
case 6:
return INTEL_I2C_IO_F;
default:
return 0;
}
}
}
status_t
Port::_SetupDpAuxI2c(i2c_bus *bus)
{
@ -2117,6 +2209,10 @@ DigitalDisplayInterface::_PortRegister()
!gInfo->shared_info->device_type.InGroup(INTEL_GROUP_SKY))
return DDI_BUF_CTL_F;
return 0;
case INTEL_PORT_G:
if (gInfo->shared_info->device_type.Generation() >= 12)
return DDI_BUF_CTL_G;
return 0;
default:
return 0;
}
@ -2127,18 +2223,7 @@ DigitalDisplayInterface::_PortRegister()
addr_t
DigitalDisplayInterface::_DDCRegister()
{
switch (PortIndex()) {
case INTEL_PORT_B:
return INTEL_I2C_IO_E;
case INTEL_PORT_C:
return INTEL_I2C_IO_D;
case INTEL_PORT_D:
return INTEL_I2C_IO_F;
default:
return 0;
}
return 0;
return Port::_DDCPin();
}

View File

@ -80,6 +80,7 @@ static status_t _SetI2CSignals(void* cookie, int clock,
bool _IsDisplayPortInVBT();
bool _IsHdmiInVBT();
bool _IsEDPPort();
addr_t _DDCPin();
status_t _SetupDpAuxI2c(struct i2c_bus *bus);
ssize_t _DpAuxTransfer(dp_aux_msg* message);

View File

@ -304,7 +304,10 @@ probe_ports()
// Digital Display Interface (for DP, HDMI, DVI and eDP)
if (gInfo->shared_info->device_type.HasDDI()) {
for (int i = INTEL_PORT_A; i <= INTEL_PORT_F; i++) {
int maxPort = INTEL_PORT_F;
if (gInfo->shared_info->device_type.Generation() >= 12)
maxPort = INTEL_PORT_G;
for (int i = INTEL_PORT_A; i <= maxPort; i++) {
TRACE("Probing DDI %d\n", i);
Port* ddiPort