Lines 1-6
Link Here
|
1 |
#include "radeonfb.h" |
1 |
#include "radeonfb.h" |
2 |
#include "../edid.h" |
2 |
#include "../edid.h" |
3 |
|
3 |
|
|
|
4 |
/* |
5 |
* TMDS PLL configuration table, taken from X.org |
6 |
*/ |
7 |
static const struct radeon_tmds_pll_info default_tmds_pll[CHIP_FAMILY_LAST][4] = |
8 |
{ |
9 |
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_UNKNOW*/ |
10 |
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_LEGACY*/ |
11 |
{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/ |
12 |
{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/ |
13 |
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/ |
14 |
{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/ |
15 |
{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/ |
16 |
{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/ |
17 |
{{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/ |
18 |
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/ |
19 |
{{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x400f7/*0x40111*/}, {0, 0}}, /*CHIP_FAMILY_RV280*/ |
20 |
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/ |
21 |
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/ |
22 |
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/ |
23 |
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV380*/ |
24 |
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R420*/ |
25 |
}; |
26 |
|
4 |
static struct fb_var_screeninfo radeonfb_default_var = { |
27 |
static struct fb_var_screeninfo radeonfb_default_var = { |
5 |
.xres = 640, |
28 |
.xres = 640, |
6 |
.yres = 480, |
29 |
.yres = 480, |
Lines 23-57
Link Here
|
23 |
.vmode = FB_VMODE_NONINTERLACED |
46 |
.vmode = FB_VMODE_NONINTERLACED |
24 |
}; |
47 |
}; |
25 |
|
48 |
|
26 |
static char *radeon_get_mon_name(int type) |
|
|
27 |
{ |
28 |
char *pret = NULL; |
29 |
|
30 |
switch (type) { |
31 |
case MT_NONE: |
32 |
pret = "no"; |
33 |
break; |
34 |
case MT_CRT: |
35 |
pret = "CRT"; |
36 |
break; |
37 |
case MT_DFP: |
38 |
pret = "DFP"; |
39 |
break; |
40 |
case MT_LCD: |
41 |
pret = "LCD"; |
42 |
break; |
43 |
case MT_CTV: |
44 |
pret = "CTV"; |
45 |
break; |
46 |
case MT_STV: |
47 |
pret = "STV"; |
48 |
break; |
49 |
} |
50 |
|
51 |
return pret; |
52 |
} |
53 |
|
54 |
|
55 |
#ifdef CONFIG_PPC_OF |
49 |
#ifdef CONFIG_PPC_OF |
56 |
/* |
50 |
/* |
57 |
* Try to find monitor informations & EDID data out of the Open Firmware |
51 |
* Try to find monitor informations & EDID data out of the Open Firmware |
Lines 59-65
Link Here
|
59 |
* models with broken OF probing by hard-coding known EDIDs for some Mac |
53 |
* models with broken OF probing by hard-coding known EDIDs for some Mac |
60 |
* laptops internal LVDS panel. (XXX: not done yet) |
54 |
* laptops internal LVDS panel. (XXX: not done yet) |
61 |
*/ |
55 |
*/ |
62 |
static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID, |
56 |
static int __devinit radeon_parse_montype_prop(struct device_node *dp, |
|
|
57 |
struct radeon_connector *conn, |
63 |
int hdno) |
58 |
int hdno) |
64 |
{ |
59 |
{ |
65 |
static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", |
60 |
static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", |
Lines 67-91
Link Here
|
67 |
u8 *pedid = NULL; |
62 |
u8 *pedid = NULL; |
68 |
u8 *pmt = NULL; |
63 |
u8 *pmt = NULL; |
69 |
u8 *tmp; |
64 |
u8 *tmp; |
70 |
int i, mt = MT_NONE; |
65 |
int i; |
71 |
|
66 |
|
72 |
RTRACE("analyzing OF properties...\n"); |
67 |
RTRACE("analyzing OF properties...\n"); |
73 |
pmt = (u8 *)get_property(dp, "display-type", NULL); |
68 |
pmt = (u8 *)get_property(dp, "display-type", NULL); |
74 |
if (!pmt) |
69 |
if (!pmt) |
75 |
return MT_NONE; |
70 |
return 1; |
76 |
RTRACE("display-type: %s\n", pmt); |
71 |
RTRACE("display-type: %s\n", pmt); |
77 |
/* OF says "LCD" for DFP as well, we discriminate from the caller of this |
72 |
if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP")) { |
78 |
* function |
73 |
/* OF says "LCD" for DFP as well.*/ |
79 |
*/ |
74 |
if (rinfo->is_mobility) { |
80 |
if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP")) |
75 |
conn->mon_type = MT_LCD; |
81 |
mt = MT_DFP; |
76 |
/* Maybe check for LVDS_GEN_CNTL here ? I need to check out |
82 |
else if (!strcmp(pmt, "CRT")) |
77 |
* what OF does when booting with lid closed |
83 |
mt = MT_CRT; |
78 |
*/ |
84 |
else { |
79 |
} else{ |
|
|
80 |
conn->mon_type = MT_DFP; |
81 |
} |
82 |
} else if (!strcmp(pmt, "CRT")) { |
83 |
conn->mon_type = MT_CRT; |
84 |
} else { |
85 |
if (strcmp(pmt, "NONE") != 0) |
85 |
if (strcmp(pmt, "NONE") != 0) |
86 |
printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n", |
86 |
printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n", |
87 |
pmt); |
87 |
pmt); |
88 |
return MT_NONE; |
88 |
return 1; |
89 |
} |
89 |
} |
90 |
|
90 |
|
91 |
for (i = 0; propnames[i] != NULL; ++i) { |
91 |
for (i = 0; propnames[i] != NULL; ++i) { |
Lines 102-127
Link Here
|
102 |
if (pedid == NULL && dp->parent && (hdno == 0)) |
102 |
if (pedid == NULL && dp->parent && (hdno == 0)) |
103 |
pedid = get_property(dp->parent, "EDID", NULL); |
103 |
pedid = get_property(dp->parent, "EDID", NULL); |
104 |
if (pedid == NULL) |
104 |
if (pedid == NULL) |
105 |
return mt; |
105 |
return 1; |
106 |
|
106 |
|
107 |
tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL); |
107 |
tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL); |
108 |
if (!tmp) |
108 |
if (tmp) { |
109 |
return mt; |
109 |
memcpy(tmp, pedid, EDID_LENGTH); |
110 |
memcpy(tmp, pedid, EDID_LENGTH); |
110 |
} |
111 |
*out_EDID = tmp; |
111 |
|
112 |
return mt; |
112 |
conn->edid = tmp; |
|
|
113 |
|
114 |
{ |
115 |
int found_tmds = 0; |
116 |
int found_crt = 0; |
117 |
int ddc_type = ddc_none; |
118 |
// XXX what about reversed DAC/TMDS?? |
119 |
radeon_fill_conn(conn, conn->mon_type, ddc_type, &found_crt, &found_tmds); |
120 |
} |
121 |
|
122 |
return 0; |
113 |
} |
123 |
} |
114 |
|
124 |
|
115 |
static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no, |
125 |
/* return a 1 on error */ |
116 |
u8 **out_EDID) |
126 |
static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no) |
|
|
127 |
|
117 |
{ |
128 |
{ |
|
|
129 |
struct radeon_connector *conn; |
118 |
struct device_node *dp; |
130 |
struct device_node *dp; |
|
|
131 |
u8 *out_EDID; |
119 |
|
132 |
|
120 |
RTRACE("radeon_probe_OF_head\n"); |
133 |
RTRACE("radeon_probe_OF_head\n"); |
121 |
|
134 |
|
|
|
135 |
conn = rinfo->connectors[head_no]; |
136 |
|
122 |
dp = rinfo->of_node; |
137 |
dp = rinfo->of_node; |
123 |
while (dp == NULL) |
138 |
if (dp == NULL) |
124 |
return MT_NONE; |
139 |
return 1; |
125 |
|
140 |
|
126 |
if (rinfo->has_CRTC2) { |
141 |
if (rinfo->has_CRTC2) { |
127 |
char *pname; |
142 |
char *pname; |
Lines 129-180
Link Here
|
129 |
|
144 |
|
130 |
dp = dp->child; |
145 |
dp = dp->child; |
131 |
do { |
146 |
do { |
132 |
if (!dp) |
147 |
if (!dp) |
133 |
return MT_NONE; |
148 |
return 1; |
|
|
149 |
|
134 |
pname = (char *)get_property(dp, "name", NULL); |
150 |
pname = (char *)get_property(dp, "name", NULL); |
135 |
if (!pname) |
151 |
if (!pname) |
136 |
return MT_NONE; |
152 |
return 1; |
|
|
153 |
|
137 |
len = strlen(pname); |
154 |
len = strlen(pname); |
138 |
RTRACE("head: %s (letter: %c, head_no: %d)\n", |
155 |
RTRACE("head: %s (letter: %c, head_no: %d)\n", |
139 |
pname, pname[len-1], head_no); |
156 |
pname, pname[len-1], head_no); |
140 |
if (pname[len-1] == 'A' && head_no == 0) { |
157 |
if (pname[len-1] == 'A' && head_no == 0) { |
141 |
int mt = radeon_parse_montype_prop(dp, out_EDID, 0); |
158 |
return radeon_parse_montype_prop(dp, conn, 0); |
142 |
/* Maybe check for LVDS_GEN_CNTL here ? I need to check out |
159 |
} else if (pname[len-1] == 'B' && head_no == 1) { |
143 |
* what OF does when booting with lid closed |
160 |
return radeon_parse_montype_prop(dp, conn, 1); |
144 |
*/ |
161 |
} |
145 |
if (mt == MT_DFP && rinfo->is_mobility) |
|
|
146 |
mt = MT_LCD; |
147 |
return mt; |
148 |
} else if (pname[len-1] == 'B' && head_no == 1) |
149 |
return radeon_parse_montype_prop(dp, out_EDID, 1); |
150 |
second = 1; |
162 |
second = 1; |
151 |
dp = dp->sibling; |
163 |
dp = dp->sibling; |
152 |
} while(!second); |
164 |
} while(!second); |
153 |
} else { |
165 |
} else { |
154 |
if (head_no > 0) |
166 |
if (head_no > 0) { |
155 |
return MT_NONE; |
167 |
return 1; |
156 |
return radeon_parse_montype_prop(dp, out_EDID, -1); |
168 |
} |
|
|
169 |
return radeon_parse_montype_prop(dp, conn, -1); |
157 |
} |
170 |
} |
158 |
return MT_NONE; |
171 |
return 1; |
159 |
} |
172 |
} |
160 |
#endif /* CONFIG_PPC_OF */ |
173 |
#endif /* CONFIG_PPC_OF */ |
161 |
|
174 |
|
162 |
|
175 |
|
163 |
static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo) |
176 |
int __devinit radeon_get_lvds_info_atom(struct radeonfb_info *rinfo) |
|
|
177 |
{ |
178 |
unsigned long tmp; |
179 |
|
180 |
if (!rinfo->bios_seg) |
181 |
return -ENODEV; |
182 |
|
183 |
tmp = BIOS_IN16(rinfo->atom_data_start + 16); |
184 |
if (!tmp) { |
185 |
RTRACE("No LVDS panel info in ATOM BIOS\n"); |
186 |
rinfo->panel_info.pwr_delay = 200; |
187 |
return -ENODEV; |
188 |
} |
189 |
|
190 |
rinfo->panel_info.xres = BIOS_IN16(tmp+6); |
191 |
rinfo->panel_info.yres = BIOS_IN16(tmp+10); |
192 |
printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n", |
193 |
rinfo->panel_info.xres, rinfo->panel_info.yres); |
194 |
rinfo->panel_info.pwr_delay = BIOS_IN16(tmp+40); |
195 |
RTRACE("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay); |
196 |
if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0) |
197 |
rinfo->panel_info.pwr_delay = 2000; |
198 |
|
199 |
/* No special divider combinations? */ |
200 |
|
201 |
rinfo->panel_info.hblank = BIOS_IN16(tmp+8); |
202 |
rinfo->panel_info.hOver_plus = BIOS_IN16(tmp+14); |
203 |
rinfo->panel_info.hSync_width = BIOS_IN16(tmp+16); |
204 |
rinfo->panel_info.vblank = BIOS_IN16(tmp+12); |
205 |
rinfo->panel_info.vOver_plus = BIOS_IN16(tmp+18); |
206 |
rinfo->panel_info.vSync_width = BIOS_IN16(tmp+20); |
207 |
rinfo->panel_info.clock = BIOS_IN16(tmp+4); |
208 |
|
209 |
/* Assume high active syncs for now until ATI tells me more... maybe we |
210 |
* can probe register values here ? |
211 |
*/ |
212 |
rinfo->panel_info.hAct_high = 1; |
213 |
rinfo->panel_info.vAct_high = 1; |
214 |
/* Mark panel infos valid */ |
215 |
rinfo->panel_info.valid = 1; |
216 |
|
217 |
return 0; |
218 |
} |
219 |
|
220 |
int __devinit radeon_get_lvds_info_legacy(struct radeonfb_info *rinfo) |
164 |
{ |
221 |
{ |
165 |
unsigned long tmp, tmp0; |
222 |
unsigned long tmp, tmp0; |
166 |
char stmp[30]; |
223 |
char stmp[30]; |
167 |
int i; |
224 |
int i; |
168 |
|
225 |
|
169 |
if (!rinfo->bios_seg) |
226 |
if (!rinfo->bios_seg) |
170 |
return 0; |
227 |
return -ENODEV; |
171 |
|
228 |
|
172 |
if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) { |
229 |
if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) { |
173 |
printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n"); |
230 |
RTRACE("No LVDS panel info in Legacy BIOS\n"); |
174 |
rinfo->panel_info.pwr_delay = 200; |
231 |
rinfo->panel_info.pwr_delay = 200; |
175 |
return 0; |
232 |
return -ENODEV; |
176 |
} |
233 |
} |
177 |
|
234 |
|
178 |
for(i=0; i<24; i++) |
235 |
for(i=0; i<24; i++) |
179 |
stmp[i] = BIOS_IN8(tmp+i+1); |
236 |
stmp[i] = BIOS_IN8(tmp+i+1); |
180 |
stmp[24] = 0; |
237 |
stmp[24] = 0; |
Lines 182-194
Link Here
|
182 |
rinfo->panel_info.xres = BIOS_IN16(tmp + 25); |
239 |
rinfo->panel_info.xres = BIOS_IN16(tmp + 25); |
183 |
rinfo->panel_info.yres = BIOS_IN16(tmp + 27); |
240 |
rinfo->panel_info.yres = BIOS_IN16(tmp + 27); |
184 |
printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n", |
241 |
printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n", |
185 |
rinfo->panel_info.xres, rinfo->panel_info.yres); |
242 |
rinfo->panel_info.xres, rinfo->panel_info.yres); |
186 |
|
243 |
|
187 |
rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44); |
244 |
rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44); |
188 |
RTRACE("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay); |
245 |
RTRACE("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay); |
189 |
if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0) |
246 |
if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0) |
190 |
rinfo->panel_info.pwr_delay = 2000; |
247 |
rinfo->panel_info.pwr_delay = 2000; |
191 |
|
248 |
|
192 |
/* |
249 |
/* |
193 |
* Some panels only work properly with some divider combinations |
250 |
* Some panels only work properly with some divider combinations |
194 |
*/ |
251 |
*/ |
Lines 203-208
Link Here
|
203 |
RTRACE("post_divider = %x\n", rinfo->panel_info.post_divider); |
260 |
RTRACE("post_divider = %x\n", rinfo->panel_info.post_divider); |
204 |
RTRACE("fbk_divider = %x\n", rinfo->panel_info.fbk_divider); |
261 |
RTRACE("fbk_divider = %x\n", rinfo->panel_info.fbk_divider); |
205 |
} |
262 |
} |
|
|
263 |
|
206 |
RTRACE("Scanning BIOS table ...\n"); |
264 |
RTRACE("Scanning BIOS table ...\n"); |
207 |
for(i=0; i<32; i++) { |
265 |
for(i=0; i<32; i++) { |
208 |
tmp0 = BIOS_IN16(tmp+64+i*2); |
266 |
tmp0 = BIOS_IN16(tmp+64+i*2); |
Lines 226-232
Link Here
|
226 |
rinfo->panel_info.vAct_high = 1; |
284 |
rinfo->panel_info.vAct_high = 1; |
227 |
/* Mark panel infos valid */ |
285 |
/* Mark panel infos valid */ |
228 |
rinfo->panel_info.valid = 1; |
286 |
rinfo->panel_info.valid = 1; |
229 |
|
287 |
|
230 |
RTRACE("Found panel in BIOS table:\n"); |
288 |
RTRACE("Found panel in BIOS table:\n"); |
231 |
RTRACE(" hblank: %d\n", rinfo->panel_info.hblank); |
289 |
RTRACE(" hblank: %d\n", rinfo->panel_info.hblank); |
232 |
RTRACE(" hOver_plus: %d\n", rinfo->panel_info.hOver_plus); |
290 |
RTRACE(" hOver_plus: %d\n", rinfo->panel_info.hOver_plus); |
Lines 235-246
Link Here
|
235 |
RTRACE(" vOver_plus: %d\n", rinfo->panel_info.vOver_plus); |
293 |
RTRACE(" vOver_plus: %d\n", rinfo->panel_info.vOver_plus); |
236 |
RTRACE(" vSync_width: %d\n", rinfo->panel_info.vSync_width); |
294 |
RTRACE(" vSync_width: %d\n", rinfo->panel_info.vSync_width); |
237 |
RTRACE(" clock: %d\n", rinfo->panel_info.clock); |
295 |
RTRACE(" clock: %d\n", rinfo->panel_info.clock); |
238 |
|
296 |
|
239 |
return 1; |
297 |
return 0; |
240 |
} |
298 |
} |
241 |
} |
299 |
} |
|
|
300 |
|
242 |
RTRACE("Didn't find panel in BIOS table !\n"); |
301 |
RTRACE("Didn't find panel in BIOS table !\n"); |
243 |
|
302 |
|
|
|
303 |
return -ENODEV; |
304 |
} |
305 |
|
306 |
/* |
307 |
* Get informations about TMDS controllers and their setup at |
308 |
* different operating frequencies |
309 |
*/ |
310 |
void __devinit radeon_get_tmds_info(struct radeonfb_info *rinfo) |
311 |
{ |
312 |
int i; |
313 |
|
314 |
/* Get default TMDS infos for this chip */ |
315 |
for (i=0; i<4; i++) { |
316 |
rinfo->tmds_pll[i].value = |
317 |
default_tmds_pll[rinfo->family][i].value; |
318 |
rinfo->tmds_pll[i].freq = |
319 |
default_tmds_pll[rinfo->family][i].freq; |
320 |
} |
321 |
|
322 |
/* Get whatever the firmware provides */ |
323 |
if (rinfo->radeon_get_tmds_info) { |
324 |
rinfo->radeon_get_tmds_info(rinfo); |
325 |
// XXX Do we care about the return value? |
326 |
} |
327 |
} |
328 |
|
329 |
int __devinit radeon_get_tmds_info_legacy(struct radeonfb_info *rinfo) |
330 |
{ |
331 |
int offset, i, n, rev; |
332 |
|
333 |
offset = BIOS_IN16(rinfo->fp_bios_start + 0x34); |
334 |
if (offset == 0) |
335 |
return -ENODEV; |
336 |
|
337 |
rev = BIOS_IN8(offset); |
338 |
RTRACE("DFP table revision: %d\n", rev); |
339 |
|
340 |
switch(rev) { |
341 |
case 3: |
342 |
n = BIOS_IN8(offset + 5) + 1; |
343 |
if (n > 4) |
344 |
n = 4; |
345 |
for (i = 0; i < n; i++) { |
346 |
/* Looks bogus ... but that's what is in X.org */ |
347 |
rinfo->tmds_pll[i].value = |
348 |
BIOS_IN32(offset+i*10+0x08); |
349 |
rinfo->tmds_pll[i].freq = |
350 |
BIOS_IN16(offset+i*10+0x10); |
351 |
} |
352 |
return 0; |
353 |
|
354 |
/* revision 4 has some problem as it appears in RV280, |
355 |
* comment it off for now, use default instead |
356 |
*/ |
357 |
#if 0 |
358 |
case 4: |
359 |
stride = 0; |
360 |
n = BIOS_IN8(offset 5) + 1; |
361 |
if (n > 4) |
362 |
n = 4; |
363 |
for (i = 0; i < n; i++) { |
364 |
rinfo->tmds_pll[i].value = |
365 |
BIOS_IN32(tmp+stride+0x08); |
366 |
rinfo->tmds_pll[i].freq = |
367 |
BIOS_IN16(tmp+stride+0x10); |
368 |
if (i == 0) |
369 |
stride += 10; |
370 |
else |
371 |
stride += 6; |
372 |
} |
373 |
return 0; |
374 |
#endif |
375 |
} |
376 |
return -ENODEV; |
377 |
} |
378 |
|
379 |
int __devinit radeon_get_tmds_info_atom(struct radeonfb_info *rinfo) |
380 |
{ |
381 |
int offset, i, maxfreq; |
382 |
|
383 |
offset = BIOS_IN16(rinfo->atom_data_start + 18); |
384 |
if (offset == 0) |
385 |
return -ENODEV; |
386 |
|
387 |
maxfreq = BIOS_IN16(offset + 4); |
388 |
|
389 |
for (i = 0; i < 4; i++) { |
390 |
rinfo->tmds_pll[i].freq = BIOS_IN16(offset+i*6+6); |
391 |
/* This assumes each field in TMDS_PLL has 6 bit as |
392 |
* in R300/R420 |
393 |
*/ |
394 |
rinfo->tmds_pll[i].value = |
395 |
((BIOS_IN8(offset+i*6+8) & 0x3f) | |
396 |
((BIOS_IN8(offset+i*6+10) & 0x3f)<<6) | |
397 |
((BIOS_IN8(offset+i*6+9) & 0xf)<<12) | |
398 |
((BIOS_IN8(offset+i*6+11) & 0xf)<<16)); |
399 |
RTRACE("TMDS PLL from BIOS: %ld %x\n", |
400 |
rinfo->tmds_pll[i].freq, rinfo->tmds_pll[i].value); |
401 |
|
402 |
if (maxfreq == rinfo->tmds_pll[i].freq) { |
403 |
rinfo->tmds_pll[i].freq = 0xffffffff; |
404 |
break; |
405 |
} |
406 |
} |
407 |
return 0; |
408 |
} |
409 |
|
410 |
|
411 |
static const char *conn_type_name[] = { |
412 |
"NONE", "VGA", "DVI-I", "DVI-D", "DVI-A", "S-Video", |
413 |
"Composite Video", "Internal Panel", "Digital", |
414 |
"Unsupported", "Proprietary" |
415 |
}; |
416 |
|
417 |
static const char *mon_type_name[] = { |
418 |
"None", "CRT", "LVDS Flat panel", |
419 |
"DVI Flat panel", "Composite TV", "S-Video TV" |
420 |
}; |
421 |
|
422 |
static void __devinit radeon_fill_conn(struct radeon_connector *conn, int mon_type, int ddc_type, int *found_tmds, int *found_crt) |
423 |
{ |
424 |
conn->mon_type = mon_type; |
425 |
conn->ddc_type = ddc_type; |
426 |
|
427 |
// XXX what about reversed DAC/TMDS?? |
428 |
|
429 |
switch(mon_type) { |
430 |
case MT_CRT: |
431 |
conn->conn_type = conn_vga; |
432 |
conn->tmds_type = tmds_unknown; |
433 |
conn->dac_type = (*found_crt) ? dac_tvdac: dac_primary; |
434 |
if (ddc_type == ddc_none) conn->ddc_type = (*found_crt) ? ddc_crt2 : ddc_vga; |
435 |
*found_crt = 1; |
436 |
break; |
437 |
case MT_DFP: |
438 |
conn->conn_type = conn_dvi_i; |
439 |
conn->tmds_type = (*found_tmds) ? tmds_external: tmds_internal; |
440 |
conn->dac_type = dac_unknown; |
441 |
if (ddc_type == ddc_none) conn->ddc_type = ddc_dvi; |
442 |
*found_tmds = 1; |
443 |
break; |
444 |
case MT_LCD: |
445 |
conn->conn_type = conn_lvds; |
446 |
conn->tmds_type = tmds_unknown; |
447 |
conn->dac_type = dac_unknown; |
448 |
if (ddc_type == ddc_none) conn->ddc_type = ddc_none; //heh |
449 |
break; |
450 |
case MT_CTV: |
451 |
conn->conn_type = conn_ctv; |
452 |
conn->tmds_type = tmds_unknown; |
453 |
conn->dac_type = dac_tvdac; |
454 |
if (ddc_type == ddc_none) conn->ddc_type = ddc_vga; // XXX ddc_crt2? |
455 |
break; |
456 |
case MT_STV: |
457 |
conn->conn_type = conn_stv; |
458 |
conn->tmds_type = tmds_unknown; |
459 |
conn->dac_type = dac_tvdac; |
460 |
if (ddc_type == ddc_none) conn->ddc_type = ddc_vga; // XXX ddc_crt2? |
461 |
break; |
462 |
case MT_UNKNOWN: |
463 |
case MT_NONE: |
464 |
conn->conn_type = conn_none; |
465 |
conn->tmds_type = tmds_unknown; |
466 |
conn->mon_type = MT_NONE; |
467 |
conn->ddc_type = ddc_none; |
468 |
conn->dac_type = dac_unknown; |
469 |
break; |
470 |
default: |
471 |
break; |
472 |
} |
473 |
// leaves conn_digital, conn_unsupported, conn_propritetary |
474 |
} |
475 |
|
476 |
/* |
477 |
* Get informations about the various connectors on this card. This is |
478 |
* the most prone to fail function as various firmwares tend to say |
479 |
* crap or not give any info at all. The Open Firmware version is just |
480 |
* a table of known cards for now for example. We'll probably need some |
481 |
* additional module params to force different settings in case of |
482 |
* misdetection here. |
483 |
* |
484 |
* This doesn _not_ try actual probing of whatever is plugged on those |
485 |
* various connectors. This will be done later. We do store whatever |
486 |
* probing info the firmware gives us though |
487 |
*/ |
488 |
void __devinit radeon_get_conn_info(struct radeonfb_info *rinfo, int ignore_conntable) |
489 |
{ |
490 |
int i; |
491 |
|
492 |
/* Clear table */ |
493 |
for (i = 0; i < RADEON_MAX_CONNECTORS; i++) { |
494 |
rinfo->connectors[i].conn_type = conn_none; |
495 |
rinfo->connectors[i].ddc_type = ddc_none; |
496 |
rinfo->connectors[i].dac_type = dac_unknown; |
497 |
rinfo->connectors[i].tmds_type = tmds_unknown; |
498 |
rinfo->connectors[i].mon_type = MT_UNKNOWN; |
499 |
rinfo->connectors[i].head = -1; |
500 |
rinfo->heads[i] = -1; |
501 |
} |
502 |
rinfo->num_heads = 0; |
503 |
|
504 |
if (ignore_conntable) { |
505 |
#if defined(CONFIG_FB_RADEON_I2C) |
506 |
struct radeon_connector conn; |
507 |
int idx = 0; |
508 |
int found_tmds = 0; |
509 |
int found_crt = 0; |
510 |
|
511 |
// XXX what about reversed DAC/TMDS?? |
512 |
|
513 |
for (i = 0; i < 4; i++) { |
514 |
conn.ddc_type = i; |
515 |
if (!radeon_probe_i2c_connector(rinfo, &conn)) { |
516 |
|
517 |
radeon_fill_conn(&rinfo->connectors[idx++], conn.mon_type, conn.ddc_type, &found_tmds, &found_crt); |
518 |
} |
519 |
} |
520 |
|
521 |
/* If we failed to probe something.. */ |
522 |
if (idx) |
523 |
goto found; |
524 |
#endif /* CONFIG_FB_RADEON_I2C */ |
525 |
} else { |
526 |
/* Try to obtain infos from firmware */ |
527 |
if (rinfo->radeon_get_conn_info) { |
528 |
if (!rinfo->radeon_get_conn_info(rinfo)) { |
529 |
goto found; |
530 |
} |
531 |
} |
532 |
} |
533 |
|
534 |
printk(KERN_INFO "radeonfb: No connector infos, using defaults...\n"); |
535 |
|
536 |
/* Here, we use defaults that are common enough ... we hope |
537 |
* For a mobility chip, we assume LVDS is on primary |
538 |
*/ |
539 |
if (rinfo->is_mobility) { |
540 |
rinfo->connectors[0].conn_type = conn_lvds; |
541 |
rinfo->connectors[0].ddc_type = ddc_dvi; |
542 |
rinfo->connectors[0].dac_type = dac_primary; |
543 |
rinfo->connectors[0].tmds_type = tmds_unknown; |
544 |
rinfo->connectors[0].mon_type = MT_UNKNOWN; |
545 |
|
546 |
rinfo->connectors[1].conn_type = conn_dvi_d; |
547 |
rinfo->connectors[1].ddc_type = ddc_vga; |
548 |
rinfo->connectors[1].dac_type = dac_primary; |
549 |
rinfo->connectors[1].tmds_type = tmds_internal; |
550 |
rinfo->connectors[1].mon_type = MT_UNKNOWN; |
551 |
|
552 |
rinfo->connectors[2].conn_type = conn_stv; |
553 |
rinfo->connectors[2].ddc_type = ddc_none; |
554 |
rinfo->connectors[2].dac_type = dac_tvdac; |
555 |
rinfo->connectors[2].tmds_type = tmds_unknown; |
556 |
rinfo->connectors[2].mon_type = MT_UNKNOWN; |
557 |
} else { |
558 |
rinfo->connectors[0].conn_type = conn_dvi_d; |
559 |
rinfo->connectors[0].ddc_type = ddc_dvi; |
560 |
rinfo->connectors[0].dac_type = dac_tvdac; |
561 |
rinfo->connectors[0].tmds_type = tmds_internal; |
562 |
rinfo->connectors[0].mon_type = MT_UNKNOWN; |
563 |
|
564 |
rinfo->connectors[1].conn_type = conn_vga; |
565 |
rinfo->connectors[1].ddc_type = ddc_vga; |
566 |
rinfo->connectors[1].dac_type = dac_primary; |
567 |
rinfo->connectors[1].tmds_type = tmds_unknown; |
568 |
rinfo->connectors[1].mon_type = MT_UNKNOWN; |
569 |
|
570 |
if (rinfo->has_CRTC2) { |
571 |
rinfo->connectors[1].conn_type = conn_vga; |
572 |
rinfo->connectors[1].ddc_type = ddc_crt2; |
573 |
rinfo->connectors[1].dac_type = dac_tvdac; |
574 |
rinfo->connectors[1].tmds_type = tmds_unknown; |
575 |
rinfo->connectors[1].mon_type = MT_UNKNOWN; |
576 |
} |
577 |
} |
578 |
|
579 |
found: |
580 |
/* Now, we do additional fixups */ |
581 |
|
582 |
/* RS300 has only one DAC, force TV-DAC on VGA port */ |
583 |
if (rinfo->family == CHIP_FAMILY_RS300) { |
584 |
for (i = 0; i < RADEON_MAX_CONNECTORS; i++) { |
585 |
if (rinfo->connectors[i].conn_type == conn_vga) |
586 |
rinfo->connectors[i].dac_type = dac_tvdac; |
587 |
else if (rinfo->connectors[i].dac_type != dac_unknown) |
588 |
rinfo->connectors[i].dac_type = dac_primary; |
589 |
} |
590 |
} |
591 |
|
592 |
/* Single head chips all use primary DAC */ |
593 |
if (!rinfo->has_CRTC2) |
594 |
rinfo->connectors[0].dac_type = dac_primary; |
595 |
|
596 |
return; |
597 |
} |
598 |
|
599 |
#ifdef CONFIG_PPC_OF |
600 |
int __devinit radeon_get_conn_info_openfirmware(struct radeonfb_info *rinfo) |
601 |
{ |
602 |
int i; |
603 |
int not_found = 1; |
604 |
|
605 |
for(i = 0 ; < 2 ; i++) { /* Only two heads for OF! */ |
606 |
if (!radeon_probe_OF_head(rinfo, i)) found = 0; |
607 |
} |
608 |
return found; |
609 |
} |
610 |
#endif /* CONFIG_PPC_OF */ |
611 |
|
612 |
int __devinit radeon_get_conn_info_atom(struct radeonfb_info *rinfo) |
613 |
{ |
614 |
int i, j, offset, valids; |
615 |
int ids[RADEON_MAX_CONNECTORS]; |
616 |
u16 portinfo, tmp0; |
617 |
int conn_index = 0; |
618 |
int conn_add = 2; |
619 |
int idx = 0; |
620 |
int ddc_type, dac_type, conn_type, tmds_type, port_id; |
621 |
int connector_found = 0; |
622 |
|
623 |
offset = BIOS_IN16(rinfo->atom_data_start + 22); |
624 |
if (offset == 0) |
625 |
return -ENODEV; |
626 |
|
627 |
/* Again, I slightly modified X.org algorithm. I assign "primary" outputs |
628 |
* to entries 0 and 1, and anything else goes after 2. |
629 |
* |
630 |
* Also, I keep an array of all port IDs matching connectors[] array, |
631 |
* unlike X which limits itself to "crtc"'s |
632 |
*/ |
633 |
for (i = 0; i < RADEON_MAX_CONNECTORS; i++) |
634 |
ids[i] = -1; |
635 |
|
636 |
valids = BIOS_IN16(offset + 4); |
637 |
for (i = 0; i < 8; i++) { |
638 |
if (!(valids & (1 << i))) |
639 |
continue; |
640 |
portinfo = BIOS_IN16(offset + 6 + i*2); |
641 |
|
642 |
conn_type = (portinfo >> 4) & 0xf; |
643 |
dac_type = (portinfo & 0xf) - 1; |
644 |
port_id = (portinfo >> 8) & 0xf; |
645 |
ddc_type = ddc_none; |
646 |
|
647 |
if ((tmp0 = BIOS_IN16(rinfo->atom_data_start + 24))) { |
648 |
switch(BIOS_IN16(tmp0 + 4 + (27 * port_id)) * 4) { |
649 |
case GPIO_MONID: |
650 |
ddc_type = ddc_monid; |
651 |
break; |
652 |
case GPIO_DVI_DDC: |
653 |
ddc_type = ddc_dvi; |
654 |
break; |
655 |
case GPIO_VGA_DDC: |
656 |
ddc_type = ddc_vga; |
657 |
break; |
658 |
case GPIO_CRT2_DDC: |
659 |
ddc_type = ddc_crt2; |
660 |
break; |
661 |
default: |
662 |
ddc_type = ddc_none; |
663 |
break; |
664 |
} |
665 |
} |
666 |
|
667 |
if (i == 3) |
668 |
tmds_type = tmds_internal; |
669 |
else if (i == 7) |
670 |
tmds_type = tmds_external; |
671 |
else |
672 |
tmds_type = tmds_unknown; |
673 |
|
674 |
RTRACE("index %d port %d conn %d dac %d ddc %d tmds %d\n", i, port_id, conn_type, dac_type, ddc_type, tmds_type); |
675 |
|
676 |
/* Ok, now we have the port ID, look for an existing port |
677 |
* already using this ID |
678 |
*/ |
679 |
for (j = 0; j < RADEON_MAX_CONNECTORS; j++) { |
680 |
if (port_id != ids[j]) |
681 |
continue; |
682 |
/* Gotcha, just "update" values */ |
683 |
if (tmds_type != tmds_unknown) |
684 |
rinfo->connectors[j].tmds_type = tmds_type; |
685 |
if (rinfo->connectors[j].dac_type == dac_unknown) |
686 |
rinfo->connectors[j].dac_type = dac_type; |
687 |
if (rinfo->connectors[j].ddc_type == dac_unknown) |
688 |
rinfo->connectors[j].ddc_type = dac_type; |
689 |
continue; |
690 |
} |
691 |
|
692 |
conn_index = (ddc_type == ddc_dvi || conn_index == 1) ? 0 : 1; |
693 |
|
694 |
/* if the port is a TV port, or both connectors are already |
695 |
* assigned, assign it after further in the table |
696 |
*/ |
697 |
if (conn_type == conn_ctv || conn_type == conn_stv || |
698 |
(rinfo->connectors[0].conn_type != conn_none && |
699 |
rinfo->connectors[1].conn_type)) |
700 |
idx = conn_add++; |
701 |
else |
702 |
idx = conn_index; |
703 |
|
704 |
rinfo->connectors[idx].tmds_type = tmds_type; |
705 |
rinfo->connectors[idx].dac_type = dac_type; |
706 |
rinfo->connectors[idx].ddc_type = ddc_type; |
707 |
rinfo->connectors[idx].conn_type = conn_type; |
708 |
|
709 |
/* increment connector_found for primary connectors only */ |
710 |
if (idx < 2) |
711 |
connector_found += (idx + 1); |
712 |
} |
713 |
|
714 |
if (connector_found == 0) |
715 |
return -ENODEV; |
716 |
|
244 |
return 0; |
717 |
return 0; |
245 |
} |
718 |
} |
246 |
|
719 |
|
Lines 248-291
Link Here
|
248 |
* doesn't quite work yet, but it's output is still useful for |
721 |
* doesn't quite work yet, but it's output is still useful for |
249 |
* debugging |
722 |
* debugging |
250 |
*/ |
723 |
*/ |
251 |
static void __devinit radeon_parse_connector_info(struct radeonfb_info *rinfo) |
724 |
int __devinit radeon_get_conn_info_legacy(struct radeonfb_info *rinfo) |
252 |
{ |
725 |
{ |
253 |
int offset, chips, connectors, tmp, i, conn, type; |
726 |
int offset, i, entry, tmp; |
254 |
|
727 |
int ddc_type, dac_type, conn_type, tmds_type; |
255 |
static char* __conn_type_table[16] = { |
728 |
int conn_index = 0; |
256 |
"NONE", "Proprietary", "CRT", "DVI-I", "DVI-D", "Unknown", "Unknown", |
729 |
int conn_add = 2; |
257 |
"Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", |
730 |
int idx = 0; |
258 |
"Unknown", "Unknown", "Unknown" |
731 |
|
|
|
732 |
/* Convert legacy to real connector types */ |
733 |
const enum radeon_conn_type legacy_conn_to_type[] = { |
734 |
conn_none, |
735 |
conn_proprietary, |
736 |
conn_vga, |
737 |
conn_dvi_i, |
738 |
conn_dvi_d, |
739 |
conn_ctv, |
740 |
conn_stv, |
741 |
conn_unsupported, |
259 |
}; |
742 |
}; |
260 |
|
743 |
|
261 |
if (!rinfo->bios_seg) |
744 |
/* Some laptops only have one connector (VGA) listed in the connector |
262 |
return; |
745 |
* table, we need to add LVDS in as a non-DDC display. |
|
|
746 |
* Note, we can't assume the listed VGA will be filled in PortInfo[0], |
747 |
* when walking through connector table. connector_found has following |
748 |
* meaning: |
749 |
* 0 -- nothing found, |
750 |
* 1 -- only connectors[0] filled, |
751 |
* 2 -- only connectors[1] filled, |
752 |
* 3 -- both are filled. |
753 |
* |
754 |
* Note: I modified X.org algorithm to add additional entries if any |
755 |
* after the second table slot. Those entries do not affect the value |
756 |
* of connector_found. --BenH. |
757 |
*/ |
758 |
int connector_found = 0; |
263 |
|
759 |
|
264 |
offset = BIOS_IN16(rinfo->fp_bios_start + 0x50); |
760 |
offset = BIOS_IN16(rinfo->fp_bios_start + 0x50); |
265 |
if (offset == 0) { |
761 |
if (offset == 0) |
266 |
printk(KERN_WARNING "radeonfb: No connector info table detected\n"); |
762 |
return -ENODEV; |
267 |
return; |
763 |
|
268 |
} |
764 |
for (i = 1; i < 4; i++) { |
269 |
|
765 |
entry = offset + i*2; |
270 |
/* Don't do much more at this point but displaying the data if |
766 |
|
271 |
* DEBUG is enabled |
767 |
/* End of table */ |
272 |
*/ |
768 |
if (!BIOS_IN8(entry) && i > 1) |
273 |
chips = BIOS_IN8(offset++) >> 4; |
769 |
break; |
274 |
RTRACE("%d chips in connector info\n", chips); |
770 |
|
275 |
for (i = 0; i < chips; i++) { |
771 |
/* Read table entry, check connector type */ |
276 |
tmp = BIOS_IN8(offset++); |
772 |
tmp = BIOS_IN16(entry); |
277 |
connectors = tmp & 0x0f; |
773 |
conn_type = (tmp >> 12) & 0xf; |
278 |
RTRACE(" - chip %d has %d connectors\n", tmp >> 4, connectors); |
774 |
if (conn_type == legacy_conn_none) |
279 |
for (conn = 0; ; conn++) { |
775 |
continue; |
280 |
tmp = BIOS_IN16(offset); |
776 |
ddc_type = (tmp >> 8) & 0xf; |
281 |
if (tmp == 0) |
777 |
dac_type = (tmp & 0x01) ? dac_tvdac : dac_primary; |
282 |
break; |
778 |
tmds_type = (tmp & 0x10) ? tmds_external : tmds_internal; |
283 |
offset += 2; |
779 |
|
284 |
type = (tmp >> 12) & 0x0f; |
780 |
/* same connector */ |
285 |
RTRACE(" * connector %d of type %d (%s) : %04x\n", |
781 |
if (connector_found > 0) { |
286 |
conn, type, __conn_type_table[type], tmp); |
782 |
if (rinfo->connectors[conn_index].ddc_type == ddc_type) |
|
|
783 |
continue; |
287 |
} |
784 |
} |
|
|
785 |
|
786 |
/* sanity checks */ |
787 |
if (ddc_type > ddc_crt2) |
788 |
ddc_type = ddc_none; |
789 |
if (conn_type > legacy_conn_unsupported) |
790 |
conn_type = legacy_conn_unsupported; |
791 |
if (conn_type != legacy_conn_dvi_d && |
792 |
conn_type != legacy_conn_dvi_i && |
793 |
tmds_type == tmds_internal) |
794 |
tmds_type= tmds_unknown; |
795 |
|
796 |
/* convert connector type */ |
797 |
conn_type = legacy_conn_to_type[conn_type]; |
798 |
|
799 |
/* internal DDC_DVI port will get assigned to connector[0], or |
800 |
* if there is no DDC_DVI (like in some IGPs). |
801 |
*/ |
802 |
conn_index = (ddc_type == ddc_dvi || conn_index == 1) ? 0 : 1; |
803 |
|
804 |
/* if the port is a TV port, or both connectors are already |
805 |
* assigned, assign it after further in the table |
806 |
*/ |
807 |
if (conn_type == conn_ctv || conn_type == conn_stv || |
808 |
(rinfo->connectors[0].conn_type != conn_none && |
809 |
rinfo->connectors[1].conn_type)) |
810 |
idx = conn_add++; |
811 |
else |
812 |
idx = conn_index; |
813 |
|
814 |
/* if table full, exit */ |
815 |
if (idx >= RADEON_MAX_CONNECTORS) { |
816 |
printk(KERN_WARNING "radeonfb: Connector table full !\n"); |
817 |
break; |
818 |
} |
819 |
rinfo->connectors[idx].conn_type = conn_type; |
820 |
rinfo->connectors[idx].ddc_type = ddc_type; |
821 |
rinfo->connectors[idx].dac_type = dac_type; |
822 |
rinfo->connectors[idx].tmds_type = tmds_type; |
823 |
|
824 |
/* increment connector_found for primary connectors only */ |
825 |
if (idx < 2) |
826 |
connector_found += (idx + 1); |
827 |
} |
828 |
|
829 |
if (rinfo->is_mobility) { |
830 |
/* For the cases where only one VGA connector is found, |
831 |
* we assume LVDS is not listed in the connector table, |
832 |
* add it in here as the first port. |
833 |
* |
834 |
* TODO: Check what's up with laptops that have a DVI output |
835 |
* and no LVDS entry in the table. I suspect some thinkpads |
836 |
* may play trick with us here... We may want to check the |
837 |
* presence of a panel via LVDS_GEN_CNTL to be sure... |
838 |
*/ |
839 |
if ((connector_found < 3) && |
840 |
(rinfo->connectors[idx].conn_type == conn_vga)) { |
841 |
if (connector_found == 1) { |
842 |
memcpy(&rinfo->connectors[1], |
843 |
&rinfo->connectors[0], |
844 |
sizeof(struct radeon_connector)); |
845 |
} |
846 |
/* Fixme: TV DAC is probably elsewhere ... */ |
847 |
rinfo->connectors[0].dac_type = dac_tvdac; |
848 |
rinfo->connectors[0].tmds_type = tmds_unknown; |
849 |
rinfo->connectors[0].ddc_type = ddc_none; |
850 |
rinfo->connectors[0].conn_type = conn_proprietary; |
851 |
|
852 |
printk(KERN_WARNING "radeonfb: LVDS port is not in connector table, added in.\n"); |
853 |
if (connector_found == 0) |
854 |
connector_found = 1; |
855 |
else |
856 |
connector_found = 3; |
857 |
} |
858 |
|
859 |
/* Check for LCD DDC info table */ |
860 |
if ((offset = BIOS_IN16(rinfo->fp_bios_start + 0x42))) { |
861 |
if ((tmp = BIOS_IN16(offset + 0x15))) { |
862 |
if ((ddc_type = BIOS_IN8(tmp+2) & 0x07)) { |
863 |
rinfo->connectors[0].ddc_type = ddc_type; |
864 |
printk(KERN_WARNING "radeonfb: LCD DDC Info Table found, " |
865 |
"forcing primary port to %d\n", |
866 |
ddc_type); |
867 |
} |
868 |
} |
869 |
} |
870 |
} else if (connector_found == 2) { |
871 |
memcpy(&rinfo->connectors[0], &rinfo->connectors[1], |
872 |
sizeof (struct radeon_connector)); |
873 |
rinfo->connectors[1].dac_type = dac_unknown; |
874 |
rinfo->connectors[1].tmds_type = tmds_unknown; |
875 |
rinfo->connectors[1].ddc_type = ddc_none; |
876 |
rinfo->connectors[1].conn_type = conn_none; |
877 |
connector_found = 1; |
288 |
} |
878 |
} |
|
|
879 |
|
880 |
if (connector_found == 0) |
881 |
return -ENODEV; |
882 |
|
883 |
/* External TMDS Table, not used now */ |
884 |
return 0; |
289 |
} |
885 |
} |
290 |
|
886 |
|
291 |
|
887 |
|
Lines 362-367
Link Here
|
362 |
return connected ? MT_CRT : MT_NONE; |
958 |
return connected ? MT_CRT : MT_NONE; |
363 |
} |
959 |
} |
364 |
|
960 |
|
|
|
961 |
/* Find if the desired connector and monitor are compatible */ |
962 |
static int __devinit radeon_conn_monitor_compatible(int mon_type, int conn_type) |
963 |
{ |
964 |
switch(mon_type) { |
965 |
case MT_CRT: |
966 |
return ((conn_type == conn_vga) || (conn_type == conn_dvi_a)); |
967 |
case MT_DFP: |
968 |
return ((conn_type == conn_dvi_i) || (conn_type == conn_dvi_d)); |
969 |
case MT_LCD: |
970 |
return (conn_type == conn_lvds); |
971 |
case MT_CTV: |
972 |
return (conn_type == conn_ctv); |
973 |
case MT_STV: |
974 |
return (conn_type == conn_stv); |
975 |
case MT_UNKNOWN: |
976 |
case MT_NONE: |
977 |
default: |
978 |
return 0; |
979 |
} |
980 |
// leaves conn_digital, conn_unsupported, conn_propritetary |
981 |
} |
982 |
|
983 |
/* Find a suitable connector for this display type */ |
984 |
static int __devinit radeon_find_connector_for_mon(struct radeonfb_info *rinfo, int mon_type) |
985 |
{ |
986 |
int i; |
987 |
|
988 |
if (mon_type <= MT_NONE) return 0; |
989 |
|
990 |
for (i = 0; i < RADEON_MAX_CONNECTORS ; i++) { |
991 |
if (radeon_conn_monitor_compatible(mon_type, rinfo->connectors[i].conn_type) && |
992 |
(rinfo->connectors[i].mon_type <= MT_NONE)) { |
993 |
rinfo->connectors[i].mon_type = mon_type; |
994 |
rinfo->connectors[i].head = rinfo->num_heads; |
995 |
rinfo->heads[rinfo->num_heads] = i; |
996 |
rinfo->num_heads++; |
997 |
return 0; |
998 |
} |
999 |
} |
1000 |
|
1001 |
printk(KERN_INFO "radeonfb: couldn't find a connector for monitor %d\n", mon_type); |
1002 |
return -1; |
1003 |
} |
1004 |
|
365 |
/* |
1005 |
/* |
366 |
* Parse the "monitor_layout" string if any. This code is mostly |
1006 |
* Parse the "monitor_layout" string if any. This code is mostly |
367 |
* copied from XFree's radeon driver |
1007 |
* copied from XFree's radeon driver |
Lines 407-425
Link Here
|
407 |
s1[i] = 0; |
1047 |
s1[i] = 0; |
408 |
s2[0] = 0; |
1048 |
s2[0] = 0; |
409 |
} |
1049 |
} |
|
|
1050 |
|
410 |
if (strcmp(s1, "CRT") == 0) |
1051 |
if (strcmp(s1, "CRT") == 0) |
411 |
rinfo->mon1_type = MT_CRT; |
1052 |
radeon_find_connector_for_mon(rinfo, MT_CRT); |
412 |
else if (strcmp(s1, "TMDS") == 0) |
1053 |
else if (strcmp(s1, "TMDS") == 0) |
413 |
rinfo->mon1_type = MT_DFP; |
1054 |
radeon_find_connector_for_mon(rinfo, MT_DFP); |
414 |
else if (strcmp(s1, "LVDS") == 0) |
1055 |
else if (strcmp(s1, "LVDS") == 0) |
415 |
rinfo->mon1_type = MT_LCD; |
1056 |
radeon_find_connector_for_mon(rinfo, MT_LCD); |
416 |
|
1057 |
|
417 |
if (strcmp(s2, "CRT") == 0) |
1058 |
if (strcmp(s2, "CRT") == 0) |
418 |
rinfo->mon2_type = MT_CRT; |
1059 |
radeon_find_connector_for_mon(rinfo, MT_CRT); |
419 |
else if (strcmp(s2, "TMDS") == 0) |
1060 |
else if (strcmp(s2, "TMDS") == 0) |
420 |
rinfo->mon2_type = MT_DFP; |
1061 |
radeon_find_connector_for_mon(rinfo, MT_DFP); |
421 |
else if (strcmp(s2, "LVDS") == 0) |
1062 |
else if (strcmp(s2, "LVDS") == 0) |
422 |
rinfo->mon2_type = MT_LCD; |
1063 |
radeon_find_connector_for_mon(rinfo, MT_LCD); |
423 |
|
1064 |
|
424 |
return 1; |
1065 |
return 1; |
425 |
} |
1066 |
} |
Lines 433-444
Link Here
|
433 |
void __devinit radeon_probe_screens(struct radeonfb_info *rinfo, |
1074 |
void __devinit radeon_probe_screens(struct radeonfb_info *rinfo, |
434 |
const char *monitor_layout, int ignore_edid) |
1075 |
const char *monitor_layout, int ignore_edid) |
435 |
{ |
1076 |
{ |
436 |
#ifdef CONFIG_FB_RADEON_I2C |
1077 |
int i; |
437 |
int ddc_crt2_used = 0; |
|
|
438 |
#endif |
439 |
int tmp, i; |
440 |
|
441 |
radeon_parse_connector_info(rinfo); |
442 |
|
1078 |
|
443 |
if (radeon_parse_monitor_layout(rinfo, monitor_layout)) { |
1079 |
if (radeon_parse_monitor_layout(rinfo, monitor_layout)) { |
444 |
|
1080 |
|
Lines 449-478
Link Here
|
449 |
* a layout for each card ? |
1085 |
* a layout for each card ? |
450 |
*/ |
1086 |
*/ |
451 |
|
1087 |
|
452 |
RTRACE("Using specified monitor layout: %s", monitor_layout); |
1088 |
RTRACE("Using specified monitor layout: %s\n", monitor_layout); |
453 |
#ifdef CONFIG_FB_RADEON_I2C |
1089 |
#ifdef CONFIG_FB_RADEON_I2C |
454 |
if (!ignore_edid) { |
1090 |
if (!ignore_edid) { |
455 |
if (rinfo->mon1_type != MT_NONE) |
1091 |
int mon_type; |
456 |
if (!radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID)) { |
1092 |
|
457 |
radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID); |
1093 |
/* If the DDC detection fails, |
458 |
ddc_crt2_used = 1; |
1094 |
we still want to use the user's specified layout! */ |
|
|
1095 |
mon_type = PRIMARY_MONITOR(rinfo); |
1096 |
|
1097 |
if (PRIMARY_MONITOR(rinfo) > MT_NONE) |
1098 |
if (radeon_probe_i2c_connector(rinfo, &PRIMARY_HEAD(rinfo))) |
1099 |
PRIMARY_MONITOR(rinfo) = mon_type; |
1100 |
if (SECONDARY_HEAD_PRESENT(rinfo)) { |
1101 |
mon_type = SECONDARY_MONITOR(rinfo); |
1102 |
if (SECONDARY_MONITOR(rinfo) > MT_NONE) { |
1103 |
if (radeon_probe_i2c_connector(rinfo, &SECONDARY_HEAD(rinfo))) { |
1104 |
rinfo->connectors[rinfo->heads[1]].mon_type = mon_type; |
1105 |
} |
459 |
} |
1106 |
} |
460 |
if (rinfo->mon2_type != MT_NONE) |
1107 |
} |
461 |
if (!radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID) && |
|
|
462 |
!ddc_crt2_used) |
463 |
radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID); |
464 |
} |
1108 |
} |
465 |
#endif /* CONFIG_FB_RADEON_I2C */ |
1109 |
#endif /* CONFIG_FB_RADEON_I2C */ |
466 |
if (rinfo->mon1_type == MT_NONE) { |
1110 |
|
467 |
if (rinfo->mon2_type != MT_NONE) { |
1111 |
/* If the user specified a bogus monitor layout... */ |
468 |
rinfo->mon1_type = rinfo->mon2_type; |
1112 |
if (PRIMARY_MONITOR(rinfo) <= MT_NONE) { |
469 |
rinfo->mon1_EDID = rinfo->mon2_EDID; |
1113 |
radeon_find_connector_for_mon(rinfo, MT_CRT); |
470 |
} else { |
1114 |
printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n"); |
471 |
rinfo->mon1_type = MT_CRT; |
|
|
472 |
printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n"); |
473 |
} |
474 |
rinfo->mon2_type = MT_NONE; |
475 |
rinfo->mon2_EDID = NULL; |
476 |
} |
1115 |
} |
477 |
} else { |
1116 |
} else { |
478 |
/* |
1117 |
/* |
Lines 481-662
Link Here
|
481 |
|
1120 |
|
482 |
RTRACE("Starting monitor auto detection...\n"); |
1121 |
RTRACE("Starting monitor auto detection...\n"); |
483 |
|
1122 |
|
484 |
#if DEBUG && defined(CONFIG_FB_RADEON_I2C) |
|
|
485 |
{ |
486 |
u8 *EDIDs[4] = { NULL, NULL, NULL, NULL }; |
487 |
int mon_types[4] = {MT_NONE, MT_NONE, MT_NONE, MT_NONE}; |
488 |
int i; |
489 |
|
490 |
for (i = 0; i < 4; i++) |
491 |
mon_types[i] = radeon_probe_i2c_connector(rinfo, |
492 |
i+1, &EDIDs[i]); |
493 |
} |
494 |
#endif /* DEBUG */ |
495 |
/* |
1123 |
/* |
496 |
* Old single head cards |
1124 |
* Old single head cards |
497 |
*/ |
1125 |
*/ |
498 |
if (!rinfo->has_CRTC2) { |
1126 |
if (!rinfo->has_CRTC2) { |
499 |
#ifdef CONFIG_PPC_OF |
|
|
500 |
if (rinfo->mon1_type == MT_NONE) |
501 |
rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0, |
502 |
&rinfo->mon1_EDID); |
503 |
#endif /* CONFIG_PPC_OF */ |
504 |
#ifdef CONFIG_FB_RADEON_I2C |
1127 |
#ifdef CONFIG_FB_RADEON_I2C |
505 |
if (rinfo->mon1_type == MT_NONE) |
1128 |
/* Probe each connector */ |
506 |
rinfo->mon1_type = |
1129 |
for(i = 0 ; i < RADEON_MAX_CONNECTORS ; i++) { |
507 |
radeon_probe_i2c_connector(rinfo, ddc_dvi, |
1130 |
if (PRIMARY_MONITOR(rinfo) > MT_NONE) break; /* only one head */ |
508 |
&rinfo->mon1_EDID); |
1131 |
if (!radeon_probe_i2c_connector(rinfo, &rinfo->connectors[i])) { |
509 |
if (rinfo->mon1_type == MT_NONE) |
1132 |
rinfo->heads[rinfo->num_heads] = i; |
510 |
rinfo->mon1_type = |
1133 |
rinfo->connectors[i].head = rinfo->num_heads++; |
511 |
radeon_probe_i2c_connector(rinfo, ddc_vga, |
1134 |
} |
512 |
&rinfo->mon1_EDID); |
1135 |
} |
513 |
if (rinfo->mon1_type == MT_NONE) |
|
|
514 |
rinfo->mon1_type = |
515 |
radeon_probe_i2c_connector(rinfo, ddc_crt2, |
516 |
&rinfo->mon1_EDID); |
517 |
#endif /* CONFIG_FB_RADEON_I2C */ |
1136 |
#endif /* CONFIG_FB_RADEON_I2C */ |
518 |
if (rinfo->mon1_type == MT_NONE) |
1137 |
if (PRIMARY_MONITOR(rinfo) <= MT_NONE) { |
519 |
rinfo->mon1_type = MT_CRT; |
1138 |
radeon_find_connector_for_mon(rinfo, MT_CRT); |
|
|
1139 |
} |
520 |
goto bail; |
1140 |
goto bail; |
521 |
} |
1141 |
} |
522 |
|
1142 |
|
523 |
/* |
1143 |
/* Probe heads */ |
524 |
* Check for cards with reversed DACs or TMDS controllers using BIOS |
1144 |
#ifdef CONFIG_FB_RADEON_I2C |
525 |
*/ |
1145 |
/* Probe each connector in turn. */ |
526 |
if (rinfo->bios_seg && |
1146 |
for(i = 0 ; i < RADEON_MAX_CONNECTORS ; i++) { |
527 |
(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x50))) { |
1147 |
if (rinfo->connectors[i].mon_type > MT_NONE) continue; /* Don't probe "detected" stuff again */ |
528 |
for (i = 1; i < 4; i++) { |
1148 |
if (!radeon_probe_i2c_connector(rinfo, &rinfo->connectors[i])) { |
529 |
unsigned int tmp0; |
1149 |
rinfo->heads[rinfo->num_heads] = i; |
530 |
|
1150 |
rinfo->connectors[i].head = rinfo->num_heads++; |
531 |
if (!BIOS_IN8(tmp + i*2) && i > 1) |
|
|
532 |
break; |
533 |
tmp0 = BIOS_IN16(tmp + i*2); |
534 |
if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0x0f) == ddc_dvi)) { |
535 |
rinfo->reversed_DAC = 1; |
536 |
printk(KERN_INFO "radeonfb: Reversed DACs detected\n"); |
537 |
} |
538 |
if ((((tmp0 >> 8) & 0x0f) == ddc_dvi) && ((tmp0 >> 4) & 0x01)) { |
539 |
rinfo->reversed_TMDS = 1; |
540 |
printk(KERN_INFO "radeonfb: Reversed TMDS detected\n"); |
541 |
} |
542 |
} |
1151 |
} |
543 |
} |
1152 |
} |
|
|
1153 |
|
1154 |
#endif /* CONFIG_FB_RADEON_I2C */ |
544 |
|
1155 |
|
545 |
/* |
1156 |
/* Mobility chips usually have LCDs... */ |
546 |
* Probe primary head (DVI or laptop internal panel) |
1157 |
if ((PRIMARY_MONITOR(rinfo) <= MT_NONE) && |
547 |
*/ |
1158 |
rinfo->is_mobility && |
548 |
#ifdef CONFIG_PPC_OF |
1159 |
((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4)) || |
549 |
if (rinfo->mon1_type == MT_NONE) |
1160 |
(INREG(LVDS_GEN_CNTL) & (LVDS_EN|LVDS_ON)))) { |
550 |
rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0, |
1161 |
printk(KERN_INFO "radeonfb: Non-DDC laptop panel detected\n"); |
551 |
&rinfo->mon1_EDID); |
1162 |
radeon_find_connector_for_mon(rinfo, MT_LCD); |
552 |
#endif /* CONFIG_PPC_OF */ |
1163 |
if (rinfo->radeon_get_lvds_info) { |
553 |
#ifdef CONFIG_FB_RADEON_I2C |
1164 |
rinfo->radeon_get_lvds_info(rinfo); |
554 |
if (rinfo->mon1_type == MT_NONE) |
1165 |
} |
555 |
rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi, |
|
|
556 |
&rinfo->mon1_EDID); |
557 |
if (rinfo->mon1_type == MT_NONE) { |
558 |
rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_crt2, |
559 |
&rinfo->mon1_EDID); |
560 |
if (rinfo->mon1_type != MT_NONE) |
561 |
ddc_crt2_used = 1; |
562 |
} |
1166 |
} |
563 |
#endif /* CONFIG_FB_RADEON_I2C */ |
1167 |
|
564 |
if (rinfo->mon1_type == MT_NONE && rinfo->is_mobility && |
1168 |
/* Probe for monitors on the primary and secondary crtc heads */ |
565 |
((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4)) |
1169 |
if (PRIMARY_MONITOR(rinfo) <= MT_NONE) { |
566 |
|| (INREG(LVDS_GEN_CNTL) & LVDS_ON))) { |
1170 |
radeon_find_connector_for_mon(rinfo, radeon_crt_is_connected(rinfo, 1)); |
567 |
rinfo->mon1_type = MT_LCD; |
|
|
568 |
printk("Non-DDC laptop panel detected\n"); |
569 |
} |
1171 |
} |
570 |
if (rinfo->mon1_type == MT_NONE) |
|
|
571 |
rinfo->mon1_type = radeon_crt_is_connected(rinfo, rinfo->reversed_DAC); |
572 |
|
1172 |
|
573 |
/* |
1173 |
/* If we still haven't found anything, just force it to be on the CRT.. */ |
574 |
* Probe secondary head (mostly VGA, can be DVI) |
1174 |
if (PRIMARY_MONITOR(rinfo) <= MT_NONE) { |
575 |
*/ |
1175 |
radeon_find_connector_for_mon(rinfo, MT_CRT); |
576 |
#ifdef CONFIG_PPC_OF |
1176 |
} |
577 |
if (rinfo->mon2_type == MT_NONE) |
|
|
578 |
rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1, |
579 |
&rinfo->mon2_EDID); |
580 |
#endif /* CONFIG_PPC_OF */ |
581 |
#ifdef CONFIG_FB_RADEON_I2C |
582 |
if (rinfo->mon2_type == MT_NONE) |
583 |
rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_vga, |
584 |
&rinfo->mon2_EDID); |
585 |
if (rinfo->mon2_type == MT_NONE && !ddc_crt2_used) |
586 |
rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_crt2, |
587 |
&rinfo->mon2_EDID); |
588 |
#endif /* CONFIG_FB_RADEON_I2C */ |
589 |
if (rinfo->mon2_type == MT_NONE) |
590 |
rinfo->mon2_type = radeon_crt_is_connected(rinfo, !rinfo->reversed_DAC); |
591 |
|
1177 |
|
592 |
/* |
1178 |
/* Always keep internal TMDS as primary head */ |
593 |
* If we only detected port 2, we swap them, if none detected, |
1179 |
if (SECONDARY_HEAD_PRESENT(rinfo) && (SECONDARY_HEAD(rinfo).tmds_type == tmds_internal) && (SECONDARY_MONITOR(rinfo) == MT_DFP)) { |
594 |
* assume CRT (maybe fallback to old BIOS_SCRATCH stuff ? or look |
1180 |
int head = rinfo->heads[0]; |
595 |
* at FP registers ?) |
1181 |
rinfo->heads[0] = rinfo->heads[1]; |
596 |
*/ |
1182 |
rinfo->heads[1] = head; |
597 |
if (rinfo->mon1_type == MT_NONE) { |
|
|
598 |
if (rinfo->mon2_type != MT_NONE) { |
599 |
rinfo->mon1_type = rinfo->mon2_type; |
600 |
rinfo->mon1_EDID = rinfo->mon2_EDID; |
601 |
} else |
602 |
rinfo->mon1_type = MT_CRT; |
603 |
rinfo->mon2_type = MT_NONE; |
604 |
rinfo->mon2_EDID = NULL; |
605 |
} |
1183 |
} |
|
|
1184 |
} |
1185 |
bail: |
606 |
|
1186 |
|
607 |
/* |
1187 |
/* Dump out the heads we've found so far */ |
608 |
* Deal with reversed TMDS |
1188 |
for (i = 0; i < RADEON_MAX_CONNECTORS; i++) { |
609 |
*/ |
1189 |
|
610 |
if (rinfo->reversed_TMDS) { |
1190 |
if (rinfo->connectors[i].conn_type == conn_none) |
611 |
/* Always keep internal TMDS as primary head */ |
1191 |
continue; |
612 |
if (rinfo->mon1_type == MT_DFP || rinfo->mon2_type == MT_DFP) { |
1192 |
printk(KERN_INFO " * Connector %d is %s. Head %d, Monitor: %s ", i+1, |
613 |
int tmp_type = rinfo->mon1_type; |
1193 |
conn_type_name[rinfo->connectors[i].conn_type], |
614 |
u8 *tmp_EDID = rinfo->mon1_EDID; |
1194 |
rinfo->connectors[i].head, |
615 |
rinfo->mon1_type = rinfo->mon2_type; |
1195 |
rinfo->connectors[i].mon_type == MT_UNKNOWN ? |
616 |
rinfo->mon1_EDID = rinfo->mon2_EDID; |
1196 |
"Not Probed Yet" : |
617 |
rinfo->mon2_type = tmp_type; |
1197 |
mon_type_name[rinfo->connectors[i].mon_type]); |
618 |
rinfo->mon2_EDID = tmp_EDID; |
1198 |
if (rinfo->connectors[i].edid) { |
619 |
if (rinfo->mon1_type == MT_CRT || rinfo->mon2_type == MT_CRT) |
1199 |
printk("(EDID probed)\n"); |
620 |
rinfo->reversed_DAC ^= 1; |
1200 |
} else { |
621 |
} |
1201 |
printk("\n"); |
622 |
} |
1202 |
} |
|
|
1203 |
printk(KERN_INFO " ddc port: %d, dac: %d, tmds: %d\n", |
1204 |
rinfo->connectors[i].ddc_type, |
1205 |
rinfo->connectors[i].dac_type, |
1206 |
rinfo->connectors[i].tmds_type); |
623 |
} |
1207 |
} |
624 |
if (ignore_edid) { |
|
|
625 |
kfree(rinfo->mon1_EDID); |
626 |
rinfo->mon1_EDID = NULL; |
627 |
kfree(rinfo->mon2_EDID); |
628 |
rinfo->mon2_EDID = NULL; |
629 |
} |
630 |
|
631 |
bail: |
632 |
printk(KERN_INFO "radeonfb: Monitor 1 type %s found\n", |
633 |
radeon_get_mon_name(rinfo->mon1_type)); |
634 |
if (rinfo->mon1_EDID) |
635 |
printk(KERN_INFO "radeonfb: EDID probed\n"); |
636 |
if (!rinfo->has_CRTC2) |
637 |
return; |
638 |
printk(KERN_INFO "radeonfb: Monitor 2 type %s found\n", |
639 |
radeon_get_mon_name(rinfo->mon2_type)); |
640 |
if (rinfo->mon2_EDID) |
641 |
printk(KERN_INFO "radeonfb: EDID probed\n"); |
642 |
} |
1208 |
} |
643 |
|
1209 |
|
644 |
|
1210 |
|
645 |
/* |
|
|
646 |
* This functions applyes any arch/model/machine specific fixups |
647 |
* to the panel info. It may eventually alter EDID block as |
648 |
* well or whatever is specific to a given model and not probed |
649 |
* properly by the default code |
650 |
*/ |
651 |
static void radeon_fixup_panel_info(struct radeonfb_info *rinfo) |
652 |
{ |
653 |
#ifdef CONFIG_PPC_OF |
1211 |
#ifdef CONFIG_PPC_OF |
|
|
1212 |
int __devinit radeon_get_lvds_info_openfirmware(struct radeonfb_info *rinfo) |
1213 |
{ |
1214 |
|
654 |
/* |
1215 |
/* |
655 |
* LCD Flat panels should use fixed dividers, we enfore that on |
1216 |
* LCD Flat panels should use fixed dividers, we enfore that on |
656 |
* PPC only for now... |
1217 |
* PPC only for now... |
657 |
*/ |
1218 |
*/ |
658 |
if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type == MT_LCD |
1219 |
If (!rinfo->panel_info.use_bios_dividers && (PRIMARY_MONITOR(rinfo) == MT_LCD) && |
659 |
&& rinfo->is_mobility) { |
1220 |
rinfo->is_mobility) { |
660 |
int ppll_div_sel; |
1221 |
int ppll_div_sel; |
661 |
u32 ppll_divn; |
1222 |
u32 ppll_divn; |
662 |
ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3; |
1223 |
ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3; |
Lines 667-681
Link Here
|
667 |
rinfo->panel_info.post_divider = (ppll_divn >> 16) & 0x7; |
1228 |
rinfo->panel_info.post_divider = (ppll_divn >> 16) & 0x7; |
668 |
rinfo->panel_info.use_bios_dividers = 1; |
1229 |
rinfo->panel_info.use_bios_dividers = 1; |
669 |
|
1230 |
|
670 |
printk(KERN_DEBUG "radeonfb: Using Firmware dividers 0x%08x " |
1231 |
printk(KERN_INFO "Using Firmware dividers 0x%08x " |
671 |
"from PPLL %d\n", |
1232 |
"from PPLL %d\n", |
672 |
rinfo->panel_info.fbk_divider | |
1233 |
rinfo->panel_info.fbk_divider | |
673 |
(rinfo->panel_info.post_divider << 16), |
1234 |
(rinfo->panel_info.post_divider << 16), |
674 |
ppll_div_sel); |
1235 |
ppll_div_sel); |
|
|
1236 |
return 0; |
675 |
} |
1237 |
} |
676 |
#endif /* CONFIG_PPC_OF */ |
1238 |
return 1; |
677 |
} |
1239 |
} |
678 |
|
1240 |
#endif /* CONFIG_PPC_OF */ |
679 |
|
1241 |
|
680 |
/* |
1242 |
/* |
681 |
* Fill up panel infos from a mode definition, either returned by the EDID |
1243 |
* Fill up panel infos from a mode definition, either returned by the EDID |
Lines 742-763
Link Here
|
742 |
info->var = radeonfb_default_var; |
1304 |
info->var = radeonfb_default_var; |
743 |
INIT_LIST_HEAD(&info->modelist); |
1305 |
INIT_LIST_HEAD(&info->modelist); |
744 |
|
1306 |
|
745 |
/* |
1307 |
/* If we're an LCD and don't have a valid setup... */ |
746 |
* First check out what BIOS has to say |
1308 |
if ((PRIMARY_MONITOR(rinfo) == MT_LCD) && |
747 |
*/ |
1309 |
!rinfo->panel_info.valid && |
748 |
if (rinfo->mon1_type == MT_LCD) |
1310 |
rinfo->radeon_get_lvds_info) { |
749 |
radeon_get_panel_info_BIOS(rinfo); |
1311 |
rinfo->radeon_get_lvds_info(rinfo); |
|
|
1312 |
} |
1313 |
|
1314 |
#if 0 |
1315 |
/* If we're a mobility and still haven't detected a screen..? */ |
1316 |
if ((PRIMARY_MONITOR(rinfo) <= MT_NONE) && |
1317 |
rinfo->is_mobility && |
1318 |
rinfo->radeon_get_lvds_info) { |
1319 |
if (! rinfo->radeon_get_lvds_info(rinfo)) { |
1320 |
radeon_find_connector_for_mon(rinfo, MT_LCD); |
1321 |
} |
1322 |
} |
1323 |
#endif |
750 |
|
1324 |
|
751 |
/* |
1325 |
/* |
752 |
* Parse EDID detailed timings and deduce panel infos if any. Right now |
1326 |
* Parse EDID detailed timings and deduce panel infos if any. Right now |
753 |
* we only deal with first entry returned by parse_EDID, we may do better |
1327 |
* we only deal with first entry returned by parse_EDID, we may do better |
754 |
* some day... |
1328 |
* some day... |
755 |
*/ |
1329 |
*/ |
756 |
if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type != MT_CRT |
1330 |
if (!rinfo->panel_info.use_bios_dividers && |
757 |
&& rinfo->mon1_EDID) { |
1331 |
(PRIMARY_MONITOR(rinfo) != MT_CRT) && |
|
|
1332 |
PRIMARY_HEAD(rinfo).edid) { |
758 |
struct fb_var_screeninfo var; |
1333 |
struct fb_var_screeninfo var; |
759 |
RTRACE("Parsing EDID data for panel info\n"); |
1334 |
RTRACE("Parsing EDID data for panel info\n"); |
760 |
if (fb_parse_edid(rinfo->mon1_EDID, &var) == 0) { |
1335 |
if (fb_parse_edid(PRIMARY_HEAD(rinfo).edid, &var) == 0) { |
761 |
if (var.xres >= rinfo->panel_info.xres && |
1336 |
if (var.xres >= rinfo->panel_info.xres && |
762 |
var.yres >= rinfo->panel_info.yres) |
1337 |
var.yres >= rinfo->panel_info.yres) |
763 |
radeon_var_to_panel_info(rinfo, &var); |
1338 |
radeon_var_to_panel_info(rinfo, &var); |
Lines 765-779
Link Here
|
765 |
} |
1340 |
} |
766 |
|
1341 |
|
767 |
/* |
1342 |
/* |
768 |
* Do any additional platform/arch fixups to the panel infos |
|
|
769 |
*/ |
770 |
radeon_fixup_panel_info(rinfo); |
771 |
|
772 |
/* |
773 |
* If we have some valid panel infos, we setup the default mode based on |
1343 |
* If we have some valid panel infos, we setup the default mode based on |
774 |
* those |
1344 |
* those |
775 |
*/ |
1345 |
*/ |
776 |
if (rinfo->mon1_type != MT_CRT && rinfo->panel_info.valid) { |
1346 |
if ((PRIMARY_MONITOR(rinfo) != MT_CRT) && rinfo->panel_info.valid) { |
777 |
struct fb_var_screeninfo *var = &info->var; |
1347 |
struct fb_var_screeninfo *var = &info->var; |
778 |
|
1348 |
|
779 |
RTRACE("Setting up default mode based on panel info\n"); |
1349 |
RTRACE("Setting up default mode based on panel info\n"); |
Lines 804-816
Link Here
|
804 |
/* |
1374 |
/* |
805 |
* Now build modedb from EDID |
1375 |
* Now build modedb from EDID |
806 |
*/ |
1376 |
*/ |
807 |
if (rinfo->mon1_EDID) { |
1377 |
if (PRIMARY_HEAD(rinfo).edid) { |
808 |
fb_edid_to_monspecs(rinfo->mon1_EDID, &info->monspecs); |
1378 |
fb_edid_to_monspecs(PRIMARY_HEAD(rinfo).edid, &info->monspecs); |
809 |
fb_videomode_to_modelist(info->monspecs.modedb, |
1379 |
fb_videomode_to_modelist(info->monspecs.modedb, |
810 |
info->monspecs.modedb_len, |
1380 |
info->monspecs.modedb_len, |
811 |
&info->modelist); |
1381 |
&info->modelist); |
812 |
rinfo->mon1_modedb = info->monspecs.modedb; |
1382 |
PRIMARY_HEAD(rinfo).modedb = info->monspecs.modedb; |
813 |
rinfo->mon1_dbsize = info->monspecs.modedb_len; |
1383 |
PRIMARY_HEAD(rinfo).modedb_size = info->monspecs.modedb_len; |
814 |
} |
1384 |
} |
815 |
|
1385 |
|
816 |
|
1386 |
|
Lines 819-825
Link Here
|
819 |
* we try to read it from card), we try to pick a default mode |
1389 |
* we try to read it from card), we try to pick a default mode |
820 |
* and create some panel infos. Whatever... |
1390 |
* and create some panel infos. Whatever... |
821 |
*/ |
1391 |
*/ |
822 |
if (rinfo->mon1_type != MT_CRT && !rinfo->panel_info.valid) { |
1392 |
if ((PRIMARY_MONITOR(rinfo) != MT_CRT) && !rinfo->panel_info.valid) { |
823 |
struct fb_videomode *modedb; |
1393 |
struct fb_videomode *modedb; |
824 |
int dbsize; |
1394 |
int dbsize; |
825 |
char modename[32]; |
1395 |
char modename[32]; |
Lines 833-853
Link Here
|
833 |
} |
1403 |
} |
834 |
if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) { |
1404 |
if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) { |
835 |
printk(KERN_WARNING "radeonfb: Can't find panel size, going back to CRT\n"); |
1405 |
printk(KERN_WARNING "radeonfb: Can't find panel size, going back to CRT\n"); |
836 |
rinfo->mon1_type = MT_CRT; |
1406 |
radeon_find_connector_for_mon(rinfo, MT_CRT); |
837 |
goto pickup_default; |
1407 |
goto pickup_default; |
838 |
} |
1408 |
} |
839 |
printk(KERN_WARNING "radeonfb: Assuming panel size %dx%d\n", |
1409 |
printk(KERN_WARNING "radeonfb: Assuming panel size %dx%d\n", |
840 |
rinfo->panel_info.xres, rinfo->panel_info.yres); |
1410 |
rinfo->panel_info.xres, rinfo->panel_info.yres); |
841 |
modedb = rinfo->mon1_modedb; |
1411 |
modedb = PRIMARY_HEAD(rinfo).modedb; |
842 |
dbsize = rinfo->mon1_dbsize; |
1412 |
dbsize = PRIMARY_HEAD(rinfo).modedb_size; |
843 |
snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres); |
1413 |
snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres); |
844 |
if (fb_find_mode(&info->var, info, modename, |
1414 |
if (fb_find_mode(&info->var, info, modename, |
845 |
modedb, dbsize, NULL, 8) == 0) { |
1415 |
modedb, dbsize, NULL, 8) == 0) { |
846 |
printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n"); |
1416 |
printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n"); |
847 |
rinfo->mon1_type = MT_CRT; |
1417 |
radeon_find_connector_for_mon(rinfo, MT_CRT); |
848 |
goto pickup_default; |
1418 |
goto pickup_default; |
849 |
} |
1419 |
} |
850 |
has_default_mode = 1; |
1420 |
has_default_mode = 1; |
|
|
1421 |
radeon_find_connector_for_mon(rinfo, MT_LCD); |
851 |
radeon_var_to_panel_info(rinfo, &info->var); |
1422 |
radeon_var_to_panel_info(rinfo, &info->var); |
852 |
} |
1423 |
} |
853 |
|
1424 |
|
Lines 947-960
Link Here
|
947 |
memcpy(dest, src, sizeof(struct fb_var_screeninfo)); |
1518 |
memcpy(dest, src, sizeof(struct fb_var_screeninfo)); |
948 |
|
1519 |
|
949 |
/* Check if we have a modedb built from EDID */ |
1520 |
/* Check if we have a modedb built from EDID */ |
950 |
if (rinfo->mon1_modedb) { |
1521 |
if (PRIMARY_HEAD(rinfo).modedb) { |
951 |
db = rinfo->mon1_modedb; |
1522 |
db = PRIMARY_HEAD(rinfo).modedb; |
952 |
dbsize = rinfo->mon1_dbsize; |
1523 |
dbsize = PRIMARY_HEAD(rinfo).modedb_size; |
953 |
native_db = 1; |
1524 |
native_db = 1; |
954 |
} |
1525 |
} |
955 |
|
1526 |
|
956 |
/* Check if we have a scaler allowing any fancy mode */ |
1527 |
/* Check if we have a scaler allowing any fancy mode */ |
957 |
has_rmx = rinfo->mon1_type == MT_LCD || rinfo->mon1_type == MT_DFP; |
1528 |
has_rmx = (PRIMARY_MONITOR(rinfo) == MT_LCD) || (PRIMARY_MONITOR(rinfo) == MT_DFP); |
958 |
|
1529 |
|
959 |
/* If we have a scaler and are passed FB_ACTIVATE_TEST or |
1530 |
/* If we have a scaler and are passed FB_ACTIVATE_TEST or |
960 |
* FB_ACTIVATE_NOW, just do basic checking and return if the |
1531 |
* FB_ACTIVATE_NOW, just do basic checking and return if the |
Lines 967-973
Link Here
|
967 |
* 640x480-60, but I assume userland knows what it's doing here |
1538 |
* 640x480-60, but I assume userland knows what it's doing here |
968 |
* (though I may be proven wrong...) |
1539 |
* (though I may be proven wrong...) |
969 |
*/ |
1540 |
*/ |
970 |
if (has_rmx == 0 && rinfo->mon1_modedb) |
1541 |
if (has_rmx == 0 && PRIMARY_HEAD(rinfo).modedb) |
971 |
if (fb_validate_mode((struct fb_var_screeninfo *)src, rinfo->info)) |
1542 |
if (fb_validate_mode((struct fb_var_screeninfo *)src, rinfo->info)) |
972 |
return -EINVAL; |
1543 |
return -EINVAL; |
973 |
return 0; |
1544 |
return 0; |