186ce7d2af2944157f01b160b8c6763b814fe95c
[profile/ivi/intel-emgd-kmod.git] / emgd / display / pi / cmn / displayid.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: displayid.c
4  * $Revision: 1.11 $
5  *-----------------------------------------------------------------------------
6  * Copyright (c) 2002-2010, Intel Corporation.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  *-----------------------------------------------------------------------------
27  * Description:
28  *  This file contains functions to parse DisplayID into a data strucuture.
29  *  Supported DisplayID versions:
30  *  VESA DisplayID Standard Verion 1 12/13/2007
31  *-----------------------------------------------------------------------------
32  */
33
34 #define MODULE_NAME hal.dpd
35
36 #include <io.h>
37 #include <memory.h>
38
39 #include <igd_errno.h>
40
41 #include <displayid.h>
42 #include <pi.h>
43
44 /*!
45  * @addtogroup display_group
46  * @{
47  */
48
49 #ifndef CONFIG_NO_DISPLAYID
50
51 /* IMP NOTE:
52  *     Keep the order of datablocks as it is.
53  *     DisplayID parser directly access the offset using tag as an index.
54  */
55 unsigned short db_offset[] = {
56 #ifdef CONFIG_MICRO
57         OS_OFFSETOF(displayid_t, dummy_db),        /* PRODUCTID        0x00 */
58         OS_OFFSETOF(displayid_t, display_params),  /* DISPLAY_PARAMS   0x01 */
59         OS_OFFSETOF(displayid_t, dummy_db),        /* COLOR_CHARS      0x02 */
60         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_1_DETAIL  0x03 */
61         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_2_DETAIL  0x04 */
62         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_3_SHORT   0x05 */
63         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_4_DMTID   0x06 */
64         OS_OFFSETOF(displayid_t, dummy_db),        /* VESA_TIMING_STD  0x07 */
65         OS_OFFSETOF(displayid_t, dummy_db),        /* CEA_TIMING_STD   0x08 */
66         OS_OFFSETOF(displayid_t, timing_range),    /* VIDEO_RANGE      0x09 */
67         OS_OFFSETOF(displayid_t, dummy_db),        /* SERIAL_NUMBER    0x0A */
68         OS_OFFSETOF(displayid_t, dummy_db),        /* ASCII_STRING     0x0B */
69         OS_OFFSETOF(displayid_t, display_dev),     /* DISPLAY_DEVICE   0x0C */
70         OS_OFFSETOF(displayid_t, lvds),            /* LVDS_INTERFACE   0x0D */
71         OS_OFFSETOF(displayid_t, dummy_db),        /* TRANSFER_CHAR    0x0E */
72         OS_OFFSETOF(displayid_t, display_intf),    /* DISPLAY_INTF     0x0F */
73         OS_OFFSETOF(displayid_t, dummy_db),        /* STEREO_INTF      0x10 */
74 #else
75         OS_OFFSETOF(displayid_t, productid),       /* PRODUCTID        0x00 */
76         OS_OFFSETOF(displayid_t, display_params),  /* DISPLAY_PARAMS   0x01 */
77         OS_OFFSETOF(displayid_t, color_char),      /* COLOR_CHARS      0x02 */
78         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_1_DETAIL  0x03 */
79         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_2_DETAIL  0x04 */
80         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_3_SHORT   0x05 */
81         OS_OFFSETOF(displayid_t, dummy_db),        /* TIMING_4_DMTID   0x06 */
82         OS_OFFSETOF(displayid_t, dummy_db),        /* VESA_TIMING_STD  0x07 */
83         OS_OFFSETOF(displayid_t, dummy_db),        /* CEA_TIMING_STD   0x08 */
84         OS_OFFSETOF(displayid_t, timing_range),    /* VIDEO_RANGE      0x09 */
85         OS_OFFSETOF(displayid_t, serial_num),      /* SERIAL_NUMBER    0x0A */
86         OS_OFFSETOF(displayid_t, general_string),  /* ASCII_STRING     0x0B */
87         OS_OFFSETOF(displayid_t, display_dev),     /* DISPLAY_DEVICE   0x0C */
88         OS_OFFSETOF(displayid_t, lvds),            /* LVDS_INTERFACE   0x0D */
89         OS_OFFSETOF(displayid_t, transfer_char),   /* TRANSFER_CHAR    0x0E */
90         OS_OFFSETOF(displayid_t, display_intf),    /* DISPLAY_INTF     0x0F */
91         OS_OFFSETOF(displayid_t, stereo_intf),     /* STEREO_INTF      0x10 */
92 #endif
93
94
95 #if 0
96         /* Vendor specific tag is out of order, so it cannot be here. See
97          * case DATABLOCK_VENDOR_SPECIFIC for implementation. */
98         OS_OFFSETOF(displayid_t, vendor),          /* VENDOR_SPECIFIC  0x7F */
99 #endif
100 };
101
102 type_std_t vesa_std_lookup[] =
103 {
104         /* width  height refresh flags */
105         /* byte 0 bit 0->7 */
106         {  640,    350,    85,   0                 },   /* bit 0 */
107         {  640,    400,    85,   0                 },   /* bit 1 */
108         {  720,    400,    85,   0                 },   /* bit 2 */
109         {  640,    480,    60,   0                 },   /* bit 3 */
110         {  640,    480,    72,   0                 },   /* bit 4 */
111         {  640,    480,    75,   0                 },   /* bit 5 */
112         {  640,    480,    85,   0                 },   /* bit 6 */
113         {  800,    600,    56,   0                 },   /* bit 7 */
114
115         /* byte 1 bit 0->7 */
116         {  800,    600,    60,   0                 },   /* bit 0 */
117         {  800,    600,    72,   0                 },   /* bit 1 */
118         {  800,    600,    75,   0                 },   /* bit 2 */
119         {  800,    600,    85,   0                 },   /* bit 3 */
120         {  800,    600,   120,   PD_MODE_RB        },   /* bit 4 */
121         {  848,    480,    60,   0                 },   /* bit 5 */
122         { 1024,    768,    43,   PD_SCAN_INTERLACE },   /* bit 6 */
123         { 1024,    768,    60,   0                 },   /* bit 7 */
124
125         /* byte 2 bit 0->7 */
126         { 1024,    768,    70,   0                 },   /* bit 0 */
127         { 1024,    768,    75,   0                 },   /* bit 1 */
128         { 1024,    768,    85,   0                 },   /* bit 2 */
129         { 1024,    768,   120,   PD_MODE_RB        },   /* bit 3 */
130         { 1152,    864,    75,   0                 },   /* bit 4 */
131         { 1280,    768,    60,   PD_MODE_RB        },   /* bit 5 */
132         { 1280,    768,    60,   0                 },   /* bit 6 */
133         { 1280,    768,    75,   0                 },   /* bit 7 */
134
135         /* byte 3 bit 0->7 */
136         { 1280,    768,    85,   0                 },   /* bit 0 */
137         { 1280,    768,   120,   PD_MODE_RB        },   /* bit 1 */
138         { 1280,    800,    60,   PD_MODE_RB        },   /* bit 2 */
139         { 1280,    800,    60,   0                 },   /* bit 3 */
140         { 1280,    800,    75,   0                 },   /* bit 4 */
141         { 1280,    800,    85,   0                 },   /* bit 5 */
142         { 1280,    800,   120,   PD_MODE_RB        },   /* bit 6 */
143         { 1280,    960,    60,   0                 },   /* bit 7 */
144
145         /* byte 4 bit 0->7 */
146         { 1280,    960,    85,   0                 },   /* bit 0 */
147         { 1280,    960,   120,   PD_MODE_RB        },   /* bit 1 */
148         { 1280,   1024,    60,   0                 },   /* bit 2 */
149         { 1280,   1024,    75,   0                 },   /* bit 3 */
150         { 1280,   1024,    85,   0                 },   /* bit 4 */
151         { 1280,   1024,   120,   PD_MODE_RB        },   /* bit 5 */
152         { 1360,    768,    60,   0                 },   /* bit 6 */
153         { 1360,    768,   120,   PD_MODE_RB        },   /* bit 7 */
154
155         /* byte 5 bit 0->7 */
156         { 1400,   1050,    60,   PD_MODE_RB        },   /* bit 0 */
157         { 1400,   1050,    60,   0                 },   /* bit 1 */
158         { 1400,   1050,    75,   0                 },   /* bit 2 */
159         { 1400,   1050,    85,   0                 },   /* bit 3 */
160         { 1400,   1050,   120,   PD_MODE_RB        },   /* bit 4 */
161         { 1440,    900,    60,   PD_MODE_RB        },   /* bit 5 */
162         { 1440,    900,    60,   0                 },   /* bit 6 */
163         { 1440,    900,    75,   0                 },   /* bit 7 */
164
165         /* byte 6 bit 0->7 */
166         { 1440,    900,    85,   0                 },   /* bit 0 */
167         { 1440,    900,   120,   PD_MODE_RB        },   /* bit 1 */
168         { 1600,   1200,    60,   0                 },   /* bit 2 */
169         { 1600,   1200,    65,   0                 },   /* bit 3 */
170         { 1600,   1200,    70,   0                 },   /* bit 4 */
171         { 1600,   1200,    75,   0                 },   /* bit 5 */
172         { 1600,   1200,    85,   0                 },   /* bit 6 */
173         { 1600,   1200,   120,   PD_MODE_RB        },   /* bit 7 */
174
175         /* byte 7 bit 0->7 */
176         { 1680,   1050,    60,   PD_MODE_RB        },   /* bit 0 */
177         { 1680,   1050,    60,   0                 },   /* bit 1 */
178         { 1680,   1050,    75,   0                 },   /* bit 2 */
179         { 1680,   1050,    85,   0                 },   /* bit 3 */
180         { 1680,   1050,   120,   PD_MODE_RB        },   /* bit 4 */
181         { 1792,   1344,    60,   0                 },   /* bit 5 */
182         { 1792,   1344,    75,   0                 },   /* bit 6 */
183         { 1792,   1344,   120,   PD_MODE_RB        },   /* bit 7 */
184
185         /* byte 8 bit 0->7 */
186         { 1856,   1392,    60,   0                 },   /* bit 0 */
187         { 1856,   1392,    75,   0                 },   /* bit 1 */
188         { 1856,   1392,   120,   PD_MODE_RB        },   /* bit 2 */
189         { 1920,   1200,    60,   PD_MODE_RB        },   /* bit 3 */
190         { 1920,   1200,    60,   0                 },   /* bit 4 */
191         { 1920,   1200,    75,   0                 },   /* bit 5 */
192         { 1920,   1200,    85,   0                 },   /* bit 6 */
193         { 1920,   1200,   120,   PD_MODE_RB        },   /* bit 7 */
194
195         /* byte 9 bit 0->7 */
196         { 1920,   1440,    60,   0                 },   /* bit 0 */
197         { 1920,   1440,    75,   0                 },   /* bit 1 */
198         { 1920,   1440,   120,   PD_MODE_RB        },   /* bit 2 */
199         { 2560,   1600,    60,   PD_MODE_RB        },   /* bit 3 */
200         { 2560,   1600,    60,   0                 },   /* bit 4 */
201         { 2560,   1600,    75,   0                 },   /* bit 5 */
202         { 2560,   1600,    85,   0                 },   /* bit 6 */
203         { 2560,   1600,   120,   PD_MODE_RB        },   /* bit 7 */
204 };
205
206 #ifndef CONFIG_MICRO
207 /*!
208  * Function to replace common timings in 1st list with 2nd list, 2nd list
209  * is unchanged.
210  *
211  * @param dtds1
212  * @param dtds2
213  *
214  * @return void
215  */
216 void replace_vesa_dtds_with_cea_dtds(igd_timing_info_t *dtds1,
217         igd_timing_info_t *dtds2)
218 {
219         igd_timing_info_t *temp;
220
221         if (!dtds2 || !dtds1) {
222                 return;
223         }
224
225         while (dtds1->width != IGD_TIMING_TABLE_END) {
226                 temp = dtds2;
227
228                 while (temp->width != IGD_TIMING_TABLE_END) {
229                         if ((temp->width   == dtds1->width) &&
230                                 (temp->height  == dtds1->height) &&
231                                 (temp->refresh == dtds1->refresh)) {
232                                 dtds1->mode_info_flags &= ~PD_MODE_SUPPORTED;
233                         }
234                         temp++;
235                 }
236                 dtds1++;
237         }
238 }
239 #endif
240
241 #ifdef DEBUG_FIRMWARE
242 /*!
243  *
244  * @param db
245  *
246  * @return void
247  */
248 void displayid_print_datablock(datablock_t *db)
249 {
250         unsigned char payload_string[800];
251         unsigned char i, j;
252
253         /* Get the payload data into a string */
254         OS_MEMSET(payload_string, 0, sizeof(payload_string));
255         for (i=0, j=0; i<db->payload; i++,j+=5) {
256                 payload_string[j] = '0';
257                 payload_string[j+1] = 'x';
258                 if ((db->payload_data[i]>>4) <= 0x9) {
259                         payload_string[j+2] = '0' + (db->payload_data[i]>>4);
260                 } else {
261                         payload_string[j+2] = 'A' + (db->payload_data[i]>>4) - 0xA;
262                 }
263                 if ((db->payload_data[i] & 0x0F) <= 0x9) {
264                         payload_string[j+3] = '0' + (db->payload_data[i]&0x0F);
265                 } else {
266                         payload_string[j+3] = 'A' + (db->payload_data[i]&0x0F) - 0xA;
267                 }
268                 payload_string[j+4] = ' ';
269         }
270         payload_string[j] = '\0';
271
272         EMGD_DEBUG("Tag = %u", db->tag);
273         EMGD_DEBUG("Version = %u", db->revision);
274         EMGD_DEBUG("Payload = %u", db->payload);
275         EMGD_DEBUG("Payload data = %s", payload_string);
276 }
277
278 /*!
279  *
280  * @param buffer
281  * @param did
282  *
283  * @return void
284  */
285 void displayid_print(unsigned char *buffer, displayid_t *did)
286 {
287         unsigned short i;
288         display_params_t *dp = &did->display_params;
289         timing_range_t   *tr = &did->timing_range;
290         lvds_display_t   *ld = &did->lvds;
291         display_dev_t    *dd = &did->display_dev;
292         display_intf_t   *di = &did->display_intf;
293 #ifndef CONFIG_MICRO
294         productid_t      *pi = &did->productid;
295         color_char_t     *cc = &did->color_char;
296         serial_number_t  *sn = &did->serial_num;
297         general_string_t *gs = &did->general_string;
298         transfer_char_t  *tc = &did->transfer_char;
299         stereo_intf_t    *si = &did->stereo_intf;
300         vendor_t         *vi = &did->vendor;
301 #endif
302
303         DISPLAYID_PRINT_LINE();
304         EMGD_DEBUG("DisplayID Version: %d", did->version);
305         EMGD_DEBUG("DisplayID Revision: %d", did->revision);
306         DISPLAYID_PRINT_LINE();
307         EMGD_DEBUG("Size of different structures:");
308         DISPLAYID_PRINT_LINE();
309         EMGD_DEBUG("     displayid_t = %d", sizeof(displayid_t));
310         EMGD_DEBUG("display_params_t = %d", sizeof(display_params_t));
311         EMGD_DEBUG("     type1_dtd_t = %d", sizeof(type1_dtd_t));
312         EMGD_DEBUG("     type2_dtd_t = %d", sizeof(type2_dtd_t));
313         EMGD_DEBUG("     type3_cvt_t = %d", sizeof(type3_cvt_t));
314         EMGD_DEBUG("      type_std_t = %d", sizeof(type_std_t));
315         EMGD_DEBUG("  timing_range_t = %d", sizeof(timing_range_t));
316         EMGD_DEBUG("   display_dev_t = %d", sizeof(display_dev_t));
317         EMGD_DEBUG("  lvds_display_t = %d", sizeof(lvds_display_t));
318         EMGD_DEBUG("  display_intf_t = %d", sizeof(display_intf_t));
319         EMGD_DEBUG("        dummy_db = %d", 256);
320         EMGD_DEBUG("         timings = %d",
321                 sizeof(pd_timing_t)*DISPLAYID_MAX_NUM_TIMINGS);
322         EMGD_DEBUG("           attrs = %d",
323                 sizeof(pd_attr_t)*DISPLAYID_MAX_ATTRS);
324
325 #ifndef CONFIG_MICRO
326         EMGD_DEBUG("     productid_t = %d", sizeof(productid_t));
327         EMGD_DEBUG("    color_char_t = %d", sizeof(color_char_t));
328         EMGD_DEBUG(" serial_number_t = %d", sizeof(serial_number_t));
329         EMGD_DEBUG("general_string_t = %d", sizeof(general_string_t));
330         EMGD_DEBUG(" transfer_char_t = %d", sizeof(transfer_char_t));
331         EMGD_DEBUG("   stereo_intf_t = %d", sizeof(stereo_intf_t));
332         EMGD_DEBUG("        vendor_t = %d", sizeof(vendor_t));
333
334         DISPLAYID_PRINT_LINE();
335         EMGD_DEBUG("PRODUCT ID DATA BLOCK");
336         DISPLAYID_PRINT_LINE();
337         displayid_print_datablock((datablock_t *)pi);
338         EMGD_DEBUG("       vendor = %c%c%c",
339                 pi->vendor[0], pi->vendor[1], pi->vendor[2]);
340         EMGD_DEBUG(" product_code = %u", pi->product_code);
341         EMGD_DEBUG("serial_number = %lu", pi->serial_number);
342         EMGD_DEBUG("    manf_week = %u", pi->manf_week);
343         EMGD_DEBUG("    manf_year = %u", pi->manf_year+2000);
344         EMGD_DEBUG("   string_len = %u", pi->string_size);
345         EMGD_DEBUG("       string = %s", pi->string);
346
347         DISPLAYID_PRINT_LINE();
348         EMGD_DEBUG("COLOR CHARACTERISTICS DATA BLOCK");
349         DISPLAYID_PRINT_LINE();
350         displayid_print_datablock((datablock_t *)cc);
351
352         DISPLAYID_PRINT_LINE();
353         EMGD_DEBUG("SERIAL NUMBER DATA BLOCK");
354         DISPLAYID_PRINT_LINE();
355         displayid_print_datablock((datablock_t *)sn);
356
357         DISPLAYID_PRINT_LINE();
358         EMGD_DEBUG("GENERAL PURPOSE ASCII STRING DATA BLOCK");
359         DISPLAYID_PRINT_LINE();
360         displayid_print_datablock((datablock_t *)gs);
361
362         DISPLAYID_PRINT_LINE();
363         EMGD_DEBUG("TRANSFER CHARACTERISTICS DATA BLOCK");
364         DISPLAYID_PRINT_LINE();
365         displayid_print_datablock((datablock_t *)tc);
366
367         DISPLAYID_PRINT_LINE();
368         EMGD_DEBUG("STEREO INTERFACE DATA BLOCK");
369         DISPLAYID_PRINT_LINE();
370         displayid_print_datablock((datablock_t *)si);
371
372         DISPLAYID_PRINT_LINE();
373         EMGD_DEBUG("VENDOR SPECIFIC DATA BLOCK");
374         DISPLAYID_PRINT_LINE();
375         displayid_print_datablock((datablock_t *)vi);
376 #endif
377
378         DISPLAYID_PRINT_LINE();
379         EMGD_DEBUG("DISPLAY PARAMETERS DATA BLOCK");
380         DISPLAYID_PRINT_LINE();
381         displayid_print_datablock((datablock_t *)dp);
382         EMGD_DEBUG("horz_image_size = %u", dp->horz_image_size);
383         EMGD_DEBUG("vert_image_size = %u", dp->vert_image_size);
384         EMGD_DEBUG("    horz_pixels = %u", dp->horz_pixels);
385         EMGD_DEBUG("    vert_pixels = %u", dp->vert_pixels);
386         EMGD_DEBUG(" deinterlacable = %u", dp->deinterlacing);
387         EMGD_DEBUG("   fixed_timing = %u", dp->fixed_timing);
388         EMGD_DEBUG("      fixed_res = %u", dp->fixed_res);
389         EMGD_DEBUG("   aspect_ratio = %u", dp->aspect_ratio);
390         EMGD_DEBUG(" native_color_depth(bppc) = %u", dp->native_color_depth+1);
391         EMGD_DEBUG("overall_color_depth(bppc) = %u", dp->overall_color_depth+1);
392
393         DISPLAYID_PRINT_LINE();
394         EMGD_DEBUG("VIDEO TIMING RANGESS DATA BLOCK");
395         DISPLAYID_PRINT_LINE();
396         displayid_print_datablock((datablock_t *)tr);
397         EMGD_DEBUG("  min_dclk = %lu KHz", tr->min_dclk);
398         EMGD_DEBUG("  max_dclk = %lu KHz", tr->max_dclk);
399         EMGD_DEBUG(" min_hrate = %u KHz", tr->min_hrate);
400         EMGD_DEBUG(" max_hrate = %u KHz", tr->max_hrate);
401         EMGD_DEBUG("min_hblank = %u pixels", tr->min_hblank);
402         EMGD_DEBUG(" min_vrate = %u Hz", tr->min_vrate);
403         EMGD_DEBUG(" max_vrate = %u Hz", tr->max_vrate);
404         EMGD_DEBUG("min_vblank = %u lines", tr->min_vblank);
405
406         DISPLAYID_PRINT_LINE();
407         EMGD_DEBUG("LVDS DISPLAY DATA BLOCK");
408         DISPLAYID_PRINT_LINE();
409         displayid_print_datablock((datablock_t *)ld);
410         EMGD_DEBUG("min_T1 = %u ms", ld->min_t1/10);
411         EMGD_DEBUG("max_T1 = %u ms", ld->max_t1*2);
412         EMGD_DEBUG("max_T2 = %u ms", ld->max_t2*2);
413         EMGD_DEBUG("max_T3 = %u ms", ld->max_t3*2);
414         EMGD_DEBUG("min_T4 = %u ms", ld->min_t4*10);
415         EMGD_DEBUG("min_T5 = %u ms", ld->min_t5*10);
416         EMGD_DEBUG("min_T6 = %u ms", ld->min_t6*10);
417
418         DISPLAYID_PRINT_LINE();
419         EMGD_DEBUG("DISPLAY DEVICE DATA BLOCK");
420         DISPLAYID_PRINT_LINE();
421         displayid_print_datablock((datablock_t *)dd);
422         EMGD_DEBUG("   horz_pixel_count = %u", dd->horz_pixel_count);
423         EMGD_DEBUG("   vert_pixel_count = %u", dd->vert_pixel_count);
424         EMGD_DEBUG("display_color_depth = %u", dd->display_color_depth);
425
426         DISPLAYID_PRINT_LINE();
427         EMGD_DEBUG("DISPLAY INTERFACE DATA BLOCK");
428         DISPLAYID_PRINT_LINE();
429         displayid_print_datablock((datablock_t *)di);
430         EMGD_DEBUG("         num_channels = %u", di->num_channels);
431         EMGD_DEBUG("            intf_type = %u", di->intf_type);
432         EMGD_DEBUG("      RGB_color_depth = %u", di->rgb_color_depth);
433         EMGD_DEBUG("YCrCb_444_color_depth = %u", di->ycbcr_444_color_depth);
434         EMGD_DEBUG("YCrCb_422_color_depth = %u", di->ycbcr_422_color_depth);
435         if(di->intf_type == INTERFACE_LVDS) {
436                 EMGD_DEBUG("         openldi = %u", di->lvds.openldi);
437         }
438
439         DISPLAYID_PRINT_LINE();
440         EMGD_DEBUG("Detailed Timing Descriptors");
441         DISPLAYID_PRINT_LINE();
442
443         for (i=0; i<did->num_timings; i++) {
444                 EMGD_DEBUG("DTD: %u", i+1);
445                 EMGD_DEBUG("          dclk = %lu", did->timings[i].dclk);
446                 EMGD_DEBUG("       hactive = %u", did->timings[i].width);
447                 EMGD_DEBUG("        htotal = %u", did->timings[i].htotal);
448                 EMGD_DEBUG("  hblank_start = %u", did->timings[i].hblank_start);
449                 EMGD_DEBUG("   hsync_start = %u", did->timings[i].hsync_start);
450                 EMGD_DEBUG("     hsync_end = %u", did->timings[i].hsync_end);
451                 EMGD_DEBUG("    hblank_end = %u", did->timings[i].hblank_end);
452                 EMGD_DEBUG("       vactive = %u", did->timings[i].height);
453                 EMGD_DEBUG("        vtotal = %u", did->timings[i].vtotal);
454                 EMGD_DEBUG("  vblank_start = %u", did->timings[i].vblank_start);
455                 EMGD_DEBUG("   vsync_start = %u", did->timings[i].vsync_start);
456                 EMGD_DEBUG("     vsync_end = %u", did->timings[i].vsync_end);
457                 EMGD_DEBUG("    vblank_end = %u", did->timings[i].vblank_end);
458                 EMGD_DEBUG("        native = %u",
459                         (did->timings[i].mode_info_flags&PD_MODE_DTD_FP_NATIVE)?1:0);
460                 EMGD_DEBUG("     interlace = %u",
461                         (did->timings[i].mode_info_flags&PD_SCAN_INTERLACE)?1:0);
462                 EMGD_DEBUG("hsync_polarity = %s",
463                         (did->timings[i].mode_info_flags & PD_HSYNC_HIGH)?
464                         "ACTIVE HIGH":"ACTIVE LOW");
465                 EMGD_DEBUG("vsync_polarity = %s",
466                         (did->timings[i].mode_info_flags & PD_VSYNC_HIGH)?
467                         "ACTIVE HIGH":"ACTIVE LOW");
468                 DISPLAYID_PRINT_LINE();
469         }
470
471         /* Print the attributes */
472         if (did->num_attrs) {
473                 EMGD_DEBUG("\tAttr\tID\tVALUE");
474                 EMGD_DEBUG("----------------------");
475                 for (i=0; i<did->num_attrs; i++) {
476                         EMGD_DEBUG("\t%u\t%lu\t%lu", i+1, did->attr_list[i].id,
477                                 did->attr_list[i].current_value);
478                 }
479                 EMGD_DEBUG("----------------------");
480         }
481 }
482 #endif
483
484 /*!
485  * Function to convert Type I - Detailed to pd_timing_t
486  *
487  * @param timing
488  * @param dtd
489  *
490  * @return void
491  */
492 void convert_type1_to_pd(pd_timing_t *timing, type1_dtd_t *dtd)
493 {
494         unsigned long refresh;
495         timing->dclk =                            /* change to KHz */
496                 ((unsigned long)dtd->dclk.lsb_dclk|
497                 ((unsigned long)dtd->dclk.msb_dclk<<16))*10;
498
499         /* DisplayID fields are 0 based but should be interpreted as 1-based.
500          * For example hsync_width value can be read as 0-65,535 pixels but
501          * interpreted as 1-65,536. So, to get the right value add 1.
502          * But pd_timing_t values are 0 based except width and height,
503          * so care should be taken while converting DisplayID fields into
504          * pd_timing_t values */
505         timing->hblank_start = dtd->hactive;
506         timing->width = dtd->hactive + 1;
507         timing->hblank_end = timing->hblank_start + dtd->hblank + 1;
508         timing->hsync_start = timing->hblank_start + dtd->hsync_offset + 1;
509         timing->hsync_end = timing->hsync_start + dtd->hsync_width + 1;
510         timing->htotal = timing->hblank_end;
511
512         timing->vblank_start = dtd->vactive;
513         timing->height = dtd->vactive + 1;
514         timing->vblank_end = timing->vblank_start + dtd->vblank + 1;
515         timing->vsync_start = timing->vblank_start + dtd->vsync_offset + 1;
516         timing->vsync_end = timing->vsync_start + dtd->vsync_width + 1;
517         timing->vtotal = timing->vblank_end;
518
519         refresh = ((timing->dclk * 1000L)/timing->htotal)/timing->vtotal;
520         timing->refresh = (unsigned short) refresh;
521
522         timing->mode_info_flags = PD_MODE_DTD|PD_MODE_SUPPORTED;
523         if (dtd->hsync_polarity) {
524                 timing->mode_info_flags |= PD_HSYNC_HIGH;
525         }
526         if (dtd->vsync_polarity) {
527                 timing->mode_info_flags |= PD_VSYNC_HIGH;
528         }
529         if (dtd->interlaced) {
530                 timing->mode_info_flags |= PD_SCAN_INTERLACE;
531         }
532         if (dtd->preferred) {
533                 timing->mode_info_flags |= PD_MODE_DTD_FP_NATIVE;
534         }
535 }
536
537 /*!
538  * Function to convert Type II - Detailed to pd_timing_t
539  *
540  * @param timing
541  * @param dtd
542  *
543  * @return void
544  */
545 void convert_type2_to_pd(pd_timing_t *timing, type2_dtd_t *dtd)
546 {
547         unsigned long refresh;
548         timing->dclk =                            /* change to KHz */
549                 ((unsigned long)dtd->dclk.lsb_dclk|
550                 ((unsigned long)dtd->dclk.msb_dclk<<16))*10;
551
552         /* DisplayID fields are 0 based but should be interpreted as 1-based.
553          * For example hsync_width value can be read as 0-15 OCTETs but
554          * interpreted as 1-16 OCTETs. So, to get the right value add 1.
555          * But pd_timing_t values are 0 based except width and height,
556          * so care should be taken while converting DisplayID fields into
557          * pd_timing_t values */
558         timing->width = (dtd->hactive + 1) * 8;    /* change to pixels */
559         timing->hblank_start = timing->width - 1;
560         timing->hblank_end = timing->hblank_start + (dtd->hblank + 1) * 8;
561         timing->hsync_start = timing->hblank_start + (dtd->hsync_offset + 1) * 8;
562         timing->hsync_end = timing->hsync_start + (dtd->hsync_width + 1) * 8;
563         timing->htotal = timing->hblank_end;
564
565         timing->vblank_start = dtd->vactive;
566         timing->height = dtd->vactive + 1;
567         timing->vblank_end = timing->vblank_start + dtd->vblank + 1;
568         timing->vsync_start = timing->vblank_start + dtd->vsync_offset + 1;
569         timing->vsync_end = timing->vsync_start + dtd->vsync_width + 1;
570         timing->vtotal = timing->vblank_end;
571
572         refresh = ((timing->dclk * 1000L)/timing->htotal)/timing->vtotal;
573         timing->refresh = (unsigned short) refresh;
574
575         timing->mode_info_flags = PD_MODE_DTD|PD_MODE_SUPPORTED;
576         if (dtd->interlaced) {
577                 timing->mode_info_flags |= PD_SCAN_INTERLACE;
578         }
579         if (dtd->preferred) {
580                 timing->mode_info_flags |= PD_MODE_DTD_FP_NATIVE;
581         }
582 }
583
584 /*!
585  * Function to filter timing table based on range block
586  *
587  * @param tt
588  * @param range
589  * @param firmware_type
590  *
591  * @return void
592  */
593 void displayid_filter_range_timings(pd_timing_t *tt, timing_range_t *range,
594         unsigned char firmware_type)
595 {
596         unsigned short hfreq;
597
598 #define _HUNDRETHS(_n, _d)  ((100*_n)/_d)-((100*_n_d)/100),
599
600         #ifdef DEBUG_FIRMWARE
601         char result_str[60];
602         unsigned char pass_count = 0;
603         unsigned char fail_count = 0;
604
605         EMGD_DEBUG("Range limits:");
606         EMGD_DEBUG("\tmin_dclk = %lu KHz max_dclk = %lu KHz",
607                 range->min_dclk, range->max_dclk);
608         EMGD_DEBUG("\t   h_min = %u h_max = %u KHz",
609                 range->min_hrate, range->max_hrate);
610         EMGD_DEBUG("\t   v_min = %u v_max = %u",
611                 range->min_vrate,range->max_vrate);
612         EMGD_DEBUG("WIDTH\tHEIGHT\tREFRESH\tH-FREQ\tDOTCLOCK\tRESULT");
613         EMGD_DEBUG("     \t      \t (Hz)  \t (KHz)\t (MHz)  \t      ");
614         EMGD_DEBUG("=====\t======\t=======\t======\t========\t======");
615 #endif
616
617         /* If the display is a discreate frequency display, don't enable any
618          * intermediate timings. Only continuous frequency displays requires
619          * enabling range timings */
620         if (range->discrete_display) {
621                 EMGD_DEBUG("Discrete display: Ranges aren't used.");
622                 return;
623         }
624
625         /* If no timing table return */
626         if (tt == NULL) {
627                 return;
628         }
629
630         /* Mark the timings that fall in the ranges */
631         /* Compare
632          *     dclk in KHz
633          *     hfreq in KHz
634          *     vfreq in Hz */
635         while(tt->width != IGD_TIMING_TABLE_END) {
636                 hfreq = (unsigned short)(tt->dclk/(unsigned long)tt->htotal); /* KHz */
637                 if ((tt->dclk    >= (unsigned long)range->min_dclk)&&  /* compare KHz */
638                         (tt->dclk    <= (unsigned long)range->max_dclk)&&  /* compare KHz */
639                         (tt->refresh >= range->min_vrate) &&   /* compare Hz */
640                         (tt->refresh <= range->max_vrate) &&   /* compare Hz */
641                         (hfreq       >= range->min_hrate) &&   /* compare KHz */
642                         (hfreq       <= range->max_hrate) &&   /* compare KHz */
643                         (tt->hblank_end - tt->hblank_start) > range->min_hblank &&
644                         (tt->vblank_end - tt->vblank_start) > range->min_vblank) {
645                         tt->mode_info_flags |= PD_MODE_SUPPORTED;
646 #ifdef DEBUG_FIRMWARE
647                         if (tt->mode_info_flags & PD_MODE_SUPPORTED) {
648                                 EMGD_DEBUG("%5u\t%6u\t%7u\t%6u.%2u\t%8u.%2u\tPASSED",
649                                         tt->width, tt->height, tt->refresh,
650                                         tt->dclk/tt->htotal,
651                                         _HUNDRETHS(tt->dclk,tt->htotal),
652                                         tt->dclk/1000,
653                                         _HUNDRETHS(tt->dclk,1000);
654
655                                 pass_count++;
656                         } else {
657                         }
658 #endif
659                 } else {
660                         /* Unmark the mode that falls out of range */
661                         /* DTD, FACTORY and NATIVE timings are "GOLD" even if they
662                          * fall outside the range limits */
663                         if (!(tt->mode_info_flags &
664                                 (PD_MODE_DTD|PD_MODE_FACTORY|PD_MODE_DTD_FP_NATIVE))) {
665 #ifdef DEBUG_FIRMWARE
666                                 if ((tt->dclk <            /* compare KHz */
667                                                 (unsigned long)range->min_dclk)||
668                                         (tt->dclk >
669                                                 (unsigned long)range->max_dclk)) {
670                                         OS_MEMCPY(result_str, "FAILED DCLK    \0", 16);
671                                         fail_count++;
672                                 } else if ((tt->refresh > range->max_vrate) ||
673                                         (tt->refresh < range->min_vrate)) {
674                                         OS_MEMCPY(result_str, "FAILED REFRESH \0", 16);
675                                         fail_count++;
676                                 } else if ((hfreq < range->min_hrate) ||
677                                         (hfreq > range->max_hrate)) {
678                                         OS_MEMCPY(result_str, "FAILED H-FREQ  \0", 16);
679                                         fail_count++;
680                                 } else if ((tt->hblank_end-tt->hblank_start) <
681                                         range->min_hblank){
682                                         OS_MEMCPY(result_str, "FAILED MIN_HBLK\0", 16);
683                                 } else if ((tt->vblank_end-tt->vblank_start) <
684                                         range->min_vblank){
685                                         OS_MEMCPY(result_str, "FAILED MIN_VBLK\0", 16);
686                                 }
687                                 EMGD_DEBUG("%5u\t%6u\t%7u\t%6u.%2u\t%8u.%2u\t%s",
688                                         tt->width, tt->height, tt->refresh,
689                                         tt->dclk/tt->htotal,
690                                         _HUNDRETHS(tt->dclk,tt->htotal),
691                                         tt->dclk/1000,
692                                         _HUNDRETHS(tt->dclk,1000),
693                                         result_str);
694                                         ((float) tt->dclk)/1000, result_str);
695
696                                 /* TODO: For multiple range blocks, don't disable the modes
697                                  * that are outside the range. We already started with
698                                  * an "empty supported table" */
699
700                                 /* But above assertion of "empty supported table" broke
701                                  * if EDID ETF rules were met to enable all timings.
702                                  * See edid.c for ETF conditions. So below line
703                                  * cannot be commented out to support multiple range
704                                  * blocks for DisplayID. */
705 #endif
706                                 tt->mode_info_flags &= ~PD_MODE_SUPPORTED;
707                         }
708                 }
709                 tt++;
710                 if (tt->width == IGD_TIMING_TABLE_END && tt->extn_ptr) {
711                         tt = tt->extn_ptr;
712                 }
713         }
714 #ifdef DEBUG_FIRMWARE
715         EMGD_DEBUG("pass count = %u, fail count = %u total = %u",
716                 pass_count, fail_count, pass_count+fail_count);
717 #endif
718 } /* end displayid_filter_range_timings() */
719
720 #define VESA_STD    1
721 #define CEA_STD     2
722
723 /*!
724  * Function to enable std timings: VESA STD or CEA STD
725  *
726  * @param tt1
727  * @param db_data
728  * @param lookup
729  * @param num_lookup
730  * @param std_type
731  *
732  * @return void
733  */
734 void displayid_enable_std_timings(pd_timing_t *tt1, unsigned char *db_data,
735         type_std_t *lookup, unsigned short num_lookup, unsigned char std_type)
736 {
737         unsigned short i;
738         pd_timing_t    *tt;
739         /* If no timing table return. This can happen if no edid_avail set not to
740          * use std timings */
741         if (!tt1) {
742                 return;
743         }
744
745         /* For every factory supported mode, enable it in the timing table */
746         for (i = 0; i < num_lookup; i++) {
747                 tt = tt1;
748                 /* i>>3 is nothing but dividing by 8, that gives the byte number,
749                  * i&0x7 is nothing but getting the bit position in that byte */
750                 if (db_data[i>>3] & 1<<(i&0x7)) {
751                         while(tt->width != IGD_TIMING_TABLE_END) {
752                                 if (lookup[i].width == tt->width &&
753                                         lookup[i].height == tt->height &&
754 #if 0
755                                         (!((lookup[i].flags & (PD_SCAN_INTERLACE|PD_MODE_RB)) ^
756                                         (tt->mode_info_flags & (PD_SCAN_INTERLACE|PD_MODE_RB)))) &&
757 #endif
758                                         (!((lookup[i].flags & PD_SCAN_INTERLACE) ^
759                                         (tt->mode_info_flags & PD_SCAN_INTERLACE))) &&
760                                         (!((lookup[i].flags & PD_ASPECT_16_9) ^
761                                         (tt->mode_info_flags & PD_ASPECT_16_9))) &&
762                                         lookup[i].refresh == tt->refresh) {
763                                         tt->mode_info_flags |= (PD_MODE_FACTORY|PD_MODE_SUPPORTED);
764                                         break;
765                                 }
766                                 tt++;
767                                 if (tt->width == IGD_TIMING_TABLE_END && tt->extn_ptr) {
768                                         tt = tt->extn_ptr;
769                                 }
770                         }
771                 }
772         }
773 }
774
775 static void displayid_parse_orientation_info (unsigned char orientation_blob,
776         igd_DID_rotation_info_t * rotation_info) {
777
778         unsigned int def_orientation = DEFAULT_ORIENTATION(orientation_blob);
779         unsigned int zero_pixel = ZERO_PIXEL(orientation_blob);
780         unsigned int scan_dir = SCAN_DIRECTION(orientation_blob);
781
782         /* Start with no rotation */
783         rotation_info->rotation = 0;
784         rotation_info->flip = 0;
785
786
787         if (def_orientation >= DEF_ORIENTATION_UNKNOWN) {
788                 /* Display ID blob is corrupted or unknown configuration set */
789                 EMGD_DEBUG("DisplayID: Unknown default orientation value: %d",
790                         def_orientation);
791                 return;
792         }
793
794         if (scan_dir == SCAN_DIRECTION_LONG) {
795                 if (def_orientation == DEF_ORIENTATION_PORTRAIT) {
796                         rotation_info->flip =
797                                 (zero_pixel == ZP_UPPER_LEFT || zero_pixel == ZP_LOWER_RIGHT);
798                         rotation_info->rotation += 90;
799                 } else { /* Landscape */
800                         rotation_info->flip =
801                                 (zero_pixel == ZP_UPPER_RIGHT || zero_pixel == ZP_LOWER_LEFT);
802                 }
803
804         } else if (scan_dir == SCAN_DIRECTION_SHORT) {
805                 if (def_orientation == DEF_ORIENTATION_PORTRAIT) {
806                         rotation_info->flip =
807                                 (zero_pixel == ZP_UPPER_RIGHT || zero_pixel == ZP_LOWER_LEFT);
808                 }
809                 else { /* Landscape */
810                         rotation_info->flip =
811                                 (zero_pixel == ZP_UPPER_LEFT || zero_pixel == ZP_LOWER_RIGHT);
812                         rotation_info->rotation += 90;
813                 }
814         } else { /* Unknown scan direction */
815                 EMGD_DEBUG("DisplayID: Unknown scan direction value: %d", scan_dir);
816                 return;
817         }
818
819         /* zero pixel is in the lower-half: need to rotate by 180 degs */
820         if (zero_pixel == ZP_LOWER_LEFT || zero_pixel == ZP_LOWER_RIGHT)
821                 rotation_info->rotation += 180;
822 }
823
824 /*!
825  * Function to parse DisplayID
826  *
827  * @param buffer
828  * @param did
829  * @param timing_table
830  * @param count
831  * @param upscale
832  *
833  * @return void
834  */
835 int displayid_parse(
836                 unsigned char *buffer,
837                 displayid_t   *did,
838                 pd_timing_t   *timing_table,
839                 int           count,
840                 unsigned char upscale)
841 {
842         //unsigned char e = 0;
843         unsigned char checksum = 0, bytes_left;
844         unsigned short i;
845         unsigned short did_size;
846 #ifndef CONFIG_MICRO
847         pd_timing_t   *cea_tmg_table;
848 #endif
849         /* Read 4 bytes: (DisplayID Header)
850          *       version, revision
851          *       payload
852          *       display product type identifier
853          *       number of extensions */
854         *(unsigned long *) did = *(unsigned long *)buffer;
855
856         /* Check for version and revision */
857         if (did->version != 1 && did->revision != 0) {
858                 EMGD_DEBUG("DisplayID Version %d.%d Unknown. Will Ignore.",
859                         did->version, did->revision);
860                 return DISPLAYID_NOT_SUPPORTED;
861         }
862
863         if (did->payload > 251) {
864                 EMGD_DEBUG("DispID: Error: payload = %u not in [0..251]", did->payload);
865                 return DISPLAYID_ERROR_PARSE;
866         }
867
868         /* Check sum check */
869         /* +5 is for 5 mandatory bytes */
870         did_size = (unsigned short) (did->payload + 5);
871         EMGD_DEBUG("DisplayID size = %u", did_size);
872         for (i = 0; i < did_size; i++) {
873                 checksum += buffer[i];
874         }
875
876         /* bytes_left starts without DisplayID header */
877         bytes_left = did->payload;
878         /* current pointer is at 4 not at 5, because checksum byte is at the end */
879         buffer += 4;
880
881         if (checksum) {
882                 EMGD_DEBUG("DisplayID checksum is incorrect! Will ignore.");
883                 return DISPLAYID_ERROR_PARSE;
884         }
885
886         /* DisplayID parsing should start by disabling all modes.
887          * Based on DisplayID data blocks modes will be enabled. */
888         enable_disable_timings(timing_table, 0);
889
890         /* Repeat for all extensions */
891         //e = did->num_extensions;
892         //while (e) {
893         {
894                 //if (e != did->num_extensions) {
895                         /* TODO: If there aren't enough bytes left in the buffer,
896                          * call I2C read function to read next DisplayID section */
897
898                         /* Skip next section header 4 bytes */
899                         //bytes_left -= 4;
900                         //break;
901                 //}
902
903                 /* Parse Data Blocks */
904                 /* Check minimum number of bytes required for Data Block were left */
905                 while ((bytes_left > 3) && (bytes_left >= (buffer[2]+3))) {
906                         unsigned char *db_data;
907                         unsigned char payload = buffer[2] + 3;
908
909                         /* displayid->datablock = buffer (for payload bytes) */
910                         if (buffer[0] < sizeof(db_offset)/sizeof(unsigned short)) {
911                                 OS_MEMCPY(((unsigned char*)did) + db_offset[buffer[0]],
912                                         buffer, payload);
913                         }
914
915                         /* db_data points to payload data after db header (3 bytes),
916                          * Note: dummy_db offset is used for some DATA BLOCKS. See
917                          *       db_offset table above. */
918                         db_data = (unsigned char *) &did->dummy_db[3];
919
920                         switch (buffer[0]) {
921                         /* Supported in Driver and VBIOS */
922                         case DATABLOCK_DISPLAY_PARAMS:
923                                 /* Use following fields for fp_info:
924                                  *     embedded use:      fixed timing
925                                  *     horizontal pixels: fp_width
926                                  *     vertical pixels:   fp_height */
927                                 did->attr_list[did->num_attrs].id = PD_ATTR_ID_PANEL_DEPTH;
928                                 did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
929                                 did->attr_list[did->num_attrs++].current_value =
930                                         (did->display_params.overall_color_depth+1)*3;
931                                 break;
932
933                         case DATABLOCK_TIMING_1_DETAIL:
934                                 /* One Type I block can have multiple DTDs */
935                                 while (payload>=20&&did->num_timings<DISPLAYID_MAX_NUM_TIMINGS){
936                                         convert_type1_to_pd(&did->timings[did->num_timings++],
937                                                 (type1_dtd_t *)db_data);
938                                         db_data += 20;
939                                         payload -= 20;
940                                         bytes_left -= 20;
941                                         buffer += 20;
942                                 }
943                                 /* Mark the end of the list */
944                                 did->timings[did->num_timings].width = IGD_TIMING_TABLE_END;
945                                 break;
946
947                         case DATABLOCK_TIMING_2_DETAIL:
948                                 /* One Type II block can have multiple DTDs */
949                                 while (payload>=11&&did->num_timings<DISPLAYID_MAX_NUM_TIMINGS){
950                                         convert_type2_to_pd(&did->timings[did->num_timings++],
951                                                 (type2_dtd_t *)db_data);
952                                         db_data += 11;
953                                         payload -= 11;
954                                         bytes_left -= 11;
955                                         buffer += 11;
956                                 }
957                                 did->timings[did->num_timings].width = IGD_TIMING_TABLE_END;
958                                 break;
959
960                         case DATABLOCK_VESA_TIMING_STD:
961                                 /* VESA Standard Timings */
962                                 displayid_enable_std_timings(
963                                         timing_table,
964                                         db_data,
965                                         vesa_std_lookup,
966                                         sizeof(vesa_std_lookup)/sizeof(type_std_t),
967                                         VESA_STD);
968                                 break;
969
970                         case DATABLOCK_VIDEO_RANGE:
971                                 /* convert from Hz/10,000 -> KHz by multiplying by 10 */
972                                 did->timing_range.min_dclk =
973                                         ((unsigned long)did->timing_range.mindclk.lsb_min_dclk|
974                                         ((unsigned long)did->timing_range.mindclk.msb_min_dclk
975                                                 <<16))*10;
976
977                                 did->timing_range.max_dclk =
978                                         ((unsigned long)did->timing_range.maxdclk.lsb_max_dclk|
979                                         ((unsigned long)did->timing_range.maxdclk.msb_max_dclk
980                                                 <<16))*10;
981                                 displayid_filter_range_timings(timing_table,&did->timing_range,
982                                         PI_FIRMWARE_DISPLAYID);
983                                 break;
984
985                         case DATABLOCK_DISPLAY_DEVICE:
986                                 /* Get panel color depth */
987                                 did->attr_list[did->num_attrs].id = PD_ATTR_ID_PANEL_DEPTH;
988                                 did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
989                                 did->attr_list[did->num_attrs++].current_value =
990                                         (did->display_dev.display_color_depth+1)*3;
991                                 displayid_parse_orientation_info(did->display_dev.orientation,
992                                                                                                 &(did->rotation_info));
993                                 break;
994
995                         case DATABLOCK_LVDS_INTERFACE:
996                                 /* Get T1-T5 values */
997                                 did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T1;
998                                 did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
999                                 did->attr_list[did->num_attrs++].current_value =
1000                                         did->lvds.max_t1*2 + did->lvds.max_t2*2;
1001
1002                                 did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T2;
1003                                 did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
1004                                 did->attr_list[did->num_attrs++].current_value =
1005                                         did->lvds.min_t5*10;
1006
1007                                 did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T3;
1008                                 did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
1009                                 did->attr_list[did->num_attrs++].current_value =
1010                                         did->lvds.min_t6*10;
1011
1012                                 did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T4;
1013                                 did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
1014                                 did->attr_list[did->num_attrs++].current_value =
1015                                         did->lvds.max_t3*2;
1016
1017                                 did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T5;
1018                                 did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
1019                                 did->attr_list[did->num_attrs++].current_value =
1020                                         did->lvds.min_t4*10 + did->lvds.max_t1*2;
1021                                 break;
1022
1023                         case DATABLOCK_DISPLAY_INTF:
1024                                 if (did->display_intf.intf_type == INTERFACE_LVDS) {
1025                                         /* Get number of channels: 0=singlechannel 1=dualchannel */
1026                                         did->attr_list[did->num_attrs].id =
1027                                                 PD_ATTR_ID_2_CHANNEL_PANEL;
1028                                         did->attr_list[did->num_attrs].flags =
1029                                                 PD_ATTR_FLAG_VALUE_CHANGED;
1030                                         if (did->display_intf.num_channels == 2) {
1031                                                 did->attr_list[did->num_attrs++].current_value = 1;
1032                                         }
1033
1034                                         /* Get panel type value: 0=normal 1=OpenLDI */
1035                                         did->attr_list[did->num_attrs].id =
1036                                                 PD_ATTR_ID_LVDS_PANEL_TYPE;
1037                                         did->attr_list[did->num_attrs].flags =
1038                                                 PD_ATTR_FLAG_VALUE_CHANGED;
1039                                         did->attr_list[did->num_attrs++].current_value =
1040                                                 did->display_intf.lvds.openldi;
1041                                 }
1042
1043                                 break;
1044
1045 #ifndef CONFIG_MICRO
1046                         /* Support in Driver only */
1047                         case DATABLOCK_PRODUCTID:
1048                                 break;
1049
1050                         case DATABLOCK_SERIAL_NUMBER:
1051                                 break;
1052
1053                         case DATABLOCK_ASCII_STRING:
1054                                 break;
1055
1056                         case DATABLOCK_VENDOR_SPECIFIC:
1057                                 /* Because vendor specific datablock tag is out-of-order,
1058                                  * copy data from buffer to vendor structure */
1059                                 OS_MEMCPY(&did->vendor, buffer, buffer[2] + 3);
1060                                 break;
1061
1062                         /* Future support in Driver and VBIOS */
1063                         case DATABLOCK_TIMING_3_SHORT:
1064                                 break;
1065
1066                         case DATABLOCK_TIMING_4_DMTID:
1067                                 break;
1068
1069                         /* Future support in Driver */
1070                         case DATABLOCK_COLOR_CHARS:
1071                                 break;
1072
1073                         case DATABLOCK_CEA_TIMING_STD:
1074                                 cea_tmg_table = (igd_timing_info_t *)
1075                                         OS_ALLOC(cea_timing_table_size);
1076                                 OS_MEMCPY(cea_tmg_table, cea_timing_table,
1077                                         cea_timing_table_size);
1078                                 /* Disable the CEA timings */
1079                                 enable_disable_timings(cea_tmg_table, 0);
1080                                 displayid_enable_std_timings(
1081                                         cea_tmg_table,
1082                                         db_data,
1083                                         cea_std_lookup,
1084                                         (unsigned short)cea_std_lookup_size,
1085                                         CEA_STD);
1086
1087                                 replace_vesa_dtds_with_cea_dtds(timing_table, cea_tmg_table);
1088                                 cea_tmg_table[cea_timing_table_size-1].extn_ptr =
1089                                         (void *)timing_table;
1090                                 timing_table = cea_tmg_table;
1091                                 break;
1092 #endif
1093                         case DATABLOCK_TRANSFER_CHAR:
1094                                 break;
1095                         }
1096
1097                         /* Subtract data block payload */
1098                         bytes_left -= payload;
1099                         buffer += payload;
1100                 }
1101                 /* Extension count */
1102                 //e--;
1103         }
1104
1105         return 0;
1106 }
1107
1108 #endif
1109