forked from Minki/linux
drm/nouveau/bios: allow passing in crtc to the init table parser
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
4784e4aa47
commit
02e4f5877d
@ -296,6 +296,11 @@ munge_reg(struct nvbios *bios, uint32_t reg)
|
||||
if (dev_priv->card_type < NV_50)
|
||||
return reg;
|
||||
|
||||
if (reg & 0x80000000) {
|
||||
BUG_ON(bios->display.crtc < 0);
|
||||
reg += bios->display.crtc * 0x800;
|
||||
}
|
||||
|
||||
if (reg & 0x40000000) {
|
||||
BUG_ON(!dcbent);
|
||||
|
||||
@ -304,7 +309,7 @@ munge_reg(struct nvbios *bios, uint32_t reg)
|
||||
reg += 0x00000080;
|
||||
}
|
||||
|
||||
reg &= ~0x60000000;
|
||||
reg &= ~0xe0000000;
|
||||
return reg;
|
||||
}
|
||||
|
||||
@ -4496,8 +4501,8 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
|
||||
uint32_t sub, int pxclk)
|
||||
nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
|
||||
struct dcb_entry *dcbent, int crtc)
|
||||
{
|
||||
/*
|
||||
* The display script table is located by the BIT 'U' table.
|
||||
@ -4587,22 +4592,22 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pxclk < -2 || pxclk > 0) {
|
||||
if (pclk < -2 || pclk > 0) {
|
||||
/* Try to find matching script table entry */
|
||||
for (i = 0; i < otable[5]; i++) {
|
||||
if (ROM16(otable[table[4] + i*6]) == sub)
|
||||
if (ROM16(otable[table[4] + i*6]) == type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == otable[5]) {
|
||||
NV_ERROR(dev, "Table 0x%04x not found for %d/%d, "
|
||||
"using first\n",
|
||||
sub, dcbent->type, dcbent->or);
|
||||
type, dcbent->type, dcbent->or);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pxclk == 0) {
|
||||
if (pclk == 0) {
|
||||
script = ROM16(otable[6]);
|
||||
if (!script) {
|
||||
NV_DEBUG_KMS(dev, "output script 0 not found\n");
|
||||
@ -4610,9 +4615,9 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
|
||||
}
|
||||
|
||||
NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
|
||||
} else
|
||||
if (pxclk == -1) {
|
||||
if (pclk == -1) {
|
||||
script = ROM16(otable[8]);
|
||||
if (!script) {
|
||||
NV_DEBUG_KMS(dev, "output script 1 not found\n");
|
||||
@ -4620,9 +4625,9 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
|
||||
}
|
||||
|
||||
NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
|
||||
} else
|
||||
if (pxclk == -2) {
|
||||
if (pclk == -2) {
|
||||
if (table[4] >= 12)
|
||||
script = ROM16(otable[10]);
|
||||
else
|
||||
@ -4633,31 +4638,31 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
|
||||
}
|
||||
|
||||
NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
|
||||
} else
|
||||
if (pxclk > 0) {
|
||||
if (pclk > 0) {
|
||||
script = ROM16(otable[table[4] + i*6 + 2]);
|
||||
if (script)
|
||||
script = clkcmptable(bios, script, pxclk);
|
||||
script = clkcmptable(bios, script, pclk);
|
||||
if (!script) {
|
||||
NV_DEBUG_KMS(dev, "clock script 0 not found\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
|
||||
} else
|
||||
if (pxclk < 0) {
|
||||
if (pclk < 0) {
|
||||
script = ROM16(otable[table[4] + i*6 + 4]);
|
||||
if (script)
|
||||
script = clkcmptable(bios, script, -pxclk);
|
||||
script = clkcmptable(bios, script, -pclk);
|
||||
if (!script) {
|
||||
NV_DEBUG_KMS(dev, "clock script 1 not found\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent);
|
||||
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -6804,7 +6809,7 @@ uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev)
|
||||
|
||||
void
|
||||
nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
|
||||
struct dcb_entry *dcbent)
|
||||
struct dcb_entry *dcbent, int crtc)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nvbios *bios = &dev_priv->vbios;
|
||||
@ -6812,6 +6817,7 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
|
||||
|
||||
spin_lock_bh(&bios->lock);
|
||||
bios->display.output = dcbent;
|
||||
bios->display.crtc = crtc;
|
||||
parse_init_table(bios, table, &iexec);
|
||||
bios->display.output = NULL;
|
||||
spin_unlock_bh(&bios->lock);
|
||||
@ -6898,9 +6904,8 @@ nouveau_run_vbios_init(struct drm_device *dev)
|
||||
|
||||
if (dev_priv->card_type >= NV_50) {
|
||||
for (i = 0; i < bios->dcb.entries; i++) {
|
||||
nouveau_bios_run_display_table(dev,
|
||||
&bios->dcb.entry[i],
|
||||
0, 0);
|
||||
nouveau_bios_run_display_table(dev, 0, 0,
|
||||
&bios->dcb.entry[i], -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,6 +289,7 @@ struct nvbios {
|
||||
|
||||
struct {
|
||||
struct dcb_entry *output;
|
||||
int crtc;
|
||||
uint16_t script_table_ptr;
|
||||
uint16_t dp_table_ptr;
|
||||
} display;
|
||||
|
@ -300,7 +300,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder)
|
||||
if (dpe->script0) {
|
||||
NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
|
||||
nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
|
||||
nv_encoder->dcb);
|
||||
nv_encoder->dcb, -1);
|
||||
}
|
||||
|
||||
train:
|
||||
@ -433,7 +433,7 @@ stop:
|
||||
if (dpe->script1) {
|
||||
NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
|
||||
nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
|
||||
nv_encoder->dcb);
|
||||
nv_encoder->dcb, -1);
|
||||
}
|
||||
|
||||
/* re-enable hotplug detect */
|
||||
|
@ -1039,7 +1039,7 @@ extern int nouveau_bios_init(struct drm_device *);
|
||||
extern void nouveau_bios_takedown(struct drm_device *dev);
|
||||
extern int nouveau_run_vbios_init(struct drm_device *);
|
||||
extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table,
|
||||
struct dcb_entry *);
|
||||
struct dcb_entry *, int crtc);
|
||||
extern struct dcb_gpio_entry *nouveau_bios_gpio_entry(struct drm_device *,
|
||||
enum dcb_gpio_tag);
|
||||
extern struct dcb_connector_table_entry *
|
||||
@ -1047,9 +1047,8 @@ nouveau_bios_connector_entry(struct drm_device *, int index);
|
||||
extern u32 get_pll_register(struct drm_device *, enum pll_types);
|
||||
extern int get_pll_limits(struct drm_device *, uint32_t limit_match,
|
||||
struct pll_lims *);
|
||||
extern int nouveau_bios_run_display_table(struct drm_device *,
|
||||
struct dcb_entry *,
|
||||
uint32_t script, int pxclk);
|
||||
extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk,
|
||||
struct dcb_entry *, int crtc);
|
||||
extern void *nouveau_bios_dp_table(struct drm_device *, struct dcb_entry *,
|
||||
int *length);
|
||||
extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
|
||||
|
@ -689,7 +689,7 @@ nv50_display_unk10_handler(struct drm_device *dev)
|
||||
struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i];
|
||||
|
||||
if (dcb->type == type && (dcb->or & (1 << or))) {
|
||||
nouveau_bios_run_display_table(dev, dcb, 0, -1);
|
||||
nouveau_bios_run_display_table(dev, 0, -1, dcb, -1);
|
||||
disp->irq.dcb = dcb;
|
||||
goto ack;
|
||||
}
|
||||
@ -744,7 +744,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
|
||||
NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
|
||||
dcb = disp->irq.dcb;
|
||||
if (dcb) {
|
||||
nouveau_bios_run_display_table(dev, dcb, 0, -2);
|
||||
nouveau_bios_run_display_table(dev, 0, -2, dcb, -1);
|
||||
disp->irq.dcb = NULL;
|
||||
}
|
||||
|
||||
@ -828,7 +828,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
|
||||
}
|
||||
|
||||
script = nv50_display_script_select(dev, dcb, mc, pclk);
|
||||
nouveau_bios_run_display_table(dev, dcb, script, pclk);
|
||||
nouveau_bios_run_display_table(dev, script, pclk, dcb, -1);
|
||||
|
||||
nv50_display_unk20_dp_hack(dev, dcb);
|
||||
|
||||
@ -895,7 +895,7 @@ nv50_display_unk40_handler(struct drm_device *dev)
|
||||
if (!dcb)
|
||||
goto ack;
|
||||
|
||||
nouveau_bios_run_display_table(dev, dcb, script, -pclk);
|
||||
nouveau_bios_run_display_table(dev, script, -pclk, dcb, -1);
|
||||
nv50_display_unk40_dp_set_tmds(dev, dcb);
|
||||
|
||||
ack:
|
||||
|
@ -115,15 +115,15 @@ nv50_pm_clock_set(struct drm_device *dev, void *pre_state)
|
||||
BIT_M.version == 1 && BIT_M.length >= 0x0b) {
|
||||
script = ROM16(BIT_M.data[0x05]);
|
||||
if (script)
|
||||
nouveau_bios_run_init_table(dev, script, NULL);
|
||||
nouveau_bios_run_init_table(dev, script, NULL, -1);
|
||||
script = ROM16(BIT_M.data[0x07]);
|
||||
if (script)
|
||||
nouveau_bios_run_init_table(dev, script, NULL);
|
||||
nouveau_bios_run_init_table(dev, script, NULL, -1);
|
||||
script = ROM16(BIT_M.data[0x09]);
|
||||
if (script)
|
||||
nouveau_bios_run_init_table(dev, script, NULL);
|
||||
nouveau_bios_run_init_table(dev, script, NULL, -1);
|
||||
|
||||
nouveau_bios_run_init_table(dev, perflvl->memscript, NULL);
|
||||
nouveau_bios_run_init_table(dev, perflvl->memscript, NULL, -1);
|
||||
}
|
||||
|
||||
if (state->type == PLL_MEMORY) {
|
||||
|
Loading…
Reference in New Issue
Block a user