Root/
Source at commit 970 created 13 years 23 days ago. By macman, ati.c, removed duplicate default "ATI Radeon HD 5400 Series", added Gigabyte "AMD Radeon HD 6850" OC device ID and added additional AMD 6000 cards with their default settings. Removed some blank lines. | |
---|---|
1 | /*␊ |
2 | * edid.c␊ |
3 | * ␊ |
4 | *␊ |
5 | * Created by Evan Lojewski on 12/1/09.␊ |
6 | * Copyright 2009. All rights reserved.␊ |
7 | *␊ |
8 | */␊ |
9 | ␊ |
10 | ␊ |
11 | #include "libsaio.h"␊ |
12 | #include "edid.h"␊ |
13 | #include "vbe.h"␊ |
14 | #include "graphics.h"␊ |
15 | #include "boot.h"␊ |
16 | ␊ |
17 | void getResolution(UInt32* x, UInt32* y, UInt32* bp)␊ |
18 | {␊ |
19 | ␉int val;␊ |
20 | ␉static UInt32 xResolution, yResolution, bpResolution;␊ |
21 | ␊ |
22 | ␉if(getIntForKey(kScreenWidth, &val, &bootInfo->bootConfig))␊ |
23 | ␉{␊ |
24 | ␉␉xResolution = val;␊ |
25 | ␉}␊ |
26 | ␉␊ |
27 | ␉if(getIntForKey(kScreenHeight, &val, &bootInfo->bootConfig))␊ |
28 | ␉{␊ |
29 | ␉␉yResolution = val;␊ |
30 | ␉}␊ |
31 | ␊ |
32 | ␉bpResolution = 32;␉// assume 32bits␊ |
33 | ␊ |
34 | ␉␊ |
35 | ␉if(!xResolution || !yResolution || !bpResolution)␊ |
36 | ␉{␊ |
37 | ␉␉␊ |
38 | ␉␉char* edidInfo = readEDID();␊ |
39 | ␉␉␊ |
40 | ␉␉if(!edidInfo) return;␊ |
41 | ␉␉␊ |
42 | ␉␉// TODO: check *all* resolutions reported and either use the highest, or the native resolution (if there is a flag for that)␊ |
43 | ␉␉xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);␊ |
44 | ␉␉yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);␊ |
45 | ␉␉␊ |
46 | ␉␉//printf("H Active = %d", edidInfo[56] | ((edidInfo[58] & 0xF0) << 4) );␊ |
47 | ␉␉//printf("V Active = %d", edidInfo[59] | ((edidInfo[61] & 0xF0) << 4) );␊ |
48 | ␉␉␊ |
49 | ␉␉free( edidInfo );␊ |
50 | ␉␉␊ |
51 | ␉␉if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH;␊ |
52 | ␉␉if(!yResolution) yResolution = DEFAULT_SCREEN_HEIGHT;␊ |
53 | ␊ |
54 | ␉}␊ |
55 | ␊ |
56 | ␉*x = xResolution;␊ |
57 | ␉*y = yResolution;␊ |
58 | ␉*bp = bpResolution;␊ |
59 | ␊ |
60 | }␊ |
61 | ␊ |
62 | char* readEDID()␊ |
63 | {␊ |
64 | ␉SInt16 last_reported = -1;␊ |
65 | ␉UInt8 edidInfo[EDID_BLOCK_SIZE];␊ |
66 | ␊ |
67 | ␉UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};␊ |
68 | ␉UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};␊ |
69 | ␉␊ |
70 | ␉SInt16 status;␊ |
71 | ␉UInt16 blocks_left = 1;␊ |
72 | ␉␊ |
73 | ␉do␊ |
74 | ␉{␊ |
75 | ␉␉// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block␊ |
76 | ␊ |
77 | ␉␉bzero( edidInfo, EDID_BLOCK_SIZE);␊ |
78 | ␊ |
79 | ␉␉status = getEDID(edidInfo, blocks_left);␊ |
80 | ␉␉␊ |
81 | ␉␉␊ |
82 | ␉␉//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));␊ |
83 | ␉␉/*␊ |
84 | ␉␉int j, i;␊ |
85 | ␉␉for (j = 0; j < 8; j++) {␊ |
86 | ␉␉␉for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);␊ |
87 | ␊ |
88 | ␉␉}␊ |
89 | ␉␉printf("\n");␊ |
90 | ␉␉*/␊ |
91 | ␉␉␊ |
92 | ␉␉if(status == 0)␊ |
93 | ␉␉{␊ |
94 | ␉␉␉//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)␊ |
95 | ␉␉␉if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||␊ |
96 | ␉␉␉ (memcmp(edidInfo, header2, sizeof(header2)) != 0) )␊ |
97 | ␉␉␉{␊ |
98 | ␉␉␉␉blocks_left--;␊ |
99 | ␉␉␉␉int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];␊ |
100 | ␉␉␉␉␊ |
101 | ␉␉␉␉if ( reported > blocks_left )␊ |
102 | ␉␉␉␉{␊ |
103 | ␉␉␉␉␉␊ |
104 | ␉␉␉␉␉printf("EDID claims %d more blocks left\n", reported);␊ |
105 | ␉␉␉␉}␊ |
106 | ␉␉␉␉␊ |
107 | ␉␉␉␉if ( (last_reported <= reported && last_reported != -1)␊ |
108 | ␉␉␉␉␉|| reported == 0xff␊ |
109 | ␉␉␉␉␉/* 0xff frequently comes up in corrupt edids */␊ |
110 | ␉␉␉␉␉//|| reported == MAGIC␊ |
111 | ␉␉␉␉␉)␊ |
112 | ␉␉␉␉{␊ |
113 | ␉␉␉␉␉printf("Last reported %d\n", last_reported);␊ |
114 | ␉␉␉␉␉printf( "EDID blocks left is wrong.\n"␊ |
115 | ␉␉␉␉␉␉ "Your EDID is probably invalid.\n");␊ |
116 | ␉␉␉␉␉return 0;␊ |
117 | ␉␉␉␉}␊ |
118 | ␉␉␉␉else␊ |
119 | ␉␉␉␉{␊ |
120 | ␉␉␉␉␉//printf("Reading EDID block\n");␊ |
121 | ␉␉␉␉␉//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );␊ |
122 | ␉␉␉␉␉//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );␊ |
123 | ␊ |
124 | ␉␉␉␉␉last_reported = reported;␊ |
125 | ␉␉␉␉␉blocks_left = reported;␊ |
126 | ␉␉␉␉}␊ |
127 | ␉␉␉} ␊ |
128 | ␉␉␉else␊ |
129 | ␉␉␉{␊ |
130 | ␉␉␉␉printf("Invalid block %d\n", blocks_left);␊ |
131 | ␉␉␉␉printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );␊ |
132 | ␉␉␉␉printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );␊ |
133 | ␉␉␉␉return 0;␊ |
134 | ␉␉␉}␊ |
135 | ␉␉}␊ |
136 | ␉␉blocks_left = 0;␉␊ |
137 | ␉} while(blocks_left);␊ |
138 | ␊ |
139 | ␉char* ret = malloc(sizeof(edidInfo));␊ |
140 | ␉memcpy(ret, edidInfo, sizeof(edidInfo));␊ |
141 | ␉return ret;␊ |
142 | }␊ |
143 |