drm/nouveau: bios parser fixes for eDP boards
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
90af89b93c
Коммит
25908b7797
|
@ -26,6 +26,7 @@
|
|||
#define NV_DEBUG_NOTRACE
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "nouveau_encoder.h"
|
||||
|
||||
/* these defines are made up */
|
||||
#define NV_CIO_CRE_44_HEADA 0x0
|
||||
|
@ -1066,6 +1067,126 @@ init_io_flag_condition(struct nvbios *bios, uint16_t offset,
|
|||
return 2;
|
||||
}
|
||||
|
||||
static int
|
||||
init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
/*
|
||||
* INIT_DP_CONDITION opcode: 0x3A ('')
|
||||
*
|
||||
* offset (8 bit): opcode
|
||||
* offset + 1 (8 bit): "sub" opcode
|
||||
* offset + 2 (8 bit): unknown
|
||||
*
|
||||
*/
|
||||
|
||||
struct bit_displayport_encoder_table *dpe = NULL;
|
||||
struct dcb_entry *dcb = bios->display.output;
|
||||
struct drm_device *dev = bios->dev;
|
||||
uint8_t cond = bios->data[offset + 1];
|
||||
int dummy;
|
||||
|
||||
BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond);
|
||||
|
||||
if (!iexec->execute)
|
||||
return 3;
|
||||
|
||||
dpe = nouveau_bios_dp_table(dev, dcb, &dummy);
|
||||
if (!dpe) {
|
||||
NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (cond) {
|
||||
case 0:
|
||||
{
|
||||
struct dcb_connector_table_entry *ent =
|
||||
&bios->dcb.connector.entry[dcb->connector];
|
||||
|
||||
if (ent->type != DCB_CONNECTOR_eDP)
|
||||
iexec->execute = false;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (!(dpe->unknown & cond))
|
||||
iexec->execute = false;
|
||||
break;
|
||||
case 5:
|
||||
{
|
||||
struct nouveau_i2c_chan *auxch;
|
||||
int ret;
|
||||
|
||||
auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index);
|
||||
if (!auxch)
|
||||
return -ENODEV;
|
||||
|
||||
ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (cond & 1)
|
||||
iexec->execute = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NV_WARN(dev, "0x%04X: unknown INIT_3A op: %d\n", offset, cond);
|
||||
break;
|
||||
}
|
||||
|
||||
if (iexec->execute)
|
||||
BIOSLOG(bios, "0x%04X: continuing to execute\n", offset);
|
||||
else
|
||||
BIOSLOG(bios, "0x%04X: skipping following commands\n", offset);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int
|
||||
init_op_3b(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
/*
|
||||
* INIT_3B opcode: 0x3B ('')
|
||||
*
|
||||
* offset (8 bit): opcode
|
||||
* offset + 1 (8 bit): crtc index
|
||||
*
|
||||
*/
|
||||
|
||||
uint8_t or = ffs(bios->display.output->or) - 1;
|
||||
uint8_t index = bios->data[offset + 1];
|
||||
uint8_t data;
|
||||
|
||||
if (!iexec->execute)
|
||||
return 2;
|
||||
|
||||
data = bios_idxprt_rd(bios, 0x3d4, index);
|
||||
bios_idxprt_wr(bios, 0x3d4, index, data & ~(1 << or));
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int
|
||||
init_op_3c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
/*
|
||||
* INIT_3C opcode: 0x3C ('')
|
||||
*
|
||||
* offset (8 bit): opcode
|
||||
* offset + 1 (8 bit): crtc index
|
||||
*
|
||||
*/
|
||||
|
||||
uint8_t or = ffs(bios->display.output->or) - 1;
|
||||
uint8_t index = bios->data[offset + 1];
|
||||
uint8_t data;
|
||||
|
||||
if (!iexec->execute)
|
||||
return 2;
|
||||
|
||||
data = bios_idxprt_rd(bios, 0x3d4, index);
|
||||
bios_idxprt_wr(bios, 0x3d4, index, data | (1 << or));
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int
|
||||
init_idx_addr_latched(struct nvbios *bios, uint16_t offset,
|
||||
struct init_exec *iexec)
|
||||
|
@ -2934,6 +3055,9 @@ static struct init_tbl_entry itbl_entry[] = {
|
|||
{ "INIT_COPY" , 0x37, init_copy },
|
||||
{ "INIT_NOT" , 0x38, init_not },
|
||||
{ "INIT_IO_FLAG_CONDITION" , 0x39, init_io_flag_condition },
|
||||
{ "INIT_DP_CONDITION" , 0x3A, init_dp_condition },
|
||||
{ "INIT_OP_3B" , 0x3B, init_op_3b },
|
||||
{ "INIT_OP_3C" , 0x3C, init_op_3c },
|
||||
{ "INIT_INDEX_ADDRESS_LATCHED" , 0x49, init_idx_addr_latched },
|
||||
{ "INIT_IO_RESTRICT_PLL2" , 0x4A, init_io_restrict_pll2 },
|
||||
{ "INIT_PLL2" , 0x4B, init_pll2 },
|
||||
|
|
Загрузка…
Ссылка в новой задаче