Importing sys/dev/videomode
NetBSD provides an in-kernel EDID parser, validator, and printer along with other useful functions. This code will be re-used by the Minix fb driver as it is a complete and well tested implementation. Change-Id: I46fe3005d9957cd90d4972030ddcce7bc3bd7924
This commit is contained in:
parent
6405d78182
commit
bdf33c702a
19 changed files with 3089 additions and 0 deletions
|
@ -109,6 +109,7 @@
|
|||
2013/04/23 12:00:00,sys/dev/Makefile
|
||||
2013/04/23 12:00:00,sys/dev/i2c/Makefile
|
||||
2013/04/23 12:00:00,sys/dev/i2c/i2c_io.h
|
||||
2013/07/22 12:00:00,sys/dev/videomode
|
||||
2012/01/16 18:47:57,sys/lib/libsa
|
||||
2012/10/17 12:00:00,sys/lib/libz
|
||||
2012/10/17 12:00:00,sys/Makefile
|
||||
|
|
15
sys/dev/videomode/Makefile.ediddevs
Normal file
15
sys/dev/videomode/Makefile.ediddevs
Normal file
|
@ -0,0 +1,15 @@
|
|||
# $NetBSD: Makefile.ediddevs,v 1.2 2008/10/19 22:05:23 apb Exp $
|
||||
#
|
||||
# As per tron@NetBSD.org, the proper procedure is
|
||||
#
|
||||
# 1.) Change "src/sys/dev/videomode/ediddevs".
|
||||
# 2.) Commit "src/sys/dev/videomode/ediddevs".
|
||||
# 3.) Execute "make -f Makefile.ediddevs" in "src/sys/dev/videomode".
|
||||
# 4.) Commit "src/sys/dev/videomode/ediddevs.h" and
|
||||
# "src/sys/dev/videomode/ediddevs_data.h".
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
ediddevs.h ediddevs_data.h: ediddevs devlist2h.awk
|
||||
/bin/rm -f ediddevs.h ediddevs_data.h
|
||||
${TOOL_AWK} -f devlist2h.awk ediddevs
|
17
sys/dev/videomode/Makefile.videomode
Normal file
17
sys/dev/videomode/Makefile.videomode
Normal file
|
@ -0,0 +1,17 @@
|
|||
# $NetBSD: Makefile.videomode,v 1.2 2008/10/19 22:05:23 apb Exp $
|
||||
#
|
||||
# As per tron@NetBSD.org, the proper procedure is
|
||||
#
|
||||
# 1.) Change "src/sys/dev/videomode/modelines".
|
||||
# 2.) Commit "src/sys/dev/videomode/modelines".
|
||||
# 3.) Execute "make -f Makefile.videomode" in "src/sys/dev/videomode".
|
||||
# 4.) Commit "src/sys/dev/videomode/videomode.c"
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
videomode.c: modelines modelines2c.awk
|
||||
/bin/rm -f videomode.c
|
||||
${TOOL_AWK} -f modelines2c.awk modelines > videomode.c
|
||||
|
||||
test: videomode.c videomode.h test.c
|
||||
${CC} -I ../../ -o test test.c videomode.c
|
192
sys/dev/videomode/devlist2h.awk
Normal file
192
sys/dev/videomode/devlist2h.awk
Normal file
|
@ -0,0 +1,192 @@
|
|||
#! /usr/bin/awk -f
|
||||
# $NetBSD: devlist2h.awk,v 1.1 2006/05/11 01:49:53 gdamore Exp $
|
||||
#
|
||||
# Copyright (c) 1995, 1996 Christopher G. Demetriou
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by Christopher G. Demetriou.
|
||||
# 4. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
BEGIN {
|
||||
nproducts = nvendors = blanklines = 0
|
||||
dfile="ediddevs_data.h"
|
||||
hfile="ediddevs.h"
|
||||
}
|
||||
NR == 1 {
|
||||
VERSION = $0
|
||||
gsub("\\$", "", VERSION)
|
||||
gsub(/ $/, "", VERSION)
|
||||
|
||||
printf("/*\t$NetBSD" "$\t*/\n\n") > dfile
|
||||
printf("/*\n") > dfile
|
||||
printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
|
||||
> dfile
|
||||
printf(" *\n") > dfile
|
||||
printf(" * generated from:\n") > dfile
|
||||
printf(" *\t%s\n", VERSION) > dfile
|
||||
printf(" */\n") > dfile
|
||||
|
||||
printf("/*\t$NetBSD" "$\t*/\n\n") > hfile
|
||||
printf("/*\n") > hfile
|
||||
printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
|
||||
> hfile
|
||||
printf(" *\n") > hfile
|
||||
printf(" * generated from:\n") > hfile
|
||||
printf(" *\t%s\n", VERSION) > hfile
|
||||
printf(" */\n") > hfile
|
||||
|
||||
next
|
||||
}
|
||||
|
||||
NF > 0 && $1 == "vendor" {
|
||||
nvendors++
|
||||
|
||||
vendorindex[$2] = nvendors; # record index for this name, for later.
|
||||
vendors[nvendors, 1] = $2; # name/ID
|
||||
i = 2; f = 3;
|
||||
|
||||
printf("#define\tEDID_VENDOR_%s\t\"", vendors[nvendors, 1]) > hfile
|
||||
|
||||
# comments
|
||||
oparen = 0
|
||||
while (f <= NF) {
|
||||
if ($f == "#") {
|
||||
printf("(") > hfile
|
||||
oparen = 1
|
||||
f++
|
||||
continue
|
||||
}
|
||||
if (oparen) {
|
||||
printf("%s", $f) > hfile
|
||||
f++
|
||||
continue
|
||||
}
|
||||
vendors[nvendors, i] = $f
|
||||
printf("%s", vendors[nvendors, i]) > hfile
|
||||
if (f < NF)
|
||||
printf(" ") > hfile
|
||||
i++; f++;
|
||||
}
|
||||
if (oparen)
|
||||
printf(")") > hfile
|
||||
printf("\"") > hfile
|
||||
printf("\n") > hfile
|
||||
|
||||
next
|
||||
}
|
||||
|
||||
NF > 0 && $1 == "product" {
|
||||
nproducts++
|
||||
|
||||
products[nproducts, 1] = $2; # vendor name
|
||||
products[nproducts, 2] = $3; # product id
|
||||
products[nproducts, 3] = $4; # id
|
||||
printf("#define\tEDID_PRODUCT_%s_%s\t%s", products[nproducts, 1],
|
||||
products[nproducts, 2], products[nproducts, 3]) > hfile
|
||||
|
||||
i = 4; f = 5;
|
||||
|
||||
ocomment = oparen = 0
|
||||
if (f <= NF) {
|
||||
printf("\t\t/* ") > hfile
|
||||
ocomment = 1;
|
||||
}
|
||||
while (f <= NF) {
|
||||
if ($f == "#") {
|
||||
printf("(") > hfile
|
||||
oparen = 1
|
||||
f++
|
||||
continue
|
||||
}
|
||||
if (oparen) {
|
||||
printf("%s", $f) > hfile
|
||||
if (f < NF)
|
||||
printf(" ") > hfile
|
||||
f++
|
||||
continue
|
||||
}
|
||||
products[nproducts, i] = $f
|
||||
printf("%s", products[nproducts, i]) > hfile
|
||||
if (f < NF)
|
||||
printf(" ") > hfile
|
||||
i++; f++;
|
||||
}
|
||||
if (oparen)
|
||||
printf(")") > hfile
|
||||
if (ocomment)
|
||||
printf(" */") > hfile
|
||||
printf("\n") > hfile
|
||||
|
||||
next
|
||||
}
|
||||
{
|
||||
if ($0 == "")
|
||||
blanklines++
|
||||
if (blanklines != 2 && blanklines != 3)
|
||||
print $0 > hfile
|
||||
if (blanklines < 2)
|
||||
print $0 > dfile
|
||||
}
|
||||
END {
|
||||
# print out the match tables
|
||||
|
||||
printf("\n") > dfile
|
||||
printf("const struct edid_vendor edid_vendors[] = {\n") > dfile
|
||||
|
||||
for (i = 1; i <= nvendors; i++) {
|
||||
printf("\t{") > dfile
|
||||
printf(" \"%s\", EDID_VENDOR_%s", vendors[i, 1], \
|
||||
vendors[i, 1]) > dfile
|
||||
printf(" },\n") > dfile
|
||||
}
|
||||
printf("};\n") > dfile
|
||||
printf("const int edid_nvendors = %d;\n", nvendors) > dfile
|
||||
|
||||
printf("\n") > dfile
|
||||
|
||||
printf("const struct edid_product edid_products[] = {\n") > dfile
|
||||
for (i = 1; i <= nproducts; i++) {
|
||||
printf("\t{\n") > dfile
|
||||
printf("\t \"%s\", EDID_PRODUCT_%s_%s,\n", \
|
||||
products[i, 1], products[i, 1], products[i, 2]) > dfile
|
||||
printf("\t \"") > dfile
|
||||
j = 4
|
||||
needspace = 0
|
||||
while ((i, j) in products) {
|
||||
if (needspace)
|
||||
printf(" ") > dfile
|
||||
printf("%s", products[i, j]) > dfile
|
||||
needspace = 1
|
||||
j++
|
||||
}
|
||||
printf("\",\n") > dfile
|
||||
printf("\t},\n") > dfile
|
||||
}
|
||||
printf("};\n") > dfile
|
||||
printf("const int edid_nproducts = %d;\n", nproducts) >dfile
|
||||
|
||||
close(dfile)
|
||||
close(hfile)
|
||||
}
|
651
sys/dev/videomode/edid.c
Normal file
651
sys/dev/videomode/edid.c
Normal file
|
@ -0,0 +1,651 @@
|
|||
/* $NetBSD: edid.c,v 1.12 2013/02/08 16:35:10 skrll Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: edid.c,v 1.12 2013/02/08 16:35:10 skrll Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifdef __minix
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifndef aprint_debug
|
||||
#define aprint_debug if (0) printf
|
||||
#endif /* !aprint_debug */
|
||||
#else /* !__minix */
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#endif /* !__minix */
|
||||
#include <dev/videomode/videomode.h>
|
||||
#include <dev/videomode/ediddevs.h>
|
||||
#include <dev/videomode/edidreg.h>
|
||||
#include <dev/videomode/edidvar.h>
|
||||
#include <dev/videomode/vesagtf.h>
|
||||
|
||||
#define EDIDVERBOSE 1
|
||||
#define DIVIDE(x,y) (((x) + ((y) / 2)) / (y))
|
||||
|
||||
/* These are reversed established timing order */
|
||||
static const char *_edid_modes[] = {
|
||||
"1280x1024x75",
|
||||
"1024x768x75",
|
||||
"1024x768x70",
|
||||
"1024x768x60",
|
||||
"1024x768x87i",
|
||||
"832x624x74", /* rounding error, 74.55 Hz aka "832x624x75" */
|
||||
"800x600x75",
|
||||
"800x600x72",
|
||||
"800x600x60",
|
||||
"800x600x56",
|
||||
"640x480x75",
|
||||
"640x480x72",
|
||||
"640x480x67",
|
||||
"640x480x60",
|
||||
"720x400x87", /* rounding error, 87.85 Hz aka "720x400x88" */
|
||||
"720x400x70",
|
||||
};
|
||||
|
||||
#ifdef EDIDVERBOSE
|
||||
struct edid_vendor {
|
||||
const char *vendor;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct edid_product {
|
||||
const char *vendor;
|
||||
uint16_t product;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#include <dev/videomode/ediddevs_data.h>
|
||||
#endif /* EDIDVERBOSE */
|
||||
|
||||
static const char *
|
||||
edid_findvendor(const char *vendor)
|
||||
{
|
||||
#ifdef EDIDVERBOSE
|
||||
int n;
|
||||
|
||||
for (n = 0; n < edid_nvendors; n++)
|
||||
if (memcmp(edid_vendors[n].vendor, vendor, 3) == 0)
|
||||
return edid_vendors[n].name;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
edid_findproduct(const char *vendor, uint16_t product)
|
||||
{
|
||||
#ifdef EDIDVERBOSE
|
||||
int n;
|
||||
|
||||
for (n = 0; n < edid_nproducts; n++)
|
||||
if (edid_products[n].product == product &&
|
||||
memcmp(edid_products[n].vendor, vendor, 3) == 0)
|
||||
return edid_products[n].name;
|
||||
#endif /* EDIDVERBOSE */
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
edid_strchomp(char *ptr)
|
||||
{
|
||||
for (;;) {
|
||||
switch (*ptr) {
|
||||
case '\0':
|
||||
return;
|
||||
case '\r':
|
||||
case '\n':
|
||||
*ptr = '\0';
|
||||
return;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
edid_is_valid(uint8_t *d)
|
||||
{
|
||||
int sum = 0, i;
|
||||
uint8_t sig[8] = EDID_SIGNATURE;
|
||||
|
||||
if (memcmp(d, sig, 8) != 0)
|
||||
return EINVAL;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
sum += d[i];
|
||||
if ((sum & 0xff) != 0)
|
||||
return EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
edid_print(struct edid_info *edid)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (edid == NULL)
|
||||
return;
|
||||
printf("Vendor: [%s] %s\n", edid->edid_vendor, edid->edid_vendorname);
|
||||
printf("Product: [%04X] %s\n", edid->edid_product,
|
||||
edid->edid_productname);
|
||||
printf("Serial number: %s\n", edid->edid_serial);
|
||||
printf("Manufactured %d Week %d\n",
|
||||
edid->edid_year, edid->edid_week);
|
||||
printf("EDID Version %d.%d\n", edid->edid_version,
|
||||
edid->edid_revision);
|
||||
printf("EDID Comment: %s\n", edid->edid_comment);
|
||||
|
||||
printf("Video Input: %x\n", edid->edid_video_input);
|
||||
if (edid->edid_video_input & EDID_VIDEO_INPUT_DIGITAL) {
|
||||
printf("\tDigital");
|
||||
if (edid->edid_video_input & EDID_VIDEO_INPUT_DFP1_COMPAT)
|
||||
printf(" (DFP 1.x compatible)");
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("\tAnalog\n");
|
||||
switch (EDID_VIDEO_INPUT_LEVEL(edid->edid_video_input)) {
|
||||
case 0:
|
||||
printf("\t-0.7, 0.3V\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("\t-0.714, 0.286V\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("\t-1.0, 0.4V\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("\t-0.7, 0.0V\n");
|
||||
break;
|
||||
}
|
||||
if (edid->edid_video_input & EDID_VIDEO_INPUT_BLANK_TO_BLACK)
|
||||
printf("\tBlank-to-black setup\n");
|
||||
if (edid->edid_video_input & EDID_VIDEO_INPUT_SEPARATE_SYNCS)
|
||||
printf("\tSeperate syncs\n");
|
||||
if (edid->edid_video_input & EDID_VIDEO_INPUT_COMPOSITE_SYNC)
|
||||
printf("\tComposite sync\n");
|
||||
if (edid->edid_video_input & EDID_VIDEO_INPUT_SYNC_ON_GRN)
|
||||
printf("\tSync on green\n");
|
||||
if (edid->edid_video_input & EDID_VIDEO_INPUT_SERRATION)
|
||||
printf("\tSerration vsync\n");
|
||||
}
|
||||
|
||||
printf("Gamma: %d.%02d\n",
|
||||
edid->edid_gamma / 100, edid->edid_gamma % 100);
|
||||
|
||||
printf("Max Size: %d cm x %d cm\n",
|
||||
edid->edid_max_hsize, edid->edid_max_vsize);
|
||||
|
||||
printf("Features: %x\n", edid->edid_features);
|
||||
if (edid->edid_features & EDID_FEATURES_STANDBY)
|
||||
printf("\tDPMS standby\n");
|
||||
if (edid->edid_features & EDID_FEATURES_SUSPEND)
|
||||
printf("\tDPMS suspend\n");
|
||||
if (edid->edid_features & EDID_FEATURES_ACTIVE_OFF)
|
||||
printf("\tDPMS active-off\n");
|
||||
switch (EDID_FEATURES_DISP_TYPE(edid->edid_features)) {
|
||||
case EDID_FEATURES_DISP_TYPE_MONO:
|
||||
printf("\tMonochrome\n");
|
||||
break;
|
||||
case EDID_FEATURES_DISP_TYPE_RGB:
|
||||
printf("\tRGB\n");
|
||||
break;
|
||||
case EDID_FEATURES_DISP_TYPE_NON_RGB:
|
||||
printf("\tMulticolor\n");
|
||||
break;
|
||||
case EDID_FEATURES_DISP_TYPE_UNDEFINED:
|
||||
printf("\tUndefined monitor type\n");
|
||||
break;
|
||||
}
|
||||
if (edid->edid_features & EDID_FEATURES_STD_COLOR)
|
||||
printf("\tStandard color space\n");
|
||||
if (edid->edid_features & EDID_FEATURES_PREFERRED_TIMING)
|
||||
printf("\tPreferred timing\n");
|
||||
if (edid->edid_features & EDID_FEATURES_DEFAULT_GTF)
|
||||
printf("\tDefault GTF supported\n");
|
||||
|
||||
printf("Chroma Info:\n");
|
||||
printf("\tRed X: 0.%03d\n", edid->edid_chroma.ec_redx);
|
||||
printf("\tRed Y: 0.%03d\n", edid->edid_chroma.ec_redy);
|
||||
printf("\tGrn X: 0.%03d\n", edid->edid_chroma.ec_greenx);
|
||||
printf("\tGrn Y: 0.%03d\n", edid->edid_chroma.ec_greeny);
|
||||
printf("\tBlu X: 0.%03d\n", edid->edid_chroma.ec_bluex);
|
||||
printf("\tBlu Y: 0.%03d\n", edid->edid_chroma.ec_bluey);
|
||||
printf("\tWht X: 0.%03d\n", edid->edid_chroma.ec_whitex);
|
||||
printf("\tWht Y: 0.%03d\n", edid->edid_chroma.ec_whitey);
|
||||
|
||||
if (edid->edid_have_range) {
|
||||
printf("Range:\n");
|
||||
printf("\tHorizontal: %d - %d kHz\n",
|
||||
edid->edid_range.er_min_hfreq,
|
||||
edid->edid_range.er_max_hfreq);
|
||||
printf("\tVertical: %d - %d Hz\n",
|
||||
edid->edid_range.er_min_vfreq,
|
||||
edid->edid_range.er_max_vfreq);
|
||||
printf("\tMax Dot Clock: %d MHz\n",
|
||||
edid->edid_range.er_max_clock);
|
||||
if (edid->edid_range.er_have_gtf2) {
|
||||
printf("\tGTF2 hfreq: %d\n",
|
||||
edid->edid_range.er_gtf2_hfreq);
|
||||
printf("\tGTF2 C: %d\n", edid->edid_range.er_gtf2_c);
|
||||
printf("\tGTF2 M: %d\n", edid->edid_range.er_gtf2_m);
|
||||
printf("\tGTF2 J: %d\n", edid->edid_range.er_gtf2_j);
|
||||
printf("\tGTF2 K: %d\n", edid->edid_range.er_gtf2_k);
|
||||
}
|
||||
}
|
||||
printf("Video modes:\n");
|
||||
for (i = 0; i < edid->edid_nmodes; i++) {
|
||||
printf("\t%dx%d @ %dHz",
|
||||
edid->edid_modes[i].hdisplay,
|
||||
edid->edid_modes[i].vdisplay,
|
||||
DIVIDE(DIVIDE(edid->edid_modes[i].dot_clock * 1000,
|
||||
edid->edid_modes[i].htotal), edid->edid_modes[i].vtotal));
|
||||
printf(" (%d %d %d %d %d %d %d",
|
||||
edid->edid_modes[i].dot_clock,
|
||||
edid->edid_modes[i].hsync_start,
|
||||
edid->edid_modes[i].hsync_end,
|
||||
edid->edid_modes[i].htotal,
|
||||
edid->edid_modes[i].vsync_start,
|
||||
edid->edid_modes[i].vsync_end,
|
||||
edid->edid_modes[i].vtotal);
|
||||
printf(" %s%sH %s%sV)\n",
|
||||
edid->edid_modes[i].flags & VID_PHSYNC ? "+" : "",
|
||||
edid->edid_modes[i].flags & VID_NHSYNC ? "-" : "",
|
||||
edid->edid_modes[i].flags & VID_PVSYNC ? "+" : "",
|
||||
edid->edid_modes[i].flags & VID_NVSYNC ? "-" : "");
|
||||
}
|
||||
if (edid->edid_preferred_mode)
|
||||
printf("Preferred mode: %dx%d @ %dHz\n",
|
||||
edid->edid_preferred_mode->hdisplay,
|
||||
edid->edid_preferred_mode->vdisplay,
|
||||
DIVIDE(DIVIDE(edid->edid_preferred_mode->dot_clock * 1000,
|
||||
edid->edid_preferred_mode->htotal),
|
||||
edid->edid_preferred_mode->vtotal));
|
||||
}
|
||||
|
||||
static const struct videomode *
|
||||
edid_mode_lookup_list(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < videomode_count; i++)
|
||||
if (strcmp(name, videomode_list[i].name) == 0)
|
||||
return &videomode_list[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct videomode *
|
||||
edid_search_mode(struct edid_info *edid, const struct videomode *mode)
|
||||
{
|
||||
int refresh, i;
|
||||
|
||||
refresh = DIVIDE(DIVIDE(mode->dot_clock * 1000,
|
||||
mode->htotal), mode->vtotal);
|
||||
for (i = 0; i < edid->edid_nmodes; i++) {
|
||||
if (mode->hdisplay == edid->edid_modes[i].hdisplay &&
|
||||
mode->vdisplay == edid->edid_modes[i].vdisplay &&
|
||||
refresh == DIVIDE(DIVIDE(
|
||||
edid->edid_modes[i].dot_clock * 1000,
|
||||
edid->edid_modes[i].htotal), edid->edid_modes[i].vtotal)) {
|
||||
return &edid->edid_modes[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
edid_std_timing(uint8_t *data, struct videomode *vmp)
|
||||
{
|
||||
unsigned x, y, f;
|
||||
const struct videomode *lookup;
|
||||
char name[80];
|
||||
|
||||
if ((data[0] == 1 && data[1] == 1) ||
|
||||
(data[0] == 0 && data[1] == 0) ||
|
||||
(data[0] == 0x20 && data[1] == 0x20))
|
||||
return 0;
|
||||
|
||||
x = EDID_STD_TIMING_HRES(data);
|
||||
switch (EDID_STD_TIMING_RATIO(data)) {
|
||||
case EDID_STD_TIMING_RATIO_16_10:
|
||||
y = x * 10 / 16;
|
||||
break;
|
||||
case EDID_STD_TIMING_RATIO_4_3:
|
||||
y = x * 3 / 4;
|
||||
break;
|
||||
case EDID_STD_TIMING_RATIO_5_4:
|
||||
y = x * 4 / 5;
|
||||
break;
|
||||
case EDID_STD_TIMING_RATIO_16_9:
|
||||
default:
|
||||
y = x * 9 / 16;
|
||||
break;
|
||||
}
|
||||
f = EDID_STD_TIMING_VFREQ(data);
|
||||
|
||||
/* first try to lookup the mode as a DMT timing */
|
||||
snprintf(name, sizeof(name), "%dx%dx%d", x, y, f);
|
||||
if ((lookup = edid_mode_lookup_list(name)) != NULL) {
|
||||
*vmp = *lookup;
|
||||
} else {
|
||||
/* failing that, calculate it using gtf */
|
||||
/*
|
||||
* Hmm. I'm not using alternate GTF timings, which
|
||||
* could, in theory, be present.
|
||||
*/
|
||||
vesagtf_mode(x, y, f, vmp);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
edid_det_timing(uint8_t *data, struct videomode *vmp)
|
||||
{
|
||||
unsigned hactive, hblank, hsyncwid, hsyncoff;
|
||||
unsigned vactive, vblank, vsyncwid, vsyncoff;
|
||||
uint8_t flags;
|
||||
|
||||
flags = EDID_DET_TIMING_FLAGS(data);
|
||||
|
||||
/* we don't support stereo modes (for now) */
|
||||
if (flags & (EDID_DET_TIMING_FLAG_STEREO |
|
||||
EDID_DET_TIMING_FLAG_STEREO_MODE))
|
||||
return 0;
|
||||
|
||||
vmp->dot_clock = EDID_DET_TIMING_DOT_CLOCK(data) / 1000;
|
||||
|
||||
hactive = EDID_DET_TIMING_HACTIVE(data);
|
||||
hblank = EDID_DET_TIMING_HBLANK(data);
|
||||
hsyncwid = EDID_DET_TIMING_HSYNC_WIDTH(data);
|
||||
hsyncoff = EDID_DET_TIMING_HSYNC_OFFSET(data);
|
||||
|
||||
vactive = EDID_DET_TIMING_VACTIVE(data);
|
||||
vblank = EDID_DET_TIMING_VBLANK(data);
|
||||
vsyncwid = EDID_DET_TIMING_VSYNC_WIDTH(data);
|
||||
vsyncoff = EDID_DET_TIMING_VSYNC_OFFSET(data);
|
||||
|
||||
/* Borders are contained within the blank areas. */
|
||||
|
||||
vmp->hdisplay = hactive;
|
||||
vmp->htotal = hactive + hblank;
|
||||
vmp->hsync_start = hactive + hsyncoff;
|
||||
vmp->hsync_end = vmp->hsync_start + hsyncwid;
|
||||
|
||||
vmp->vdisplay = vactive;
|
||||
vmp->vtotal = vactive + vblank;
|
||||
vmp->vsync_start = vactive + vsyncoff;
|
||||
vmp->vsync_end = vmp->vsync_start + vsyncwid;
|
||||
|
||||
vmp->flags = 0;
|
||||
|
||||
if (flags & EDID_DET_TIMING_FLAG_INTERLACE)
|
||||
vmp->flags |= VID_INTERLACE;
|
||||
if (flags & EDID_DET_TIMING_FLAG_HSYNC_POSITIVE)
|
||||
vmp->flags |= VID_PHSYNC;
|
||||
else
|
||||
vmp->flags |= VID_NHSYNC;
|
||||
|
||||
if (flags & EDID_DET_TIMING_FLAG_VSYNC_POSITIVE)
|
||||
vmp->flags |= VID_PVSYNC;
|
||||
else
|
||||
vmp->flags |= VID_NVSYNC;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
edid_block(struct edid_info *edid, uint8_t *data)
|
||||
{
|
||||
int i;
|
||||
struct videomode mode, *exist_mode;
|
||||
|
||||
if (EDID_BLOCK_IS_DET_TIMING(data)) {
|
||||
if (!edid_det_timing(data, &mode))
|
||||
return;
|
||||
/* Does this mode already exist? */
|
||||
exist_mode = edid_search_mode(edid, &mode);
|
||||
if (exist_mode != NULL) {
|
||||
*exist_mode = mode;
|
||||
if (edid->edid_preferred_mode == NULL)
|
||||
edid->edid_preferred_mode = exist_mode;
|
||||
} else {
|
||||
edid->edid_modes[edid->edid_nmodes] = mode;
|
||||
if (edid->edid_preferred_mode == NULL)
|
||||
edid->edid_preferred_mode =
|
||||
&edid->edid_modes[edid->edid_nmodes];
|
||||
edid->edid_nmodes++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (EDID_BLOCK_TYPE(data)) {
|
||||
case EDID_DESC_BLOCK_TYPE_SERIAL:
|
||||
memcpy(edid->edid_serial, data + EDID_DESC_ASCII_DATA_OFFSET,
|
||||
EDID_DESC_ASCII_DATA_LEN);
|
||||
edid->edid_serial[sizeof(edid->edid_serial) - 1] = 0;
|
||||
break;
|
||||
|
||||
case EDID_DESC_BLOCK_TYPE_ASCII:
|
||||
memcpy(edid->edid_comment, data + EDID_DESC_ASCII_DATA_OFFSET,
|
||||
EDID_DESC_ASCII_DATA_LEN);
|
||||
edid->edid_comment[sizeof(edid->edid_comment) - 1] = 0;
|
||||
break;
|
||||
|
||||
case EDID_DESC_BLOCK_TYPE_RANGE:
|
||||
edid->edid_have_range = 1;
|
||||
edid->edid_range.er_min_vfreq = EDID_DESC_RANGE_MIN_VFREQ(data);
|
||||
edid->edid_range.er_max_vfreq = EDID_DESC_RANGE_MAX_VFREQ(data);
|
||||
edid->edid_range.er_min_hfreq = EDID_DESC_RANGE_MIN_HFREQ(data);
|
||||
edid->edid_range.er_max_hfreq = EDID_DESC_RANGE_MAX_HFREQ(data);
|
||||
edid->edid_range.er_max_clock = EDID_DESC_RANGE_MAX_CLOCK(data);
|
||||
if (!EDID_DESC_RANGE_HAVE_GTF2(data))
|
||||
break;
|
||||
edid->edid_range.er_have_gtf2 = 1;
|
||||
edid->edid_range.er_gtf2_hfreq =
|
||||
EDID_DESC_RANGE_GTF2_HFREQ(data);
|
||||
edid->edid_range.er_gtf2_c = EDID_DESC_RANGE_GTF2_C(data);
|
||||
edid->edid_range.er_gtf2_m = EDID_DESC_RANGE_GTF2_M(data);
|
||||
edid->edid_range.er_gtf2_j = EDID_DESC_RANGE_GTF2_J(data);
|
||||
edid->edid_range.er_gtf2_k = EDID_DESC_RANGE_GTF2_K(data);
|
||||
break;
|
||||
|
||||
case EDID_DESC_BLOCK_TYPE_NAME:
|
||||
/* copy the product name into place */
|
||||
memcpy(edid->edid_productname,
|
||||
data + EDID_DESC_ASCII_DATA_OFFSET,
|
||||
EDID_DESC_ASCII_DATA_LEN);
|
||||
break;
|
||||
|
||||
case EDID_DESC_BLOCK_TYPE_STD_TIMING:
|
||||
data += EDID_DESC_STD_TIMING_START;
|
||||
for (i = 0; i < EDID_DESC_STD_TIMING_COUNT; i++) {
|
||||
if (edid_std_timing(data, &mode)) {
|
||||
/* Does this mode already exist? */
|
||||
exist_mode = edid_search_mode(edid, &mode);
|
||||
if (exist_mode == NULL) {
|
||||
edid->edid_modes[edid->edid_nmodes] =
|
||||
mode;
|
||||
edid->edid_nmodes++;
|
||||
}
|
||||
}
|
||||
data += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case EDID_DESC_BLOCK_TYPE_COLOR_POINT:
|
||||
/* XXX: not implemented yet */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets EDID version in BCD, e.g. EDID v1.3 returned as 0x0103
|
||||
*/
|
||||
int
|
||||
edid_parse(uint8_t *data, struct edid_info *edid)
|
||||
{
|
||||
uint16_t manfid, estmodes;
|
||||
const struct videomode *vmp;
|
||||
int i;
|
||||
const char *name;
|
||||
int max_dotclock = 0;
|
||||
int mhz;
|
||||
|
||||
if (edid_is_valid(data) != 0)
|
||||
return -1;
|
||||
|
||||
/* get product identification */
|
||||
manfid = EDID_VENDOR_ID(data);
|
||||
edid->edid_vendor[0] = EDID_MANFID_0(manfid);
|
||||
edid->edid_vendor[1] = EDID_MANFID_1(manfid);
|
||||
edid->edid_vendor[2] = EDID_MANFID_2(manfid);
|
||||
edid->edid_vendor[3] = 0; /* null terminate for convenience */
|
||||
|
||||
edid->edid_product = data[EDID_OFFSET_PRODUCT_ID] +
|
||||
(data[EDID_OFFSET_PRODUCT_ID + 1] << 8);
|
||||
|
||||
name = edid_findvendor(edid->edid_vendor);
|
||||
if (name != NULL)
|
||||
strlcpy(edid->edid_vendorname, name,
|
||||
sizeof(edid->edid_vendorname));
|
||||
else
|
||||
edid->edid_vendorname[0] = '\0';
|
||||
|
||||
name = edid_findproduct(edid->edid_vendor, edid->edid_product);
|
||||
if (name != NULL)
|
||||
strlcpy(edid->edid_productname, name,
|
||||
sizeof(edid->edid_productname));
|
||||
else
|
||||
edid->edid_productname[0] = '\0';
|
||||
|
||||
snprintf(edid->edid_serial, sizeof(edid->edid_serial), "%08x",
|
||||
EDID_SERIAL_NUMBER(data));
|
||||
|
||||
edid->edid_week = EDID_WEEK(data);
|
||||
edid->edid_year = EDID_YEAR(data);
|
||||
|
||||
/* get edid revision */
|
||||
edid->edid_version = EDID_VERSION(data);
|
||||
edid->edid_revision = EDID_REVISION(data);
|
||||
|
||||
edid->edid_video_input = EDID_VIDEO_INPUT(data);
|
||||
edid->edid_max_hsize = EDID_MAX_HSIZE(data);
|
||||
edid->edid_max_vsize = EDID_MAX_VSIZE(data);
|
||||
|
||||
edid->edid_gamma = EDID_GAMMA(data);
|
||||
edid->edid_features = EDID_FEATURES(data);
|
||||
|
||||
edid->edid_chroma.ec_redx = EDID_CHROMA_REDX(data);
|
||||
edid->edid_chroma.ec_redy = EDID_CHROMA_REDX(data);
|
||||
edid->edid_chroma.ec_greenx = EDID_CHROMA_GREENX(data);
|
||||
edid->edid_chroma.ec_greeny = EDID_CHROMA_GREENY(data);
|
||||
edid->edid_chroma.ec_bluex = EDID_CHROMA_BLUEX(data);
|
||||
edid->edid_chroma.ec_bluey = EDID_CHROMA_BLUEY(data);
|
||||
edid->edid_chroma.ec_whitex = EDID_CHROMA_WHITEX(data);
|
||||
edid->edid_chroma.ec_whitey = EDID_CHROMA_WHITEY(data);
|
||||
|
||||
/* lookup established modes */
|
||||
edid->edid_nmodes = 0;
|
||||
edid->edid_preferred_mode = NULL;
|
||||
estmodes = EDID_EST_TIMING(data);
|
||||
/* Iterate in esztablished timing order */
|
||||
for (i = 15; i >= 0; i--) {
|
||||
if (estmodes & (1 << i)) {
|
||||
vmp = edid_mode_lookup_list(_edid_modes[i]);
|
||||
if (vmp != NULL) {
|
||||
edid->edid_modes[edid->edid_nmodes] = *vmp;
|
||||
edid->edid_nmodes++;
|
||||
}
|
||||
#ifdef DIAGNOSTIC
|
||||
else
|
||||
printf("no data for est. mode %s\n",
|
||||
_edid_modes[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* do standard timing section */
|
||||
for (i = 0; i < EDID_STD_TIMING_COUNT; i++) {
|
||||
struct videomode mode, *exist_mode;
|
||||
if (edid_std_timing(data + EDID_OFFSET_STD_TIMING + i * 2,
|
||||
&mode)) {
|
||||
/* Does this mode already exist? */
|
||||
exist_mode = edid_search_mode(edid, &mode);
|
||||
if (exist_mode == NULL) {
|
||||
edid->edid_modes[edid->edid_nmodes] = mode;
|
||||
edid->edid_nmodes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* do detailed timings and descriptors */
|
||||
for (i = 0; i < EDID_BLOCK_COUNT; i++) {
|
||||
edid_block(edid, data + EDID_OFFSET_DESC_BLOCK +
|
||||
i * EDID_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
edid_strchomp(edid->edid_vendorname);
|
||||
edid_strchomp(edid->edid_productname);
|
||||
edid_strchomp(edid->edid_serial);
|
||||
edid_strchomp(edid->edid_comment);
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* some monitors lie about their maximum supported dot clock
|
||||
* by claiming to support modes which need a higher dot clock
|
||||
* than the stated maximum.
|
||||
* For sanity's sake we bump it to the highest dot clock we find
|
||||
* in the list of supported modes
|
||||
*/
|
||||
for (i = 0; i < edid->edid_nmodes; i++)
|
||||
if (edid->edid_modes[i].dot_clock > max_dotclock)
|
||||
max_dotclock = edid->edid_modes[i].dot_clock;
|
||||
|
||||
aprint_debug("max_dotclock according to supported modes: %d\n",
|
||||
max_dotclock);
|
||||
|
||||
mhz = (max_dotclock + 999) / 1000;
|
||||
|
||||
if (edid->edid_have_range) {
|
||||
if (mhz > edid->edid_range.er_max_clock)
|
||||
edid->edid_range.er_max_clock = mhz;
|
||||
} else
|
||||
edid->edid_range.er_max_clock = mhz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
105
sys/dev/videomode/ediddevs
Normal file
105
sys/dev/videomode/ediddevs
Normal file
|
@ -0,0 +1,105 @@
|
|||
$NetBSD: ediddevs,v 1.3 2009/01/21 14:40:02 jnemeth Exp $
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Use "make -f Makefile.ediddevs" to regenerate ediddevs.h and ediddevs_data.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* List of known EDID monitor vendors
|
||||
*
|
||||
* These are standard PNP ids, managed (apparently) by Microsoft.
|
||||
* It is likely that this list is grossly incomplete.
|
||||
*/
|
||||
vendor AAC AcerView
|
||||
vendor AOC AOC
|
||||
vendor APP Apple Computer
|
||||
vendor AST AST Research
|
||||
vendor CPL Compal
|
||||
vendor CPQ Compaq
|
||||
vendor CTX CTX
|
||||
vendor DEC DEC
|
||||
vendor DEL Dell
|
||||
vendor DPC Delta
|
||||
vendor DWE Daewoo
|
||||
vendor EIZ EIZO
|
||||
vendor ELS ELSA
|
||||
vendor EPI Envision
|
||||
vendor FCM Funai
|
||||
vendor FUJ Fujitsu
|
||||
vendor GSM LG Electronics
|
||||
vendor GWY Gateway 2000
|
||||
vendor HEI Hyundai
|
||||
vendor HIT Hitachi
|
||||
vendor HSL Hansol
|
||||
vendor HTC Hitachi/Nissei
|
||||
vendor HWP HP
|
||||
vendor IBM IBM
|
||||
vendor ICL Fujitsu ICL
|
||||
vendor IVM Iiyama
|
||||
vendor KDS Korea Data Systems
|
||||
vendor MEI Panasonic
|
||||
vendor MEL Mitsubishi Electronics
|
||||
vendor NAN Nanao
|
||||
vendor NEC NEC
|
||||
vendor NOK Nokia Data
|
||||
vendor PHL Philips
|
||||
vendor REL Relisys
|
||||
vendor SAM Samsung
|
||||
vendor SGI SGI
|
||||
vendor SNY Sony
|
||||
vendor SRC Shamrock
|
||||
vendor SUN Sun Microsystems
|
||||
vendor TAT Tatung
|
||||
vendor TOS Toshiba
|
||||
vendor TSB Toshiba
|
||||
vendor VSC ViewSonic
|
||||
vendor ZCM Zenith
|
||||
|
||||
/*
|
||||
* List of known products, grouped and sorted by vendor.
|
||||
*
|
||||
* EDID version 1.3 requires that monitors expose the monitor name with
|
||||
* the ASCII descriptor type 0xFC, so for monitors using that block, this
|
||||
* information is redundant, and there is not point in listing them here,
|
||||
* unless it is desired to have a symbolic macro to detect the monitor in
|
||||
* special handling code or somesuch.
|
||||
*/
|
||||
|
||||
/* Dell - this exists for now as a sample. I don't have one of these. */
|
||||
product DEL ULTRASCAN14XE_REVA 0x139A Ultrascan 14XE
|
||||
product DEL ULTRASCAN14XE_REVB 0x139B Ultrascan 14XE
|
||||
|
||||
/* ViewSonic */
|
||||
product VSC 17GS 0x0c00 17GS
|
||||
product VSC 17PS 0x0c0f 17PS
|
91
sys/dev/videomode/ediddevs.h
Normal file
91
sys/dev/videomode/ediddevs.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* $NetBSD: ediddevs.h,v 1.2 2007/03/07 18:47:55 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
*
|
||||
* generated from:
|
||||
* NetBSD: ediddevs,v 1.1 2006/05/11 01:49:53 gdamore Exp
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#define EDID_VENDOR_AAC "AcerView"
|
||||
#define EDID_VENDOR_AOC "AOC"
|
||||
#define EDID_VENDOR_APP "Apple Computer"
|
||||
#define EDID_VENDOR_AST "AST Research"
|
||||
#define EDID_VENDOR_CPL "Compal"
|
||||
#define EDID_VENDOR_CPQ "Compaq"
|
||||
#define EDID_VENDOR_CTX "CTX"
|
||||
#define EDID_VENDOR_DEC "DEC"
|
||||
#define EDID_VENDOR_DEL "Dell"
|
||||
#define EDID_VENDOR_DPC "Delta"
|
||||
#define EDID_VENDOR_DWE "Daewoo"
|
||||
#define EDID_VENDOR_EIZ "EIZO"
|
||||
#define EDID_VENDOR_ELS "ELSA"
|
||||
#define EDID_VENDOR_EPI "Envision"
|
||||
#define EDID_VENDOR_FCM "Funai"
|
||||
#define EDID_VENDOR_FUJ "Fujitsu"
|
||||
#define EDID_VENDOR_GSM "LG Electronics"
|
||||
#define EDID_VENDOR_GWY "Gateway 2000"
|
||||
#define EDID_VENDOR_HEI "Hyundai"
|
||||
#define EDID_VENDOR_HIT "Hitachi"
|
||||
#define EDID_VENDOR_HSL "Hansol"
|
||||
#define EDID_VENDOR_HTC "Hitachi/Nissei"
|
||||
#define EDID_VENDOR_HWP "HP"
|
||||
#define EDID_VENDOR_IBM "IBM"
|
||||
#define EDID_VENDOR_ICL "Fujitsu ICL"
|
||||
#define EDID_VENDOR_IVM "Iiyama"
|
||||
#define EDID_VENDOR_KDS "Korea Data Systems"
|
||||
#define EDID_VENDOR_MEI "Panasonic"
|
||||
#define EDID_VENDOR_MEL "Mitsubishi Electronics"
|
||||
#define EDID_VENDOR_NAN "Nanao"
|
||||
#define EDID_VENDOR_NEC "NEC"
|
||||
#define EDID_VENDOR_NOK "Nokia Data"
|
||||
#define EDID_VENDOR_PHL "Philips"
|
||||
#define EDID_VENDOR_REL "Relisys"
|
||||
#define EDID_VENDOR_SAM "Samsung"
|
||||
#define EDID_VENDOR_SGI "SGI"
|
||||
#define EDID_VENDOR_SNY "Sony"
|
||||
#define EDID_VENDOR_SRC "Shamrock"
|
||||
#define EDID_VENDOR_SUN "Sun Microsystems"
|
||||
#define EDID_VENDOR_TAT "Tatung"
|
||||
#define EDID_VENDOR_TOS "Toshiba"
|
||||
#define EDID_VENDOR_TSB "Toshiba"
|
||||
#define EDID_VENDOR_VSC "ViewSonic"
|
||||
#define EDID_VENDOR_ZCM "Zenith"
|
||||
|
||||
/* Dell - this exists for now as a sample. I don't have one of these. */
|
||||
#define EDID_PRODUCT_DEL_ULTRASCAN14XE_REVA 0x139A /* Ultrascan 14XE */
|
||||
#define EDID_PRODUCT_DEL_ULTRASCAN14XE_REVB 0x139B /* Ultrascan 14XE */
|
||||
|
||||
/* ViewSonic */
|
||||
#define EDID_PRODUCT_VSC_17GS 0x0c00 /* 17GS */
|
||||
#define EDID_PRODUCT_VSC_17PS 0x0c0f /* 17PS */
|
107
sys/dev/videomode/ediddevs_data.h
Normal file
107
sys/dev/videomode/ediddevs_data.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* $NetBSD: ediddevs_data.h,v 1.2 2007/03/07 18:47:13 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
*
|
||||
* generated from:
|
||||
* NetBSD: ediddevs,v 1.1 2006/05/11 01:49:53 gdamore Exp
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
const struct edid_vendor edid_vendors[] = {
|
||||
{ "AAC", EDID_VENDOR_AAC },
|
||||
{ "AOC", EDID_VENDOR_AOC },
|
||||
{ "APP", EDID_VENDOR_APP },
|
||||
{ "AST", EDID_VENDOR_AST },
|
||||
{ "CPL", EDID_VENDOR_CPL },
|
||||
{ "CPQ", EDID_VENDOR_CPQ },
|
||||
{ "CTX", EDID_VENDOR_CTX },
|
||||
{ "DEC", EDID_VENDOR_DEC },
|
||||
{ "DEL", EDID_VENDOR_DEL },
|
||||
{ "DPC", EDID_VENDOR_DPC },
|
||||
{ "DWE", EDID_VENDOR_DWE },
|
||||
{ "EIZ", EDID_VENDOR_EIZ },
|
||||
{ "ELS", EDID_VENDOR_ELS },
|
||||
{ "EPI", EDID_VENDOR_EPI },
|
||||
{ "FCM", EDID_VENDOR_FCM },
|
||||
{ "FUJ", EDID_VENDOR_FUJ },
|
||||
{ "GSM", EDID_VENDOR_GSM },
|
||||
{ "GWY", EDID_VENDOR_GWY },
|
||||
{ "HEI", EDID_VENDOR_HEI },
|
||||
{ "HIT", EDID_VENDOR_HIT },
|
||||
{ "HSL", EDID_VENDOR_HSL },
|
||||
{ "HTC", EDID_VENDOR_HTC },
|
||||
{ "HWP", EDID_VENDOR_HWP },
|
||||
{ "IBM", EDID_VENDOR_IBM },
|
||||
{ "ICL", EDID_VENDOR_ICL },
|
||||
{ "IVM", EDID_VENDOR_IVM },
|
||||
{ "KDS", EDID_VENDOR_KDS },
|
||||
{ "MEI", EDID_VENDOR_MEI },
|
||||
{ "MEL", EDID_VENDOR_MEL },
|
||||
{ "NAN", EDID_VENDOR_NAN },
|
||||
{ "NEC", EDID_VENDOR_NEC },
|
||||
{ "NOK", EDID_VENDOR_NOK },
|
||||
{ "PHL", EDID_VENDOR_PHL },
|
||||
{ "REL", EDID_VENDOR_REL },
|
||||
{ "SAM", EDID_VENDOR_SAM },
|
||||
{ "SGI", EDID_VENDOR_SGI },
|
||||
{ "SNY", EDID_VENDOR_SNY },
|
||||
{ "SRC", EDID_VENDOR_SRC },
|
||||
{ "SUN", EDID_VENDOR_SUN },
|
||||
{ "TAT", EDID_VENDOR_TAT },
|
||||
{ "TOS", EDID_VENDOR_TOS },
|
||||
{ "TSB", EDID_VENDOR_TSB },
|
||||
{ "VSC", EDID_VENDOR_VSC },
|
||||
{ "ZCM", EDID_VENDOR_ZCM },
|
||||
};
|
||||
const int edid_nvendors = 44;
|
||||
|
||||
const struct edid_product edid_products[] = {
|
||||
{
|
||||
"DEL", EDID_PRODUCT_DEL_ULTRASCAN14XE_REVA,
|
||||
"Ultrascan 14XE",
|
||||
},
|
||||
{
|
||||
"DEL", EDID_PRODUCT_DEL_ULTRASCAN14XE_REVB,
|
||||
"Ultrascan 14XE",
|
||||
},
|
||||
{
|
||||
"VSC", EDID_PRODUCT_VSC_17GS,
|
||||
"17GS",
|
||||
},
|
||||
{
|
||||
"VSC", EDID_PRODUCT_VSC_17PS,
|
||||
"17PS",
|
||||
},
|
||||
};
|
||||
const int edid_nproducts = 4;
|
253
sys/dev/videomode/edidreg.h
Normal file
253
sys/dev/videomode/edidreg.h
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* $NetBSD: edidreg.h,v 1.3 2011/03/30 18:49:56 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEV_VIDEOMODE_EDIDREG_H
|
||||
#define _DEV_VIDEOMODE_EDIDREG_H
|
||||
|
||||
#define EDID_OFFSET_SIGNATURE 0x00
|
||||
#define EDID_OFFSET_MANUFACTURER_ID 0x08
|
||||
#define EDID_OFFSET_PRODUCT_ID 0x0a
|
||||
#define EDID_OFFSET_SERIAL_NUMBER 0x0c
|
||||
#define EDID_OFFSET_MANUFACTURE_WEEK 0x10
|
||||
#define EDID_OFFSET_MANUFACTURE_YEAR 0x11
|
||||
#define EDID_OFFSET_VERSION 0x12
|
||||
#define EDID_OFFSET_REVISION 0x13
|
||||
#define EDID_OFFSET_VIDEO_INPUT 0x14
|
||||
#define EDID_OFFSET_MAX_HSIZE 0x15 /* in cm */
|
||||
#define EDID_OFFSET_MAX_VSIZE 0x16
|
||||
#define EDID_OFFSET_GAMMA 0x17
|
||||
#define EDID_OFFSET_FEATURE 0x18
|
||||
#define EDID_OFFSET_CHROMA 0x19
|
||||
#define EDID_OFFSET_EST_TIMING_1 0x23
|
||||
#define EDID_OFFSET_EST_TIMING_2 0x24
|
||||
#define EDID_OFFSET_MFG_TIMING 0x25
|
||||
#define EDID_OFFSET_STD_TIMING 0x26
|
||||
#define EDID_OFFSET_DESC_BLOCK 0x36
|
||||
|
||||
#define EDID_SIGNATURE { 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0 }
|
||||
|
||||
/* assume x is 16-bit value */
|
||||
#define EDID_VENDOR_ID(ptr) ((((ptr)[8]) << 8) + ptr[9])
|
||||
#define EDID_MANFID_0(x) ((((x) >> 10) & 0x1f) + '@')
|
||||
#define EDID_MANFID_1(x) ((((x) >> 5) & 0x1f) + '@')
|
||||
#define EDID_MANFID_2(x) ((((x) >> 0) & 0x1f) + '@')
|
||||
|
||||
/* relative to edid block */
|
||||
#define EDID_PRODUCT_ID(ptr) (((ptr)[10]) | (((ptr)[11]) << 8))
|
||||
#define EDID_SERIAL_NUMBER(ptr) (((ptr)[12] << 24) + \
|
||||
((ptr)[13] << 16) + \
|
||||
((ptr)[14] << 8) + \
|
||||
(ptr)[15])
|
||||
|
||||
/* relative to edid block */
|
||||
#define EDID_WEEK(ptr) ((ptr)[16])
|
||||
#define EDID_YEAR(ptr) (((ptr)[17]) + 1990)
|
||||
|
||||
#define EDID_VERSION(ptr) ((ptr)[18])
|
||||
#define EDID_REVISION(ptr) ((ptr)[19])
|
||||
|
||||
#define EDID_VIDEO_INPUT(ptr) ((ptr)[20])
|
||||
#define EDID_VIDEO_INPUT_DIGITAL 0x80
|
||||
/* if INPUT_BIT_DIGITAL set */
|
||||
#define EDID_VIDEO_INPUT_DFP1_COMPAT 0x01
|
||||
/* if INPUT_BIT_DIGITAL not set */
|
||||
#define EDID_VIDEO_INPUT_BLANK_TO_BLACK 0x10
|
||||
#define EDID_VIDEO_INPUT_SEPARATE_SYNCS 0x08
|
||||
#define EDID_VIDEO_INPUT_COMPOSITE_SYNC 0x04
|
||||
#define EDID_VIDEO_INPUT_SYNC_ON_GRN 0x02
|
||||
#define EDID_VIDEO_INPUT_SERRATION 0x01
|
||||
#define EDID_VIDEO_INPUT_LEVEL(x) (((x) & 0x60) >> 5)
|
||||
/* meanings of level bits are as follows, I don't know names */
|
||||
/* 0 = 0.7,0.3, 1 = 0.714,0.286, 2 = 1.0,0.4, 3 = 0.7,0.0 */
|
||||
|
||||
/* relative to edid block */
|
||||
#define EDID_MAX_HSIZE(ptr) ((ptr)[21]) /* cm */
|
||||
#define EDID_MAX_VSIZE(ptr) ((ptr)[22]) /* cm */
|
||||
/* gamma is scaled by 100 (avoid fp), e.g. 213 == 2.13 */
|
||||
#define _GAMMA(x) ((x) == 0xff ? 100 : ((x) + 100))
|
||||
#define EDID_GAMMA(ptr) _GAMMA(ptr[23])
|
||||
|
||||
#define EDID_FEATURES(ptr) ((ptr)[24])
|
||||
#define EDID_FEATURES_STANDBY 0x80
|
||||
#define EDID_FEATURES_SUSPEND 0x40
|
||||
#define EDID_FEATURES_ACTIVE_OFF 0x20
|
||||
#define EDID_FEATURES_DISP_TYPE(x) (((x) & 0x18) >> 3)
|
||||
#define EDID_FEATURES_DISP_TYPE_MONO 0
|
||||
#define EDID_FEATURES_DISP_TYPE_RGB 1
|
||||
#define EDID_FEATURES_DISP_TYPE_NON_RGB 2
|
||||
#define EDID_FEATURES_DISP_TYPE_UNDEFINED 3
|
||||
#define EDID_FEATURES_STD_COLOR 0x04
|
||||
#define EDID_FEATURES_PREFERRED_TIMING 0x02
|
||||
#define EDID_FEATURES_DEFAULT_GTF 0x01
|
||||
|
||||
/* chroma values 0.0 - 0.999 scaled as 0-999 */
|
||||
#define _CHLO(byt, shft) (((byt) >> (shft)) & 0x3)
|
||||
#define _CHHI(byt) ((byt) << 2)
|
||||
#define _CHHILO(ptr, l, s, h) (_CHLO((ptr)[l], s) | _CHHI((ptr)[h]))
|
||||
#define _CHROMA(ptr, l, s, h) ((_CHHILO(ptr, l, s, h) * 1000) / 1024)
|
||||
|
||||
#define EDID_CHROMA_REDX(ptr) (_CHROMA(ptr, 25, 6, 27))
|
||||
#define EDID_CHROMA_REDY(ptr) (_CHROMA(ptr, 25, 4, 28))
|
||||
#define EDID_CHROMA_GREENX(ptr) (_CHROMA(ptr, 25, 2, 29))
|
||||
#define EDID_CHROMA_GREENY(ptr) (_CHROMA(ptr, 25, 0, 30))
|
||||
#define EDID_CHROMA_BLUEX(ptr) (_CHROMA(ptr, 26, 6, 31))
|
||||
#define EDID_CHROMA_BLUEY(ptr) (_CHROMA(ptr, 26, 4, 32))
|
||||
#define EDID_CHROMA_WHITEX(ptr) (_CHROMA(ptr, 26, 2, 33))
|
||||
#define EDID_CHROMA_WHITEY(ptr) (_CHROMA(ptr, 26, 0, 34))
|
||||
|
||||
/* relative to edid block */
|
||||
#define EDID_EST_TIMING(ptr) (((ptr)[35] << 8) | (ptr)[36])
|
||||
#define EDID_EST_TIMING_720_400_70 0x8000 /* 720x400 @ 70Hz */
|
||||
#define EDID_EST_TIMING_720_400_88 0x4000 /* 720x400 @ 88Hz */
|
||||
#define EDID_EST_TIMING_640_480_60 0x2000 /* 640x480 @ 60Hz */
|
||||
#define EDID_EST_TIMING_640_480_67 0x1000 /* 640x480 @ 67Hz */
|
||||
#define EDID_EST_TIMING_640_480_72 0x0800 /* 640x480 @ 72Hz */
|
||||
#define EDID_EST_TIMING_640_480_75 0x0400 /* 640x480 @ 75Hz */
|
||||
#define EDID_EST_TIMING_800_600_56 0x0200 /* 800x600 @ 56Hz */
|
||||
#define EDID_EST_TIMING_800_600_60 0x0100 /* 800x600 @ 60Hz */
|
||||
#define EDID_EST_TIMING_800_600_72 0x0080 /* 800x600 @ 72Hz */
|
||||
#define EDID_EST_TIMING_800_600_75 0x0040 /* 800x600 @ 75Hz */
|
||||
#define EDID_EST_TIMING_832_624_75 0x0020 /* 832x624 @ 75Hz */
|
||||
#define EDID_EST_TIMING_1024_768_87I 0x0010 /* 1024x768i @ 87Hz */
|
||||
#define EDID_EST_TIMING_1024_768_60 0x0008 /* 1024x768 @ 60Hz */
|
||||
#define EDID_EST_TIMING_1024_768_70 0x0004 /* 1024x768 @ 70Hz */
|
||||
#define EDID_EST_TIMING_1024_768_75 0x0002 /* 1024x768 @ 75Hz */
|
||||
#define EDID_EST_TIMING_1280_1024_75 0x0001 /* 1280x1024 @ 75Hz */
|
||||
|
||||
/*
|
||||
* N.B.: ptr is relative to standard timing block - used for standard timing
|
||||
* descriptors as well as standard timings section of edid!
|
||||
*/
|
||||
#define EDID_STD_TIMING_HRES(ptr) ((((ptr)[0]) * 8) + 248)
|
||||
#define EDID_STD_TIMING_VFREQ(ptr) ((((ptr)[1]) & 0x3f) + 60)
|
||||
#define EDID_STD_TIMING_RATIO(ptr) ((ptr)[1] & 0xc0)
|
||||
#define EDID_STD_TIMING_RATIO_16_10 0x00
|
||||
#define EDID_STD_TIMING_RATIO_4_3 0x40
|
||||
#define EDID_STD_TIMING_RATIO_5_4 0x80
|
||||
#define EDID_STD_TIMING_RATIO_16_9 0xc0
|
||||
|
||||
#define EDID_STD_TIMING_SIZE 16
|
||||
#define EDID_STD_TIMING_COUNT 8
|
||||
|
||||
/*
|
||||
* N.B.: ptr is relative to descriptor block start
|
||||
*/
|
||||
#define EDID_BLOCK_SIZE 18
|
||||
#define EDID_BLOCK_COUNT 4
|
||||
|
||||
/* detailed timing block.... what a mess */
|
||||
#define EDID_BLOCK_IS_DET_TIMING(ptr) ((ptr)[0] | (ptr)[1])
|
||||
|
||||
#define EDID_DET_TIMING_DOT_CLOCK(ptr) (((ptr)[0] | ((ptr)[1] << 8)) * 10000)
|
||||
#define _HACT_LO(ptr) ((ptr)[2])
|
||||
#define _HBLK_LO(ptr) ((ptr)[3])
|
||||
#define _HACT_HI(ptr) (((ptr)[4] & 0xf0) << 4)
|
||||
#define _HBLK_HI(ptr) (((ptr)[4] & 0x0f) << 8)
|
||||
#define EDID_DET_TIMING_HACTIVE(ptr) (_HACT_LO(ptr) | _HACT_HI(ptr))
|
||||
#define EDID_DET_TIMING_HBLANK(ptr) (_HBLK_LO(ptr) | _HBLK_HI(ptr))
|
||||
#define _VACT_LO(ptr) ((ptr)[5])
|
||||
#define _VBLK_LO(ptr) ((ptr)[6])
|
||||
#define _VACT_HI(ptr) (((ptr)[7] & 0xf0) << 4)
|
||||
#define _VBLK_HI(ptr) (((ptr)[7] & 0x0f) << 8)
|
||||
#define EDID_DET_TIMING_VACTIVE(ptr) (_VACT_LO(ptr) | _VACT_HI(ptr))
|
||||
#define EDID_DET_TIMING_VBLANK(ptr) (_VBLK_LO(ptr) | _VBLK_HI(ptr))
|
||||
#define _HOFF_LO(ptr) ((ptr)[8])
|
||||
#define _HWID_LO(ptr) ((ptr)[9])
|
||||
#define _VOFF_LO(ptr) ((ptr)[10] >> 4)
|
||||
#define _VWID_LO(ptr) ((ptr)[10] & 0xf)
|
||||
#define _HOFF_HI(ptr) (((ptr)[11] & 0xc0) << 2)
|
||||
#define _HWID_HI(ptr) (((ptr)[11] & 0x30) << 4)
|
||||
#define _VOFF_HI(ptr) (((ptr)[11] & 0x0c) << 2)
|
||||
#define _VWID_HI(ptr) (((ptr)[11] & 0x03) << 4)
|
||||
#define EDID_DET_TIMING_HSYNC_OFFSET(ptr) (_HOFF_LO(ptr) | _HOFF_HI(ptr))
|
||||
#define EDID_DET_TIMING_HSYNC_WIDTH(ptr) (_HWID_LO(ptr) | _HWID_HI(ptr))
|
||||
#define EDID_DET_TIMING_VSYNC_OFFSET(ptr) (_VOFF_LO(ptr) | _VOFF_HI(ptr))
|
||||
#define EDID_DET_TIMING_VSYNC_WIDTH(ptr) (_VWID_LO(ptr) | _VWID_HI(ptr))
|
||||
#define _HSZ_LO(ptr) ((ptr)[12])
|
||||
#define _VSZ_LO(ptr) ((ptr)[13])
|
||||
#define _HSZ_HI(ptr) (((ptr)[14] & 0xf0) << 4)
|
||||
#define _VSZ_HI(ptr) (((ptr)[14] & 0x0f) << 8)
|
||||
#define EDID_DET_TIMING_HSIZE(ptr) (_HSZ_LO(ptr) | _HSZ_HI(ptr))
|
||||
#define EDID_DET_TIMING_VSIZE(ptr) (_VSZ_LO(ptr) | _VSZ_HI(ptr))
|
||||
#define EDID_DET_TIMING_HBORDER(ptr) ((ptr)[15])
|
||||
#define EDID_DET_TIMING_VBORDER(ptr) ((ptr)[16])
|
||||
#define EDID_DET_TIMING_FLAGS(ptr) ((ptr)[17])
|
||||
#define EDID_DET_TIMING_FLAG_INTERLACE 0x80
|
||||
#define EDID_DET_TIMING_FLAG_STEREO 0x60 /* stereo or not */
|
||||
#define EDID_DET_TIMING_FLAG_SYNC_SEPARATE 0x18
|
||||
#define EDID_DET_TIMING_FLAG_VSYNC_POSITIVE 0x04
|
||||
#define EDID_DET_TIMING_FLAG_HSYNC_POSITIVE 0x02
|
||||
#define EDID_DET_TIMING_FLAG_STEREO_MODE 0x01 /* stereo mode */
|
||||
|
||||
|
||||
/* N.B.: these tests assume that we already checked for detailed timing! */
|
||||
#define EDID_BLOCK_TYPE(ptr) ((ptr)[3])
|
||||
|
||||
#define EDID_DESC_BLOCK_SIZE 18
|
||||
#define EDID_DESC_BLOCK_TYPE_SERIAL 0xFF
|
||||
#define EDID_DESC_BLOCK_TYPE_ASCII 0xFE
|
||||
#define EDID_DESC_BLOCK_TYPE_RANGE 0xFD
|
||||
#define EDID_DESC_BLOCK_TYPE_NAME 0xFC
|
||||
#define EDID_DESC_BLOCK_TYPE_COLOR_POINT 0xFB
|
||||
#define EDID_DESC_BLOCK_TYPE_STD_TIMING 0xFA
|
||||
|
||||
/* used for descriptors 0xFF, 0xFE, and 0xFC */
|
||||
#define EDID_DESC_ASCII_DATA_OFFSET 5
|
||||
#define EDID_DESC_ASCII_DATA_LEN 13
|
||||
|
||||
#define EDID_DESC_RANGE_MIN_VFREQ(ptr) ((ptr)[5]) /* Hz */
|
||||
#define EDID_DESC_RANGE_MAX_VFREQ(ptr) ((ptr)[6]) /* Hz */
|
||||
#define EDID_DESC_RANGE_MIN_HFREQ(ptr) ((ptr)[7]) /* kHz */
|
||||
#define EDID_DESC_RANGE_MAX_HFREQ(ptr) ((ptr)[8]) /* kHz */
|
||||
#define EDID_DESC_RANGE_MAX_CLOCK(ptr) (((ptr)[9]) * 10) /* MHz */
|
||||
#define EDID_DESC_RANGE_HAVE_GTF2(ptr) (((ptr)[10]) == 0x02)
|
||||
#define EDID_DESC_RANGE_GTF2_HFREQ(ptr) (((ptr)[12]) * 2)
|
||||
#define EDID_DESC_RANGE_GTF2_C(ptr) (((ptr)[13]) / 2)
|
||||
#define EDID_DESC_RANGE_GTF2_M(ptr) ((ptr)[14] + ((ptr)[15] << 8))
|
||||
#define EDID_DESC_RANGE_GTF2_K(ptr) ((ptr)[16])
|
||||
#define EDID_DESC_RANGE_GTF2_J(ptr) ((ptr)[17] / 2)
|
||||
|
||||
#define EDID_DESC_COLOR_WHITEX(ptr)
|
||||
#define EDID_DESC_COLOR_WHITE_INDEX_1(ptr) ((ptr)[5])
|
||||
#define EDID_DESC_COLOR_WHITEX_1(ptr) _CHROMA(ptr, 6, 2, 7)
|
||||
#define EDID_DESC_COLOR_WHITEY_1(ptr) _CHROMA(ptr, 6, 0, 8)
|
||||
#define EDID_DESC_COLOR_GAMMA_1(ptr) _GAMMA(ptr[9])
|
||||
#define EDID_DESC_COLOR_WHITE_INDEX_2(ptr) ((ptr)[10])
|
||||
#define EDID_DESC_COLOR_WHITEX_2(ptr) _CHROMA(ptr, 11, 2, 12)
|
||||
#define EDID_DESC_COLOR_WHITEY_2(ptr) _CHROMA(ptr, 11, 0, 13)
|
||||
#define EDID_DESC_COLOR_GAMMA_2(ptr) _GAMMA(ptr[14])
|
||||
|
||||
#define EDID_DESC_STD_TIMING_START 5
|
||||
#define EDID_DESC_STD_TIMING_COUNT 6
|
||||
|
||||
#endif /* _DEV_VIDEOMODE_EDIDREG_H */
|
94
sys/dev/videomode/edidvar.h
Normal file
94
sys/dev/videomode/edidvar.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* $NetBSD: edidvar.h,v 1.2 2006/05/11 19:05:41 gdamore Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEV_VIDEOMODE_EDIDVAR_H
|
||||
#define _DEV_VIDEOMODE_EDIDVAR_H
|
||||
|
||||
struct edid_chroma {
|
||||
uint16_t ec_redx;
|
||||
uint16_t ec_redy;
|
||||
uint16_t ec_greenx;
|
||||
uint16_t ec_greeny;
|
||||
uint16_t ec_bluex;
|
||||
uint16_t ec_bluey;
|
||||
uint16_t ec_whitex;
|
||||
uint16_t ec_whitey;
|
||||
};
|
||||
|
||||
struct edid_range {
|
||||
uint16_t er_min_vfreq; /* Hz */
|
||||
uint16_t er_max_vfreq; /* Hz */
|
||||
uint16_t er_min_hfreq; /* kHz */
|
||||
uint16_t er_max_hfreq; /* kHz */
|
||||
uint16_t er_max_clock; /* MHz */
|
||||
int er_have_gtf2;
|
||||
uint16_t er_gtf2_hfreq;
|
||||
uint16_t er_gtf2_c;
|
||||
uint16_t er_gtf2_m;
|
||||
uint16_t er_gtf2_k;
|
||||
uint16_t er_gtf2_j;
|
||||
};
|
||||
|
||||
struct edid_info {
|
||||
uint8_t edid_vendor[4];
|
||||
char edid_vendorname[16];
|
||||
char edid_productname[16];
|
||||
char edid_comment[16];
|
||||
char edid_serial[16];
|
||||
uint16_t edid_product;
|
||||
uint8_t edid_version;
|
||||
uint8_t edid_revision;
|
||||
int edid_year;
|
||||
int edid_week;
|
||||
uint8_t edid_video_input; /* see edidregs.h */
|
||||
uint8_t edid_max_hsize; /* in cm */
|
||||
uint8_t edid_max_vsize; /* in cm */
|
||||
uint8_t edid_gamma;
|
||||
uint8_t edid_features;
|
||||
|
||||
int edid_have_range;
|
||||
struct edid_range edid_range;
|
||||
|
||||
struct edid_chroma edid_chroma;
|
||||
|
||||
/* parsed modes */
|
||||
struct videomode *edid_preferred_mode;
|
||||
int edid_nmodes;
|
||||
struct videomode edid_modes[64];
|
||||
};
|
||||
|
||||
int edid_is_valid(uint8_t *);
|
||||
int edid_parse(uint8_t *, struct edid_info *);
|
||||
void edid_print(struct edid_info *);
|
||||
|
||||
#endif /* _DEV_VIDEOMODE_EDIDVAR_H */
|
13
sys/dev/videomode/files.videomode
Normal file
13
sys/dev/videomode/files.videomode
Normal file
|
@ -0,0 +1,13 @@
|
|||
# $NetBSD: files.videomode,v 1.4 2010/05/04 21:17:10 macallan Exp $
|
||||
|
||||
define videomode
|
||||
define edid
|
||||
define vesagtf
|
||||
|
||||
file dev/videomode/videomode.c videomode | edid
|
||||
|
||||
file dev/videomode/edid.c edid
|
||||
file dev/videomode/pickmode.c videomode
|
||||
defflag opt_videomode.h PICKMODE_DEBUG
|
||||
|
||||
file dev/videomode/vesagtf.c vesagtf | edid
|
180
sys/dev/videomode/modelines
Normal file
180
sys/dev/videomode/modelines
Normal file
|
@ -0,0 +1,180 @@
|
|||
// $NetBSD: modelines,v 1.9 2011/03/30 18:45:04 jdc Exp $
|
||||
//
|
||||
// This file was imported from XFree86, and is made of the contents of both
|
||||
// the vesamodes and extramodes files. As a result these should correspond
|
||||
// to the same default modes compiled into XFree86.
|
||||
//
|
||||
// Default modes distilled from
|
||||
// "VESA and Industry Standards and Guide for Computer Display Monitor
|
||||
// Timing", version 1.0, revision 0.8, adopted September 17, 1998.
|
||||
//
|
||||
// $XFree86: xc/programs/Xserver/hw/xfree86/etc/vesamodes,v 1.3 1999/11/16 03:28:03 tsi Exp $
|
||||
// $XFree86: xc/programs/Xserver/hw/xfree86/etc/extramodes,v 1.5 2002/06/05 19:43:05 dawes Exp $
|
||||
//
|
||||
//
|
||||
// Use "make -f Makefile.videomode" to regenerate videomode.c
|
||||
//
|
||||
|
||||
# 640x350 @ 85Hz (VESA) hsync: 37.9kHz
|
||||
ModeLine "640x350" 31.5 640 672 736 832 350 382 385 445 +hsync -vsync
|
||||
|
||||
# 640x400 @ 85Hz (VESA) hsync: 37.9kHz
|
||||
ModeLine "640x400" 31.5 640 672 736 832 400 401 404 445 -hsync +vsync
|
||||
|
||||
# 720x400 @ 70Hz (EDID established timing) hsync: 31.47kHz
|
||||
ModeLine "720x400" 28.32 720 738 846 900 400 412 414 449 -hsync +vsync
|
||||
|
||||
# 720x400 @ 85Hz (VESA) hsync: 37.9kHz
|
||||
ModeLine "720x400" 35.5 720 756 828 936 400 401 404 446 -hsync +vsync
|
||||
|
||||
# 720x400 @ 88Hz (EDID established timing) hsync: 39.44kHz
|
||||
ModeLine "720x400" 35.5 720 738 846 900 400 421 423 449 -hsync -vsync
|
||||
|
||||
# 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz
|
||||
ModeLine "640x480" 25.175 640 656 752 800 480 490 492 525 -hsync -vsync
|
||||
|
||||
# 640x480 @ 72Hz (VESA) hsync: 37.9kHz
|
||||
ModeLine "640x480" 31.5 640 664 704 832 480 489 492 520 -hsync -vsync
|
||||
|
||||
# 640x480 @ 75Hz (VESA) hsync: 37.5kHz
|
||||
ModeLine "640x480" 31.5 640 656 720 840 480 481 484 500 -hsync -vsync
|
||||
|
||||
# 640x480 @ 85Hz (VESA) hsync: 43.3kHz
|
||||
ModeLine "640x480" 36.0 640 696 752 832 480 481 484 509 -hsync -vsync
|
||||
|
||||
# 800x600 @ 56Hz (VESA) hsync: 35.2kHz
|
||||
ModeLine "800x600" 36.0 800 824 896 1024 600 601 603 625 +hsync +vsync
|
||||
|
||||
# 800x600 @ 60Hz (VESA) hsync: 37.9kHz
|
||||
ModeLine "800x600" 40.0 800 840 968 1056 600 601 605 628 +hsync +vsync
|
||||
|
||||
# 800x600 @ 72Hz (VESA) hsync: 48.1kHz
|
||||
ModeLine "800x600" 50.0 800 856 976 1040 600 637 643 666 +hsync +vsync
|
||||
|
||||
# 800x600 @ 75Hz (VESA) hsync: 46.9kHz
|
||||
ModeLine "800x600" 49.5 800 816 896 1056 600 601 604 625 +hsync +vsync
|
||||
|
||||
# 800x600 @ 85Hz (VESA) hsync: 53.7kHz
|
||||
ModeLine "800x600" 56.25 800 832 896 1048 600 601 604 631 +hsync +vsync
|
||||
|
||||
# 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz
|
||||
ModeLine "1024x768" 44.9 1024 1032 1208 1264 768 768 776 817 +hsync +vsync Interlace
|
||||
|
||||
# 1024x768 @ 60Hz (VESA) hsync: 48.4kHz
|
||||
ModeLine "1024x768" 65.0 1024 1048 1184 1344 768 771 777 806 -hsync -vsync
|
||||
|
||||
# 1024x768 @ 70Hz (VESA) hsync: 56.5kHz
|
||||
ModeLine "1024x768" 75.0 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
|
||||
|
||||
# 1024x768 @ 75Hz (VESA) hsync: 60.0kHz
|
||||
ModeLine "1024x768" 78.75 1024 1040 1136 1312 768 769 772 800 +hsync +vsync
|
||||
|
||||
# 1024x768 @ 85Hz (VESA) hsync: 68.7kHz
|
||||
ModeLine "1024x768" 94.5 1024 1072 1168 1376 768 769 772 808 +hsync +vsync
|
||||
|
||||
# 1024x768 @ 89Hz (non-standard) hsync: 72.0kHz
|
||||
ModeLine "1024x768" 100 1024 1108 1280 1408 768 768 780 796 +hsync +vsync
|
||||
|
||||
# 1152x864 @ 75Hz (VESA) hsync: 67.5kHz
|
||||
ModeLine "1152x864" 108.0 1152 1216 1344 1600 864 865 868 900 +hsync +vsync
|
||||
|
||||
# 1280x768 @ 75Hz (non-standard) hsync: 60.6kHz
|
||||
ModeLine "1280x768" 105.64 1280 1312 1712 1744 768 782 792 807 -hsync +vsync
|
||||
|
||||
# 1280x960 @ 60Hz (VESA) hsync: 60.0kHz
|
||||
ModeLine "1280x960" 108.0 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync
|
||||
|
||||
# 1280x960 @ 85Hz (VESA) hsync: 85.9kHz
|
||||
ModeLine "1280x960" 148.5 1280 1344 1504 1728 960 961 964 1011 +hsync +vsync
|
||||
|
||||
# 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz
|
||||
ModeLine "1280x1024" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
|
||||
|
||||
# 1280x1024 @ 70Hz (non-standard) hsync: 74.0kHz
|
||||
ModeLine "1280x1024" 126.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
|
||||
|
||||
# 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz
|
||||
ModeLine "1280x1024" 135.0 1280 1296 1440 1688 1024 1025 1028 1066 +hsync +vsync
|
||||
|
||||
# 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz
|
||||
ModeLine "1280x1024" 157.5 1280 1344 1504 1728 1024 1025 1028 1072 +hsync +vsync
|
||||
|
||||
# 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz
|
||||
ModeLine "1600x1200" 162.0 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
||||
|
||||
# 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz
|
||||
ModeLine "1600x1200" 175.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
||||
|
||||
# 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz
|
||||
ModeLine "1600x1200" 189.0 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
||||
|
||||
# 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz
|
||||
ModeLine "1600x1200" 202.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
||||
|
||||
# 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz
|
||||
ModeLine "1600x1200" 229.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
||||
|
||||
# 1680x1050 @ 60.00Hz (GTF) hsync: 65.22 kHz; pclk: 147.14 MHz
|
||||
ModeLine "1680x1050" 147.14 1680 1784 1968 2256 1050 1051 1054 1087 +hsync +vsync
|
||||
|
||||
# 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz
|
||||
ModeLine "1792x1344" 204.8 1792 1920 2120 2448 1344 1345 1348 1394 -hsync +vsync
|
||||
|
||||
# 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz
|
||||
ModeLine "1792x1344" 261.0 1792 1888 2104 2456 1344 1345 1348 1417 -hsync +vsync
|
||||
|
||||
# 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz
|
||||
ModeLine "1856x1392" 218.3 1856 1952 2176 2528 1392 1393 1396 1439 -hsync +vsync
|
||||
|
||||
# 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz
|
||||
ModeLine "1856x1392" 288.0 1856 1984 2208 2560 1392 1393 1396 1500 -hsync +vsync
|
||||
|
||||
# 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz
|
||||
ModeLine "1920x1440" 234.0 1920 2048 2256 2600 1440 1441 1444 1500 -hsync +vsync
|
||||
|
||||
# 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz
|
||||
ModeLine "1920x1440" 297.0 1920 2064 2288 2640 1440 1441 1444 1500 -hsync +vsync
|
||||
|
||||
|
||||
//
|
||||
// Extra modes to include as default modes in the X server.
|
||||
//
|
||||
// $XFree86: xc/programs/Xserver/hw/xfree86/etc/extramodes,v 1.5 2002/06/05 19:43:05 dawes Exp $
|
||||
//
|
||||
|
||||
# 832x624 @ 75Hz (74.55Hz) (fix if the official/Apple spec is different) hsync: 49.725kHz
|
||||
ModeLine "832x624" 57.284 832 864 928 1152 624 625 628 667 -Hsync -Vsync
|
||||
|
||||
# 1152x768 @ 54.8Hz (Titanium PowerBook) hsync: 44.2kHz
|
||||
ModeLine "1152x768" 64.995 1152 1178 1314 1472 768 771 777 806 +hsync +vsync
|
||||
|
||||
# 1400x1050 @ 60Hz (VESA GTF) hsync: 65.5kHz
|
||||
ModeLine "1400x1050" 122.0 1400 1488 1640 1880 1050 1052 1064 1082 +hsync +vsync
|
||||
|
||||
# 1400x1050 @ 75Hz (VESA GTF) hsync: 82.2kHz
|
||||
ModeLine "1400x1050" 155.8 1400 1464 1784 1912 1050 1052 1064 1090 +hsync +vsync
|
||||
|
||||
# 1600x1024 @ 60Hz (SGI 1600SW) hsync: 64.0kHz
|
||||
Modeline "1600x1024" 106.910 1600 1620 1640 1670 1024 1027 1030 1067 -hsync -vsync
|
||||
|
||||
# 1920x1440 @ 85Hz (VESA GTF) hsync: 128.5kHz
|
||||
Modeline "1920x1440" 341.35 1920 2072 2288 2656 1440 1441 1444 1512 -hsync +vsync
|
||||
|
||||
# 2048x1536 @ 60Hz (VESA GTF) hsync: 95.3kHz
|
||||
Modeline "2048x1536" 266.95 2048 2200 2424 2800 1536 1537 1540 1589 -hsync +vsync
|
||||
|
||||
# 2048x1536 @ 75Hz (VESA GTF) hsync: 120.2kHz
|
||||
Modeline "2048x1536" 340.48 2048 2216 2440 2832 1536 1537 1540 1603 -hsync +vsync
|
||||
|
||||
# 2048x1536 @ 85Hz (VESA GTF) hsync: 137.0kHz
|
||||
Modeline "2048x1536" 388.04 2048 2216 2440 2832 1536 1537 1540 1612 -hsync +vsync
|
||||
|
||||
//
|
||||
// some Sun-specific modes
|
||||
//
|
||||
|
||||
# 1152x900 @ 66Hz - default on most SBus graphics devices
|
||||
ModeLine "1152x900" 94.50 1152 1192 1320 1528 900 902 906 937 -hsync -vsync
|
||||
|
||||
# 1152x900 @ 76Hz
|
||||
ModeLine "1152x900" 105.56 1152 1168 1280 1472 900 902 906 943 -hsync -vsync
|
149
sys/dev/videomode/modelines2c.awk
Normal file
149
sys/dev/videomode/modelines2c.awk
Normal file
|
@ -0,0 +1,149 @@
|
|||
#! /usr/bin/awk -f
|
||||
# $NetBSD: modelines2c.awk,v 1.5 2011/03/21 19:32:26 jdc Exp $
|
||||
#
|
||||
# Copyright (c) 2006 Itronix Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Written by Garrett D'Amore for Itronix Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. The name of Itronix Inc. may not be used to endorse
|
||||
# or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
BEGIN {
|
||||
nmodes = 0;
|
||||
}
|
||||
|
||||
NR == 1 {
|
||||
split($0,v,"$");
|
||||
|
||||
VERSION=v[2];
|
||||
|
||||
printf("/*\t$NetBSD" "$\t*/\n\n");
|
||||
printf("/*\n") ;
|
||||
printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n");
|
||||
printf(" *\n");
|
||||
printf(" * generated from:\n");
|
||||
printf(" *\t%s\n", VERSION);
|
||||
printf(" */\n\n");
|
||||
|
||||
printf("#include <sys/cdefs.h>\n");
|
||||
printf("__KERNEL_RCSID(0, \"$NetBSD" "$\");\n\n");
|
||||
|
||||
printf("#include <dev/videomode/videomode.h>\n\n");
|
||||
|
||||
printf("/*\n");
|
||||
printf(" * These macros help the modelines below fit on one line.\n");
|
||||
printf(" */\n");
|
||||
printf("#define HP VID_PHSYNC\n");
|
||||
printf("#define HN VID_NHSYNC\n");
|
||||
printf("#define VP VID_PVSYNC\n");
|
||||
printf("#define VN VID_NVSYNC\n");
|
||||
printf("#define I VID_INTERLACE\n");
|
||||
printf("#define DS VID_DBLSCAN\n");
|
||||
printf("\n");
|
||||
|
||||
printf("#define M(nm,hr,vr,clk,hs,he,ht,vs,ve,vt,f) \\\n");
|
||||
printf("\t{ clk, hr, hs, he, ht, vr, vs, ve, vt, f, nm } \n\n");
|
||||
|
||||
printf("const struct videomode videomode_list[] = {\n");
|
||||
|
||||
next
|
||||
}
|
||||
|
||||
(/^ModeLine/) {
|
||||
dotclock = $3;
|
||||
|
||||
hdisplay = $4;
|
||||
hsyncstart = $5;
|
||||
hsyncend = $6;
|
||||
htotal = $7;
|
||||
|
||||
vdisplay = $8;
|
||||
vsyncstart = $9;
|
||||
vsyncend = $10;
|
||||
vtotal = $11;
|
||||
|
||||
macro = "MODE";
|
||||
iflag = "";
|
||||
iflags = "";
|
||||
hflags = "HP";
|
||||
vflags = "VP";
|
||||
|
||||
if ($12 ~ "^-")
|
||||
hflags = "HN";
|
||||
|
||||
if ($13 ~ "^-")
|
||||
vflags = "VN";
|
||||
|
||||
ifactor=1.0;
|
||||
if ($14 ~ "[Ii][Nn][Tt][Ee][Rr][Ll][Aa][Cc][Ee]") {
|
||||
iflag = "i";
|
||||
iflags = "|I";
|
||||
ifactor = 2.0;
|
||||
}
|
||||
|
||||
# We truncate the vrefresh figure, but some mode descriptions rely
|
||||
# on rounding, so we can't win here. Adding an additional .1
|
||||
# compensates to some extent.
|
||||
|
||||
hrefresh= (dotclock * 1000000) / htotal;
|
||||
vrefresh= int(((hrefresh * ifactor) / vtotal) + .1);
|
||||
|
||||
modestr = sprintf("%dx%dx%d%s", hdisplay, vdisplay, vrefresh, iflag);
|
||||
|
||||
# printf("/* %dx%d%s refresh %d Hz, hsync %d kHz */\n",
|
||||
# hdisplay, vdisplay, iflag, vrefresh, hrefresh/1000);
|
||||
printf("M(\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%s),\n",
|
||||
modestr,
|
||||
hdisplay, vdisplay, dotclock * 1000,
|
||||
hsyncstart, hsyncend, htotal,
|
||||
vsyncstart, vsyncend, vtotal, hflags "|" vflags iflags);
|
||||
|
||||
modestr = sprintf("%dx%dx%d%s",
|
||||
hdisplay/2 , vdisplay/2, vrefresh, iflag);
|
||||
|
||||
dmodes[nmodes]=sprintf("M(\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%s),",
|
||||
modestr,
|
||||
hdisplay/2, vdisplay/2, dotclock * 1000 / 2,
|
||||
hsyncstart/2, hsyncend/2, htotal/2,
|
||||
vsyncstart/2, vsyncend/2, vtotal/2,
|
||||
hflags "|" vflags "|DS" iflags);
|
||||
|
||||
nmodes = nmodes + 1
|
||||
|
||||
}
|
||||
|
||||
END {
|
||||
|
||||
printf("\n/* Derived Double Scan Modes */\n\n");
|
||||
|
||||
for ( i = 0; i < nmodes; i++ )
|
||||
{
|
||||
print dmodes[i];
|
||||
}
|
||||
|
||||
printf("};\n\n");
|
||||
printf("const int videomode_count = %d;\n", nmodes);
|
||||
}
|
208
sys/dev/videomode/pickmode.c
Normal file
208
sys/dev/videomode/pickmode.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/* $NetBSD: pickmode.c,v 1.4 2011/04/09 20:53:39 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* this code was contributed to The NetBSD Foundation by Michael Lorenz
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE NETBSD FOUNDATION BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pickmode.c,v 1.4 2011/04/09 20:53:39 christos Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <dev/videomode/videomode.h>
|
||||
#ifndef __minix
|
||||
#include "opt_videomode.h"
|
||||
#endif
|
||||
#ifndef abs
|
||||
#define abs(x) (((x) < 0) ? -(x) : (x))
|
||||
#endif
|
||||
|
||||
#ifdef PICKMODE_DEBUG
|
||||
#define DPRINTF printf
|
||||
#else
|
||||
#define DPRINTF while (0) printf
|
||||
#endif
|
||||
|
||||
const struct videomode *
|
||||
pick_mode_by_dotclock(int width, int height, int dotclock)
|
||||
{
|
||||
const struct videomode *this, *best = NULL;
|
||||
int i;
|
||||
|
||||
DPRINTF("%s: looking for %d x %d at up to %d kHz\n", __func__, width,
|
||||
height, dotclock);
|
||||
for (i = 0; i < videomode_count; i++) {
|
||||
this = &videomode_list[i];
|
||||
if ((this->hdisplay != width) || (this->vdisplay != height) ||
|
||||
(this->dot_clock > dotclock))
|
||||
continue;
|
||||
if (best != NULL) {
|
||||
if (this->dot_clock > best->dot_clock)
|
||||
best = this;
|
||||
} else
|
||||
best = this;
|
||||
}
|
||||
if (best != NULL)
|
||||
DPRINTF("found %s\n", best->name);
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
const struct videomode *
|
||||
pick_mode_by_ref(int width, int height, int refresh)
|
||||
{
|
||||
const struct videomode *this, *best = NULL;
|
||||
int mref, closest = 1000, i, diff;
|
||||
|
||||
DPRINTF("%s: looking for %d x %d at up to %d Hz\n", __func__, width,
|
||||
height, refresh);
|
||||
for (i = 0; i < videomode_count; i++) {
|
||||
|
||||
this = &videomode_list[i];
|
||||
mref = this->dot_clock * 1000 / (this->htotal * this->vtotal);
|
||||
diff = abs(mref - refresh);
|
||||
if ((this->hdisplay != width) || (this->vdisplay != height))
|
||||
continue;
|
||||
DPRINTF("%s in %d hz, diff %d\n", this->name, mref, diff);
|
||||
if (best != NULL) {
|
||||
if (diff < closest) {
|
||||
best = this;
|
||||
closest = diff;
|
||||
}
|
||||
} else {
|
||||
best = this;
|
||||
closest = diff;
|
||||
}
|
||||
}
|
||||
if (best != NULL)
|
||||
DPRINTF("found %s %d\n", best->name, best->dot_clock);
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
static inline void
|
||||
swap_modes(struct videomode *left, struct videomode *right)
|
||||
{
|
||||
struct videomode temp;
|
||||
|
||||
temp = *left;
|
||||
*left = *right;
|
||||
*right = temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort modes by refresh rate, aspect ratio (*), then resolution.
|
||||
* Preferred mode or largest mode is first in the list and other modes
|
||||
* are sorted on closest match to that mode.
|
||||
* (*) Note that the aspect ratio calculation treats "close" aspect ratios
|
||||
* (within 12.5%) as the same for this purpose.
|
||||
*/
|
||||
#define DIVIDE(x, y) (((x) + ((y) / 2)) / (y))
|
||||
void
|
||||
sort_modes(struct videomode *modes, struct videomode **preferred, int nmodes)
|
||||
{
|
||||
int aspect, refresh, hbest, vbest, abest, atemp, rbest, rtemp;
|
||||
int i, j;
|
||||
struct videomode *mtemp = NULL;
|
||||
|
||||
if (nmodes < 2)
|
||||
return;
|
||||
|
||||
if (*preferred != NULL) {
|
||||
/* Put the preferred mode first in the list */
|
||||
aspect = (*preferred)->hdisplay * 100 / (*preferred)->vdisplay;
|
||||
refresh = DIVIDE(DIVIDE((*preferred)->dot_clock * 1000,
|
||||
(*preferred)->htotal), (*preferred)->vtotal);
|
||||
if (*preferred != modes) {
|
||||
swap_modes(*preferred, modes);
|
||||
*preferred = modes;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Find the largest horizontal and vertical mode and put that
|
||||
* first in the list. Preferred refresh rate is taken from
|
||||
* the first mode of this size.
|
||||
*/
|
||||
hbest = 0;
|
||||
vbest = 0;
|
||||
for (i = 0; i < nmodes; i++) {
|
||||
if (modes[i].hdisplay > hbest) {
|
||||
hbest = modes[i].hdisplay;
|
||||
vbest = modes[i].vdisplay;
|
||||
mtemp = &modes[i];
|
||||
} else if (modes[i].hdisplay == hbest &&
|
||||
modes[i].vdisplay > vbest) {
|
||||
vbest = modes[i].vdisplay;
|
||||
mtemp = &modes[i];
|
||||
}
|
||||
}
|
||||
aspect = mtemp->hdisplay * 100 / mtemp->vdisplay;
|
||||
refresh = DIVIDE(DIVIDE(mtemp->dot_clock * 1000,
|
||||
mtemp->htotal), mtemp->vtotal);
|
||||
if (mtemp != modes)
|
||||
swap_modes(mtemp, modes);
|
||||
}
|
||||
|
||||
/* Sort other modes by refresh rate, aspect ratio, then resolution */
|
||||
for (j = 1; j < nmodes - 1; j++) {
|
||||
rbest = 1000;
|
||||
abest = 1000;
|
||||
hbest = 0;
|
||||
vbest = 0;
|
||||
for (i = j; i < nmodes; i++) {
|
||||
rtemp = abs(refresh -
|
||||
DIVIDE(DIVIDE(modes[i].dot_clock * 1000,
|
||||
modes[i].htotal), modes[i].vtotal));
|
||||
atemp = (modes[i].hdisplay * 100 / modes[i].vdisplay);
|
||||
if (rtemp < rbest) {
|
||||
rbest = rtemp;
|
||||
mtemp = &modes[i];
|
||||
}
|
||||
if (rtemp == rbest) {
|
||||
/* Treat "close" aspect ratios as identical */
|
||||
if (abs(abest - atemp) > (abest / 8) &&
|
||||
abs(aspect - atemp) < abs(aspect - abest)) {
|
||||
abest = atemp;
|
||||
mtemp = &modes[i];
|
||||
}
|
||||
if (atemp == abest ||
|
||||
abs(abest - atemp) <= (abest / 8)) {
|
||||
if (modes[i].hdisplay > hbest) {
|
||||
hbest = modes[i].hdisplay;
|
||||
mtemp = &modes[i];
|
||||
}
|
||||
if (modes[i].hdisplay == hbest &&
|
||||
modes[i].vdisplay > vbest) {
|
||||
vbest = modes[i].vdisplay;
|
||||
mtemp = &modes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mtemp != &modes[j])
|
||||
swap_modes(mtemp, &modes[j]);
|
||||
}
|
||||
}
|
25
sys/dev/videomode/test.c
Normal file
25
sys/dev/videomode/test.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "videomode.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 1; i < argc ; i++) {
|
||||
for (j = 0; j < videomode_count; j++) {
|
||||
if (strcmp(videomode_list[j].name, argv[i]) == 0) {
|
||||
printf("dotclock for mode %s = %d, flags %x\n",
|
||||
argv[i],
|
||||
videomode_list[j].dot_clock,
|
||||
videomode_list[j].flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == videomode_count) {
|
||||
printf("dotclock for mode %s not found\n", argv[i]);
|
||||
}
|
||||
}
|
||||
}
|
704
sys/dev/videomode/vesagtf.c
Normal file
704
sys/dev/videomode/vesagtf.c
Normal file
|
@ -0,0 +1,704 @@
|
|||
/* $NetBSD: vesagtf.c,v 1.1 2006/05/11 01:49:53 gdamore Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This was derived from a userland GTF program supplied by NVIDIA.
|
||||
* NVIDIA's original boilerplate follows.
|
||||
*
|
||||
* Note that I have heavily modified the program for use in the EDID
|
||||
* kernel code for NetBSD, including removing the use of floating
|
||||
* point operations and making significant adjustments to minimize
|
||||
* error propogation while operating with integer only math.
|
||||
*
|
||||
* This has required the use of 64-bit integers in a few places, but
|
||||
* the upshot is that for a calculation of 1920x1200x85 (as an
|
||||
* example), the error deviates by only ~.004% relative to the
|
||||
* floating point version. This error is *well* within VESA
|
||||
* tolerances.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, Andy Ritger aritger@nvidia.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* o Neither the name of NVIDIA nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
||||
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*
|
||||
* This program is based on the Generalized Timing Formula(GTF TM)
|
||||
* Standard Version: 1.0, Revision: 1.0
|
||||
*
|
||||
* The GTF Document contains the following Copyright information:
|
||||
*
|
||||
* Copyright (c) 1994, 1995, 1996 - Video Electronics Standards
|
||||
* Association. Duplication of this document within VESA member
|
||||
* companies for review purposes is permitted. All other rights
|
||||
* reserved.
|
||||
*
|
||||
* While every precaution has been taken in the preparation
|
||||
* of this standard, the Video Electronics Standards Association and
|
||||
* its contributors assume no responsibility for errors or omissions,
|
||||
* and make no warranties, expressed or implied, of functionality
|
||||
* of suitability for any purpose. The sample code contained within
|
||||
* this standard may be used without restriction.
|
||||
*
|
||||
*
|
||||
*
|
||||
* The GTF EXCEL(TM) SPREADSHEET, a sample (and the definitive)
|
||||
* implementation of the GTF Timing Standard, is available at:
|
||||
*
|
||||
* ftp://ftp.vesa.org/pub/GTF/GTF_V1R1.xls
|
||||
*
|
||||
*
|
||||
*
|
||||
* This program takes a desired resolution and vertical refresh rate,
|
||||
* and computes mode timings according to the GTF Timing Standard.
|
||||
* These mode timings can then be formatted as an XFree86 modeline
|
||||
* or a mode description for use by fbset(8).
|
||||
*
|
||||
*
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* The GTF allows for computation of "margins" (the visible border
|
||||
* surrounding the addressable video); on most non-overscan type
|
||||
* systems, the margin period is zero. I've implemented the margin
|
||||
* computations but not enabled it because 1) I don't really have
|
||||
* any experience with this, and 2) neither XFree86 modelines nor
|
||||
* fbset fb.modes provide an obvious way for margin timings to be
|
||||
* included in their mode descriptions (needs more investigation).
|
||||
*
|
||||
* The GTF provides for computation of interlaced mode timings;
|
||||
* I've implemented the computations but not enabled them, yet.
|
||||
* I should probably enable and test this at some point.
|
||||
*
|
||||
*
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* o Add support for interlaced modes.
|
||||
*
|
||||
* o Implement the other portions of the GTF: compute mode timings
|
||||
* given either the desired pixel clock or the desired horizontal
|
||||
* frequency.
|
||||
*
|
||||
* o It would be nice if this were more general purpose to do things
|
||||
* outside the scope of the GTF: like generate double scan mode
|
||||
* timings, for example.
|
||||
*
|
||||
* o Printing digits to the right of the decimal point when the
|
||||
* digits are 0 annoys me.
|
||||
*
|
||||
* o Error checking.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: vesagtf.c,v 1.1 2006/05/11 01:49:53 gdamore Exp $");
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <dev/videomode/videomode.h>
|
||||
#include <dev/videomode/vesagtf.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include "videomode.h"
|
||||
#include "vesagtf.h"
|
||||
|
||||
void print_xf86_mode(struct videomode *m);
|
||||
#endif
|
||||
|
||||
#define CELL_GRAN 8 /* assumed character cell granularity */
|
||||
|
||||
/* C' and M' are part of the Blanking Duty Cycle computation */
|
||||
/*
|
||||
* #define C_PRIME (((C - J) * K/256.0) + J)
|
||||
* #define M_PRIME (K/256.0 * M)
|
||||
*/
|
||||
|
||||
/*
|
||||
* C' and M' multiplied by 256 to give integer math. Make sure to
|
||||
* scale results using these back down, appropriately.
|
||||
*/
|
||||
#define C_PRIME256(p) (((p->C - p->J) * p->K) + (p->J * 256))
|
||||
#define M_PRIME256(p) (p->K * p->M)
|
||||
|
||||
#define DIVIDE(x,y) (((x) + ((y) / 2)) / (y))
|
||||
|
||||
/*
|
||||
* print_value() - print the result of the named computation; this is
|
||||
* useful when comparing against the GTF EXCEL spreadsheet.
|
||||
*/
|
||||
|
||||
#ifdef GTFDEBUG
|
||||
|
||||
static void
|
||||
print_value(int n, const char *name, unsigned val)
|
||||
{
|
||||
printf("%2d: %-27s: %u\n", n, name, val);
|
||||
}
|
||||
#else
|
||||
#define print_value(n, name, val)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* vert_refresh() - as defined by the GTF Timing Standard, compute the
|
||||
* Stage 1 Parameters using the vertical refresh frequency. In other
|
||||
* words: input a desired resolution and desired refresh rate, and
|
||||
* output the GTF mode timings.
|
||||
*
|
||||
* XXX All the code is in place to compute interlaced modes, but I don't
|
||||
* feel like testing it right now.
|
||||
*
|
||||
* XXX margin computations are implemented but not tested (nor used by
|
||||
* XFree86 of fbset mode descriptions, from what I can tell).
|
||||
*/
|
||||
|
||||
void
|
||||
vesagtf_mode_params(unsigned h_pixels, unsigned v_lines, unsigned freq,
|
||||
struct vesagtf_params *params, int flags, struct videomode *vmp)
|
||||
{
|
||||
unsigned v_field_rqd;
|
||||
unsigned top_margin;
|
||||
unsigned bottom_margin;
|
||||
unsigned interlace;
|
||||
uint64_t h_period_est;
|
||||
unsigned vsync_plus_bp;
|
||||
unsigned v_back_porch;
|
||||
unsigned total_v_lines;
|
||||
uint64_t v_field_est;
|
||||
uint64_t h_period;
|
||||
unsigned v_field_rate;
|
||||
unsigned v_frame_rate;
|
||||
unsigned left_margin;
|
||||
unsigned right_margin;
|
||||
unsigned total_active_pixels;
|
||||
uint64_t ideal_duty_cycle;
|
||||
unsigned h_blank;
|
||||
unsigned total_pixels;
|
||||
unsigned pixel_freq;
|
||||
|
||||
unsigned h_sync;
|
||||
unsigned h_front_porch;
|
||||
unsigned v_odd_front_porch_lines;
|
||||
|
||||
#ifdef GTFDEBUG
|
||||
unsigned h_freq;
|
||||
#endif
|
||||
|
||||
/* 1. In order to give correct results, the number of horizontal
|
||||
* pixels requested is first processed to ensure that it is divisible
|
||||
* by the character size, by rounding it to the nearest character
|
||||
* cell boundary:
|
||||
*
|
||||
* [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
|
||||
*/
|
||||
|
||||
h_pixels = DIVIDE(h_pixels, CELL_GRAN) * CELL_GRAN;
|
||||
|
||||
print_value(1, "[H PIXELS RND]", h_pixels);
|
||||
|
||||
|
||||
/* 2. If interlace is requested, the number of vertical lines assumed
|
||||
* by the calculation must be halved, as the computation calculates
|
||||
* the number of vertical lines per field. In either case, the
|
||||
* number of lines is rounded to the nearest integer.
|
||||
*
|
||||
* [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
|
||||
* ROUND([V LINES],0))
|
||||
*/
|
||||
|
||||
v_lines = (flags & VESAGTF_FLAG_ILACE) ? DIVIDE(v_lines, 2) : v_lines;
|
||||
|
||||
print_value(2, "[V LINES RND]", v_lines);
|
||||
|
||||
|
||||
/* 3. Find the frame rate required:
|
||||
*
|
||||
* [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
|
||||
* [I/P FREQ RQD])
|
||||
*/
|
||||
|
||||
v_field_rqd = (flags & VESAGTF_FLAG_ILACE) ? (freq * 2) : (freq);
|
||||
|
||||
print_value(3, "[V FIELD RATE RQD]", v_field_rqd);
|
||||
|
||||
|
||||
/* 4. Find number of lines in Top margin:
|
||||
* 5. Find number of lines in Bottom margin:
|
||||
*
|
||||
* [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
|
||||
* ROUND(([MARGIN%]/100*[V LINES RND]),0),
|
||||
* 0)
|
||||
*
|
||||
* Ditto for bottom margin. Note that instead of %, we use PPT, which
|
||||
* is parts per thousand. This helps us with integer math.
|
||||
*/
|
||||
|
||||
top_margin = bottom_margin = (flags & VESAGTF_FLAG_MARGINS) ?
|
||||
DIVIDE(v_lines * params->margin_ppt, 1000) : 0;
|
||||
|
||||
print_value(4, "[TOP MARGIN (LINES)]", top_margin);
|
||||
print_value(5, "[BOT MARGIN (LINES)]", bottom_margin);
|
||||
|
||||
|
||||
/* 6. If interlace is required, then set variable [INTERLACE]=0.5:
|
||||
*
|
||||
* [INTERLACE]=(IF([INT RQD?]="y",0.5,0))
|
||||
*
|
||||
* To make this integer friendly, we use some special hacks in step
|
||||
* 7 below. Please read those comments to understand why I am using
|
||||
* a whole number of 1.0 instead of 0.5 here.
|
||||
*/
|
||||
interlace = (flags & VESAGTF_FLAG_ILACE) ? 1 : 0;
|
||||
|
||||
print_value(6, "[2*INTERLACE]", interlace);
|
||||
|
||||
|
||||
/* 7. Estimate the Horizontal period
|
||||
*
|
||||
* [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) /
|
||||
* ([V LINES RND] + (2*[TOP MARGIN (LINES)]) +
|
||||
* [MIN PORCH RND]+[INTERLACE]) * 1000000
|
||||
*
|
||||
* To make it integer friendly, we pre-multiply the 1000000 to get to
|
||||
* usec. This gives us:
|
||||
*
|
||||
* [H PERIOD EST] = ((1000000/[V FIELD RATE RQD]) - [MIN VSYNC+BP]) /
|
||||
* ([V LINES RND] + (2 * [TOP MARGIN (LINES)]) +
|
||||
* [MIN PORCH RND]+[INTERLACE])
|
||||
*
|
||||
* The other problem is that the interlace value is wrong. To get
|
||||
* the interlace to a whole number, we multiply both the numerator and
|
||||
* divisor by 2, so we can use a value of either 1 or 0 for the interlace
|
||||
* factor.
|
||||
*
|
||||
* This gives us:
|
||||
*
|
||||
* [H PERIOD EST] = ((2*((1000000/[V FIELD RATE RQD]) - [MIN VSYNC+BP])) /
|
||||
* (2*([V LINES RND] + (2*[TOP MARGIN (LINES)]) +
|
||||
* [MIN PORCH RND]) + [2*INTERLACE]))
|
||||
*
|
||||
* Finally we multiply by another 1000, to get value in picosec.
|
||||
* Why picosec? To minimize rounding errors. Gotta love integer
|
||||
* math and error propogation.
|
||||
*/
|
||||
|
||||
h_period_est = DIVIDE(((DIVIDE(2000000000000ULL, v_field_rqd)) -
|
||||
(2000000 * params->min_vsbp)),
|
||||
((2 * (v_lines + (2 * top_margin) + params->min_porch)) + interlace));
|
||||
|
||||
print_value(7, "[H PERIOD EST (ps)]", h_period_est);
|
||||
|
||||
|
||||
/* 8. Find the number of lines in V sync + back porch:
|
||||
*
|
||||
* [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
|
||||
*
|
||||
* But recall that h_period_est is in psec. So multiply by 1000000.
|
||||
*/
|
||||
|
||||
vsync_plus_bp = DIVIDE(params->min_vsbp * 1000000, h_period_est);
|
||||
|
||||
print_value(8, "[V SYNC+BP]", vsync_plus_bp);
|
||||
|
||||
|
||||
/* 9. Find the number of lines in V back porch alone:
|
||||
*
|
||||
* [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND]
|
||||
*
|
||||
* XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]?
|
||||
*/
|
||||
|
||||
v_back_porch = vsync_plus_bp - params->vsync_rqd;
|
||||
|
||||
print_value(9, "[V BACK PORCH]", v_back_porch);
|
||||
|
||||
|
||||
/* 10. Find the total number of lines in Vertical field period:
|
||||
*
|
||||
* [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] +
|
||||
* [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] +
|
||||
* [MIN PORCH RND]
|
||||
*/
|
||||
|
||||
total_v_lines = v_lines + top_margin + bottom_margin + vsync_plus_bp +
|
||||
interlace + params->min_porch;
|
||||
|
||||
print_value(10, "[TOTAL V LINES]", total_v_lines);
|
||||
|
||||
|
||||
/* 11. Estimate the Vertical field frequency:
|
||||
*
|
||||
* [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
|
||||
*
|
||||
* Again, we want to pre multiply by 10^9 to convert for nsec, thereby
|
||||
* making it usable in integer math.
|
||||
*
|
||||
* So we get:
|
||||
*
|
||||
* [V FIELD RATE EST] = 1000000000 / [H PERIOD EST] / [TOTAL V LINES]
|
||||
*
|
||||
* This is all scaled to get the result in uHz. Again, we're trying to
|
||||
* minimize error propogation.
|
||||
*/
|
||||
v_field_est = DIVIDE(DIVIDE(1000000000000000ULL, h_period_est),
|
||||
total_v_lines);
|
||||
|
||||
print_value(11, "[V FIELD RATE EST(uHz)]", v_field_est);
|
||||
|
||||
|
||||
/* 12. Find the actual horizontal period:
|
||||
*
|
||||
* [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
|
||||
*/
|
||||
|
||||
h_period = DIVIDE(h_period_est * v_field_est, v_field_rqd * 1000);
|
||||
|
||||
print_value(12, "[H PERIOD(ps)]", h_period);
|
||||
|
||||
|
||||
/* 13. Find the actual Vertical field frequency:
|
||||
*
|
||||
* [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000
|
||||
*
|
||||
* And again, we convert to nsec ahead of time, giving us:
|
||||
*
|
||||
* [V FIELD RATE] = 1000000 / [H PERIOD] / [TOTAL V LINES]
|
||||
*
|
||||
* And another rescaling back to mHz. Gotta love it.
|
||||
*/
|
||||
|
||||
v_field_rate = DIVIDE(1000000000000ULL, h_period * total_v_lines);
|
||||
|
||||
print_value(13, "[V FIELD RATE]", v_field_rate);
|
||||
|
||||
|
||||
/* 14. Find the Vertical frame frequency:
|
||||
*
|
||||
* [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE]))
|
||||
*
|
||||
* N.B. that the result here is in mHz.
|
||||
*/
|
||||
|
||||
v_frame_rate = (flags & VESAGTF_FLAG_ILACE) ?
|
||||
v_field_rate / 2 : v_field_rate;
|
||||
|
||||
print_value(14, "[V FRAME RATE]", v_frame_rate);
|
||||
|
||||
|
||||
/* 15. Find number of pixels in left margin:
|
||||
* 16. Find number of pixels in right margin:
|
||||
*
|
||||
* [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
|
||||
* (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
|
||||
* [CELL GRAN RND]),0)) * [CELL GRAN RND],
|
||||
* 0))
|
||||
*
|
||||
* Again, we deal with margin percentages as PPT (parts per thousand).
|
||||
* And the calculations for left and right are the same.
|
||||
*/
|
||||
|
||||
left_margin = right_margin = (flags & VESAGTF_FLAG_MARGINS) ?
|
||||
DIVIDE(DIVIDE(h_pixels * params->margin_ppt, 1000),
|
||||
CELL_GRAN) * CELL_GRAN : 0;
|
||||
|
||||
print_value(15, "[LEFT MARGIN (PIXELS)]", left_margin);
|
||||
print_value(16, "[RIGHT MARGIN (PIXELS)]", right_margin);
|
||||
|
||||
|
||||
/* 17. Find total number of active pixels in image and left and right
|
||||
* margins:
|
||||
*
|
||||
* [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] +
|
||||
* [RIGHT MARGIN (PIXELS)]
|
||||
*/
|
||||
|
||||
total_active_pixels = h_pixels + left_margin + right_margin;
|
||||
|
||||
print_value(17, "[TOTAL ACTIVE PIXELS]", total_active_pixels);
|
||||
|
||||
|
||||
/* 18. Find the ideal blanking duty cycle from the blanking duty cycle
|
||||
* equation:
|
||||
*
|
||||
* [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
|
||||
*
|
||||
* However, we have modified values for [C'] as [256*C'] and
|
||||
* [M'] as [256*M']. Again the idea here is to get good scaling.
|
||||
* We use 256 as the factor to make the math fast.
|
||||
*
|
||||
* Note that this means that we have to scale it appropriately in
|
||||
* later calculations.
|
||||
*
|
||||
* The ending result is that our ideal_duty_cycle is 256000x larger
|
||||
* than the duty cycle used by VESA. But again, this reduces error
|
||||
* propogation.
|
||||
*/
|
||||
|
||||
ideal_duty_cycle =
|
||||
((C_PRIME256(params) * 1000) -
|
||||
(M_PRIME256(params) * h_period / 1000000));
|
||||
|
||||
print_value(18, "[IDEAL DUTY CYCLE]", ideal_duty_cycle);
|
||||
|
||||
|
||||
/* 19. Find the number of pixels in the blanking time to the nearest
|
||||
* double character cell:
|
||||
*
|
||||
* [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] *
|
||||
* [IDEAL DUTY CYCLE] /
|
||||
* (100-[IDEAL DUTY CYCLE]) /
|
||||
* (2*[CELL GRAN RND])), 0))
|
||||
* * (2*[CELL GRAN RND])
|
||||
*
|
||||
* Of course, we adjust to make this rounding work in integer math.
|
||||
*/
|
||||
|
||||
h_blank = DIVIDE(DIVIDE(total_active_pixels * ideal_duty_cycle,
|
||||
(256000 * 100ULL) - ideal_duty_cycle),
|
||||
2 * CELL_GRAN) * (2 * CELL_GRAN);
|
||||
|
||||
print_value(19, "[H BLANK (PIXELS)]", h_blank);
|
||||
|
||||
|
||||
/* 20. Find total number of pixels:
|
||||
*
|
||||
* [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
|
||||
*/
|
||||
|
||||
total_pixels = total_active_pixels + h_blank;
|
||||
|
||||
print_value(20, "[TOTAL PIXELS]", total_pixels);
|
||||
|
||||
|
||||
/* 21. Find pixel clock frequency:
|
||||
*
|
||||
* [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
|
||||
*
|
||||
* We calculate this in Hz rather than MHz, to get a value that
|
||||
* is usable with integer math. Recall that the [H PERIOD] is in
|
||||
* nsec.
|
||||
*/
|
||||
|
||||
pixel_freq = DIVIDE(total_pixels * 1000000, DIVIDE(h_period, 1000));
|
||||
|
||||
print_value(21, "[PIXEL FREQ]", pixel_freq);
|
||||
|
||||
|
||||
/* 22. Find horizontal frequency:
|
||||
*
|
||||
* [H FREQ] = 1000 / [H PERIOD]
|
||||
*
|
||||
* I've ifdef'd this out, because we don't need it for any of
|
||||
* our calculations.
|
||||
* We calculate this in Hz rather than kHz, to avoid rounding
|
||||
* errors. Recall that the [H PERIOD] is in usec.
|
||||
*/
|
||||
|
||||
#ifdef GTFDEBUG
|
||||
h_freq = 1000000000 / h_period;
|
||||
|
||||
print_value(22, "[H FREQ]", h_freq);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Stage 1 computations are now complete; I should really pass
|
||||
the results to another function and do the Stage 2
|
||||
computations, but I only need a few more values so I'll just
|
||||
append the computations here for now */
|
||||
|
||||
|
||||
|
||||
/* 17. Find the number of pixels in the horizontal sync period:
|
||||
*
|
||||
* [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] /
|
||||
* [CELL GRAN RND]),0))*[CELL GRAN RND]
|
||||
*
|
||||
* Rewriting for integer math:
|
||||
*
|
||||
* [H SYNC (PIXELS)]=(ROUND((H SYNC%] * [TOTAL PIXELS] / 100 /
|
||||
* [CELL GRAN RND),0))*[CELL GRAN RND]
|
||||
*/
|
||||
|
||||
h_sync = DIVIDE(((params->hsync_pct * total_pixels) / 100), CELL_GRAN) *
|
||||
CELL_GRAN;
|
||||
|
||||
print_value(17, "[H SYNC (PIXELS)]", h_sync);
|
||||
|
||||
|
||||
/* 18. Find the number of pixels in the horizontal front porch period:
|
||||
*
|
||||
* [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
|
||||
*
|
||||
* Note that h_blank is always an even number of characters (i.e.
|
||||
* h_blank % (CELL_GRAN * 2) == 0)
|
||||
*/
|
||||
|
||||
h_front_porch = (h_blank / 2) - h_sync;
|
||||
|
||||
print_value(18, "[H FRONT PORCH (PIXELS)]", h_front_porch);
|
||||
|
||||
|
||||
/* 36. Find the number of lines in the odd front porch period:
|
||||
*
|
||||
* [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE])
|
||||
*
|
||||
* Adjusting for the fact that the interlace is scaled:
|
||||
*
|
||||
* [V ODD FRONT PORCH(LINES)]=(([MIN PORCH RND] * 2) + [2*INTERLACE]) / 2
|
||||
*/
|
||||
|
||||
v_odd_front_porch_lines = ((2 * params->min_porch) + interlace) / 2;
|
||||
|
||||
print_value(36, "[V ODD FRONT PORCH(LINES)]", v_odd_front_porch_lines);
|
||||
|
||||
|
||||
/* finally, pack the results in the mode struct */
|
||||
|
||||
vmp->hsync_start = h_pixels + h_front_porch;
|
||||
vmp->hsync_end = vmp->hsync_start + h_sync;
|
||||
vmp->htotal = total_pixels;
|
||||
vmp->hdisplay = h_pixels;
|
||||
|
||||
vmp->vsync_start = v_lines + v_odd_front_porch_lines;
|
||||
vmp->vsync_end = vmp->vsync_start + params->vsync_rqd;
|
||||
vmp->vtotal = total_v_lines;
|
||||
vmp->vdisplay = v_lines;
|
||||
|
||||
vmp->dot_clock = pixel_freq;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vesagtf_mode(unsigned x, unsigned y, unsigned refresh, struct videomode *vmp)
|
||||
{
|
||||
struct vesagtf_params params;
|
||||
|
||||
params.margin_ppt = VESAGTF_MARGIN_PPT;
|
||||
params.min_porch = VESAGTF_MIN_PORCH;
|
||||
params.vsync_rqd = VESAGTF_VSYNC_RQD;
|
||||
params.hsync_pct = VESAGTF_HSYNC_PCT;
|
||||
params.min_vsbp = VESAGTF_MIN_VSBP;
|
||||
params.M = VESAGTF_M;
|
||||
params.C = VESAGTF_C;
|
||||
params.K = VESAGTF_K;
|
||||
params.J = VESAGTF_J;
|
||||
|
||||
vesagtf_mode_params(x, y, refresh, ¶ms, 0, vmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* The tidbit here is so that you can compile this file as a
|
||||
* standalone user program to generate X11 modelines using VESA GTF.
|
||||
* This also allows for testing of the code itself, without
|
||||
* necessitating a full kernel recompile.
|
||||
*/
|
||||
|
||||
/* print_xf86_mode() - print the XFree86 modeline, given mode timings. */
|
||||
|
||||
#ifndef __minix
|
||||
#ifndef _KERNEL
|
||||
void
|
||||
print_xf86_mode (struct videomode *vmp)
|
||||
{
|
||||
float vf, hf;
|
||||
|
||||
hf = 1000.0 * vmp->dot_clock / vmp->htotal;
|
||||
vf = 1.0 * hf / vmp->vtotal;
|
||||
|
||||
printf("\n");
|
||||
printf(" # %dx%d @ %.2f Hz (GTF) hsync: %.2f kHz; pclk: %.2f MHz\n",
|
||||
vmp->hdisplay, vmp->vdisplay, vf, hf, vmp->dot_clock / 1000.0);
|
||||
|
||||
printf(" Modeline \"%dx%d_%.2f\" %.2f"
|
||||
" %d %d %d %d"
|
||||
" %d %d %d %d"
|
||||
" -HSync +Vsync\n\n",
|
||||
vmp->hdisplay, vmp->vdisplay, vf, (vmp->dot_clock / 1000.0),
|
||||
vmp->hdisplay, vmp->hsync_start, vmp->hsync_end, vmp->htotal,
|
||||
vmp->vdisplay, vmp->vsync_start, vmp->vsync_end, vmp->vtotal);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
struct videomode m;
|
||||
|
||||
if (argc != 4) {
|
||||
printf("usage: %s x y refresh\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vesagtf_mode(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), &m);
|
||||
|
||||
print_xf86_mode(&m);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif /* !__minix */
|
85
sys/dev/videomode/vesagtf.h
Normal file
85
sys/dev/videomode/vesagtf.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* $NetBSD: vesagtf.h,v 1.1 2006/05/11 01:49:53 gdamore Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by Garrett D'Amore for Itronix Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of Itronix Inc. may not be used to endorse
|
||||
* or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEV_VIDEOMODE_VESAGTF_H
|
||||
#define _DEV_VIDEOMODE_VESAGTF_H
|
||||
|
||||
/*
|
||||
* Use VESA GTF formula to generate a monitor mode, given resolution and
|
||||
* refresh rates.
|
||||
*/
|
||||
|
||||
struct vesagtf_params {
|
||||
unsigned margin_ppt; /* vertical margin size, percent * 10
|
||||
* think parts-per-thousand */
|
||||
unsigned min_porch; /* minimum front porch */
|
||||
unsigned vsync_rqd; /* width of vsync in lines */
|
||||
unsigned hsync_pct; /* hsync as % of total width */
|
||||
unsigned min_vsbp; /* minimum vsync + back porch (usec) */
|
||||
unsigned M; /* blanking formula gradient */
|
||||
unsigned C; /* blanking formula offset */
|
||||
unsigned K; /* blanking formula scaling factor */
|
||||
unsigned J; /* blanking formula scaling factor */
|
||||
};
|
||||
|
||||
/*
|
||||
* Default values to use for params.
|
||||
*/
|
||||
#define VESAGTF_MARGIN_PPT 18 /* 1.8% */
|
||||
#define VESAGTF_MIN_PORCH 1 /* minimum front porch */
|
||||
#define VESAGTF_VSYNC_RQD 3 /* vsync width in lines */
|
||||
#define VESAGTF_HSYNC_PCT 8 /* width of hsync % of total line */
|
||||
#define VESAGTF_MIN_VSBP 550 /* min vsync + back porch (usec) */
|
||||
#define VESAGTF_M 600 /* blanking formula gradient */
|
||||
#define VESAGTF_C 40 /* blanking formula offset */
|
||||
#define VESAGTF_K 128 /* blanking formula scaling factor */
|
||||
#define VESAGTF_J 20 /* blanking formula scaling factor */
|
||||
|
||||
/*
|
||||
* Use VESA GTF formula to generate monitor timings. Assumes default
|
||||
* GTF parameters, non-interlaced, and no margins.
|
||||
*/
|
||||
void vesagtf_mode(unsigned x, unsigned y, unsigned refresh,
|
||||
struct videomode *);
|
||||
|
||||
/*
|
||||
* A more complete version, in case we ever want to use alternate GTF
|
||||
* parameters. EDID 1.3 allows for "secondary GTF parameters".
|
||||
*/
|
||||
void vesagtf_mode_params(unsigned x, unsigned y, unsigned refresh,
|
||||
struct vesagtf_params *, int flags, struct videomode *);
|
||||
|
||||
#define VESAGTF_FLAG_ILACE 0x0001 /* use interlace */
|
||||
#define VESAGTF_FLAG_MARGINS 0x0002 /* use margins */
|
||||
|
||||
#endif /* _DEV_VIDEOMODE_VESAGTF_H */
|
126
sys/dev/videomode/videomode.c
Normal file
126
sys/dev/videomode/videomode.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/* $NetBSD: videomode.c,v 1.11 2011/03/30 18:46:32 jdc Exp $ */
|
||||
|
||||
/*
|
||||
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
*
|
||||
* generated from:
|
||||
* NetBSD: modelines,v 1.9 2011/03/30 18:45:04 jdc Exp
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: videomode.c,v 1.11 2011/03/30 18:46:32 jdc Exp $");
|
||||
|
||||
#include <dev/videomode/videomode.h>
|
||||
|
||||
/*
|
||||
* These macros help the modelines below fit on one line.
|
||||
*/
|
||||
#define HP VID_PHSYNC
|
||||
#define HN VID_NHSYNC
|
||||
#define VP VID_PVSYNC
|
||||
#define VN VID_NVSYNC
|
||||
#define I VID_INTERLACE
|
||||
#define DS VID_DBLSCAN
|
||||
|
||||
#define M(nm,hr,vr,clk,hs,he,ht,vs,ve,vt,f) \
|
||||
{ clk, hr, hs, he, ht, vr, vs, ve, vt, f, nm }
|
||||
|
||||
const struct videomode videomode_list[] = {
|
||||
M("640x350x85",640,350,31500,672,736,832,382,385,445,HP|VN),
|
||||
M("640x400x85",640,400,31500,672,736,832,401,404,445,HN|VP),
|
||||
M("720x400x70",720,400,28320,738,846,900,412,414,449,HN|VP),
|
||||
M("720x400x85",720,400,35500,756,828,936,401,404,446,HN|VP),
|
||||
M("720x400x87",720,400,35500,738,846,900,421,423,449,HN|VN),
|
||||
M("640x480x60",640,480,25175,656,752,800,490,492,525,HN|VN),
|
||||
M("640x480x72",640,480,31500,664,704,832,489,492,520,HN|VN),
|
||||
M("640x480x75",640,480,31500,656,720,840,481,484,500,HN|VN),
|
||||
M("640x480x85",640,480,36000,696,752,832,481,484,509,HN|VN),
|
||||
M("800x600x56",800,600,36000,824,896,1024,601,603,625,HP|VP),
|
||||
M("800x600x60",800,600,40000,840,968,1056,601,605,628,HP|VP),
|
||||
M("800x600x72",800,600,50000,856,976,1040,637,643,666,HP|VP),
|
||||
M("800x600x75",800,600,49500,816,896,1056,601,604,625,HP|VP),
|
||||
M("800x600x85",800,600,56250,832,896,1048,601,604,631,HP|VP),
|
||||
M("1024x768x87i",1024,768,44900,1032,1208,1264,768,776,817,HP|VP|I),
|
||||
M("1024x768x60",1024,768,65000,1048,1184,1344,771,777,806,HN|VN),
|
||||
M("1024x768x70",1024,768,75000,1048,1184,1328,771,777,806,HN|VN),
|
||||
M("1024x768x75",1024,768,78750,1040,1136,1312,769,772,800,HP|VP),
|
||||
M("1024x768x85",1024,768,94500,1072,1168,1376,769,772,808,HP|VP),
|
||||
M("1024x768x89",1024,768,100000,1108,1280,1408,768,780,796,HP|VP),
|
||||
M("1152x864x75",1152,864,108000,1216,1344,1600,865,868,900,HP|VP),
|
||||
M("1280x768x75",1280,768,105640,1312,1712,1744,782,792,807,HN|VP),
|
||||
M("1280x960x60",1280,960,108000,1376,1488,1800,961,964,1000,HP|VP),
|
||||
M("1280x960x85",1280,960,148500,1344,1504,1728,961,964,1011,HP|VP),
|
||||
M("1280x1024x60",1280,1024,108000,1328,1440,1688,1025,1028,1066,HP|VP),
|
||||
M("1280x1024x70",1280,1024,126000,1328,1440,1688,1025,1028,1066,HP|VP),
|
||||
M("1280x1024x75",1280,1024,135000,1296,1440,1688,1025,1028,1066,HP|VP),
|
||||
M("1280x1024x85",1280,1024,157500,1344,1504,1728,1025,1028,1072,HP|VP),
|
||||
M("1600x1200x60",1600,1200,162000,1664,1856,2160,1201,1204,1250,HP|VP),
|
||||
M("1600x1200x65",1600,1200,175500,1664,1856,2160,1201,1204,1250,HP|VP),
|
||||
M("1600x1200x70",1600,1200,189000,1664,1856,2160,1201,1204,1250,HP|VP),
|
||||
M("1600x1200x75",1600,1200,202500,1664,1856,2160,1201,1204,1250,HP|VP),
|
||||
M("1600x1200x85",1600,1200,229500,1664,1856,2160,1201,1204,1250,HP|VP),
|
||||
M("1680x1050x60",1680,1050,147140,1784,1968,2256,1051,1054,1087,HP|VP),
|
||||
M("1792x1344x60",1792,1344,204800,1920,2120,2448,1345,1348,1394,HN|VP),
|
||||
M("1792x1344x75",1792,1344,261000,1888,2104,2456,1345,1348,1417,HN|VP),
|
||||
M("1856x1392x60",1856,1392,218300,1952,2176,2528,1393,1396,1439,HN|VP),
|
||||
M("1856x1392x75",1856,1392,288000,1984,2208,2560,1393,1396,1500,HN|VP),
|
||||
M("1920x1440x60",1920,1440,234000,2048,2256,2600,1441,1444,1500,HN|VP),
|
||||
M("1920x1440x75",1920,1440,297000,2064,2288,2640,1441,1444,1500,HN|VP),
|
||||
M("832x624x74",832,624,57284,864,928,1152,625,628,667,HN|VN),
|
||||
M("1152x768x54",1152,768,64995,1178,1314,1472,771,777,806,HP|VP),
|
||||
M("1400x1050x60",1400,1050,122000,1488,1640,1880,1052,1064,1082,HP|VP),
|
||||
M("1400x1050x74",1400,1050,155800,1464,1784,1912,1052,1064,1090,HP|VP),
|
||||
M("1152x900x66",1152,900,94500,1192,1320,1528,902,906,937,HN|VN),
|
||||
M("1152x900x76",1152,900,105560,1168,1280,1472,902,906,943,HN|VN),
|
||||
|
||||
/* Derived Double Scan Modes */
|
||||
|
||||
M("320x175x85",320,175,15750,336,368,416,191,192,222,HP|VN|DS),
|
||||
M("320x200x85",320,200,15750,336,368,416,200,202,222,HN|VP|DS),
|
||||
M("360x200x70",360,200,14160,369,423,450,206,207,224,HN|VP|DS),
|
||||
M("360x200x85",360,200,17750,378,414,468,200,202,223,HN|VP|DS),
|
||||
M("360x200x87",360,200,17750,369,423,450,210,211,224,HN|VN|DS),
|
||||
M("320x240x60",320,240,12587,328,376,400,245,246,262,HN|VN|DS),
|
||||
M("320x240x72",320,240,15750,332,352,416,244,246,260,HN|VN|DS),
|
||||
M("320x240x75",320,240,15750,328,360,420,240,242,250,HN|VN|DS),
|
||||
M("320x240x85",320,240,18000,348,376,416,240,242,254,HN|VN|DS),
|
||||
M("400x300x56",400,300,18000,412,448,512,300,301,312,HP|VP|DS),
|
||||
M("400x300x60",400,300,20000,420,484,528,300,302,314,HP|VP|DS),
|
||||
M("400x300x72",400,300,25000,428,488,520,318,321,333,HP|VP|DS),
|
||||
M("400x300x75",400,300,24750,408,448,528,300,302,312,HP|VP|DS),
|
||||
M("400x300x85",400,300,28125,416,448,524,300,302,315,HP|VP|DS),
|
||||
M("512x384x87i",512,384,22450,516,604,632,384,388,408,HP|VP|DS|I),
|
||||
M("512x384x60",512,384,32500,524,592,672,385,388,403,HN|VN|DS),
|
||||
M("512x384x70",512,384,37500,524,592,664,385,388,403,HN|VN|DS),
|
||||
M("512x384x75",512,384,39375,520,568,656,384,386,400,HP|VP|DS),
|
||||
M("512x384x85",512,384,47250,536,584,688,384,386,404,HP|VP|DS),
|
||||
M("512x384x89",512,384,50000,554,640,704,384,390,398,HP|VP|DS),
|
||||
M("576x432x75",576,432,54000,608,672,800,432,434,450,HP|VP|DS),
|
||||
M("640x384x75",640,384,52820,656,856,872,391,396,403,HN|VP|DS),
|
||||
M("640x480x60",640,480,54000,688,744,900,480,482,500,HP|VP|DS),
|
||||
M("640x480x85",640,480,74250,672,752,864,480,482,505,HP|VP|DS),
|
||||
M("640x512x60",640,512,54000,664,720,844,512,514,533,HP|VP|DS),
|
||||
M("640x512x70",640,512,63000,664,720,844,512,514,533,HP|VP|DS),
|
||||
M("640x512x75",640,512,67500,648,720,844,512,514,533,HP|VP|DS),
|
||||
M("640x512x85",640,512,78750,672,752,864,512,514,536,HP|VP|DS),
|
||||
M("800x600x60",800,600,81000,832,928,1080,600,602,625,HP|VP|DS),
|
||||
M("800x600x65",800,600,87750,832,928,1080,600,602,625,HP|VP|DS),
|
||||
M("800x600x70",800,600,94500,832,928,1080,600,602,625,HP|VP|DS),
|
||||
M("800x600x75",800,600,101250,832,928,1080,600,602,625,HP|VP|DS),
|
||||
M("800x600x85",800,600,114750,832,928,1080,600,602,625,HP|VP|DS),
|
||||
M("840x525x60",840,525,73570,892,984,1128,525,527,543,HP|VP|DS),
|
||||
M("896x672x60",896,672,102400,960,1060,1224,672,674,697,HN|VP|DS),
|
||||
M("896x672x75",896,672,130500,944,1052,1228,672,674,708,HN|VP|DS),
|
||||
M("928x696x60",928,696,109150,976,1088,1264,696,698,719,HN|VP|DS),
|
||||
M("928x696x75",928,696,144000,992,1104,1280,696,698,750,HN|VP|DS),
|
||||
M("960x720x60",960,720,117000,1024,1128,1300,720,722,750,HN|VP|DS),
|
||||
M("960x720x75",960,720,148500,1032,1144,1320,720,722,750,HN|VP|DS),
|
||||
M("416x312x74",416,312,28642,432,464,576,312,314,333,HN|VN|DS),
|
||||
M("576x384x54",576,384,32497,589,657,736,385,388,403,HP|VP|DS),
|
||||
M("700x525x60",700,525,61000,744,820,940,526,532,541,HP|VP|DS),
|
||||
M("700x525x74",700,525,77900,732,892,956,526,532,545,HP|VP|DS),
|
||||
M("576x450x66",576,450,47250,596,660,764,451,453,468,HN|VN|DS),
|
||||
M("576x450x76",576,450,52780,584,640,736,451,453,471,HN|VN|DS),
|
||||
};
|
||||
|
||||
const int videomode_count = 46;
|
73
sys/dev/videomode/videomode.h
Normal file
73
sys/dev/videomode/videomode.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* $NetBSD: videomode.h,v 1.3 2011/04/09 18:22:31 jdc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, 2002 Bang Jun-Young
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEV_VIDEOMODE_H
|
||||
#define _DEV_VIDEOMODE_H
|
||||
|
||||
struct videomode {
|
||||
int dot_clock; /* Dot clock frequency in kHz. */
|
||||
int hdisplay;
|
||||
int hsync_start;
|
||||
int hsync_end;
|
||||
int htotal;
|
||||
int vdisplay;
|
||||
int vsync_start;
|
||||
int vsync_end;
|
||||
int vtotal;
|
||||
int flags; /* Video mode flags; see below. */
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/*
|
||||
* Video mode flags.
|
||||
*/
|
||||
|
||||
#define VID_PHSYNC 0x0001
|
||||
#define VID_NHSYNC 0x0002
|
||||
#define VID_PVSYNC 0x0004
|
||||
#define VID_NVSYNC 0x0008
|
||||
#define VID_INTERLACE 0x0010
|
||||
#define VID_DBLSCAN 0x0020
|
||||
#define VID_CSYNC 0x0040
|
||||
#define VID_PCSYNC 0x0080
|
||||
#define VID_NCSYNC 0x0100
|
||||
#define VID_HSKEW 0x0200
|
||||
#define VID_BCAST 0x0400
|
||||
#define VID_PIXMUX 0x1000
|
||||
#define VID_DBLCLK 0x2000
|
||||
#define VID_CLKDIV2 0x4000
|
||||
|
||||
extern const struct videomode videomode_list[];
|
||||
extern const int videomode_count;
|
||||
|
||||
const struct videomode *pick_mode_by_dotclock(int, int, int);
|
||||
const struct videomode *pick_mode_by_ref(int, int, int);
|
||||
void sort_modes(struct videomode *, struct videomode **, int);
|
||||
|
||||
#endif /* _DEV_VIDEOMODE_H */
|
Loading…
Reference in a new issue