Subversion Repositories Kolibri OS

Rev

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

Rev 6660 Rev 6937
Line 22... Line 22...
22
 *
22
 *
23
 * Authors:
23
 * Authors:
24
 *    Eric Anholt 
24
 *    Eric Anholt 
25
 *
25
 *
26
 */
26
 */
27
#include 
-
 
-
 
27
 
28
#include 
28
#include 
29
#include 
29
#include 
30
#include 
30
#include 
31
#include "i915_drv.h"
31
#include "i915_drv.h"
32
#include "intel_bios.h"
32
#include "intel_bios.h"
Line 330... Line 330...
330
 
330
 
331
	DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n");
331
	DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n");
332
	drm_mode_debug_printmodeline(panel_fixed_mode);
332
	drm_mode_debug_printmodeline(panel_fixed_mode);
Line 333... Line 333...
333
}
333
}
334
 
334
 
335
static int intel_bios_ssc_frequency(struct drm_device *dev,
335
static int intel_bios_ssc_frequency(struct drm_i915_private *dev_priv,
336
				    bool alternate)
336
				    bool alternate)
337
{
337
{
338
	switch (INTEL_INFO(dev)->gen) {
338
	switch (INTEL_INFO(dev_priv)->gen) {
339
	case 2:
339
	case 2:
340
		return alternate ? 66667 : 48000;
340
		return alternate ? 66667 : 48000;
341
	case 3:
341
	case 3:
Line 348... Line 348...
348
 
348
 
349
static void
349
static void
350
parse_general_features(struct drm_i915_private *dev_priv,
350
parse_general_features(struct drm_i915_private *dev_priv,
351
		       const struct bdb_header *bdb)
351
		       const struct bdb_header *bdb)
352
{
-
 
353
	struct drm_device *dev = dev_priv->dev;
352
{
Line 354... Line 353...
354
	const struct bdb_general_features *general;
353
	const struct bdb_general_features *general;
355
 
354
 
-
 
355
	general = find_section(bdb, BDB_GENERAL_FEATURES);
-
 
356
	if (!general)
356
	general = find_section(bdb, BDB_GENERAL_FEATURES);
357
		return;
-
 
358
 
-
 
359
		dev_priv->vbt.int_tv_support = general->int_tv_support;
-
 
360
	/* int_crt_support can't be trusted on earlier platforms */
357
	if (general) {
361
	if (bdb->version >= 155 &&
358
		dev_priv->vbt.int_tv_support = general->int_tv_support;
362
	    (HAS_DDI(dev_priv) || IS_VALLEYVIEW(dev_priv)))
359
		dev_priv->vbt.int_crt_support = general->int_crt_support;
363
		dev_priv->vbt.int_crt_support = general->int_crt_support;
360
		dev_priv->vbt.lvds_use_ssc = general->enable_ssc;
364
		dev_priv->vbt.lvds_use_ssc = general->enable_ssc;
361
		dev_priv->vbt.lvds_ssc_freq =
365
		dev_priv->vbt.lvds_ssc_freq =
362
			intel_bios_ssc_frequency(dev, general->ssc_freq);
366
		intel_bios_ssc_frequency(dev_priv, general->ssc_freq);
363
		dev_priv->vbt.display_clock_mode = general->display_clock_mode;
367
		dev_priv->vbt.display_clock_mode = general->display_clock_mode;
364
		dev_priv->vbt.fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
368
		dev_priv->vbt.fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
365
		DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n",
369
		DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n",
366
			      dev_priv->vbt.int_tv_support,
370
			      dev_priv->vbt.int_tv_support,
367
			      dev_priv->vbt.int_crt_support,
371
			      dev_priv->vbt.int_crt_support,
368
			      dev_priv->vbt.lvds_use_ssc,
372
			      dev_priv->vbt.lvds_use_ssc,
369
			      dev_priv->vbt.lvds_ssc_freq,
373
			      dev_priv->vbt.lvds_ssc_freq,
370
			      dev_priv->vbt.display_clock_mode,
374
			      dev_priv->vbt.display_clock_mode,
371
			      dev_priv->vbt.fdi_rx_polarity_inverted);
-
 
Line 372... Line 375...
372
	}
375
			      dev_priv->vbt.fdi_rx_polarity_inverted);
373
}
376
	}
374
 
377
 
375
static void
378
static void
Line 1052... Line 1055...
1052
}
1055
}
Line 1053... Line 1056...
1053
 
1056
 
1054
static void parse_ddi_ports(struct drm_i915_private *dev_priv,
1057
static void parse_ddi_ports(struct drm_i915_private *dev_priv,
1055
			    const struct bdb_header *bdb)
1058
			    const struct bdb_header *bdb)
1056
{
-
 
1057
	struct drm_device *dev = dev_priv->dev;
1059
{
Line 1058... Line 1060...
1058
	enum port port;
1060
	enum port port;
1059
 
1061
 
Line 1060... Line 1062...
1060
	if (!HAS_DDI(dev))
1062
	if (!HAS_DDI(dev_priv))
1061
		return;
1063
		return;
Line 1168... Line 1170...
1168
}
1170
}
Line 1169... Line 1171...
1169
 
1171
 
1170
static void
1172
static void
1171
init_vbt_defaults(struct drm_i915_private *dev_priv)
1173
init_vbt_defaults(struct drm_i915_private *dev_priv)
1172
{
-
 
1173
	struct drm_device *dev = dev_priv->dev;
1174
{
Line 1174... Line 1175...
1174
	enum port port;
1175
	enum port port;
Line 1175... Line 1176...
1175
 
1176
 
Line 1193... Line 1194...
1193
	dev_priv->vbt.lvds_use_ssc = 1;
1194
	dev_priv->vbt.lvds_use_ssc = 1;
1194
	/*
1195
	/*
1195
	 * Core/SandyBridge/IvyBridge use alternative (120MHz) reference
1196
	 * Core/SandyBridge/IvyBridge use alternative (120MHz) reference
1196
	 * clock for LVDS.
1197
	 * clock for LVDS.
1197
	 */
1198
	 */
1198
	dev_priv->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(dev,
1199
	dev_priv->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(dev_priv,
1199
			!HAS_PCH_SPLIT(dev));
1200
			!HAS_PCH_SPLIT(dev_priv));
1200
	DRM_DEBUG_KMS("Set default to SSC at %d kHz\n", dev_priv->vbt.lvds_ssc_freq);
1201
	DRM_DEBUG_KMS("Set default to SSC at %d kHz\n", dev_priv->vbt.lvds_ssc_freq);
Line 1201... Line 1202...
1201
 
1202
 
1202
	for (port = PORT_A; port < I915_MAX_PORTS; port++) {
1203
	for (port = PORT_A; port < I915_MAX_PORTS; port++) {
1203
		struct ddi_vbt_port_info *info =
1204
		struct ddi_vbt_port_info *info =
Line 1209... Line 1210...
1209
		info->supports_hdmi = info->supports_dvi;
1210
		info->supports_hdmi = info->supports_dvi;
1210
		info->supports_dp = (port != PORT_E);
1211
		info->supports_dp = (port != PORT_E);
1211
	}
1212
	}
1212
}
1213
}
Line 1213... Line 1214...
1213
 
1214
 
1214
static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
1215
static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
1215
{
-
 
1216
	DRM_DEBUG_KMS("Falling back to manually reading VBT from "
-
 
1217
		      "VBIOS ROM for %s\n",
1216
{
1218
		      id->ident);
-
 
1219
	return 1;
-
 
1220
}
-
 
1221
 
-
 
1222
static const struct dmi_system_id intel_no_opregion_vbt[] = {
-
 
1223
	{
-
 
1224
		.callback = intel_no_opregion_vbt_callback,
-
 
1225
		.ident = "ThinkCentre A57",
-
 
1226
		.matches = {
-
 
1227
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-
 
1228
			DMI_MATCH(DMI_PRODUCT_NAME, "97027RG"),
-
 
1229
		},
-
 
1230
	},
-
 
1231
	{ }
-
 
Line -... Line 1217...
-
 
1217
	const void *_vbt = vbt;
-
 
1218
 
-
 
1219
	return _vbt + vbt->bdb_offset;
-
 
1220
}
1232
};
1221
 
-
 
1222
/**
1233
 
1223
 * intel_bios_is_valid_vbt - does the given buffer contain a valid VBT
-
 
1224
 * @buf:	pointer to a buffer to validate
1234
static const struct bdb_header *validate_vbt(const void *base,
1225
 * @size:	size of the buffer
-
 
1226
 *
1235
					     size_t size,
1227
 * Returns true on valid VBT.
1236
					     const void *_vbt,
1228
 */
1237
					     const char *source)
-
 
1238
{
1229
bool intel_bios_is_valid_vbt(const void *buf, size_t size)
1239
	size_t offset = _vbt - base;
1230
	{
Line -... Line 1231...
-
 
1231
	const struct vbt_header *vbt = buf;
-
 
1232
	const struct bdb_header *bdb;
-
 
1233
 
1240
	const struct vbt_header *vbt = _vbt;
1234
	if (!vbt)
1241
	const struct bdb_header *bdb;
1235
		return false;
1242
 
1236
 
1243
	if (offset + sizeof(struct vbt_header) > size) {
1237
	if (sizeof(struct vbt_header) > size) {
Line 1244... Line 1238...
1244
		DRM_DEBUG_DRIVER("VBT header incomplete\n");
1238
		DRM_DEBUG_DRIVER("VBT header incomplete\n");
1245
		return NULL;
1239
		return false;
1246
	}
1240
	}
1247
 
1241
 
Line 1248... Line -...
1248
	if (memcmp(vbt->signature, "$VBT", 4)) {
-
 
1249
		DRM_DEBUG_DRIVER("VBT invalid signature\n");
1242
	if (memcmp(vbt->signature, "$VBT", 4)) {
1250
		return NULL;
1243
		DRM_DEBUG_DRIVER("VBT invalid signature\n");
1251
	}
1244
		return false;
1252
 
1245
	}
Line 1253... Line 1246...
1253
	offset += vbt->bdb_offset;
1246
 
1254
	if (offset + sizeof(struct bdb_header) > size) {
1247
	if (vbt->bdb_offset + sizeof(struct bdb_header) > size) {
1255
		DRM_DEBUG_DRIVER("BDB header incomplete\n");
1248
		DRM_DEBUG_DRIVER("BDB header incomplete\n");
1256
		return NULL;
1249
		return false;
1257
	}
1250
	}
Line 1258... Line -...
1258
 
-
 
1259
	bdb = base + offset;
-
 
1260
	if (offset + bdb->bdb_size > size) {
1251
 
1261
		DRM_DEBUG_DRIVER("BDB incomplete\n");
1252
	bdb = get_bdb_header(vbt);
Line 1262... Line 1253...
1262
		return NULL;
1253
	if (vbt->bdb_offset + bdb->bdb_size > size) {
1263
	}
1254
		DRM_DEBUG_DRIVER("BDB incomplete\n");
1264
 
-
 
1265
	DRM_DEBUG_KMS("Using VBT from %s: %20s\n",
1255
		return false;
Line 1266... Line 1256...
1266
		      source, vbt->signature);
1256
	}
1267
	return bdb;
1257
 
-
 
1258
	return vbt;
-
 
1259
}
1268
}
1260
 
-
 
1261
static const struct vbt_header *find_vbt(void __iomem *bios, size_t size)
-
 
1262
{
1269
 
1263
	size_t i;
1270
static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
1264
 
1271
{
1265
	/* Scour memory looking for the VBT signature. */
1272
	const struct bdb_header *bdb = NULL;
-
 
1273
	size_t i;
-
 
1274
 
1266
	for (i = 0; i + 4 < size; i++) {
1275
	/* Scour memory looking for the VBT signature. */
1267
		void *vbt;
-
 
1268
 
-
 
1269
		if (ioread32(bios + i) != *((const u32 *) "$VBT"))
Line 1276... Line -...
1276
	for (i = 0; i + 4 < size; i++) {
-
 
1277
		if (ioread32(bios + i) == *((const u32 *) "$VBT")) {
1270
			continue;
1278
			/*
1271
 
1279
			 * This is the one place where we explicitly discard the
-
 
Line 1280... Line 1272...
1280
			 * address space (__iomem) of the BIOS/VBT. From now on
1272
			/*
1281
			 * everything is based on 'base', and treated as regular
1273
		 * This is the one place where we explicitly discard the address
Line 1282... Line 1274...
1282
			 * memory.
1274
		 * space (__iomem) of the BIOS/VBT.
1283
			 */
1275
			 */
1284
			void *_bios = (void __force *) bios;
1276
		vbt = (void __force *) bios + i;
1285
 
1277
		if (intel_bios_is_valid_vbt(vbt, size - i))
1286
			bdb = validate_vbt(_bios, size, _bios + i, "PCI ROM");
1278
			return vbt;
1287
			break;
1279
 
1288
		}
1280
			break;
1289
	}
1281
		}
1290
 
1282
 
1291
	return bdb;
1283
	return NULL;
1292
}
1284
}
1293
 
1285
 
1294
/**
1286
/**
1295
 * intel_parse_bios - find VBT and initialize settings from the BIOS
1287
 * intel_bios_init - find VBT and initialize settings from the BIOS
1296
 * @dev: DRM device
1288
 * @dev: DRM device
1297
 *
1289
 *
Line 1298... Line 1290...
1298
 * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
1290
 * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
1299
 * to appropriate values.
1291
 * to appropriate values.
Line 1300... Line 1292...
1300
 *
1292
 *
Line 1301... Line -...
1301
 * Returns 0 on success, nonzero on failure.
-
 
1302
 */
-
 
1303
int
-
 
1304
intel_parse_bios(struct drm_device *dev)
-
 
1305
{
-
 
1306
	struct drm_i915_private *dev_priv = dev->dev_private;
1293
 * Returns 0 on success, nonzero on failure.
1307
	struct pci_dev *pdev = dev->pdev;
1294
 */
Line 1308... Line 1295...
1308
	const struct bdb_header *bdb = NULL;
1295
int
1309
	u8 __iomem *bios = NULL;
1296
intel_bios_init(struct drm_i915_private *dev_priv)
1310
 
1297
{
Line 1311... Line 1298...
1311
	if (HAS_PCH_NOP(dev))
1298
	struct pci_dev *pdev = dev_priv->dev->pdev;
1312
		return -ENODEV;
1299
	const struct vbt_header *vbt = dev_priv->opregion.vbt;
1313
 
1300
	const struct bdb_header *bdb;
1314
	init_vbt_defaults(dev_priv);
1301
	u8 __iomem *bios = NULL;
1315
 
1302
 
-
 
1303
	if (HAS_PCH_NOP(dev_priv))
-
 
1304
		return -ENODEV;
1316
	/* XXX Should this validation be moved to intel_opregion.c? */
1305
 
Line -... Line 1306...
-
 
1306
	init_vbt_defaults(dev_priv);
-
 
1307
 
-
 
1308
	if (!vbt) {
-
 
1309
		size_t size;
-
 
1310
 
1317
	if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt)
1311
		bios = pci_map_rom(pdev, &size);
1318
		bdb = validate_vbt(dev_priv->opregion.header, OPREGION_SIZE,
1312
		if (!bios)
1319
				   dev_priv->opregion.vbt, "OpRegion");
1313
			return -1;
1320
 
1314
 
1321
	if (bdb == NULL) {
1315
		vbt = find_vbt(bios, size);
Line 1349... Line 1343...
1349
	if (bios)
1343
	if (bios)
1350
		pci_unmap_rom(pdev, bios);
1344
		pci_unmap_rom(pdev, bios);
Line 1351... Line 1345...
1351
 
1345
 
1352
	return 0;
1346
	return 0;
1353
}
-
 
1354
 
-
 
1355
/**
-
 
1356
 * intel_bios_is_port_present - is the specified digital port present
-
 
1357
 * @dev_priv:	i915 device instance
-
 
1358
 * @port:	port to check
-
 
1359
 *
-
 
1360
 * Return true if the device in %port is present.
-
 
1361
 */
-
 
1362
bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port)
-
 
1363
{
-
 
1364
	static const struct {
-
 
1365
		u16 dp, hdmi;
-
 
1366
	} port_mapping[] = {
-
 
1367
		[PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
-
 
1368
		[PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
-
 
1369
		[PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
-
 
1370
		[PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
-
 
1371
	};
-
 
1372
	int i;
-
 
1373
 
-
 
1374
	/* FIXME maybe deal with port A as well? */
-
 
1375
	if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping))
-
 
1376
		return false;
-
 
1377
 
-
 
1378
	if (!dev_priv->vbt.child_dev_num)
-
 
1379
		return false;
-
 
1380
 
-
 
1381
	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
-
 
1382
		const union child_device_config *p_child =
-
 
1383
			&dev_priv->vbt.child_dev[i];
-
 
1384
		if ((p_child->common.dvo_port == port_mapping[port].dp ||
-
 
1385
		     p_child->common.dvo_port == port_mapping[port].hdmi) &&
-
 
1386
		    (p_child->common.device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING |
-
 
1387
						    DEVICE_TYPE_DISPLAYPORT_OUTPUT)))
-
 
1388
			return true;
-
 
1389
	}
-
 
1390
 
-
 
1391
	return false;
-