From e1ecb1c8d7cdb81d80453486e09e35ed7e107fbd Mon Sep 17 00:00:00 2001 From: macallan Date: Tue, 11 Dec 2012 03:00:00 +0000 Subject: [PATCH] work around a bug in some (all?) nvidia OF ROMs: the color! method always changes only the palette registers associated with the first, usually analog head, even if the monitor in use is on port 2, usually DVI or ADC. Don't enable cmap_callback when we find out we're on port 2 of an nvidia card, that way genfb won't try to use R3G3B2 colours and assume something resembling an ANSI palette which will at least gives us something usable, as opposed to black on mostly black. --- sys/arch/macppc/macppc/machdep.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c index a38295d5537d..1c31f8d282ad 100644 --- a/sys/arch/macppc/macppc/machdep.c +++ b/sys/arch/macppc/macppc/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.163 2012/03/13 17:26:05 macallan Exp $ */ +/* $NetBSD: machdep.c,v 1.164 2012/12/11 03:00:00 macallan Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.163 2012/03/13 17:26:05 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.164 2012/12/11 03:00:00 macallan Exp $"); #include "opt_compat_netbsd.h" #include "opt_ddb.h" @@ -112,6 +112,7 @@ struct genfb_parameter_callback gpc_backlight, gpc_brightness; * state so we assume the backlight is on and about 4/5 up which seems * reasonable for most laptops */ + int backlight_state = 1; int brightness_level = 200; @@ -269,9 +270,11 @@ callback(void *p) void copy_disp_props(device_t dev, int node, prop_dictionary_t dict) { + char name[32]; uint32_t temp; uint64_t cmap_cb, backlight_cb, brightness_cb; int have_backlight = 0; + int have_palette = 1; if (node != console_node) { /* @@ -316,7 +319,19 @@ copy_disp_props(device_t dev, int node, prop_dictionary_t dict) if (fbaddr != 0) prop_dictionary_set_uint32(dict, "address", fbaddr); } - of_to_dataprop(dict, node, "EDID", "EDID"); + if (of_to_dataprop(dict, node, "EDID", "EDID")) { + aprint_verbose("found EDID property...\n"); + } else if (of_to_dataprop(dict, node, "EDID,A", "EDID")) { + aprint_verbose("found EDID,A\n"); + } else if (of_to_dataprop(dict, node, "EDID,B", "EDID")) { + memset(name, 0, sizeof(name)); + OF_getprop(node, "name", name, sizeof(name)); + if (strcmp(name, "NVDA,NVMac") == 0) { + aprint_verbose("found EDID,B on nvidia - assuming digital output\n"); + prop_dictionary_set_bool(dict, "no_palette_control", 1); + have_palette = 0; + } + } add_model_specifics(dict); temp = 0; @@ -328,10 +343,12 @@ copy_disp_props(device_t dev, int node, prop_dictionary_t dict) if (temp != 0) prop_dictionary_set_uint32(dict, "refclk", temp / 10); - gfb_cb.gcc_cookie = (void *)console_instance; - gfb_cb.gcc_set_mapreg = of_set_palette; - cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; - prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); + if (have_palette) { + gfb_cb.gcc_cookie = (void *)console_instance; + gfb_cb.gcc_set_mapreg = of_set_palette; + cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; + prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); + } /* not let's look for backlight control */ have_backlight = 0; @@ -342,6 +359,7 @@ copy_disp_props(device_t dev, int node, prop_dictionary_t dict) have_backlight = 1; } if (have_backlight) { + gpc_backlight.gpc_cookie = (void *)console_instance; gpc_backlight.gpc_set_parameter = of_set_backlight; gpc_backlight.gpc_get_parameter = of_get_backlight;