Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148330019
D28604.id83759.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D28604.id83759.diff
View Options
Index: sys/dev/vt/hw/ofwfb/ofwfb.c
===================================================================
--- sys/dev/vt/hw/ofwfb/ofwfb.c
+++ sys/dev/vt/hw/ofwfb/ofwfb.c
@@ -47,6 +47,7 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_subr.h>
struct ofwfb_softc {
struct fb_info fb;
@@ -55,8 +56,13 @@
ihandle_t sc_handle;
bus_space_tag_t sc_memt;
int iso_palette;
+ int argb;
+ int endian_flip;
+ uint32_t vendor_id;
};
+#define PCI_VENDOR_ID_NVIDIA 0x10de
+
static void ofwfb_initialize(struct vt_device *vd);
static vd_probe_t ofwfb_probe;
static vd_init_t ofwfb_init;
@@ -297,7 +303,6 @@
struct ofwfb_softc *sc = vd->vd_softc;
int i, err;
cell_t retval;
- uint32_t oldpix;
sc->fb.fb_cmsize = 16;
@@ -311,6 +316,10 @@
sc->iso_palette = 0;
switch (sc->fb.fb_bpp) {
case 8:
+ /*
+ * No color format issues here, since we are passing the RGB
+ * components separately to Open Firmware.
+ */
vt_generate_cons_palette(sc->fb.fb_cmap, COLOR_FORMAT_RGB, 255,
16, 255, 8, 255, 0);
@@ -330,21 +339,38 @@
case 32:
/*
- * We bypass the usual bus_space_() accessors here, mostly
- * for performance reasons. In particular, we don't want
- * any barrier operations that may be performed and handle
- * endianness slightly different. Figure out the host-view
- * endianness of the frame buffer.
+ * There are two main color formats in use.
+ * ARGB32 is used mainly on hardware that was designed for
+ * LE systems, and RGBA32 is used mainly on hardware designed
+ * for BE systems.
+ *
+ * PowerMacs use either, depending on the video card option.
+ * NVidia cards tend to be RGBA32, and ATI cards tend to be ARGB32.
+ *
+ * There is no good way to determine the correct option, as this
+ * is independent of endian swapping.
*/
- oldpix = bus_space_read_4(sc->sc_memt, sc->fb.fb_vbase, 0);
- bus_space_write_4(sc->sc_memt, sc->fb.fb_vbase, 0, 0xff000000);
- if (*(uint8_t *)(sc->fb.fb_vbase) == 0xff)
- vt_generate_cons_palette(sc->fb.fb_cmap,
- COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16);
+ if (sc->vendor_id == PCI_VENDOR_ID_NVIDIA)
+ sc->argb = 0;
else
- vt_generate_cons_palette(sc->fb.fb_cmap,
- COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0);
- bus_space_write_4(sc->sc_memt, sc->fb.fb_vbase, 0, oldpix);
+ sc->argb = 1;
+
+ TUNABLE_INT_FETCH("hw.ofwfb.argb32_pixel", &sc->argb);
+ if (sc->endian_flip) {
+ if (sc->argb)
+ vt_generate_cons_palette(sc->fb.fb_cmap,
+ COLOR_FORMAT_RGB, 255, 8, 255, 16, 255, 24);
+ else
+ vt_generate_cons_palette(sc->fb.fb_cmap,
+ COLOR_FORMAT_RGB, 255, 24, 255, 16, 255, 8);
+ } else {
+ if (sc->argb)
+ vt_generate_cons_palette(sc->fb.fb_cmap,
+ COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0);
+ else
+ vt_generate_cons_palette(sc->fb.fb_cmap,
+ COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16);
+ }
break;
default:
@@ -361,8 +387,12 @@
phandle_t chosen;
phandle_t node;
uint32_t depth, height, width, stride;
- uint32_t fb_phys;
- int i, len;
+ uint32_t vendor_id = 0;
+ cell_t adr[2];
+ uint64_t user_phys;
+ bus_addr_t fb_phys;
+ bus_size_t fb_phys_size;
+ int i, j, len;
/* Initialize softc */
vd->vd_softc = sc = &ofwfb_conssoftc;
@@ -391,6 +421,16 @@
if (strcmp(buf, "display") != 0)
return (CN_DEAD);
+ /*
+ * Retrieve vendor-id from /chosen parent node, usually pointing to
+ * video card device. This is used to select pixel format later on
+ * ofwfb_initialize()
+ */
+ if (OF_getencprop(OF_parent(node), "vendor-id", &vendor_id,
+ sizeof(vendor_id)) == sizeof(vendor_id))
+ sc->vendor_id = vendor_id;
+
+
/* Keep track of the OF node */
sc->sc_node = node;
@@ -419,35 +459,69 @@
sizeof(stride))
stride = width*depth/8;
+
sc->fb.fb_height = height;
sc->fb.fb_width = width;
sc->fb.fb_stride = stride;
sc->fb.fb_size = sc->fb.fb_height * sc->fb.fb_stride;
+ sc->endian_flip = 0;
+
+#if defined(__powerpc__)
+ if (OF_hasprop(node, "little-endian")) {
+ sc->sc_memt = &bs_le_tag;
+#if BYTE_ORDER == BIG_ENDIAN
+ sc->endian_flip = 1;
+#endif
+ } else if (OF_hasprop(node, "big-endian")) {
+ sc->sc_memt = &bs_be_tag;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ sc->endian_flip = 1;
+#endif
+ }
+ else {
+ /* Assume the framebuffer is in native endian. */
+#if BYTE_ORDER == BIG_ENDIAN
+ sc->sc_memt = &bs_be_tag;
+#else
+ sc->sc_memt = &bs_le_tag;
+#endif
+ }
+#elif defined(__arm__)
+ sc->sc_memt = fdtbus_bs_tag;
+#else
+ #error Unsupported platform!
+#endif
+
/*
* Grab the physical address of the framebuffer, and then map it
* into our memory space. If the MMU is not yet up, it will be
* remapped for us when relocation turns on.
*/
- if (OF_getproplen(node, "address") == sizeof(fb_phys)) {
- /* XXX We assume #address-cells is 1 at this point. */
- OF_getprop(node, "address", &fb_phys, sizeof(fb_phys));
-
- #if defined(__powerpc__)
- sc->sc_memt = &bs_be_tag;
- bus_space_map(sc->sc_memt, fb_phys, sc->fb.fb_size,
- BUS_SPACE_MAP_PREFETCHABLE, &sc->fb.fb_vbase);
- #elif defined(__arm__)
- sc->sc_memt = fdtbus_bs_tag;
- bus_space_map(sc->sc_memt, sc->fb.fb_pbase, sc->fb.fb_size,
- BUS_SPACE_MAP_PREFETCHABLE,
- (bus_space_handle_t *)&sc->fb.fb_vbase);
- #else
- #error Unsupported platform!
- #endif
+ user_phys = 0;
+ TUNABLE_UINT64_FETCH("hw.ofwfb.physaddr", &user_phys);
+ fb_phys = (bus_addr_t)user_phys;
+ if (fb_phys)
+ sc->fb.fb_pbase = (vm_paddr_t)fb_phys;
+ else if (OF_hasprop(node, "address")) {
+
+ switch (OF_getproplen(node, "address")) {
+ case 4:
+ OF_getencprop(node, "address", adr, 4);
+ fb_phys = adr[0];
+ break;
+ case 8:
+ OF_getencprop(node, "address", adr, 8);
+ fb_phys = ((uint64_t)adr[0] << 32) | adr[1];
+ break;
+ default:
+ /* Bad property? */
+ return (CN_DEAD);
+ }
- sc->fb.fb_pbase = fb_phys;
+ sc->fb.fb_pbase = (vm_paddr_t)fb_phys;
} else {
+#if defined(__powerpc__)
/*
* Some IBM systems don't have an address property. Try to
* guess the framebuffer region from the assigned addresses.
@@ -473,7 +547,7 @@
len = 0;
num_pciaddrs = len / sizeof(struct ofw_pci_register);
- fb_phys = num_pciaddrs;
+ j = num_pciaddrs;
for (i = 0; i < num_pciaddrs; i++) {
/* If it is too small, not the framebuffer */
if (pciaddrs[i].size_lo < sc->fb.fb_stride * height)
@@ -484,26 +558,33 @@
continue;
/* This could be the framebuffer */
- fb_phys = i;
+ j = i;
/* If it is prefetchable, it certainly is */
if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE)
break;
}
- if (fb_phys == num_pciaddrs) /* No candidates found */
+ if (j == num_pciaddrs) /* No candidates found */
return (CN_DEAD);
- #if defined(__powerpc__)
- OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->fb.fb_vbase,
- NULL);
- sc->fb.fb_pbase = sc->fb.fb_vbase & ~DMAP_BASE_ADDRESS;
- #else
+ if (ofw_reg_to_paddr(node, j, &fb_phys, &fb_phys_size, NULL) < 0)
+ return (CN_DEAD);
+
+ sc->fb.fb_pbase = (vm_paddr_t)fb_phys;
+#else
/* No ability to interpret assigned-addresses otherwise */
return (CN_DEAD);
- #endif
+#endif
}
+ if (!sc->fb.fb_pbase)
+ return (CN_DEAD);
+
+ bus_space_map(sc->sc_memt, sc->fb.fb_pbase, sc->fb.fb_size,
+ BUS_SPACE_MAP_PREFETCHABLE,
+ (bus_space_handle_t *)&sc->fb.fb_vbase);
+
#if defined(__powerpc__)
/*
* If we are running on PowerPC in real mode (supported only on AIM
Index: sys/sys/fbio.h
===================================================================
--- sys/sys/fbio.h
+++ sys/sys/fbio.h
@@ -136,8 +136,8 @@
fb_leave_t *leave;
fb_setblankmode_t *setblankmode;
- uintptr_t fb_pbase; /* For FB mmap. */
- uintptr_t fb_vbase; /* if NULL, use fb_write/fb_read. */
+ vm_paddr_t fb_pbase; /* For FB mmap. */
+ vm_offset_t fb_vbase; /* if NULL, use fb_write/fb_read. */
void *fb_priv; /* First argument for read/write. */
const char *fb_name;
uint32_t fb_flags;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 18, 5:11 AM (13 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29882254
Default Alt Text
D28604.id83759.diff (7 KB)
Attached To
Mode
D28604: ofwfb: fix incorrect colors on powerpc*, add new tunable parameters
Attached
Detach File
Event Timeline
Log In to Comment