~gma500/+junk/emgd160

« back to all changes in this revision

Viewing changes to emgd-dkms-kernel39/emgd/display/pi/cmn/displayid.c

  • Committer: Luca Forina
  • Date: 2011-05-10 07:28:19 UTC
  • Revision ID: luca.forina@gmail.com-20110510072819-pgj21l6igboa9dsx
emgd-dkms for kernel .39

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- pse-c -*-
 
2
 *-----------------------------------------------------------------------------
 
3
 * Filename: displayid.c
 
4
 * $Revision: 1.7 $
 
5
 *-----------------------------------------------------------------------------
 
6
 * Copyright © 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
/*!
 
776
 * Function to parse DisplayID
 
777
 *
 
778
 * @param buffer
 
779
 * @param did
 
780
 * @param timing_table
 
781
 * @param count
 
782
 * @param upscale
 
783
 *
 
784
 * @return void
 
785
 */
 
786
int displayid_parse(
 
787
                unsigned char *buffer,
 
788
                displayid_t   *did,
 
789
                pd_timing_t   *timing_table,
 
790
                int           count,
 
791
                unsigned char upscale)
 
792
{
 
793
        //unsigned char e = 0;
 
794
        unsigned char checksum = 0, bytes_left;
 
795
        unsigned short i;
 
796
        unsigned short did_size;
 
797
#ifndef CONFIG_MICRO
 
798
        pd_timing_t   *cea_tmg_table;
 
799
#endif
 
800
        /* Read 4 bytes: (DisplayID Header)
 
801
         *       version, revision
 
802
         *       payload
 
803
         *       display product type identifier
 
804
         *       number of extensions */
 
805
        *(unsigned long *) did = *(unsigned long *)buffer;
 
806
 
 
807
        /* Check for version and revision */
 
808
        if (did->version != 1 && did->revision != 0) {
 
809
                EMGD_DEBUG("DisplayID Version %d.%d Unknown. Will Ignore.",
 
810
                        did->version, did->revision);
 
811
                return DISPLAYID_NOT_SUPPORTED;
 
812
        }
 
813
 
 
814
        if (did->payload > 251) {
 
815
                EMGD_DEBUG("DispID: Error: payload = %u not in [0..251]", did->payload);
 
816
                return DISPLAYID_ERROR_PARSE;
 
817
        }
 
818
 
 
819
        /* Check sum check */
 
820
        /* +5 is for 5 mandatory bytes */
 
821
        did_size = (unsigned short) (did->payload + 5);
 
822
        EMGD_DEBUG("DisplayID size = %u", did_size);
 
823
        for (i = 0; i < did_size; i++) {
 
824
                checksum += buffer[i];
 
825
        }
 
826
 
 
827
        /* bytes_left starts without DisplayID header */
 
828
        bytes_left = did->payload;
 
829
        /* current pointer is at 4 not at 5, because checksum byte is at the end */
 
830
        buffer += 4;
 
831
 
 
832
        if (checksum) {
 
833
                EMGD_DEBUG("DisplayID checksum is incorrect! Will ignore.");
 
834
                return DISPLAYID_ERROR_PARSE;
 
835
        }
 
836
 
 
837
        /* DisplayID parsing should start by disabling all modes.
 
838
         * Based on DisplayID data blocks modes will be enabled. */
 
839
        enable_disable_timings(timing_table, 0);
 
840
 
 
841
        /* Repeat for all extensions */
 
842
        //e = did->num_extensions;
 
843
        //while (e) {
 
844
        {
 
845
                //if (e != did->num_extensions) {
 
846
                        /* TODO: If there aren't enough bytes left in the buffer,
 
847
                         * call I2C read function to read next DisplayID section */
 
848
 
 
849
                        /* Skip next section header 4 bytes */
 
850
                        //bytes_left -= 4;
 
851
                        //break;
 
852
                //}
 
853
 
 
854
                /* Parse Data Blocks */
 
855
                /* Check minimum number of bytes required for Data Block were left */
 
856
                while ((bytes_left > 3) && (bytes_left >= (buffer[2]+3))) {
 
857
                        unsigned char *db_data;
 
858
                        unsigned char payload = buffer[2] + 3;
 
859
 
 
860
                        /* displayid->datablock = buffer (for payload bytes) */
 
861
                        if (buffer[0] < sizeof(db_offset)/sizeof(unsigned short)) {
 
862
                                OS_MEMCPY(((unsigned char*)did) + db_offset[buffer[0]],
 
863
                                        buffer, payload);
 
864
                        }
 
865
 
 
866
                        /* db_data points to payload data after db header (3 bytes),
 
867
                         * Note: dummy_db offset is used for some DATA BLOCKS. See
 
868
                         *       db_offset table above. */
 
869
                        db_data = (unsigned char *) &did->dummy_db[3];
 
870
 
 
871
                        switch (buffer[0]) {
 
872
                        /* Supported in Driver and VBIOS */
 
873
                        case DATABLOCK_DISPLAY_PARAMS:
 
874
                                /* Use following fields for fp_info:
 
875
                                 *     embedded use:      fixed timing
 
876
                                 *     horizontal pixels: fp_width
 
877
                                 *     vertical pixels:   fp_height */
 
878
                                did->attr_list[did->num_attrs].id = PD_ATTR_ID_PANEL_DEPTH;
 
879
                                did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
 
880
                                did->attr_list[did->num_attrs++].current_value =
 
881
                                        (did->display_params.overall_color_depth+1)*3;
 
882
                                break;
 
883
 
 
884
                        case DATABLOCK_TIMING_1_DETAIL:
 
885
                                /* One Type I block can have multiple DTDs */
 
886
                                while (payload>=20&&did->num_timings<DISPLAYID_MAX_NUM_TIMINGS){
 
887
                                        convert_type1_to_pd(&did->timings[did->num_timings++],
 
888
                                                (type1_dtd_t *)db_data);
 
889
                                        db_data += 20;
 
890
                                        payload -= 20;
 
891
                                        bytes_left -= 20;
 
892
                                        buffer += 20;
 
893
                                }
 
894
                                /* Mark the end of the list */
 
895
                                did->timings[did->num_timings].width = IGD_TIMING_TABLE_END;
 
896
                                break;
 
897
 
 
898
                        case DATABLOCK_TIMING_2_DETAIL:
 
899
                                /* One Type II block can have multiple DTDs */
 
900
                                while (payload>=11&&did->num_timings<DISPLAYID_MAX_NUM_TIMINGS){
 
901
                                        convert_type2_to_pd(&did->timings[did->num_timings++],
 
902
                                                (type2_dtd_t *)db_data);
 
903
                                        db_data += 11;
 
904
                                        payload -= 11;
 
905
                                        bytes_left -= 11;
 
906
                                        buffer += 11;
 
907
                                }
 
908
                                did->timings[did->num_timings].width = IGD_TIMING_TABLE_END;
 
909
                                break;
 
910
 
 
911
                        case DATABLOCK_VESA_TIMING_STD:
 
912
                                /* VESA Standard Timings */
 
913
                                displayid_enable_std_timings(
 
914
                                        timing_table,
 
915
                                        db_data,
 
916
                                        vesa_std_lookup,
 
917
                                        sizeof(vesa_std_lookup)/sizeof(type_std_t),
 
918
                                        VESA_STD);
 
919
                                break;
 
920
 
 
921
                        case DATABLOCK_VIDEO_RANGE:
 
922
                                /* convert from Hz/10,000 -> KHz by multiplying by 10 */
 
923
                                did->timing_range.min_dclk =
 
924
                                        ((unsigned long)did->timing_range.mindclk.lsb_min_dclk|
 
925
                                        ((unsigned long)did->timing_range.mindclk.msb_min_dclk
 
926
                                                <<16))*10;
 
927
 
 
928
                                did->timing_range.max_dclk =
 
929
                                        ((unsigned long)did->timing_range.maxdclk.lsb_max_dclk|
 
930
                                        ((unsigned long)did->timing_range.maxdclk.msb_max_dclk
 
931
                                                <<16))*10;
 
932
                                displayid_filter_range_timings(timing_table,&did->timing_range,
 
933
                                        PI_FIRMWARE_DISPLAYID);
 
934
                                break;
 
935
 
 
936
                        case DATABLOCK_DISPLAY_DEVICE:
 
937
                                /* Get panel color depth */
 
938
                                did->attr_list[did->num_attrs].id = PD_ATTR_ID_PANEL_DEPTH;
 
939
                                did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
 
940
                                did->attr_list[did->num_attrs++].current_value =
 
941
                                        (did->display_dev.display_color_depth+1)*3;
 
942
                                break;
 
943
 
 
944
                        case DATABLOCK_LVDS_INTERFACE:
 
945
                                /* Get T1-T5 values */
 
946
                                did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T1;
 
947
                                did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
 
948
                                did->attr_list[did->num_attrs++].current_value =
 
949
                                        did->lvds.max_t1*2 + did->lvds.max_t2*2;
 
950
 
 
951
                                did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T2;
 
952
                                did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
 
953
                                did->attr_list[did->num_attrs++].current_value =
 
954
                                        did->lvds.min_t5*10;
 
955
 
 
956
                                did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T3;
 
957
                                did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
 
958
                                did->attr_list[did->num_attrs++].current_value =
 
959
                                        did->lvds.min_t6*10;
 
960
 
 
961
                                did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T4;
 
962
                                did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
 
963
                                did->attr_list[did->num_attrs++].current_value =
 
964
                                        did->lvds.max_t3*2;
 
965
 
 
966
                                did->attr_list[did->num_attrs].id = PD_ATTR_ID_FP_PWR_T5;
 
967
                                did->attr_list[did->num_attrs].flags=PD_ATTR_FLAG_VALUE_CHANGED;
 
968
                                did->attr_list[did->num_attrs++].current_value =
 
969
                                        did->lvds.min_t4*10 + did->lvds.max_t1*2;
 
970
                                break;
 
971
 
 
972
                        case DATABLOCK_DISPLAY_INTF:
 
973
                                if (did->display_intf.intf_type == INTERFACE_LVDS) {
 
974
                                        /* Get number of channels: 0=singlechannel 1=dualchannel */
 
975
                                        did->attr_list[did->num_attrs].id =
 
976
                                                PD_ATTR_ID_2_CHANNEL_PANEL;
 
977
                                        did->attr_list[did->num_attrs].flags =
 
978
                                                PD_ATTR_FLAG_VALUE_CHANGED;
 
979
                                        if (did->display_intf.num_channels == 2) {
 
980
                                                did->attr_list[did->num_attrs++].current_value = 1;
 
981
                                        }
 
982
 
 
983
                                        /* Get panel type value: 0=normal 1=OpenLDI */
 
984
                                        did->attr_list[did->num_attrs].id =
 
985
                                                PD_ATTR_ID_LVDS_PANEL_TYPE;
 
986
                                        did->attr_list[did->num_attrs].flags =
 
987
                                                PD_ATTR_FLAG_VALUE_CHANGED;
 
988
                                        did->attr_list[did->num_attrs++].current_value =
 
989
                                                did->display_intf.lvds.openldi;
 
990
                                }
 
991
 
 
992
                                break;
 
993
 
 
994
#ifndef CONFIG_MICRO
 
995
                        /* Support in Driver only */
 
996
                        case DATABLOCK_PRODUCTID:
 
997
                                break;
 
998
 
 
999
                        case DATABLOCK_SERIAL_NUMBER:
 
1000
                                break;
 
1001
 
 
1002
                        case DATABLOCK_ASCII_STRING:
 
1003
                                break;
 
1004
 
 
1005
                        case DATABLOCK_VENDOR_SPECIFIC:
 
1006
                                /* Because vendor specific datablock tag is out-of-order,
 
1007
                                 * copy data from buffer to vendor structure */
 
1008
                                OS_MEMCPY(&did->vendor, buffer, buffer[2] + 3);
 
1009
                                break;
 
1010
 
 
1011
                        /* Future support in Driver and VBIOS */
 
1012
                        case DATABLOCK_TIMING_3_SHORT:
 
1013
                                break;
 
1014
 
 
1015
                        case DATABLOCK_TIMING_4_DMTID:
 
1016
                                break;
 
1017
 
 
1018
                        /* Future support in Driver */
 
1019
                        case DATABLOCK_COLOR_CHARS:
 
1020
                                break;
 
1021
 
 
1022
                        case DATABLOCK_CEA_TIMING_STD:
 
1023
                                cea_tmg_table = (igd_timing_info_t *)
 
1024
                                        OS_ALLOC(cea_timing_table_size);
 
1025
                                OS_MEMCPY(cea_tmg_table, cea_timing_table,
 
1026
                                        cea_timing_table_size);
 
1027
                                /* Disable the CEA timings */
 
1028
                                enable_disable_timings(cea_tmg_table, 0);
 
1029
                                displayid_enable_std_timings(
 
1030
                                        cea_tmg_table,
 
1031
                                        db_data,
 
1032
                                        cea_std_lookup,
 
1033
                                        (unsigned short)cea_std_lookup_size,
 
1034
                                        CEA_STD);
 
1035
 
 
1036
                                replace_vesa_dtds_with_cea_dtds(timing_table, cea_tmg_table);
 
1037
                                cea_tmg_table[cea_timing_table_size-1].extn_ptr =
 
1038
                                        (void *)timing_table;
 
1039
                                timing_table = cea_tmg_table;
 
1040
                                break;
 
1041
#endif
 
1042
                        case DATABLOCK_TRANSFER_CHAR:
 
1043
                                break;
 
1044
                        }
 
1045
 
 
1046
                        /* Subtract data block payload */
 
1047
                        bytes_left -= payload;
 
1048
                        buffer += payload;
 
1049
                }
 
1050
                /* Extension count */
 
1051
                //e--;
 
1052
        }
 
1053
 
 
1054
        return 0;
 
1055
}
 
1056
 
 
1057
#endif
 
1058
 
 
1059
/*----------------------------------------------------------------------------
 
1060
 * File Revision History
 
1061
 * $Id: displayid.c,v 1.7 2011/02/16 17:04:48 astead Exp $
 
1062
 * $Source: /nfs/fm/proj/eia/cvsroot/koheo/linux/egd_drm/emgd/display/pi/cmn/displayid.c,v $
 
1063
 *----------------------------------------------------------------------------
 
1064
 */