1/*
2 * Copyright 2003, Thomas Kurschel. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7/*!
8	Part of DDC driver
9	Dumps EDID content
10*/
11
12
13#include "edid.h"
14#if !defined(_KERNEL_MODE) && !defined(_BOOT_MODE)
15#	include "ddc_int.h"
16#endif
17
18#include <KernelExport.h>
19
20#include <stdio.h>
21
22
23void
24edid_dump(edid1_info *edid)
25{
26	int i, j;
27
28	dprintf("Vendor: %s\n", edid->vendor.manufacturer);
29	dprintf("Product ID: %d\n", (int)edid->vendor.prod_id);
30	dprintf("Serial #: %d\n", (int)edid->vendor.serial);
31	dprintf("Produced in week/year: %d/%d\n", edid->vendor.week,
32		edid->vendor.year);
33
34	dprintf("EDID version: %d.%d\n", edid->version.version,
35		edid->version.revision);
36
37	dprintf("Type: %s\n", edid->display.input_type ? "Digital" : "Analog");
38	dprintf("Size: %d cm x %d cm\n", edid->display.h_size,
39		edid->display.v_size);
40	dprintf("Gamma=%.3f\n", (edid->display.gamma + 100) / 100.0);
41	dprintf("White (X,Y)=(%.3f,%.3f)\n", edid->display.white_x / 1024.0,
42		edid->display.white_y / 1024.0);
43
44	dprintf("Supported Future Video Modes:\n");
45	for (i = 0; i < EDID1_NUM_STD_TIMING; ++i) {
46		if (edid->std_timing[i].h_size <= 256)
47			continue;
48
49		dprintf("%dx%d@%dHz (id=%d)\n",
50			edid->std_timing[i].h_size, edid->std_timing[i].v_size,
51			edid->std_timing[i].refresh, edid->std_timing[i].id);
52	}
53
54	dprintf("Supported VESA Video Modes:\n");
55	if (edid->established_timing.res_720x400x70)
56		dprintf("720x400@70Hz\n");
57	if (edid->established_timing.res_720x400x88)
58		dprintf("720x400@88Hz\n");
59	if (edid->established_timing.res_640x480x60)
60		dprintf("640x480@60Hz\n");
61	if (edid->established_timing.res_640x480x67)
62		dprintf("640x480@67Hz\n");
63	if (edid->established_timing.res_640x480x72)
64		dprintf("640x480@72Hz\n");
65	if (edid->established_timing.res_640x480x75)
66		dprintf("640x480@75Hz\n");
67	if (edid->established_timing.res_800x600x56)
68		dprintf("800x600@56Hz\n");
69	if (edid->established_timing.res_800x600x60)
70		dprintf("800x600@60Hz\n");
71
72	if (edid->established_timing.res_800x600x72)
73		dprintf("800x600@72Hz\n");
74	if (edid->established_timing.res_800x600x75)
75		dprintf("800x600@75Hz\n");
76	if (edid->established_timing.res_832x624x75)
77		dprintf("832x624@75Hz\n");
78	if (edid->established_timing.res_1024x768x87i)
79		dprintf("1024x768@87Hz interlaced\n");
80	if (edid->established_timing.res_1024x768x60)
81		dprintf("1024x768@60Hz\n");
82	if (edid->established_timing.res_1024x768x70)
83		dprintf("1024x768@70Hz\n");
84	if (edid->established_timing.res_1024x768x75)
85		dprintf("1024x768@75Hz\n");
86	if (edid->established_timing.res_1280x1024x75)
87		dprintf("1280x1024@75Hz\n");
88
89	if (edid->established_timing.res_1152x870x75)
90		dprintf("1152x870@75Hz\n");
91
92	for (i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
93		edid1_detailed_monitor *monitor = &edid->detailed_monitor[i];
94
95		switch(monitor->monitor_desc_type) {
96			case EDID1_SERIAL_NUMBER:
97				dprintf("Serial Number: %s\n", monitor->data.serial_number);
98				break;
99
100			case EDID1_ASCII_DATA:
101				dprintf("Ascii Data: %s\n", monitor->data.ascii_data);
102				break;
103
104			case EDID1_MONITOR_RANGES:
105			{
106				edid1_monitor_range monitor_range = monitor->data.monitor_range;
107
108				dprintf("Horizontal frequency range = %d..%d kHz\n",
109					monitor_range.min_h, monitor_range.max_h);
110				dprintf("Vertical frequency range = %d..%d Hz\n",
111					monitor_range.min_v, monitor_range.max_v);
112				dprintf("Maximum pixel clock = %d MHz\n",
113					(uint16)monitor_range.max_clock * 10);
114				break;
115			}
116
117			case EDID1_MONITOR_NAME:
118				dprintf("Monitor Name: %s\n", monitor->data.monitor_name);
119				break;
120
121			case EDID1_ADD_COLOUR_POINTER:
122			{
123				for (j = 0; j < EDID1_NUM_EXTRA_WHITEPOINTS; ++j) {
124					edid1_whitepoint *whitepoint = &monitor->data.whitepoint[j];
125
126					if (whitepoint->index == 0)
127						continue;
128
129					dprintf("Additional whitepoint: (X,Y)=(%f,%f) gamma=%f "
130						"index=%i\n", whitepoint->white_x / 1024.0,
131						whitepoint->white_y / 1024.0,
132						(whitepoint->gamma + 100) / 100.0, whitepoint->index);
133				}
134				break;
135			}
136
137			case EDID1_ADD_STD_TIMING:
138			{
139				for (j = 0; j < EDID1_NUM_EXTRA_STD_TIMING; ++j) {
140					edid1_std_timing *timing = &monitor->data.std_timing[j];
141
142					if (timing->h_size <= 256)
143						continue;
144
145					dprintf("%dx%d@%dHz (id=%d)\n",
146						timing->h_size, timing->v_size,
147						timing->refresh, timing->id);
148				}
149				break;
150			}
151
152			case EDID1_IS_DETAILED_TIMING:
153			{
154				edid1_detailed_timing *timing = &monitor->data.detailed_timing;
155				if (timing->h_active + timing->h_blank == 0
156					|| timing->v_active + timing->v_blank == 0) {
157					dprintf("Invalid video mode (%dx%d)\n", timing->h_active,
158						timing->v_active);
159					continue;
160				}
161				dprintf("Additional Video Mode (%dx%d@%dHz):\n",
162					timing->h_active, timing->v_active,
163					(timing->pixel_clock * 10000
164						/ (timing->h_active + timing->h_blank)
165						/ (timing->v_active + timing->v_blank)));
166					// Refresh rate = pixel clock in MHz / Htotal / Vtotal
167
168				dprintf("clock=%f MHz\n", timing->pixel_clock / 100.0);
169				dprintf("h: (%d, %d, %d, %d)\n",
170					timing->h_active, timing->h_active + timing->h_sync_off,
171					timing->h_active + timing->h_sync_off
172						+ timing->h_sync_width,
173					timing->h_active + timing->h_blank);
174				dprintf("v: (%d, %d, %d, %d)\n",
175					timing->v_active, timing->v_active + timing->v_sync_off,
176					timing->v_active + timing->v_sync_off
177						+ timing->v_sync_width,
178					timing->v_active + timing->v_blank);
179				dprintf("size: %.1f cm x %.1f cm\n",
180					timing->h_size / 10.0, timing->v_size / 10.0);
181				dprintf("border: %.1f cm x %.1f cm\n",
182					timing->h_border / 10.0, timing->v_border / 10.0);
183				break;
184			}
185		}
186	}
187}
188