linux-kernel-test/drivers/video/nvidia/nv_of.c
Benjamin Herrenschmidt 85f1503aff [PATCH] nvidiafb: Fix mode setting & PPC support
This patch fixes nvifiafb mode setting code to be closer to what the X
driver does, which actually makes it work on the 5200FX I have access to.
It also fix the routine that gets the EDID from Open Firmware on PPC, it
was broken in various ways and would crash at boot.  Compared to the patch
I posted to linux-fbdev last week, this one just changes a printk to be
closer to the other ones in the driver.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: "Antonino A. Daplas" <adaplas@hotpop.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-07 07:53:49 -08:00

87 lines
1.9 KiB
C

/*
* linux/drivers/video/nvidia/nv_of.c
*
* Copyright 2004 Antonino A. Daplas <adaplas @pol.net>
*
* Based on rivafb-i2c.c
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/fb.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include "nv_type.h"
#include "nv_local.h"
#include "nv_proto.h"
#include "../edid.h"
int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
{
struct nvidia_par *par = info->par;
struct device_node *parent, *dp;
unsigned char *pedid = NULL;
static char *propnames[] = {
"DFP,EDID", "LCD,EDID", "EDID", "EDID1",
"EDID,B", "EDID,A", NULL };
int i;
parent = pci_device_to_OF_node(par->pci_dev);
if (parent == NULL)
return -1;
if (par->twoHeads) {
char *pname;
int len;
for (dp = NULL;
(dp = of_get_next_child(parent, dp)) != NULL;) {
pname = (char *)get_property(dp, "name", NULL);
if (!pname)
continue;
len = strlen(pname);
if ((pname[len-1] == 'A' && conn == 1) ||
(pname[len-1] == 'B' && conn == 2)) {
for (i = 0; propnames[i] != NULL; ++i) {
pedid = (unsigned char *)
get_property(dp, propnames[i],
NULL);
if (pedid != NULL)
break;
}
of_node_put(dp);
break;
}
}
}
if (pedid == NULL) {
for (i = 0; propnames[i] != NULL; ++i) {
pedid = (unsigned char *)
get_property(parent, propnames[i], NULL);
if (pedid != NULL)
break;
}
}
if (pedid) {
*out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
if (*out_edid == NULL)
return -1;
memcpy(*out_edid, pedid, EDID_LENGTH);
printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
return 0;
}
return -1;
}