Skip to content

Commit 2e5702a

Browse files
curroBen Skeggs
authored andcommitted
drm/nouveau: fabricate DCB encoder table for iMac G4
In typical Apple fashion there's no standard information about what encoders are present on this machine, this patch adds a quirk to provide it. Signed-off-by: Francisco Jerez <[email protected]> Signed-off-by: Ben Skeggs <[email protected]>
1 parent 7f4a195 commit 2e5702a

File tree

1 file changed

+38
-64
lines changed

1 file changed

+38
-64
lines changed

drivers/gpu/drm/nouveau/nouveau_bios.c

Lines changed: 38 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6053,52 +6053,17 @@ static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb)
60536053
return entry;
60546054
}
60556055

6056-
static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads)
6056+
static void fabricate_dcb_output(struct dcb_table *dcb, int type, int i2c,
6057+
int heads, int or)
60576058
{
60586059
struct dcb_entry *entry = new_dcb_entry(dcb);
60596060

6060-
entry->type = 0;
6061+
entry->type = type;
60616062
entry->i2c_index = i2c;
60626063
entry->heads = heads;
6063-
entry->location = DCB_LOC_ON_CHIP;
6064-
entry->or = 1;
6065-
}
6066-
6067-
static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads)
6068-
{
6069-
struct dcb_entry *entry = new_dcb_entry(dcb);
6070-
6071-
entry->type = 2;
6072-
entry->i2c_index = LEGACY_I2C_PANEL;
6073-
entry->heads = twoHeads ? 3 : 1;
6074-
entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
6075-
entry->or = 1; /* means |0x10 gets set on CRE_LCD__INDEX */
6076-
entry->duallink_possible = false; /* SiI164 and co. are single link */
6077-
6078-
#if 0
6079-
/*
6080-
* For dvi-a either crtc probably works, but my card appears to only
6081-
* support dvi-d. "nvidia" still attempts to program it for dvi-a,
6082-
* doing the full fp output setup (program 0x6808.. fp dimension regs,
6083-
* setting 0x680848 to 0x10000111 to enable, maybe setting 0x680880);
6084-
* the monitor picks up the mode res ok and lights up, but no pixel
6085-
* data appears, so the board manufacturer probably connected up the
6086-
* sync lines, but missed the video traces / components
6087-
*
6088-
* with this introduction, dvi-a left as an exercise for the reader.
6089-
*/
6090-
fabricate_vga_output(dcb, LEGACY_I2C_PANEL, entry->heads);
6091-
#endif
6092-
}
6093-
6094-
static void fabricate_tv_output(struct dcb_table *dcb, bool twoHeads)
6095-
{
6096-
struct dcb_entry *entry = new_dcb_entry(dcb);
6097-
6098-
entry->type = 1;
6099-
entry->i2c_index = LEGACY_I2C_TV;
6100-
entry->heads = twoHeads ? 3 : 1;
6101-
entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
6064+
if (type != OUTPUT_ANALOG)
6065+
entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
6066+
entry->or = or;
61026067
}
61036068

61046069
static bool
@@ -6365,8 +6330,36 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
63656330
return true;
63666331
}
63676332

6333+
static void
6334+
fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios)
6335+
{
6336+
struct dcb_table *dcb = &bios->dcb;
6337+
int all_heads = (nv_two_heads(dev) ? 3 : 1);
6338+
6339+
#ifdef __powerpc__
6340+
/* Apple iMac G4 NV17 */
6341+
if (of_machine_is_compatible("PowerMac4,5")) {
6342+
fabricate_dcb_output(dcb, OUTPUT_TMDS, 0, all_heads, 1);
6343+
fabricate_dcb_output(dcb, OUTPUT_ANALOG, 1, all_heads, 2);
6344+
return;
6345+
}
6346+
#endif
6347+
6348+
/* Make up some sane defaults */
6349+
fabricate_dcb_output(dcb, OUTPUT_ANALOG, LEGACY_I2C_CRT, 1, 1);
6350+
6351+
if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
6352+
fabricate_dcb_output(dcb, OUTPUT_TV, LEGACY_I2C_TV,
6353+
all_heads, 0);
6354+
6355+
else if (bios->tmds.output0_script_ptr ||
6356+
bios->tmds.output1_script_ptr)
6357+
fabricate_dcb_output(dcb, OUTPUT_TMDS, LEGACY_I2C_PANEL,
6358+
all_heads, 1);
6359+
}
6360+
63686361
static int
6369-
parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
6362+
parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
63706363
{
63716364
struct drm_nouveau_private *dev_priv = dev->dev_private;
63726365
struct dcb_table *dcb = &bios->dcb;
@@ -6386,12 +6379,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
63866379

63876380
/* this situation likely means a really old card, pre DCB */
63886381
if (dcbptr == 0x0) {
6389-
NV_INFO(dev, "Assuming a CRT output exists\n");
6390-
fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
6391-
6392-
if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
6393-
fabricate_tv_output(dcb, twoHeads);
6394-
6382+
fabricate_dcb_encoder_table(dev, bios);
63956383
return 0;
63966384
}
63976385

@@ -6451,21 +6439,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
64516439
*/
64526440
NV_TRACEWARN(dev, "No useful information in BIOS output table; "
64536441
"adding all possible outputs\n");
6454-
fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
6455-
6456-
/*
6457-
* Attempt to detect TV before DVI because the test
6458-
* for the former is more accurate and it rules the
6459-
* latter out.
6460-
*/
6461-
if (nv04_tv_identify(dev,
6462-
bios->legacy.i2c_indices.tv) >= 0)
6463-
fabricate_tv_output(dcb, twoHeads);
6464-
6465-
else if (bios->tmds.output0_script_ptr ||
6466-
bios->tmds.output1_script_ptr)
6467-
fabricate_dvi_i_output(dcb, twoHeads);
6468-
6442+
fabricate_dcb_encoder_table(dev, bios);
64696443
return 0;
64706444
}
64716445

@@ -6859,7 +6833,7 @@ nouveau_bios_init(struct drm_device *dev)
68596833
if (ret)
68606834
return ret;
68616835

6862-
ret = parse_dcb_table(dev, bios, nv_two_heads(dev));
6836+
ret = parse_dcb_table(dev, bios);
68636837
if (ret)
68646838
return ret;
68656839

0 commit comments

Comments
 (0)