Rev 4560 | Rev 6084 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4560 | Rev 5060 | ||
---|---|---|---|
Line 68... | Line 68... | ||
68 | #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) |
68 | #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) |
69 | /* Force reduced-blanking timings for detailed modes */ |
69 | /* Force reduced-blanking timings for detailed modes */ |
70 | #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) |
70 | #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) |
71 | /* Force 8bpc */ |
71 | /* Force 8bpc */ |
72 | #define EDID_QUIRK_FORCE_8BPC (1 << 8) |
72 | #define EDID_QUIRK_FORCE_8BPC (1 << 8) |
- | 73 | /* Force 12bpc */ |
|
- | 74 | #define EDID_QUIRK_FORCE_12BPC (1 << 9) |
|
Line 73... | Line 75... | ||
73 | 75 | ||
74 | struct detailed_mode_closure { |
76 | struct detailed_mode_closure { |
75 | struct drm_connector *connector; |
77 | struct drm_connector *connector; |
76 | struct edid *edid; |
78 | struct edid *edid; |
Line 123... | Line 125... | ||
123 | { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP }, |
125 | { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP }, |
124 | /* Samsung SyncMaster 22[5-6]BW */ |
126 | /* Samsung SyncMaster 22[5-6]BW */ |
125 | { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, |
127 | { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, |
126 | { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, |
128 | { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, |
Line -... | Line 129... | ||
- | 129 | ||
- | 130 | /* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */ |
|
- | 131 | { "SNY", 0x2541, EDID_QUIRK_FORCE_12BPC }, |
|
127 | 132 | ||
128 | /* ViewSonic VA2026w */ |
133 | /* ViewSonic VA2026w */ |
Line 129... | Line 134... | ||
129 | { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, |
134 | { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, |
130 | 135 | ||
Line 982... | Line 987... | ||
982 | 987 | ||
983 | static const u8 edid_header[] = { |
988 | static const u8 edid_header[] = { |
984 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 |
989 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 |
Line -... | Line 990... | ||
- | 990 | }; |
|
- | 991 | ||
- | 992 | /** |
|
985 | }; |
993 | * drm_edid_header_is_valid - sanity check the header of the base EDID block |
986 | 994 | * @raw_edid: pointer to raw base EDID block |
|
- | 995 | * |
|
987 | /* |
996 | * Sanity check the header of the base EDID block. |
988 | * Sanity check the header of the base EDID block. Return 8 if the header |
997 | * |
989 | * is perfect, down to 0 if it's totally wrong. |
998 | * Return: 8 if the header is perfect, down to 0 if it's totally wrong. |
990 | */ |
999 | */ |
991 | int drm_edid_header_is_valid(const u8 *raw_edid) |
1000 | int drm_edid_header_is_valid(const u8 *raw_edid) |
Line 1003... | Line 1012... | ||
1003 | static int edid_fixup __read_mostly = 6; |
1012 | static int edid_fixup __read_mostly = 6; |
1004 | module_param_named(edid_fixup, edid_fixup, int, 0400); |
1013 | module_param_named(edid_fixup, edid_fixup, int, 0400); |
1005 | MODULE_PARM_DESC(edid_fixup, |
1014 | MODULE_PARM_DESC(edid_fixup, |
1006 | "Minimum number of valid EDID header bytes (0-8, default 6)"); |
1015 | "Minimum number of valid EDID header bytes (0-8, default 6)"); |
Line 1007... | Line 1016... | ||
1007 | 1016 | ||
1008 | /* |
1017 | /** |
1009 | * Sanity check the EDID block (base or extension). Return 0 if the block |
1018 | * drm_edid_block_valid - Sanity check the EDID block (base or extension) |
- | 1019 | * @raw_edid: pointer to raw EDID block |
|
- | 1020 | * @block: type of block to validate (0 for base, extension otherwise) |
|
- | 1021 | * @print_bad_edid: if true, dump bad EDID blocks to the console |
|
- | 1022 | * |
|
- | 1023 | * Validate a base or extension EDID block and optionally dump bad blocks to |
|
- | 1024 | * the console. |
|
- | 1025 | * |
|
1010 | * doesn't check out, or 1 if it's valid. |
1026 | * Return: True if the block is valid, false otherwise. |
1011 | */ |
1027 | */ |
1012 | bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) |
1028 | bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) |
1013 | { |
1029 | { |
1014 | int i; |
1030 | int i; |
Line 1075... | Line 1091... | ||
1075 | /** |
1091 | /** |
1076 | * drm_edid_is_valid - sanity check EDID data |
1092 | * drm_edid_is_valid - sanity check EDID data |
1077 | * @edid: EDID data |
1093 | * @edid: EDID data |
1078 | * |
1094 | * |
1079 | * Sanity-check an entire EDID record (including extensions) |
1095 | * Sanity-check an entire EDID record (including extensions) |
- | 1096 | * |
|
- | 1097 | * Return: True if the EDID data is valid, false otherwise. |
|
1080 | */ |
1098 | */ |
1081 | bool drm_edid_is_valid(struct edid *edid) |
1099 | bool drm_edid_is_valid(struct edid *edid) |
1082 | { |
1100 | { |
1083 | int i; |
1101 | int i; |
1084 | u8 *raw = (u8 *)edid; |
1102 | u8 *raw = (u8 *)edid; |
Line 1094... | Line 1112... | ||
1094 | } |
1112 | } |
1095 | EXPORT_SYMBOL(drm_edid_is_valid); |
1113 | EXPORT_SYMBOL(drm_edid_is_valid); |
Line 1096... | Line 1114... | ||
1096 | 1114 | ||
1097 | #define DDC_SEGMENT_ADDR 0x30 |
1115 | #define DDC_SEGMENT_ADDR 0x30 |
1098 | /** |
1116 | /** |
- | 1117 | * drm_do_probe_ddc_edid() - get EDID information via I2C |
|
- | 1118 | * @adapter: I2C device adaptor |
|
- | 1119 | * @buf: EDID data buffer to be filled |
|
- | 1120 | * @block: 128 byte EDID block to start fetching from |
|
1099 | * Get EDID information via I2C. |
1121 | * @len: EDID data buffer length to fetch |
1100 | * |
- | |
1101 | * \param adapter : i2c device adaptor |
1122 | * |
1102 | * \param buf : EDID data buffer to be filled |
- | |
1103 | * \param len : EDID data buffer length |
- | |
1104 | * \return 0 on success or -1 on failure. |
1123 | * Try to fetch EDID information by calling I2C driver functions. |
1105 | * |
1124 | * |
1106 | * Try to fetch EDID information by calling i2c driver function. |
1125 | * Return: 0 on success or -1 on failure. |
1107 | */ |
1126 | */ |
1108 | static int |
1127 | static int |
1109 | drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, |
1128 | drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, |
1110 | int block, int len) |
1129 | int block, int len) |
1111 | { |
1130 | { |
1112 | unsigned char start = block * EDID_LENGTH; |
1131 | unsigned char start = block * EDID_LENGTH; |
1113 | unsigned char segment = block >> 1; |
1132 | unsigned char segment = block >> 1; |
1114 | unsigned char xfers = segment ? 3 : 2; |
1133 | unsigned char xfers = segment ? 3 : 2; |
Line -... | Line 1134... | ||
- | 1134 | int ret, retries = 5; |
|
1115 | int ret, retries = 5; |
1135 | |
1116 | 1136 | /* |
|
1117 | /* The core i2c driver will automatically retry the transfer if the |
1137 | * The core I2C driver will automatically retry the transfer if the |
1118 | * adapter reports EAGAIN. However, we find that bit-banging transfers |
1138 | * adapter reports EAGAIN. However, we find that bit-banging transfers |
1119 | * are susceptible to errors under a heavily loaded machine and |
1139 | * are susceptible to errors under a heavily loaded machine and |
1120 | * generate spurious NAKs and timeouts. Retrying the transfer |
1140 | * generate spurious NAKs and timeouts. Retrying the transfer |
Line 1139... | Line 1159... | ||
1139 | .buf = buf, |
1159 | .buf = buf, |
1140 | } |
1160 | } |
1141 | }; |
1161 | }; |
Line 1142... | Line 1162... | ||
1142 | 1162 | ||
1143 | /* |
1163 | /* |
1144 | * Avoid sending the segment addr to not upset non-compliant ddc |
1164 | * Avoid sending the segment addr to not upset non-compliant |
1145 | * monitors. |
1165 | * DDC monitors. |
1146 | */ |
1166 | */ |
Line 1147... | Line 1167... | ||
1147 | ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers); |
1167 | ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers); |
1148 | 1168 | ||
Line 1210... | Line 1230... | ||
1210 | } |
1230 | } |
Line 1211... | Line 1231... | ||
1211 | 1231 | ||
1212 | if (i == 4 && print_bad_edid) { |
1232 | if (i == 4 && print_bad_edid) { |
1213 | dev_warn(connector->dev->dev, |
1233 | dev_warn(connector->dev->dev, |
1214 | "%s: Ignoring invalid EDID block %d.\n", |
1234 | "%s: Ignoring invalid EDID block %d.\n", |
Line 1215... | Line 1235... | ||
1215 | drm_get_connector_name(connector), j); |
1235 | connector->name, j); |
1216 | 1236 | ||
1217 | connector->bad_edid_counter++; |
1237 | connector->bad_edid_counter++; |
Line 1230... | Line 1250... | ||
1230 | return block; |
1250 | return block; |
Line 1231... | Line 1251... | ||
1231 | 1251 | ||
1232 | carp: |
1252 | carp: |
1233 | if (print_bad_edid) { |
1253 | if (print_bad_edid) { |
1234 | dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n", |
1254 | dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n", |
1235 | drm_get_connector_name(connector), j); |
1255 | connector->name, j); |
1236 | } |
1256 | } |
Line 1237... | Line 1257... | ||
1237 | connector->bad_edid_counter++; |
1257 | connector->bad_edid_counter++; |
1238 | 1258 | ||
1239 | out: |
1259 | out: |
1240 | kfree(block); |
1260 | kfree(block); |
Line 1241... | Line 1261... | ||
1241 | return NULL; |
1261 | return NULL; |
1242 | } |
1262 | } |
- | 1263 | ||
1243 | 1264 | /** |
|
1244 | /** |
- | |
1245 | * Probe DDC presence. |
1265 | * drm_probe_ddc() - probe DDC presence |
1246 | * |
1266 | * @adapter: I2C adapter to probe |
1247 | * \param adapter : i2c device adaptor |
1267 | * |
1248 | * \return 1 on success |
1268 | * Return: True on success, false on failure. |
1249 | */ |
1269 | */ |
1250 | bool |
1270 | bool |
Line 1257... | Line 1277... | ||
1257 | EXPORT_SYMBOL(drm_probe_ddc); |
1277 | EXPORT_SYMBOL(drm_probe_ddc); |
Line 1258... | Line 1278... | ||
1258 | 1278 | ||
1259 | /** |
1279 | /** |
1260 | * drm_get_edid - get EDID data, if available |
1280 | * drm_get_edid - get EDID data, if available |
1261 | * @connector: connector we're probing |
1281 | * @connector: connector we're probing |
1262 | * @adapter: i2c adapter to use for DDC |
1282 | * @adapter: I2C adapter to use for DDC |
1263 | * |
1283 | * |
1264 | * Poke the given i2c channel to grab EDID data if possible. If found, |
1284 | * Poke the given I2C channel to grab EDID data if possible. If found, |
1265 | * attach it to the connector. |
1285 | * attach it to the connector. |
1266 | * |
1286 | * |
1267 | * Return edid data or NULL if we couldn't find any. |
1287 | * Return: Pointer to valid EDID or NULL if we couldn't find any. |
1268 | */ |
1288 | */ |
1269 | struct edid *drm_get_edid(struct drm_connector *connector, |
1289 | struct edid *drm_get_edid(struct drm_connector *connector, |
1270 | struct i2c_adapter *adapter) |
1290 | struct i2c_adapter *adapter) |
1271 | { |
1291 | { |
Line 1280... | Line 1300... | ||
1280 | 1300 | ||
1281 | /** |
1301 | /** |
1282 | * drm_edid_duplicate - duplicate an EDID and the extensions |
1302 | * drm_edid_duplicate - duplicate an EDID and the extensions |
1283 | * @edid: EDID to duplicate |
1303 | * @edid: EDID to duplicate |
1284 | * |
1304 | * |
1285 | * Return duplicate edid or NULL on allocation failure. |
1305 | * Return: Pointer to duplicated EDID or NULL on allocation failure. |
1286 | */ |
1306 | */ |
1287 | struct edid *drm_edid_duplicate(const struct edid *edid) |
1307 | struct edid *drm_edid_duplicate(const struct edid *edid) |
1288 | { |
1308 | { |
1289 | return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL); |
1309 | return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL); |
Line 1403... | Line 1423... | ||
1403 | * @vsize: Mode height |
1423 | * @vsize: Mode height |
1404 | * @fresh: Mode refresh rate |
1424 | * @fresh: Mode refresh rate |
1405 | * @rb: Mode reduced-blanking-ness |
1425 | * @rb: Mode reduced-blanking-ness |
1406 | * |
1426 | * |
1407 | * Walk the DMT mode list looking for a match for the given parameters. |
1427 | * Walk the DMT mode list looking for a match for the given parameters. |
- | 1428 | * |
|
1408 | * Return a newly allocated copy of the mode, or NULL if not found. |
1429 | * Return: A newly allocated copy of the mode, or NULL if not found. |
1409 | */ |
1430 | */ |
1410 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, |
1431 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, |
1411 | int hsize, int vsize, int fresh, |
1432 | int hsize, int vsize, int fresh, |
1412 | bool rb) |
1433 | bool rb) |
1413 | { |
1434 | { |
Line 1584... | Line 1605... | ||
1584 | (a == 0x20 && b == 0x20); |
1605 | (a == 0x20 && b == 0x20); |
1585 | } |
1606 | } |
Line 1586... | Line 1607... | ||
1586 | 1607 | ||
1587 | /** |
1608 | /** |
- | 1609 | * drm_mode_std - convert standard mode info (width, height, refresh) into mode |
|
- | 1610 | * @connector: connector of for the EDID block |
|
1588 | * drm_mode_std - convert standard mode info (width, height, refresh) into mode |
1611 | * @edid: EDID block to scan |
1589 | * @t: standard timing params |
- | |
1590 | * @timing_level: standard timing level |
1612 | * @t: standard timing params |
1591 | * |
1613 | * |
1592 | * Take the standard timing params (in this case width, aspect, and refresh) |
1614 | * Take the standard timing params (in this case width, aspect, and refresh) |
1593 | * and convert them into a real mode using CVT/GTF/DMT. |
1615 | * and convert them into a real mode using CVT/GTF/DMT. |
1594 | */ |
1616 | */ |
1595 | static struct drm_display_mode * |
1617 | static struct drm_display_mode * |
1596 | drm_mode_std(struct drm_connector *connector, struct edid *edid, |
1618 | drm_mode_std(struct drm_connector *connector, struct edid *edid, |
1597 | struct std_timing *t, int revision) |
1619 | struct std_timing *t) |
1598 | { |
1620 | { |
1599 | struct drm_device *dev = connector->dev; |
1621 | struct drm_device *dev = connector->dev; |
1600 | struct drm_display_mode *m, *mode = NULL; |
1622 | struct drm_display_mode *m, *mode = NULL; |
1601 | int hsize, vsize; |
1623 | int hsize, vsize; |
Line 1613... | Line 1635... | ||
1613 | hsize = t->hsize * 8 + 248; |
1635 | hsize = t->hsize * 8 + 248; |
1614 | /* vrefresh_rate = vfreq + 60 */ |
1636 | /* vrefresh_rate = vfreq + 60 */ |
1615 | vrefresh_rate = vfreq + 60; |
1637 | vrefresh_rate = vfreq + 60; |
1616 | /* the vdisplay is calculated based on the aspect ratio */ |
1638 | /* the vdisplay is calculated based on the aspect ratio */ |
1617 | if (aspect_ratio == 0) { |
1639 | if (aspect_ratio == 0) { |
1618 | if (revision < 3) |
1640 | if (edid->revision < 3) |
1619 | vsize = hsize; |
1641 | vsize = hsize; |
1620 | else |
1642 | else |
1621 | vsize = (hsize * 10) / 16; |
1643 | vsize = (hsize * 10) / 16; |
1622 | } else if (aspect_ratio == 1) |
1644 | } else if (aspect_ratio == 1) |
1623 | vsize = (hsize * 3) / 4; |
1645 | vsize = (hsize * 3) / 4; |
Line 2130... | Line 2152... | ||
2130 | closure->modes += drm_est3_modes(closure->connector, timing); |
2152 | closure->modes += drm_est3_modes(closure->connector, timing); |
2131 | } |
2153 | } |
Line 2132... | Line 2154... | ||
2132 | 2154 | ||
2133 | /** |
2155 | /** |
- | 2156 | * add_established_modes - get est. modes from EDID and add them |
|
2134 | * add_established_modes - get est. modes from EDID and add them |
2157 | * @connector: connector to add mode(s) to |
2135 | * @edid: EDID block to scan |
2158 | * @edid: EDID block to scan |
2136 | * |
2159 | * |
2137 | * Each EDID block contains a bitmap of the supported "established modes" list |
2160 | * Each EDID block contains a bitmap of the supported "established modes" list |
2138 | * (defined above). Tease them out and add them to the global modes list. |
2161 | * (defined above). Tease them out and add them to the global modes list. |
Line 2180... | Line 2203... | ||
2180 | for (i = 0; i < 6; i++) { |
2203 | for (i = 0; i < 6; i++) { |
2181 | struct std_timing *std; |
2204 | struct std_timing *std; |
2182 | struct drm_display_mode *newmode; |
2205 | struct drm_display_mode *newmode; |
Line 2183... | Line 2206... | ||
2183 | 2206 | ||
2184 | std = &data->data.timings[i]; |
2207 | std = &data->data.timings[i]; |
2185 | newmode = drm_mode_std(connector, edid, std, |
- | |
2186 | edid->revision); |
2208 | newmode = drm_mode_std(connector, edid, std); |
2187 | if (newmode) { |
2209 | if (newmode) { |
2188 | drm_mode_probed_add(connector, newmode); |
2210 | drm_mode_probed_add(connector, newmode); |
2189 | closure->modes++; |
2211 | closure->modes++; |
2190 | } |
2212 | } |
2191 | } |
2213 | } |
2192 | } |
2214 | } |
Line 2193... | Line 2215... | ||
2193 | } |
2215 | } |
2194 | 2216 | ||
- | 2217 | /** |
|
2195 | /** |
2218 | * add_standard_modes - get std. modes from EDID and add them |
2196 | * add_standard_modes - get std. modes from EDID and add them |
2219 | * @connector: connector to add mode(s) to |
2197 | * @edid: EDID block to scan |
2220 | * @edid: EDID block to scan |
2198 | * |
2221 | * |
2199 | * Standard modes can be calculated using the appropriate standard (DMT, |
2222 | * Standard modes can be calculated using the appropriate standard (DMT, |
Line 2209... | Line 2232... | ||
2209 | 2232 | ||
2210 | for (i = 0; i < EDID_STD_TIMINGS; i++) { |
2233 | for (i = 0; i < EDID_STD_TIMINGS; i++) { |
Line 2211... | Line 2234... | ||
2211 | struct drm_display_mode *newmode; |
2234 | struct drm_display_mode *newmode; |
2212 | 2235 | ||
2213 | newmode = drm_mode_std(connector, edid, |
- | |
2214 | &edid->standard_timings[i], |
2236 | newmode = drm_mode_std(connector, edid, |
2215 | edid->revision); |
2237 | &edid->standard_timings[i]); |
2216 | if (newmode) { |
2238 | if (newmode) { |
2217 | drm_mode_probed_add(connector, newmode); |
2239 | drm_mode_probed_add(connector, newmode); |
2218 | modes++; |
2240 | modes++; |
Line 2413... | Line 2435... | ||
2413 | 2435 | ||
2414 | /** |
2436 | /** |
2415 | * drm_match_cea_mode - look for a CEA mode matching given mode |
2437 | * drm_match_cea_mode - look for a CEA mode matching given mode |
2416 | * @to_match: display mode |
2438 | * @to_match: display mode |
2417 | * |
2439 | * |
2418 | * Returns the CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861 |
2440 | * Return: The CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861 |
2419 | * mode. |
2441 | * mode. |
2420 | */ |
2442 | */ |
2421 | u8 drm_match_cea_mode(const struct drm_display_mode *to_match) |
2443 | u8 drm_match_cea_mode(const struct drm_display_mode *to_match) |
2422 | { |
2444 | { |
Line 2440... | Line 2462... | ||
2440 | } |
2462 | } |
2441 | return 0; |
2463 | return 0; |
2442 | } |
2464 | } |
2443 | EXPORT_SYMBOL(drm_match_cea_mode); |
2465 | EXPORT_SYMBOL(drm_match_cea_mode); |
Line -... | Line 2466... | ||
- | 2466 | ||
- | 2467 | /** |
|
- | 2468 | * drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to |
|
- | 2469 | * the input VIC from the CEA mode list |
|
- | 2470 | * @video_code: ID given to each of the CEA modes |
|
- | 2471 | * |
|
- | 2472 | * Returns picture aspect ratio |
|
- | 2473 | */ |
|
- | 2474 | enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code) |
|
- | 2475 | { |
|
- | 2476 | /* return picture aspect ratio for video_code - 1 to access the |
|
- | 2477 | * right array element |
|
- | 2478 | */ |
|
- | 2479 | return edid_cea_modes[video_code-1].picture_aspect_ratio; |
|
- | 2480 | } |
|
- | 2481 | EXPORT_SYMBOL(drm_get_cea_aspect_ratio); |
|
2444 | 2482 | ||
2445 | /* |
2483 | /* |
2446 | * Calculate the alternate clock for HDMI modes (those from the HDMI vendor |
2484 | * Calculate the alternate clock for HDMI modes (those from the HDMI vendor |
2447 | * specific block). |
2485 | * specific block). |
2448 | * |
2486 | * |
Line 2578... | Line 2616... | ||
2578 | cea_mode = (video_db[video_index] & 127) - 1; |
2616 | cea_mode = (video_db[video_index] & 127) - 1; |
2579 | if (cea_mode >= ARRAY_SIZE(edid_cea_modes)) |
2617 | if (cea_mode >= ARRAY_SIZE(edid_cea_modes)) |
2580 | return NULL; |
2618 | return NULL; |
Line 2581... | Line 2619... | ||
2581 | 2619 | ||
- | 2620 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); |
|
- | 2621 | if (!newmode) |
|
- | 2622 | return NULL; |
|
2582 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); |
2623 | |
Line 2583... | Line 2624... | ||
2583 | newmode->vrefresh = 0; |
2624 | newmode->vrefresh = 0; |
2584 | 2625 | ||
Line 3008... | Line 3049... | ||
3008 | /** |
3049 | /** |
3009 | * drm_edid_to_eld - build ELD from EDID |
3050 | * drm_edid_to_eld - build ELD from EDID |
3010 | * @connector: connector corresponding to the HDMI/DP sink |
3051 | * @connector: connector corresponding to the HDMI/DP sink |
3011 | * @edid: EDID to parse |
3052 | * @edid: EDID to parse |
3012 | * |
3053 | * |
3013 | * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. |
3054 | * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The |
3014 | * Some ELD fields are left to the graphics driver caller: |
3055 | * Conn_Type, HDCP and Port_ID ELD fields are left for the graphics driver to |
3015 | * - Conn_Type |
- | |
3016 | * - HDCP |
- | |
3017 | * - Port_ID |
3056 | * fill in. |
3018 | */ |
3057 | */ |
3019 | void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) |
3058 | void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) |
3020 | { |
3059 | { |
3021 | uint8_t *eld = connector->eld; |
3060 | uint8_t *eld = connector->eld; |
3022 | u8 *cea; |
3061 | u8 *cea; |
Line 3096... | Line 3135... | ||
3096 | * drm_edid_to_sad - extracts SADs from EDID |
3135 | * drm_edid_to_sad - extracts SADs from EDID |
3097 | * @edid: EDID to parse |
3136 | * @edid: EDID to parse |
3098 | * @sads: pointer that will be set to the extracted SADs |
3137 | * @sads: pointer that will be set to the extracted SADs |
3099 | * |
3138 | * |
3100 | * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it. |
3139 | * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it. |
3101 | * Note: returned pointer needs to be kfreed |
- | |
3102 | * |
3140 | * |
- | 3141 | * Note: The returned pointer needs to be freed using kfree(). |
|
- | 3142 | * |
|
3103 | * Return number of found SADs or negative number on error. |
3143 | * Return: The number of found SADs or negative number on error. |
3104 | */ |
3144 | */ |
3105 | int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) |
3145 | int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) |
3106 | { |
3146 | { |
3107 | int count = 0; |
3147 | int count = 0; |
3108 | int i, start, end, dbl; |
3148 | int i, start, end, dbl; |
Line 3155... | Line 3195... | ||
3155 | * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID |
3195 | * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID |
3156 | * @edid: EDID to parse |
3196 | * @edid: EDID to parse |
3157 | * @sadb: pointer to the speaker block |
3197 | * @sadb: pointer to the speaker block |
3158 | * |
3198 | * |
3159 | * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it. |
3199 | * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it. |
3160 | * Note: returned pointer needs to be kfreed |
- | |
3161 | * |
3200 | * |
- | 3201 | * Note: The returned pointer needs to be freed using kfree(). |
|
- | 3202 | * |
|
3162 | * Return number of found Speaker Allocation Blocks or negative number on error. |
3203 | * Return: The number of found Speaker Allocation Blocks or negative number on |
- | 3204 | * error. |
|
3163 | */ |
3205 | */ |
3164 | int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) |
3206 | int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) |
3165 | { |
3207 | { |
3166 | int count = 0; |
3208 | int count = 0; |
3167 | int i, start, end, dbl; |
3209 | int i, start, end, dbl; |
Line 3189... | Line 3231... | ||
3189 | if (cea_db_tag(db) == SPEAKER_BLOCK) { |
3231 | if (cea_db_tag(db) == SPEAKER_BLOCK) { |
3190 | dbl = cea_db_payload_len(db); |
3232 | dbl = cea_db_payload_len(db); |
Line 3191... | Line 3233... | ||
3191 | 3233 | ||
3192 | /* Speaker Allocation Data Block */ |
3234 | /* Speaker Allocation Data Block */ |
3193 | if (dbl == 3) { |
3235 | if (dbl == 3) { |
3194 | *sadb = kmalloc(dbl, GFP_KERNEL); |
3236 | *sadb = kmemdup(&db[1], dbl, GFP_KERNEL); |
3195 | if (!*sadb) |
3237 | if (!*sadb) |
3196 | return -ENOMEM; |
- | |
3197 | memcpy(*sadb, &db[1], dbl); |
3238 | return -ENOMEM; |
3198 | count = dbl; |
3239 | count = dbl; |
3199 | break; |
3240 | break; |
3200 | } |
3241 | } |
3201 | } |
3242 | } |
Line 3204... | Line 3245... | ||
3204 | return count; |
3245 | return count; |
3205 | } |
3246 | } |
3206 | EXPORT_SYMBOL(drm_edid_to_speaker_allocation); |
3247 | EXPORT_SYMBOL(drm_edid_to_speaker_allocation); |
Line 3207... | Line 3248... | ||
3207 | 3248 | ||
3208 | /** |
3249 | /** |
3209 | * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond |
3250 | * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay |
3210 | * @connector: connector associated with the HDMI/DP sink |
3251 | * @connector: connector associated with the HDMI/DP sink |
- | 3252 | * @mode: the display mode |
|
- | 3253 | * |
|
- | 3254 | * Return: The HDMI/DP sink's audio-video sync delay in milliseconds or 0 if |
|
3211 | * @mode: the display mode |
3255 | * the sink doesn't support audio or video. |
3212 | */ |
3256 | */ |
3213 | int drm_av_sync_delay(struct drm_connector *connector, |
3257 | int drm_av_sync_delay(struct drm_connector *connector, |
3214 | struct drm_display_mode *mode) |
3258 | struct drm_display_mode *mode) |
3215 | { |
3259 | { |
Line 3248... | Line 3292... | ||
3248 | * @encoder: the encoder just changed display mode |
3292 | * @encoder: the encoder just changed display mode |
3249 | * @mode: the adjusted display mode |
3293 | * @mode: the adjusted display mode |
3250 | * |
3294 | * |
3251 | * It's possible for one encoder to be associated with multiple HDMI/DP sinks. |
3295 | * It's possible for one encoder to be associated with multiple HDMI/DP sinks. |
3252 | * The policy is now hard coded to simply use the first HDMI/DP sink's ELD. |
3296 | * The policy is now hard coded to simply use the first HDMI/DP sink's ELD. |
- | 3297 | * |
|
- | 3298 | * Return: The connector associated with the first HDMI/DP sink that has ELD |
|
- | 3299 | * attached to it. |
|
3253 | */ |
3300 | */ |
3254 | struct drm_connector *drm_select_eld(struct drm_encoder *encoder, |
3301 | struct drm_connector *drm_select_eld(struct drm_encoder *encoder, |
3255 | struct drm_display_mode *mode) |
3302 | struct drm_display_mode *mode) |
3256 | { |
3303 | { |
3257 | struct drm_connector *connector; |
3304 | struct drm_connector *connector; |
3258 | struct drm_device *dev = encoder->dev; |
3305 | struct drm_device *dev = encoder->dev; |
Line -... | Line 3306... | ||
- | 3306 | ||
- | 3307 | WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); |
|
- | 3308 | WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); |
|
3259 | 3309 | ||
3260 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
3310 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
3261 | if (connector->encoder == encoder && connector->eld[0]) |
3311 | if (connector->encoder == encoder && connector->eld[0]) |
Line 3262... | Line 3312... | ||
3262 | return connector; |
3312 | return connector; |
3263 | 3313 | ||
3264 | return NULL; |
3314 | return NULL; |
Line 3265... | Line 3315... | ||
3265 | } |
3315 | } |
3266 | EXPORT_SYMBOL(drm_select_eld); |
3316 | EXPORT_SYMBOL(drm_select_eld); |
3267 | 3317 | ||
3268 | /** |
3318 | /** |
3269 | * drm_detect_hdmi_monitor - detect whether monitor is hdmi. |
3319 | * drm_detect_hdmi_monitor - detect whether monitor is HDMI |
- | 3320 | * @edid: monitor EDID information |
|
3270 | * @edid: monitor EDID information |
3321 | * |
3271 | * |
3322 | * Parse the CEA extension according to CEA-861-B. |
3272 | * Parse the CEA extension according to CEA-861-B. |
3323 | * |
3273 | * Return true if HDMI, false if not or unknown. |
3324 | * Return: True if the monitor is HDMI, false if not or unknown. |
3274 | */ |
3325 | */ |
3275 | bool drm_detect_hdmi_monitor(struct edid *edid) |
3326 | bool drm_detect_hdmi_monitor(struct edid *edid) |
Line 3298... | Line 3349... | ||
3298 | } |
3349 | } |
3299 | EXPORT_SYMBOL(drm_detect_hdmi_monitor); |
3350 | EXPORT_SYMBOL(drm_detect_hdmi_monitor); |
Line 3300... | Line 3351... | ||
3300 | 3351 | ||
3301 | /** |
3352 | /** |
- | 3353 | * drm_detect_monitor_audio - check monitor audio capability |
|
3302 | * drm_detect_monitor_audio - check monitor audio capability |
3354 | * @edid: EDID block to scan |
3303 | * |
3355 | * |
3304 | * Monitor should have CEA extension block. |
3356 | * Monitor should have CEA extension block. |
3305 | * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic |
3357 | * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic |
3306 | * audio' only. If there is any audio extension block and supported |
3358 | * audio' only. If there is any audio extension block and supported |
3307 | * audio format, assume at least 'basic audio' support, even if 'basic |
3359 | * audio format, assume at least 'basic audio' support, even if 'basic |
3308 | * audio' is not defined in EDID. |
3360 | * audio' is not defined in EDID. |
- | 3361 | * |
|
3309 | * |
3362 | * Return: True if the monitor supports audio, false otherwise. |
3310 | */ |
3363 | */ |
3311 | bool drm_detect_monitor_audio(struct edid *edid) |
3364 | bool drm_detect_monitor_audio(struct edid *edid) |
3312 | { |
3365 | { |
3313 | u8 *edid_ext; |
3366 | u8 *edid_ext; |
Line 3343... | Line 3396... | ||
3343 | } |
3396 | } |
3344 | EXPORT_SYMBOL(drm_detect_monitor_audio); |
3397 | EXPORT_SYMBOL(drm_detect_monitor_audio); |
Line 3345... | Line 3398... | ||
3345 | 3398 | ||
3346 | /** |
3399 | /** |
- | 3400 | * drm_rgb_quant_range_selectable - is RGB quantization range selectable? |
|
3347 | * drm_rgb_quant_range_selectable - is RGB quantization range selectable? |
3401 | * @edid: EDID block to scan |
3348 | * |
3402 | * |
3349 | * Check whether the monitor reports the RGB quantization range selection |
3403 | * Check whether the monitor reports the RGB quantization range selection |
3350 | * as supported. The AVI infoframe can then be used to inform the monitor |
3404 | * as supported. The AVI infoframe can then be used to inform the monitor |
- | 3405 | * which quantization range (full or limited) is used. |
|
- | 3406 | * |
|
3351 | * which quantization range (full or limited) is used. |
3407 | * Return: True if the RGB quantization range is selectable, false otherwise. |
3352 | */ |
3408 | */ |
3353 | bool drm_rgb_quant_range_selectable(struct edid *edid) |
3409 | bool drm_rgb_quant_range_selectable(struct edid *edid) |
3354 | { |
3410 | { |
3355 | u8 *edid_ext; |
3411 | u8 *edid_ext; |
Line 3373... | Line 3429... | ||
3373 | return false; |
3429 | return false; |
3374 | } |
3430 | } |
3375 | EXPORT_SYMBOL(drm_rgb_quant_range_selectable); |
3431 | EXPORT_SYMBOL(drm_rgb_quant_range_selectable); |
Line 3376... | Line 3432... | ||
3376 | 3432 | ||
- | 3433 | /** |
|
- | 3434 | * drm_assign_hdmi_deep_color_info - detect whether monitor supports |
|
- | 3435 | * hdmi deep color modes and update drm_display_info if so. |
|
- | 3436 | * |
|
- | 3437 | * @edid: monitor EDID information |
|
- | 3438 | * @info: Updated with maximum supported deep color bpc and color format |
|
- | 3439 | * if deep color supported. |
|
- | 3440 | * |
|
- | 3441 | * Parse the CEA extension according to CEA-861-B. |
|
- | 3442 | * Return true if HDMI deep color supported, false if not or unknown. |
|
- | 3443 | */ |
|
- | 3444 | static bool drm_assign_hdmi_deep_color_info(struct edid *edid, |
|
- | 3445 | struct drm_display_info *info, |
|
- | 3446 | struct drm_connector *connector) |
|
- | 3447 | { |
|
- | 3448 | u8 *edid_ext, *hdmi; |
|
- | 3449 | int i; |
|
- | 3450 | int start_offset, end_offset; |
|
- | 3451 | unsigned int dc_bpc = 0; |
|
- | 3452 | ||
- | 3453 | edid_ext = drm_find_cea_extension(edid); |
|
- | 3454 | if (!edid_ext) |
|
- | 3455 | return false; |
|
- | 3456 | ||
- | 3457 | if (cea_db_offsets(edid_ext, &start_offset, &end_offset)) |
|
- | 3458 | return false; |
|
- | 3459 | ||
- | 3460 | /* |
|
- | 3461 | * Because HDMI identifier is in Vendor Specific Block, |
|
- | 3462 | * search it from all data blocks of CEA extension. |
|
- | 3463 | */ |
|
- | 3464 | for_each_cea_db(edid_ext, i, start_offset, end_offset) { |
|
- | 3465 | if (cea_db_is_hdmi_vsdb(&edid_ext[i])) { |
|
- | 3466 | /* HDMI supports at least 8 bpc */ |
|
- | 3467 | info->bpc = 8; |
|
- | 3468 | ||
- | 3469 | hdmi = &edid_ext[i]; |
|
- | 3470 | if (cea_db_payload_len(hdmi) < 6) |
|
- | 3471 | return false; |
|
- | 3472 | ||
- | 3473 | if (hdmi[6] & DRM_EDID_HDMI_DC_30) { |
|
- | 3474 | dc_bpc = 10; |
|
- | 3475 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30; |
|
- | 3476 | DRM_DEBUG("%s: HDMI sink does deep color 30.\n", |
|
- | 3477 | connector->name); |
|
- | 3478 | } |
|
- | 3479 | ||
- | 3480 | if (hdmi[6] & DRM_EDID_HDMI_DC_36) { |
|
- | 3481 | dc_bpc = 12; |
|
- | 3482 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36; |
|
- | 3483 | DRM_DEBUG("%s: HDMI sink does deep color 36.\n", |
|
- | 3484 | connector->name); |
|
- | 3485 | } |
|
- | 3486 | ||
- | 3487 | if (hdmi[6] & DRM_EDID_HDMI_DC_48) { |
|
- | 3488 | dc_bpc = 16; |
|
- | 3489 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48; |
|
- | 3490 | DRM_DEBUG("%s: HDMI sink does deep color 48.\n", |
|
- | 3491 | connector->name); |
|
- | 3492 | } |
|
- | 3493 | ||
- | 3494 | if (dc_bpc > 0) { |
|
- | 3495 | DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n", |
|
- | 3496 | connector->name, dc_bpc); |
|
- | 3497 | info->bpc = dc_bpc; |
|
- | 3498 | ||
- | 3499 | /* |
|
- | 3500 | * Deep color support mandates RGB444 support for all video |
|
- | 3501 | * modes and forbids YCRCB422 support for all video modes per |
|
- | 3502 | * HDMI 1.3 spec. |
|
- | 3503 | */ |
|
- | 3504 | info->color_formats = DRM_COLOR_FORMAT_RGB444; |
|
- | 3505 | ||
- | 3506 | /* YCRCB444 is optional according to spec. */ |
|
- | 3507 | if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) { |
|
- | 3508 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
|
- | 3509 | DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n", |
|
- | 3510 | connector->name); |
|
- | 3511 | } |
|
- | 3512 | ||
- | 3513 | /* |
|
- | 3514 | * Spec says that if any deep color mode is supported at all, |
|
- | 3515 | * then deep color 36 bit must be supported. |
|
- | 3516 | */ |
|
- | 3517 | if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) { |
|
- | 3518 | DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n", |
|
- | 3519 | connector->name); |
|
- | 3520 | } |
|
- | 3521 | ||
- | 3522 | return true; |
|
- | 3523 | } |
|
- | 3524 | else { |
|
- | 3525 | DRM_DEBUG("%s: No deep color support on this HDMI sink.\n", |
|
- | 3526 | connector->name); |
|
- | 3527 | } |
|
- | 3528 | } |
|
- | 3529 | } |
|
- | 3530 | ||
- | 3531 | return false; |
|
- | 3532 | } |
|
- | 3533 | ||
3377 | /** |
3534 | /** |
3378 | * drm_add_display_info - pull display info out if present |
3535 | * drm_add_display_info - pull display info out if present |
3379 | * @edid: EDID data |
3536 | * @edid: EDID data |
- | 3537 | * @info: display info (attached to connector) |
|
3380 | * @info: display info (attached to connector) |
3538 | * @connector: connector whose edid is used to build display info |
3381 | * |
3539 | * |
3382 | * Grab any available display info and stuff it into the drm_display_info |
3540 | * Grab any available display info and stuff it into the drm_display_info |
3383 | * structure that's part of the connector. Useful for tracking bpp and |
3541 | * structure that's part of the connector. Useful for tracking bpp and |
3384 | * color spaces. |
3542 | * color spaces. |
3385 | */ |
3543 | */ |
3386 | static void drm_add_display_info(struct edid *edid, |
3544 | static void drm_add_display_info(struct edid *edid, |
- | 3545 | struct drm_display_info *info, |
|
3387 | struct drm_display_info *info) |
3546 | struct drm_connector *connector) |
3388 | { |
3547 | { |
Line 3389... | Line 3548... | ||
3389 | u8 *edid_ext; |
3548 | u8 *edid_ext; |
3390 | 3549 | ||
Line 3412... | Line 3571... | ||
3412 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
3571 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
3413 | if (edid_ext[3] & EDID_CEA_YCRCB422) |
3572 | if (edid_ext[3] & EDID_CEA_YCRCB422) |
3414 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; |
3573 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; |
3415 | } |
3574 | } |
Line -... | Line 3575... | ||
- | 3575 | ||
- | 3576 | /* HDMI deep color modes supported? Assign to info, if so */ |
|
- | 3577 | drm_assign_hdmi_deep_color_info(edid, info, connector); |
|
3416 | 3578 | ||
3417 | /* Only defined for 1.4 with digital displays */ |
3579 | /* Only defined for 1.4 with digital displays */ |
3418 | if (edid->revision < 4) |
3580 | if (edid->revision < 4) |
Line 3419... | Line 3581... | ||
3419 | return; |
3581 | return; |
Line 3441... | Line 3603... | ||
3441 | default: |
3603 | default: |
3442 | info->bpc = 0; |
3604 | info->bpc = 0; |
3443 | break; |
3605 | break; |
3444 | } |
3606 | } |
Line -... | Line 3607... | ||
- | 3607 | ||
- | 3608 | DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n", |
|
- | 3609 | connector->name, info->bpc); |
|
3445 | 3610 | ||
3446 | info->color_formats |= DRM_COLOR_FORMAT_RGB444; |
3611 | info->color_formats |= DRM_COLOR_FORMAT_RGB444; |
3447 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) |
3612 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) |
3448 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
3613 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
3449 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) |
3614 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) |
3450 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; |
3615 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; |
Line 3451... | Line 3616... | ||
3451 | } |
3616 | } |
3452 | 3617 | ||
3453 | /** |
3618 | /** |
3454 | * drm_add_edid_modes - add modes from EDID data, if available |
3619 | * drm_add_edid_modes - add modes from EDID data, if available |
3455 | * @connector: connector we're probing |
3620 | * @connector: connector we're probing |
3456 | * @edid: edid data |
3621 | * @edid: EDID data |
3457 | * |
3622 | * |
3458 | * Add the specified modes to the connector's mode list. |
3623 | * Add the specified modes to the connector's mode list. |
3459 | * |
3624 | * |
3460 | * Return number of modes added or 0 if we couldn't find any. |
3625 | * Return: The number of modes added or 0 if we couldn't find any. |
3461 | */ |
3626 | */ |
3462 | int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) |
3627 | int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) |
3463 | { |
3628 | { |
Line 3467... | Line 3632... | ||
3467 | if (edid == NULL) { |
3632 | if (edid == NULL) { |
3468 | return 0; |
3633 | return 0; |
3469 | } |
3634 | } |
3470 | if (!drm_edid_is_valid(edid)) { |
3635 | if (!drm_edid_is_valid(edid)) { |
3471 | dev_warn(connector->dev->dev, "%s: EDID invalid.\n", |
3636 | dev_warn(connector->dev->dev, "%s: EDID invalid.\n", |
3472 | drm_get_connector_name(connector)); |
3637 | connector->name); |
3473 | return 0; |
3638 | return 0; |
3474 | } |
3639 | } |
Line 3475... | Line 3640... | ||
3475 | 3640 | ||
Line 3499... | Line 3664... | ||
3499 | num_modes += add_alternate_cea_modes(connector, edid); |
3664 | num_modes += add_alternate_cea_modes(connector, edid); |
Line 3500... | Line 3665... | ||
3500 | 3665 | ||
3501 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
3666 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
Line 3502... | Line 3667... | ||
3502 | edid_fixup_preferred(connector, quirks); |
3667 | edid_fixup_preferred(connector, quirks); |
Line 3503... | Line 3668... | ||
3503 | 3668 | ||
3504 | drm_add_display_info(edid, &connector->display_info); |
3669 | drm_add_display_info(edid, &connector->display_info, connector); |
Line -... | Line 3670... | ||
- | 3670 | ||
- | 3671 | if (quirks & EDID_QUIRK_FORCE_8BPC) |
|
- | 3672 | connector->display_info.bpc = 8; |
|
3505 | 3673 | ||
3506 | if (quirks & EDID_QUIRK_FORCE_8BPC) |
3674 | if (quirks & EDID_QUIRK_FORCE_12BPC) |
3507 | connector->display_info.bpc = 8; |
3675 | connector->display_info.bpc = 12; |
Line 3508... | Line 3676... | ||
3508 | 3676 | ||
Line 3517... | Line 3685... | ||
3517 | * @vdisplay: the vertical display limit |
3685 | * @vdisplay: the vertical display limit |
3518 | * |
3686 | * |
3519 | * Add the specified modes to the connector's mode list. Only when the |
3687 | * Add the specified modes to the connector's mode list. Only when the |
3520 | * hdisplay/vdisplay is not beyond the given limit, it will be added. |
3688 | * hdisplay/vdisplay is not beyond the given limit, it will be added. |
3521 | * |
3689 | * |
3522 | * Return number of modes added or 0 if we couldn't find any. |
3690 | * Return: The number of modes added or 0 if we couldn't find any. |
3523 | */ |
3691 | */ |
3524 | int drm_add_modes_noedid(struct drm_connector *connector, |
3692 | int drm_add_modes_noedid(struct drm_connector *connector, |
3525 | int hdisplay, int vdisplay) |
3693 | int hdisplay, int vdisplay) |
3526 | { |
3694 | { |
3527 | int i, count, num_modes = 0; |
3695 | int i, count, num_modes = 0; |
Line 3556... | Line 3724... | ||
3556 | } |
3724 | } |
3557 | return num_modes; |
3725 | return num_modes; |
3558 | } |
3726 | } |
3559 | EXPORT_SYMBOL(drm_add_modes_noedid); |
3727 | EXPORT_SYMBOL(drm_add_modes_noedid); |
Line -... | Line 3728... | ||
- | 3728 | ||
- | 3729 | /** |
|
- | 3730 | * drm_set_preferred_mode - Sets the preferred mode of a connector |
|
- | 3731 | * @connector: connector whose mode list should be processed |
|
- | 3732 | * @hpref: horizontal resolution of preferred mode |
|
- | 3733 | * @vpref: vertical resolution of preferred mode |
|
- | 3734 | * |
|
- | 3735 | * Marks a mode as preferred if it matches the resolution specified by @hpref |
|
- | 3736 | * and @vpref. |
|
3560 | 3737 | */ |
|
3561 | void drm_set_preferred_mode(struct drm_connector *connector, |
3738 | void drm_set_preferred_mode(struct drm_connector *connector, |
3562 | int hpref, int vpref) |
3739 | int hpref, int vpref) |
3563 | { |
3740 | { |
Line 3564... | Line 3741... | ||
3564 | struct drm_display_mode *mode; |
3741 | struct drm_display_mode *mode; |
3565 | 3742 | ||
3566 | list_for_each_entry(mode, &connector->probed_modes, head) { |
3743 | list_for_each_entry(mode, &connector->probed_modes, head) { |
3567 | if (drm_mode_width(mode) == hpref && |
3744 | if (mode->hdisplay == hpref && |
3568 | drm_mode_height(mode) == vpref) |
3745 | mode->vdisplay == vpref) |
3569 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
3746 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
3570 | } |
3747 | } |
Line 3575... | Line 3752... | ||
3575 | * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with |
3752 | * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with |
3576 | * data from a DRM display mode |
3753 | * data from a DRM display mode |
3577 | * @frame: HDMI AVI infoframe |
3754 | * @frame: HDMI AVI infoframe |
3578 | * @mode: DRM display mode |
3755 | * @mode: DRM display mode |
3579 | * |
3756 | * |
3580 | * Returns 0 on success or a negative error code on failure. |
3757 | * Return: 0 on success or a negative error code on failure. |
3581 | */ |
3758 | */ |
3582 | int |
3759 | int |
3583 | drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, |
3760 | drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, |
3584 | const struct drm_display_mode *mode) |
3761 | const struct drm_display_mode *mode) |
3585 | { |
3762 | { |
Line 3596... | Line 3773... | ||
3596 | frame->pixel_repeat = 1; |
3773 | frame->pixel_repeat = 1; |
Line 3597... | Line 3774... | ||
3597 | 3774 | ||
Line 3598... | Line 3775... | ||
3598 | frame->video_code = drm_match_cea_mode(mode); |
3775 | frame->video_code = drm_match_cea_mode(mode); |
- | 3776 | ||
- | 3777 | frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; |
|
- | 3778 | ||
- | 3779 | /* |
|
- | 3780 | * Populate picture aspect ratio from either |
|
- | 3781 | * user input (if specified) or from the CEA mode list. |
|
- | 3782 | */ |
|
- | 3783 | if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 || |
|
- | 3784 | mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9) |
|
- | 3785 | frame->picture_aspect = mode->picture_aspect_ratio; |
|
- | 3786 | else if (frame->video_code > 0) |
|
- | 3787 | frame->picture_aspect = drm_get_cea_aspect_ratio( |
|
3599 | 3788 | frame->video_code); |
|
- | 3789 | ||
Line 3600... | Line 3790... | ||
3600 | frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; |
3790 | frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; |
3601 | frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; |
3791 | frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN; |
3602 | 3792 | ||
Line 3639... | Line 3829... | ||
3639 | * |
3829 | * |
3640 | * Note that there's is a need to send HDMI vendor infoframes only when using a |
3830 | * Note that there's is a need to send HDMI vendor infoframes only when using a |
3641 | * 4k or stereoscopic 3D mode. So when giving any other mode as input this |
3831 | * 4k or stereoscopic 3D mode. So when giving any other mode as input this |
3642 | * function will return -EINVAL, error that can be safely ignored. |
3832 | * function will return -EINVAL, error that can be safely ignored. |
3643 | * |
3833 | * |
3644 | * Returns 0 on success or a negative error code on failure. |
3834 | * Return: 0 on success or a negative error code on failure. |
3645 | */ |
3835 | */ |
3646 | int |
3836 | int |
3647 | drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, |
3837 | drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, |
3648 | const struct drm_display_mode *mode) |
3838 | const struct drm_display_mode *mode) |
3649 | { |
3839 | { |