Subversion Repositories Kolibri OS

Rev

Rev 4075 | Rev 4539 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4075 Rev 4104
Line 123... Line 123...
123
	{ "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
123
	{ "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
124
	{ "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
124
	{ "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
Line 125... Line 125...
125
 
125
 
126
	/* ViewSonic VA2026w */
126
	/* ViewSonic VA2026w */
-
 
127
	{ "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
-
 
128
 
-
 
129
	/* Medion MD 30217 PG */
127
	{ "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
130
	{ "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
Line 128... Line 131...
128
};
131
};
129
 
132
 
130
/*
133
/*
Line 929... Line 932...
929
		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
932
		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
930
		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
933
		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
931
	 .vrefresh = 100, },
934
	 .vrefresh = 100, },
932
};
935
};
Line -... Line 936...
-
 
936
 
-
 
937
/*
-
 
938
 * HDMI 1.4 4k modes.
-
 
939
 */
-
 
940
static const struct drm_display_mode edid_4k_modes[] = {
-
 
941
	/* 1 - 3840x2160@30Hz */
-
 
942
	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
-
 
943
		   3840, 4016, 4104, 4400, 0,
-
 
944
		   2160, 2168, 2178, 2250, 0,
-
 
945
		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
-
 
946
	  .vrefresh = 30, },
-
 
947
	/* 2 - 3840x2160@25Hz */
-
 
948
	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
-
 
949
		   3840, 4896, 4984, 5280, 0,
-
 
950
		   2160, 2168, 2178, 2250, 0,
-
 
951
		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
-
 
952
	  .vrefresh = 25, },
-
 
953
	/* 3 - 3840x2160@24Hz */
-
 
954
	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
-
 
955
		   3840, 5116, 5204, 5500, 0,
-
 
956
		   2160, 2168, 2178, 2250, 0,
-
 
957
		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
-
 
958
	  .vrefresh = 24, },
-
 
959
	/* 4 - 4096x2160@24Hz (SMPTE) */
-
 
960
	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000,
-
 
961
		   4096, 5116, 5204, 5500, 0,
-
 
962
		   2160, 2168, 2178, 2250, 0,
-
 
963
		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
-
 
964
	  .vrefresh = 24, },
-
 
965
};
933
 
966
 
Line 934... Line 967...
934
/*** DDC fetch and block validation ***/
967
/*** DDC fetch and block validation ***/
935
 
968
 
936
static const u8 edid_header[] = {
969
static const u8 edid_header[] = {
Line 2285... Line 2318...
2285
	drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure);
2318
	drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure);
Line 2286... Line 2319...
2286
 
2319
 
2287
	return closure.modes;
2320
	return closure.modes;
Line 2288... Line -...
2288
}
-
 
2289
 
2321
}
2290
#define HDMI_IDENTIFIER 0x000C03
2322
 
2291
#define AUDIO_BLOCK	0x01
2323
#define AUDIO_BLOCK	0x01
2292
#define VIDEO_BLOCK     0x02
2324
#define VIDEO_BLOCK     0x02
2293
#define VENDOR_BLOCK    0x03
2325
#define VENDOR_BLOCK    0x03
2294
#define SPEAKER_BLOCK	0x04
2326
#define SPEAKER_BLOCK	0x04
2295
#define VIDEO_CAPABILITY_BLOCK	0x07
2327
#define VIDEO_CAPABILITY_BLOCK	0x07
2296
#define EDID_BASIC_AUDIO	(1 << 6)
2328
#define EDID_BASIC_AUDIO	(1 << 6)
2297
#define EDID_CEA_YCRCB444	(1 << 5)
2329
#define EDID_CEA_YCRCB444	(1 << 5)
Line 2298... Line 2330...
2298
#define EDID_CEA_YCRCB422	(1 << 4)
2330
#define EDID_CEA_YCRCB422	(1 << 4)
2299
#define EDID_CEA_VCDB_QS	(1 << 6)
2331
#define EDID_CEA_VCDB_QS	(1 << 6)
2300
 
2332
 
2301
/**
2333
/*
2302
 * Search EDID for CEA extension block.
2334
 * Search EDID for CEA extension block.
2303
 */
2335
 */
2304
u8 *drm_find_cea_extension(struct edid *edid)
2336
static u8 *drm_find_cea_extension(struct edid *edid)
Line 2305... Line 2337...
2305
{
2337
{
Line 2320... Line 2352...
2320
	if (i == edid->extensions)
2352
	if (i == edid->extensions)
2321
		return NULL;
2353
		return NULL;
Line 2322... Line 2354...
2322
 
2354
 
2323
	return edid_ext;
2355
	return edid_ext;
2324
}
-
 
Line 2325... Line 2356...
2325
EXPORT_SYMBOL(drm_find_cea_extension);
2356
}
2326
 
2357
 
2327
/*
2358
/*
2328
 * Calculate the alternate clock for the CEA mode
2359
 * Calculate the alternate clock for the CEA mode
Line 2378... Line 2409...
2378
	}
2409
	}
2379
	return 0;
2410
	return 0;
2380
}
2411
}
2381
EXPORT_SYMBOL(drm_match_cea_mode);
2412
EXPORT_SYMBOL(drm_match_cea_mode);
Line -... Line 2413...
-
 
2413
 
-
 
2414
/*
-
 
2415
 * Calculate the alternate clock for HDMI modes (those from the HDMI vendor
-
 
2416
 * specific block).
-
 
2417
 *
-
 
2418
 * It's almost like cea_mode_alternate_clock(), we just need to add an
-
 
2419
 * exception for the VIC 4 mode (4096x2160@24Hz): no alternate clock for this
-
 
2420
 * one.
-
 
2421
 */
-
 
2422
static unsigned int
-
 
2423
hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
-
 
2424
{
-
 
2425
	if (hdmi_mode->vdisplay == 4096 && hdmi_mode->hdisplay == 2160)
-
 
2426
		return hdmi_mode->clock;
-
 
2427
 
-
 
2428
	return cea_mode_alternate_clock(hdmi_mode);
-
 
2429
}
-
 
2430
 
-
 
2431
/*
-
 
2432
 * drm_match_hdmi_mode - look for a HDMI mode matching given mode
-
 
2433
 * @to_match: display mode
-
 
2434
 *
-
 
2435
 * An HDMI mode is one defined in the HDMI vendor specific block.
-
 
2436
 *
-
 
2437
 * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one.
-
 
2438
 */
-
 
2439
static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
-
 
2440
{
-
 
2441
	u8 mode;
-
 
2442
 
-
 
2443
	if (!to_match->clock)
-
 
2444
		return 0;
-
 
2445
 
-
 
2446
	for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) {
-
 
2447
		const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode];
-
 
2448
		unsigned int clock1, clock2;
-
 
2449
 
-
 
2450
		/* Make sure to also match alternate clocks */
-
 
2451
		clock1 = hdmi_mode->clock;
-
 
2452
		clock2 = hdmi_mode_alternate_clock(hdmi_mode);
-
 
2453
 
-
 
2454
		if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
-
 
2455
		     KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
-
 
2456
		    drm_mode_equal_no_clocks(to_match, hdmi_mode))
-
 
2457
			return mode + 1;
-
 
2458
	}
-
 
2459
	return 0;
-
 
2460
}
2382
 
2461
 
2383
static int
2462
static int
2384
add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
2463
add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
2385
{
2464
{
2386
	struct drm_device *dev = connector->dev;
2465
	struct drm_device *dev = connector->dev;
Line 2395... Line 2474...
2395
	/*
2474
	/*
2396
	 * Go through all probed modes and create a new mode
2475
	 * Go through all probed modes and create a new mode
2397
	 * with the alternate clock for certain CEA modes.
2476
	 * with the alternate clock for certain CEA modes.
2398
	 */
2477
	 */
2399
	list_for_each_entry(mode, &connector->probed_modes, head) {
2478
	list_for_each_entry(mode, &connector->probed_modes, head) {
2400
		const struct drm_display_mode *cea_mode;
2479
		const struct drm_display_mode *cea_mode = NULL;
2401
		struct drm_display_mode *newmode;
2480
		struct drm_display_mode *newmode;
2402
		u8 cea_mode_idx = drm_match_cea_mode(mode) - 1;
2481
		u8 mode_idx = drm_match_cea_mode(mode) - 1;
2403
		unsigned int clock1, clock2;
2482
		unsigned int clock1, clock2;
Line 2404... Line 2483...
2404
 
2483
 
-
 
2484
		if (mode_idx < ARRAY_SIZE(edid_cea_modes)) {
-
 
2485
			cea_mode = &edid_cea_modes[mode_idx];
2405
		if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes))
2486
			clock2 = cea_mode_alternate_clock(cea_mode);
-
 
2487
		} else {
-
 
2488
			mode_idx = drm_match_hdmi_mode(mode) - 1;
-
 
2489
			if (mode_idx < ARRAY_SIZE(edid_4k_modes)) {
-
 
2490
				cea_mode = &edid_4k_modes[mode_idx];
-
 
2491
				clock2 = hdmi_mode_alternate_clock(cea_mode);
-
 
2492
			}
Line 2406... Line 2493...
2406
			continue;
2493
		}
-
 
2494
 
Line 2407... Line 2495...
2407
 
2495
		if (!cea_mode)
2408
		cea_mode = &edid_cea_modes[cea_mode_idx];
-
 
Line 2409... Line 2496...
2409
 
2496
			continue;
2410
		clock1 = cea_mode->clock;
2497
 
Line 2411... Line 2498...
2411
		clock2 = cea_mode_alternate_clock(cea_mode);
2498
		clock1 = cea_mode->clock;
Line 2440... Line 2527...
2440
 
2527
 
2441
	return modes;
2528
	return modes;
Line 2442... Line 2529...
2442
}
2529
}
2443
 
2530
 
2444
static int
2531
static int
2445
do_cea_modes (struct drm_connector *connector, u8 *db, u8 len)
2532
do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
-
 
2533
{
2446
{
2534
	struct drm_device *dev = connector->dev;
2447
	struct drm_device *dev = connector->dev;
2535
	const u8 *mode;
Line 2448... Line 2536...
2448
	u8 * mode, cea_mode;
2536
	u8 cea_mode;
2449
	int modes = 0;
2537
	int modes = 0;
2450
 
2538
 
Line 2463... Line 2551...
2463
	}
2551
	}
Line 2464... Line 2552...
2464
 
2552
 
2465
	return modes;
2553
	return modes;
Line -... Line 2554...
-
 
2554
}
-
 
2555
 
-
 
2556
/*
-
 
2557
 * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
-
 
2558
 * @connector: connector corresponding to the HDMI sink
-
 
2559
 * @db: start of the CEA vendor specific block
-
 
2560
 * @len: length of the CEA block payload, ie. one can access up to db[len]
-
 
2561
 *
-
 
2562
 * Parses the HDMI VSDB looking for modes to add to @connector.
-
 
2563
 */
-
 
2564
static int
-
 
2565
do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
-
 
2566
{
-
 
2567
	struct drm_device *dev = connector->dev;
-
 
2568
	int modes = 0, offset = 0, i;
-
 
2569
	u8 vic_len;
-
 
2570
 
-
 
2571
	if (len < 8)
-
 
2572
		goto out;
-
 
2573
 
-
 
2574
	/* no HDMI_Video_Present */
-
 
2575
	if (!(db[8] & (1 << 5)))
-
 
2576
		goto out;
-
 
2577
 
-
 
2578
	/* Latency_Fields_Present */
-
 
2579
	if (db[8] & (1 << 7))
-
 
2580
		offset += 2;
-
 
2581
 
-
 
2582
	/* I_Latency_Fields_Present */
-
 
2583
	if (db[8] & (1 << 6))
-
 
2584
		offset += 2;
-
 
2585
 
-
 
2586
	/* the declared length is not long enough for the 2 first bytes
-
 
2587
	 * of additional video format capabilities */
-
 
2588
	offset += 2;
-
 
2589
	if (len < (8 + offset))
-
 
2590
		goto out;
-
 
2591
 
-
 
2592
	vic_len = db[8 + offset] >> 5;
-
 
2593
 
-
 
2594
	for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
-
 
2595
		struct drm_display_mode *newmode;
-
 
2596
		u8 vic;
-
 
2597
 
-
 
2598
		vic = db[9 + offset + i];
-
 
2599
 
-
 
2600
		vic--; /* VICs start at 1 */
-
 
2601
		if (vic >= ARRAY_SIZE(edid_4k_modes)) {
-
 
2602
			DRM_ERROR("Unknown HDMI VIC: %d\n", vic);
-
 
2603
			continue;
-
 
2604
		}
-
 
2605
 
-
 
2606
		newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]);
-
 
2607
		if (!newmode)
-
 
2608
			continue;
-
 
2609
 
-
 
2610
		drm_mode_probed_add(connector, newmode);
-
 
2611
		modes++;
-
 
2612
	}
-
 
2613
 
-
 
2614
out:
-
 
2615
	return modes;
2466
}
2616
}
2467
 
2617
 
2468
static int
2618
static int
2469
cea_db_payload_len(const u8 *db)
2619
cea_db_payload_len(const u8 *db)
2470
{
2620
{
Line 2494... Line 2644...
2494
	if (*end < 4 || *end > 127)
2644
	if (*end < 4 || *end > 127)
2495
		return -ERANGE;
2645
		return -ERANGE;
2496
	return 0;
2646
	return 0;
2497
}
2647
}
Line -... Line 2648...
-
 
2648
 
-
 
2649
static bool cea_db_is_hdmi_vsdb(const u8 *db)
-
 
2650
{
-
 
2651
	int hdmi_id;
-
 
2652
 
-
 
2653
	if (cea_db_tag(db) != VENDOR_BLOCK)
-
 
2654
		return false;
-
 
2655
 
-
 
2656
	if (cea_db_payload_len(db) < 5)
-
 
2657
		return false;
-
 
2658
 
-
 
2659
	hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
-
 
2660
 
-
 
2661
	return hdmi_id == HDMI_IEEE_OUI;
-
 
2662
}
2498
 
2663
 
2499
#define for_each_cea_db(cea, i, start, end) \
2664
#define for_each_cea_db(cea, i, start, end) \
Line 2500... Line 2665...
2500
	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
2665
	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
2501
 
2666
 
2502
static int
2667
static int
2503
add_cea_modes(struct drm_connector *connector, struct edid *edid)
2668
add_cea_modes(struct drm_connector *connector, struct edid *edid)
-
 
2669
{
2504
{
2670
	const u8 *cea = drm_find_cea_extension(edid);
2505
	u8 * cea = drm_find_cea_extension(edid);
2671
	const u8 *db;
Line 2506... Line 2672...
2506
	u8 * db, dbl;
2672
	u8 dbl;
2507
	int modes = 0;
2673
	int modes = 0;
Line 2516... Line 2682...
2516
			db = &cea[i];
2682
			db = &cea[i];
2517
			dbl = cea_db_payload_len(db);
2683
			dbl = cea_db_payload_len(db);
Line 2518... Line 2684...
2518
 
2684
 
2519
			if (cea_db_tag(db) == VIDEO_BLOCK)
2685
			if (cea_db_tag(db) == VIDEO_BLOCK)
-
 
2686
				modes += do_cea_modes (connector, db+1, dbl);
-
 
2687
			else if (cea_db_is_hdmi_vsdb(db))
2520
				modes += do_cea_modes (connector, db+1, dbl);
2688
				modes += do_hdmi_vsdb_modes(connector, db, dbl);
2521
		}
2689
		}
Line 2522... Line 2690...
2522
	}
2690
	}
2523
 
2691
 
Line 2568... Line 2736...
2568
{
2736
{
2569
	if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME)
2737
	if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME)
2570
		*(u8 **)data = t->data.other_data.data.str.str;
2738
		*(u8 **)data = t->data.other_data.data.str.str;
2571
}
2739
}
Line 2572... Line -...
2572
 
-
 
2573
static bool cea_db_is_hdmi_vsdb(const u8 *db)
-
 
2574
{
-
 
2575
	int hdmi_id;
-
 
2576
 
-
 
2577
	if (cea_db_tag(db) != VENDOR_BLOCK)
-
 
2578
		return false;
-
 
2579
 
-
 
2580
	if (cea_db_payload_len(db) < 5)
-
 
2581
		return false;
-
 
2582
 
-
 
2583
	hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
-
 
2584
 
-
 
2585
	return hdmi_id == HDMI_IDENTIFIER;
-
 
2586
}
-
 
2587
 
2740
 
2588
/**
2741
/**
2589
 * drm_edid_to_eld - build ELD from EDID
2742
 * drm_edid_to_eld - build ELD from EDID
2590
 * @connector: connector corresponding to the HDMI/DP sink
2743
 * @connector: connector corresponding to the HDMI/DP sink
2591
 * @edid: EDID to parse
2744
 * @edid: EDID to parse
Line 2730... Line 2883...
2730
	return count;
2883
	return count;
2731
}
2884
}
2732
EXPORT_SYMBOL(drm_edid_to_sad);
2885
EXPORT_SYMBOL(drm_edid_to_sad);
Line 2733... Line 2886...
2733
 
2886
 
-
 
2887
/**
-
 
2888
 * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID
-
 
2889
 * @edid: EDID to parse
-
 
2890
 * @sadb: pointer to the speaker block
-
 
2891
 *
-
 
2892
 * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it.
-
 
2893
 * Note: returned pointer needs to be kfreed
-
 
2894
 *
-
 
2895
 * Return number of found Speaker Allocation Blocks or negative number on error.
-
 
2896
 */
-
 
2897
int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
-
 
2898
{
-
 
2899
	int count = 0;
-
 
2900
	int i, start, end, dbl;
-
 
2901
	const u8 *cea;
-
 
2902
 
-
 
2903
	cea = drm_find_cea_extension(edid);
-
 
2904
	if (!cea) {
-
 
2905
		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
-
 
2906
		return -ENOENT;
-
 
2907
	}
-
 
2908
 
-
 
2909
	if (cea_revision(cea) < 3) {
-
 
2910
		DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
-
 
2911
		return -ENOTSUPP;
-
 
2912
	}
-
 
2913
 
-
 
2914
	if (cea_db_offsets(cea, &start, &end)) {
-
 
2915
		DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
-
 
2916
		return -EPROTO;
-
 
2917
	}
-
 
2918
 
-
 
2919
	for_each_cea_db(cea, i, start, end) {
-
 
2920
		const u8 *db = &cea[i];
-
 
2921
 
-
 
2922
		if (cea_db_tag(db) == SPEAKER_BLOCK) {
-
 
2923
			dbl = cea_db_payload_len(db);
-
 
2924
 
-
 
2925
			/* Speaker Allocation Data Block */
-
 
2926
			if (dbl == 3) {
-
 
2927
				*sadb = kmalloc(dbl, GFP_KERNEL);
-
 
2928
				if (!*sadb)
-
 
2929
					return -ENOMEM;
-
 
2930
				memcpy(*sadb, &db[1], dbl);
-
 
2931
				count = dbl;
-
 
2932
				break;
-
 
2933
			}
-
 
2934
		}
-
 
2935
	}
-
 
2936
 
-
 
2937
	return count;
-
 
2938
}
-
 
2939
EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
-
 
2940
 
2734
/**
2941
/**
2735
 * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond
2942
 * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond
2736
 * @connector: connector associated with the HDMI/DP sink
2943
 * @connector: connector associated with the HDMI/DP sink
2737
 * @mode: the display mode
2944
 * @mode: the display mode
2738
 */
2945
 */
Line 3100... Line 3307...
3100
 
3307
 
3101
	err = hdmi_avi_infoframe_init(frame);
3308
	err = hdmi_avi_infoframe_init(frame);
3102
	if (err < 0)
3309
	if (err < 0)
Line -... Line 3310...
-
 
3310
		return err;
-
 
3311
 
-
 
3312
	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
3103
		return err;
3313
		frame->pixel_repeat = 1;
3104
 
-
 
3105
	frame->video_code = drm_match_cea_mode(mode);
-
 
Line 3106... Line 3314...
3106
	if (!frame->video_code)
3314
 
3107
		return 0;
3315
	frame->video_code = drm_match_cea_mode(mode);
Line 3108... Line 3316...
3108
 
3316
 
3109
	frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
3317
	frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
3110
	frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
3318
	frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
-
 
3319
 
-
 
3320
	return 0;
-
 
3321
}
-
 
3322
EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
-
 
3323
 
-
 
3324
/**
-
 
3325
 * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with
-
 
3326
 * data from a DRM display mode
-
 
3327
 * @frame: HDMI vendor infoframe
-
 
3328
 * @mode: DRM display mode
-
 
3329
 *
-
 
3330
 * Note that there's is a need to send HDMI vendor infoframes only when using a
-
 
3331
 * 4k or stereoscopic 3D mode. So when giving any other mode as input this
-
 
3332
 * function will return -EINVAL, error that can be safely ignored.
-
 
3333
 *
-
 
3334
 * Returns 0 on success or a negative error code on failure.
-
 
3335
 */
-
 
3336
int
-
 
3337
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
-
 
3338
					    const struct drm_display_mode *mode)
-
 
3339
{
-
 
3340
	int err;
-
 
3341
	u8 vic;
-
 
3342
 
-
 
3343
	if (!frame || !mode)
-
 
3344
		return -EINVAL;
-
 
3345
 
-
 
3346
	vic = drm_match_hdmi_mode(mode);
-
 
3347
	if (!vic)
-
 
3348
		return -EINVAL;
-
 
3349
 
-
 
3350
	err = hdmi_vendor_infoframe_init(frame);
-
 
3351
	if (err < 0)
-
 
3352
		return err;
-
 
3353
 
-
 
3354
	frame->vic = vic;