* [PATCH] follow up: aty128fb and EDID
@ 2003-02-21 1:12 Magnus Damm
0 siblings, 0 replies; only message in thread
From: Magnus Damm @ 2003-02-21 1:12 UTC (permalink / raw)
To: linuxppc-dev; +Cc: brad
[-- Attachment #1: Type: text/plain, Size: 353 bytes --]
Hi,
Here comes a quick hack that adds EDID support to aty128fb.
I took the EDID code from the radeon driver and modified it.
It's not pretty, but it might be useful for someone.
So consider it a quick fix.
The 2.5-tree has a file called fbmon.c that has EDID
functionallity broken out, that should probably be the
long term solution.
thanks /
magnus
[-- Attachment #2: linuxppc_2_4-aty128fb_edid.patch --]
[-- Type: application/octet-stream, Size: 4739 bytes --]
--- linuxppc_2_4/drivers/video/aty128fb.c 2003-02-20 20:12:35.000000000 +0000
+++ linuxppc_2_4-aty128fb_edid/drivers/video/aty128fb.c 2003-02-21 01:06:21.000000000 +0000
@@ -329,10 +329,17 @@
int crt_on, lcd_on;
u32 save_lcd_gen_cntl;
#endif
+ unsigned char *EDID;
};
static struct fb_info_aty128 *board_list = NULL;
+static void aty128_get_EDID(struct fb_info_aty128 *rinfo);
+static int aty128_dfp_parse_EDID(struct fb_info_aty128 *rinfo);
+#ifdef CONFIG_ALL_PPC
+static int aty128_get_EDID_OF(struct fb_info_aty128 *rinfo);
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
+
#ifdef CONFIG_PMAC_PBOOK
int aty128_sleep_notify(struct pmu_sleep_notifier *self, int when);
static struct pmu_sleep_notifier aty128_sleep_notifier = {
@@ -340,6 +347,8 @@
};
#endif
+#endif
+
#define round_div(n, d) ((n+(d/2))/d)
/*
@@ -1858,6 +1867,7 @@
#endif
var = default_var;
+ aty128_get_EDID(info);
#ifdef CONFIG_PPC
if (_machine == _MACH_Pmac) {
if (mode_option) {
@@ -1893,8 +1903,14 @@
if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_cmode = CMODE_8;
- if (mac_vmode_to_var(default_vmode, default_cmode, &var))
+ if (mac_vmode_to_var(default_vmode, default_cmode, &var))
var = default_var;
+
+ if (aty128_dfp_parse_EDID(info)) {
+ default_var = var;
+ aty128_dfp_parse_EDID(info);
+ var = default_var;
+ }
}
} else
#endif /* CONFIG_PPC */
@@ -2220,6 +2236,116 @@
}
#endif /* !CONFIG_PPC */
+static void aty128_get_EDID(struct fb_info_aty128 *rinfo)
+{
+#ifdef CONFIG_ALL_PPC
+ if (!aty128_get_EDID_OF(rinfo))
+ DBG("could not retrieve EDID from OF\n");
+#else
+ /* XXX use other methods later */
+#endif
+}
+
+static int aty128_dfp_parse_EDID(struct fb_info_aty128 *rinfo)
+{
+ unsigned char *block = rinfo->EDID;
+ unsigned int hblank, vblank;
+ unsigned int hOver_plus, vOver_plus;
+ unsigned int hSync_width, vSync_width;
+ unsigned int interlaced, synct, misc;
+ unsigned int hAct_high, vAct_high;
+ int k;
+
+ if (!block)
+ return 0;
+
+ /* jump to the detailed timing block section */
+ block += 54;
+
+ for (k = 0; k < 4; k++) {
+ block = &rinfo->EDID[0x36 + (k*18)];
+
+ if ((block[0] == 0) && (block[1] == 0) &&
+ (block[2] == 0) && (block[4] == 0)) {
+ continue;
+ }
+
+
+ default_var.pixclock = 100000000 / (block[0] + (block[1] << 8));
+ default_var.xres = (block[2] + ((block[4] & 0xf0) << 4));
+ default_var.xres_virtual = default_var.xres;
+ hblank = (block[3] + ((block[4] & 0x0f) << 8));
+ default_var.yres = (block[5] + ((block[7] & 0xf0) << 4));
+ default_var.yres_virtual = default_var.yres;
+ vblank = (block[6] + ((block[7] & 0x0f) << 8));
+ hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
+ hSync_width = (block[9] + ((block[11] & 0x30) << 4));
+ vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
+ vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
+
+ default_var.xoffset = default_var.yoffset = 0;
+
+ default_var.left_margin = (hblank - hOver_plus - hSync_width);
+ default_var.right_margin = hOver_plus;
+ default_var.upper_margin = (vblank - vOver_plus - vSync_width);
+ default_var.lower_margin = vOver_plus;
+ default_var.hsync_len = hSync_width;
+ default_var.vsync_len = vSync_width;
+ default_var.sync = 0;
+
+ interlaced = ((block[17] & 0x80) >> 7);
+ synct = ((block[17] & 0x18) >> 3);
+ misc = ((block[17] & 0x06) >> 1);
+ hAct_high = vAct_high = 0;
+ if (synct == 3) {
+ if (misc & 2)
+ hAct_high = 1;
+ if (misc & 1)
+ vAct_high = 1;
+ }
+
+ if (synct == 3) {
+ if (hAct_high)
+ default_var.sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (vAct_high)
+ default_var.sync |= FB_SYNC_VERT_HIGH_ACT;
+ }
+
+ default_var.vmode = 0;
+ if (interlaced)
+ default_var.vmode |= FB_VMODE_INTERLACED;
+
+ DBG("detected panel size from EDID: %dx%d\n",
+ default_var.xres, default_var.yres);
+
+ return 1;
+ }
+ return 0;
+}
+
+
+
+#ifdef CONFIG_ALL_PPC
+static int aty128_get_EDID_OF(struct fb_info_aty128 *rinfo)
+{
+ struct device_node *dp;
+ unsigned char *pedid = NULL;
+
+ dp = pci_device_to_OF_node(rinfo->pdev);
+ pedid = (unsigned char *) get_property(dp, "DFP,EDID", 0);
+ if (!pedid)
+ pedid = (unsigned char *) get_property(dp, "LCD,EDID", 0);
+ if (!pedid)
+ pedid = (unsigned char *) get_property(dp, "EDID", 0);
+
+ if (pedid) {
+ rinfo->EDID = pedid;
+ return 1;
+ } else
+ return 0;
+}
+#endif /* CONFIG_ALL_PPC */
+
/* fill in known card constants if pll_block is not available */
static void __init
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-02-21 1:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-02-21 1:12 [PATCH] follow up: aty128fb and EDID Magnus Damm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).