diff mbox

[MIPI,SEQ,PARSING,v3,06/13] drm/i915: Parsing VBT if size of VBT exceeds 6KB

Message ID 1448923632-16760-7-git-send-email-m.deepak@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Deepak M Nov. 30, 2015, 10:47 p.m. UTC
Currently the iomap for VBT works only if the size of the
VBT is less than 6KB, but if the size of the VBT exceeds
6KB than the physical address and the size of the VBT to
be iomapped is specified in the mailbox3 and is iomapped
accordingly.

v3: -Splitted the patch into small ones
    -Handeled memory unmap in intel_opregion_fini
    -removed the new file created for opregion macro`s

Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Deepak M <m.deepak@intel.com>
---
 drivers/gpu/drm/i915/intel_opregion.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

Comments

Kahola, Mika Dec. 11, 2015, 8:51 a.m. UTC | #1
When testing this patch on my BXT-M I received this error message

Hardware name: Intel Corp. Broxton M/RVP, BIOS
BXTM_IFWI_X64_R_2015_49_2_03 11/25/2015

[    0.000000] ------------[ cut here ]------------
[    0.000000] WARNING: CPU: 0 PID: 0 at drivers/iommu/dmar.c:829
warn_invalid_dmar+0x81/0xa0()
[    0.000000] Your BIOS is broken; DMAR reported at address ff000000
returns all ones!
[    0.000000] BIOS vendor: Intel Corp.; Ver:
BXTM_IFWI_X64_R_2015_49_2_03; Product Version: A1
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.4.0-rc3-bxt-p6
#1
[    0.000000] Hardware name: Intel Corp. Broxton M/RVP, BIOS
BXTM_IFWI_X64_R_2015_49_2_03 11/25/2015
[    0.000000]  ffffffff81cfa5a7 ffffffff81e03da0 ffffffff813f8609
ffffffff81e03de8
[    0.000000]  ffffffff81e03dd8 ffffffff8107c17e ffffffff830a600c
ffffffff830a60ec
[    0.000000]  00000000ff000000 ffffffffffffffff 000000000000017b
ffffffff81e03e38
[    0.000000] Call Trace:
[    0.000000]  [<ffffffff813f8609>] dump_stack+0x4e/0x85
[    0.000000]  [<ffffffff8107c17e>] warn_slowpath_common+0x9e/0xc0
[    0.000000]  [<ffffffff8107c234>] warn_slowpath_fmt_taint+0x44/0x50
[    0.000000]  [<ffffffff81f94950>] ? __acpi_map_table+0x13/0x1a
[    0.000000]  [<ffffffff81892113>] ? acpi_os_map_iomem+0x26/0x167
[    0.000000]  [<ffffffff814fb471>] warn_invalid_dmar+0x81/0xa0
[    0.000000]  [<ffffffff818923fc>] dmar_validate_one_drhd+0xac/0xc0
[    0.000000]  [<ffffffff814fb5cd>] dmar_walk_remapping_entries
+0x13d/0x180
[    0.000000]  [<ffffffff81fc77bc>] detect_intel_iommu+0x52/0xd1
[    0.000000]  [<ffffffff81892350>] ? acpi_os_unmap_memory+0x17/0x17
[    0.000000]  [<ffffffff81f8cd51>] pci_iommu_alloc+0x43/0x6c
[    0.000000]  [<ffffffff81f9b337>] mem_init+0x9/0x3e
[    0.000000]  [<ffffffff81f86def>] start_kernel+0x231/0x474
[    0.000000]  [<ffffffff81f868ed>] ? set_init_arg+0x57/0x57
[    0.000000]  [<ffffffff81f865ad>] x86_64_start_reservations+0x2a/0x2c
[    0.000000]  [<ffffffff81f86699>] x86_64_start_kernel+0xea/0xed
[    0.000000] ---[ end trace e354834df7810082 ]---

And later on

[   15.615809] IP: [<ffffffffa01a7d9c>] intel_opregion_setup+0x15c/0x420
[i915]
[   15.623687] PGD 0 
[   15.625909] Oops: 0000 [#1] PREEMPT SMP 
[   15.630246] Modules linked in: snd_seq_oss snd_seq_midi snd_rawmidi
snd_seq_midi_event i915(+)[   15.638805] sdhci-pci 0000:00:1c.0: power
 state changed by ACPI to D3cold

[   15.647060]  snd_seq i2c_algo_bit snd_seq_device drm_kms_helper
syscopyarea snd_timer sysfillrect sysimgblt fb_sys_fops drm intel_gtt
snd 
tpm_tis agpgart tpm fuse
[   15.663370] CPU: 3 PID: 341 Comm: systemd-udevd Tainted: G          I
4.4.0-rc3-bxt-p6 #1
[   15.672794] Hardware name: Intel Corp. Broxton M/RVP, BIOS
BXTM_IFWI_X64_R_2015_49_2_03 11/25/2015
[   15.672797] task: ffff8800791b4c80 ti: ffff880179e5c000 task.ti:
ffff880179e5c000
[   15.672875] RIP: 0010:[<ffffffffa01a7d9c>]  [<ffffffffa01a7d9c>]
intel_opregion_setup+0x15c/0x420 [i915]
[   15.672878] RSP: 0018:ffff880179e5f8f8  EFLAGS: 00010246
[   15.672880] RAX: 0000000000000000 RBX: ffff880079370000 RCX:
000000000000000f
[   15.672881] RDX: 000000000000000f RSI: ffffffffa0204a5c RDI:
ffff880179e5f917
[   15.672883] RBP: ffff880179e5f950 R08: 000000000000006d R09:
0000000000000000
[   15.672884] R10: ffff8800791b4c80 R11: ffff8800791b54d8 R12:
ffffc900000b8018
[   15.672885] R13: ffff880178256000 R14: ffff880179e5facc R15:
0000000000000000
[   15.672888] FS:  00007f6693826880(0000) GS:ffff88017fd80000(0000)
knlGS:0000000000000000
[   15.672889] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   15.672891] CR2: 0000000000000014 CR3: 000000017812a000 CR4:
00000000003406e0
[   15.672892] Stack:
[   15.672897]  00000000000018b8 ffff8800793717c8 79d77018a01e5bb0
49ffffffa01e5c30
[   15.672900]  706172476c65746e 086d654d73636968 ffff880079370000
ffff880178256000
[   15.672904]  0000000000000048 ffff880179e5facc ffff880079370000
ffff880179e5fb00
[   15.672905] Call Trace:
[   15.672975]  [<ffffffffa01d23ac>] i915_driver_load+0xa7c/0x15b0
[i915]
[   15.673007]  [<ffffffffa009928f>] drm_dev_register+0x6f/0xb0 [drm]
[   15.673025]  [<ffffffffa009b81a>] drm_get_pci_dev+0x10a/0x1d0 [drm]
[   15.673034]  [<ffffffff818988b1>] ? _raw_spin_unlock_irqrestore
+0x51/0x70
[   15.673074]  [<ffffffffa0118249>] i915_pci_probe+0x49/0x50 [i915]
[   15.673082]  [<ffffffff81437f50>] pci_device_probe+0x80/0xf0
[   15.673088]  [<ffffffff8150d3b8>] driver_probe_device+0x168/0x3d0
[   15.673091]  [<ffffffff8150d686>] __driver_attach+0x66/0x90
[   15.673093]  [<ffffffff8150d620>] ? driver_probe_device+0x3d0/0x3d0
[   15.673099]  [<ffffffff8150b15b>] bus_for_each_dev+0x5b/0xa0
[   15.673102]  [<ffffffff8150cd8e>] driver_attach+0x1e/0x20
[   15.673105]  [<ffffffff8150c771>] bus_add_driver+0x151/0x270
[   15.673108]  [<ffffffff8150e23c>] driver_register+0x8c/0xd0
[   15.673113]  [<ffffffff81436620>] __pci_register_driver+0x60/0x70
[   15.673130]  [<ffffffffa009b938>] drm_pci_init+0x58/0xf0 [drm]
[   15.673136]  [<ffffffff810cd27d>] ? trace_hardirqs_on+0xd/0x10
[   15.673139]  [<ffffffffa023f000>] ? 0xffffffffa023f000
[   15.673179]  [<ffffffffa023f094>] i915_init+0x94/0x9b [i915]
[   15.673185]  [<ffffffff81000436>] do_one_initcall+0x106/0x1d0
[   15.673191]  [<ffffffff810e93ee>] ? rcu_read_lock_sched_held
+0x6e/0xa0
[   15.673196]  [<ffffffff811d9a21>] ? kmem_cache_alloc_trace
+0x1c1/0x230
[   15.673203]  [<ffffffff8118bd6d>] do_init_module+0x60/0x1ea
[   15.673209]  [<ffffffff811107e0>] load_module+0x1df0/0x25a0
[   15.673212]  [<ffffffff8110c900>] ? store_uevent+0x40/0x40
[   15.673217]  [<ffffffff8110d0e5>] ? copy_module_from_fd.isra.38
+0xa5/0x140
[   15.673221]  [<ffffffff8111117f>] SyS_finit_module+0x8f/0xa0
[   15.673226]  [<ffffffff8189915b>] entry_SYSCALL_64_fastpath+0x16/0x73
[   15.673275] Code: 5c f2 ff 02 0f 84 aa 02 00 00 48 c7 c6 6d 4a 20 a0
48 c7 c7 50 26 1e a0 31 c0 e8 30 11 ef ff e9 90 02 00 00 48 8b 83 30 
96 00 00 <83> 78 14 01 76 33 48 8b 83 50 96 00 00 48 8b b8 ba 00 00 00
48 
[   15.673332] RIP  [<ffffffffa01a7d9c>] intel_opregion_setup
+0x15c/0x420 [i915]
[   15.673333]  RSP <ffff880179e5f8f8>
[   15.673334] CR2: 0000000000000014
[   15.673339] ---[ end trace e354834df7810084 ]---


On Tue, 2015-12-01 at 04:17 +0530, Deepak M wrote:
> Currently the iomap for VBT works only if the size of the
> VBT is less than 6KB, but if the size of the VBT exceeds
> 6KB than the physical address and the size of the VBT to
> be iomapped is specified in the mailbox3 and is iomapped
> accordingly.
> 
> v3: -Splitted the patch into small ones
>     -Handeled memory unmap in intel_opregion_fini
>     -removed the new file created for opregion macro`s
> 
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Deepak M <m.deepak@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_opregion.c | 33 +++++++++++++++++++++++++++------
>  1 file changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index 7908a1d..b3a5709 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -856,6 +856,8 @@ void intel_opregion_fini(struct drm_device *dev)
>  	}
>  
>  	/* just clear all opregion memory pointers now */
> +	if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
> +		memunmap(opregion->vbt);
>  	memunmap(opregion->header);
>  	opregion->header = NULL;
>  	opregion->acpi = NULL;
> @@ -933,7 +935,8 @@ int intel_opregion_setup(struct drm_device *dev)
>  	char buf[sizeof(OPREGION_SIGNATURE)];
>  	const struct vbt_header *vbt = NULL;
>  	int err = 0;
> -	void *base;
> +	void *base, *vbt_base;
> +	size_t size;
>  
>  	BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
>  	BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100);
> @@ -963,19 +966,37 @@ int intel_opregion_setup(struct drm_device *dev)
>  		goto err_out;
>  	}
>  
> -	vbt = validate_vbt(base + OPREGION_VBT_OFFSET,
> -				MAILBOX_4_SIZE, "OpRegion");
> +	/*
> +	 * Non-zero value in rvda field is an indication to driver that a
> +	 * valid Raw VBT is stored in that address and driver should not refer
> +	 * to mailbox4 for getting VBT.
> +	 */
> +	if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda) {
> +		size = opregion->asle->rvds;
> +		vbt_base = memremap(opregion->asle->rvda,
> +				size, MEMREMAP_WB);
> +	} else {
> +		size = MAILBOX_4_SIZE;
> +		vbt_base = base + OPREGION_VBT_OFFSET;
> +	}
> +
> +	vbt = validate_vbt(vbt_base, size, "OpRegion");
>  
>  	if (vbt == NULL) {
>  		err = -EINVAL;
>  		goto err_out;
>  	}
>  
> -	vbt = (const struct vbt_header *)(base + OPREGION_VBT_OFFSET);
> -	dev_priv->opregion.vbt_size = vbt->vbt_size;
> +	/* Assigning the vbt_size based on the VBT location */
> +	if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
> +		dev_priv->opregion.vbt_size = opregion->asle->rvds;
> +	else {
> +		vbt = (const struct vbt_header *)(base + OPREGION_VBT_OFFSET);
> +		dev_priv->opregion.vbt_size = vbt->vbt_size;
> +	}
>  
>  	opregion->header = base;
> -	opregion->vbt = base + OPREGION_VBT_OFFSET;
> +	opregion->vbt = vbt_base;
>  
>  	opregion->lid_state = base + ACPI_CLID;
>  	opregion->asle_ext = base + OPREGION_ASLE_EXT_OFFSET;
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 7908a1d..b3a5709 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -856,6 +856,8 @@  void intel_opregion_fini(struct drm_device *dev)
 	}
 
 	/* just clear all opregion memory pointers now */
+	if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
+		memunmap(opregion->vbt);
 	memunmap(opregion->header);
 	opregion->header = NULL;
 	opregion->acpi = NULL;
@@ -933,7 +935,8 @@  int intel_opregion_setup(struct drm_device *dev)
 	char buf[sizeof(OPREGION_SIGNATURE)];
 	const struct vbt_header *vbt = NULL;
 	int err = 0;
-	void *base;
+	void *base, *vbt_base;
+	size_t size;
 
 	BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
 	BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100);
@@ -963,19 +966,37 @@  int intel_opregion_setup(struct drm_device *dev)
 		goto err_out;
 	}
 
-	vbt = validate_vbt(base + OPREGION_VBT_OFFSET,
-				MAILBOX_4_SIZE, "OpRegion");
+	/*
+	 * Non-zero value in rvda field is an indication to driver that a
+	 * valid Raw VBT is stored in that address and driver should not refer
+	 * to mailbox4 for getting VBT.
+	 */
+	if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda) {
+		size = opregion->asle->rvds;
+		vbt_base = memremap(opregion->asle->rvda,
+				size, MEMREMAP_WB);
+	} else {
+		size = MAILBOX_4_SIZE;
+		vbt_base = base + OPREGION_VBT_OFFSET;
+	}
+
+	vbt = validate_vbt(vbt_base, size, "OpRegion");
 
 	if (vbt == NULL) {
 		err = -EINVAL;
 		goto err_out;
 	}
 
-	vbt = (const struct vbt_header *)(base + OPREGION_VBT_OFFSET);
-	dev_priv->opregion.vbt_size = vbt->vbt_size;
+	/* Assigning the vbt_size based on the VBT location */
+	if (opregion->header->opregion_ver >= 2 && opregion->asle->rvda)
+		dev_priv->opregion.vbt_size = opregion->asle->rvds;
+	else {
+		vbt = (const struct vbt_header *)(base + OPREGION_VBT_OFFSET);
+		dev_priv->opregion.vbt_size = vbt->vbt_size;
+	}
 
 	opregion->header = base;
-	opregion->vbt = base + OPREGION_VBT_OFFSET;
+	opregion->vbt = vbt_base;
 
 	opregion->lid_state = base + ACPI_CLID;
 	opregion->asle_ext = base + OPREGION_ASLE_EXT_OFFSET;