changes since v1: - added my Signed-Offs - removed additional "From"s - change cover letter to motivate need for patch1
This fixes the following problem which was seen on a Tigerlake running Debian 10 with a 5.10 kernel. The fix is in the second patch while the first patch just makes sure the latter one does apply.
[ 111.408631] Missing case (val == 65535) [ 111.408698] WARNING: CPU: 2 PID: 446 at drivers/gpu/drm/i915/intel_dram.c:95 skl_dram_get_dimm_info+0x72/0x1a0 [i915] [ 111.408699] Modules linked in: intel_powerclamp coretemp i915(+) joydev kvm_intel kvm hid_generic irqbypass crc32_pclmul snd_hda_intel ghash_clmulni_intel snd_intel_dspcfg snd_hda_codec aesni_intel glue_helper crypto_simd cryptd snd_hwdep snd_hda_core drm_kms_helper uas snd_pcm usb_storage intel_cstate mei_wdt mei_hdcp snd_timer scsi_mod usbhid hid cec wdat_wdt snd mei_me evdev mei intel_uncore rc_core watchdog pcspkr soundcore video acpi_pad acpi_tad button drm fuse configfs loop(+) efi_pstore efivarfs ip_tables x_tables autofs4 ext4 crc32c_generic crc16 mbcache jbd2 dm_mod xhci_pci xhci_hcd marvell dwmac_intel stmmac igb e1000e usbcore nvme nvme_core pcs_xpcs phylink libphy i2c_algo_bit t10_pi dca crc_t10dif crct10dif_generic intel_lpss_pci ptp vmd intel_lpss i2c_i801 crct10dif_pclmul pps_core crct10dif_common idma64 usb_common crc32c_intel i2c_smbus [ 111.408755] CPU: 2 PID: 446 Comm: (udev-worker) Not tainted 5.10.180 #2 [ 111.408756] Hardware name: SIEMENS AG SIMATIC IPC427G/no information, BIOS T29.01.02.D3.0 10/11/2022 [ 111.408797] RIP: 0010:skl_dram_get_dimm_info+0x72/0x1a0 [i915] [ 111.408799] Code: 01 00 00 0f 84 31 01 00 00 66 3d 00 01 0f 84 27 01 00 00 41 0f b7 d0 48 c7 c6 ba 81 7c c1 48 c7 c7 be 81 7c c1 e8 d2 75 89 fa <0f> 0b c6 45 01 00 44 0f b6 4d 00 31 f6 b9 01 00 00 00 c1 fb 09 83 [ 111.408801] RSP: 0018:ffffa23a40b53b10 EFLAGS: 00010286 [ 111.408802] RAX: 0000000000000000 RBX: 000000000000ffff RCX: 0000000000000027 [ 111.408803] RDX: ffff947b278a0908 RSI: 0000000000000001 RDI: ffff947b278a0900 [ 111.408804] RBP: ffffa23a40b53b78 R08: 0000000000000000 R09: ffffa23a40b53920 [ 111.408805] R10: ffffa23a40b53918 R11: 0000000000000003 R12: 0000000000000000 [ 111.408806] R13: 000000000000004c R14: ffff9479b1a00000 R15: ffff9479b1a00000 [ 111.408808] FS: 00007ff9626478c0(0000) GS:ffff947b27880000(0000) knlGS:0000000000000000 [ 111.408809] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 111.408810] CR2: 0000555753cbf15c CR3: 0000000108432002 CR4: 0000000000770ee0 [ 111.408810] PKRU: 55555554 [ 111.408811] Call Trace: [ 111.408854] skl_dram_get_channel_info+0x24/0x160 [i915] [ 111.408892] intel_dram_detect+0xef/0x630 [i915] [ 111.408931] i915_driver_probe+0xb18/0xc40 [i915] [ 111.408969] ? i915_pci_probe+0x3f/0x160 [i915] [ 111.408973] local_pci_probe+0x3b/0x80 [ 111.408975] pci_device_probe+0xfc/0x1b0 [ 111.408979] really_probe+0x26e/0x460 [ 111.408981] driver_probe_device+0xb4/0x100 [ 111.408983] device_driver_attach+0xa9/0xb0 [ 111.408984] ? device_driver_attach+0xb0/0xb0 [ 111.408985] __driver_attach+0xa1/0x140 [ 111.408987] ? device_driver_attach+0xb0/0xb0 [ 111.408989] bus_for_each_dev+0x84/0xd0 [ 111.408991] bus_add_driver+0x13e/0x200 [ 111.408993] driver_register+0x89/0xe0 [ 111.409036] i915_init+0x60/0x75 [i915] [ 111.409038] ? 0xffffffffc18b8000 [ 111.409041] do_one_initcall+0x56/0x1f0 [ 111.409044] do_init_module+0x4a/0x240 [ 111.409047] __do_sys_finit_module+0xaa/0x110 [ 111.409050] do_syscall_64+0x30/0x40 [ 111.409053] entry_SYSCALL_64_after_hwframe+0x61/0xc6 [ 111.409054] RIP: 0033:0x7ff962d534f9 [ 111.409056] Code: 08 89 e8 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d d7 08 0d 00 f7 d8 64 89 01 48 [ 111.409057] RSP: 002b:00007fff57caf5d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 111.409058] RAX: ffffffffffffffda RBX: 0000555753cad120 RCX: 00007ff962d534f9 [ 111.409059] RDX: 0000000000000000 RSI: 00007ff962ee6efd RDI: 0000000000000010 [ 111.409060] RBP: 00007ff962ee6efd R08: 0000000000000000 R09: 0000555753c7a320 [ 111.409061] R10: 0000000000000010 R11: 0000000000000246 R12: 0000000000020000 [ 111.409062] R13: 0000000000000000 R14: 0000555753ca4f30 R15: 0000555752d40e4f [ 111.409064] ---[ end trace 2da6ec0bd6f7c3a1 ]---
José Roberto de Souza (1): drm/i915/gen11+: Only load DRAM information from pcode
Matt Roper (1): drm/i915/dg1: Wait for pcode/uncore handshake at startup
drivers/gpu/drm/i915/display/intel_bw.c | 80 +++--------------------- drivers/gpu/drm/i915/i915_drv.c | 4 ++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 3 + drivers/gpu/drm/i915/intel_dram.c | 82 ++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_sideband.c | 15 +++++ drivers/gpu/drm/i915/intel_sideband.h | 2 + 7 files changed, 114 insertions(+), 73 deletions(-)
From: Matt Roper matthew.d.roper@intel.com
[ Upstream commit f9c730ede7d3f40900cb493890d94d868ff2f00f ]
DG1 does some additional pcode/uncore handshaking at boot time; this handshaking must complete before various other pcode commands are effective and before general work is submitted to the GPU. We need to poll a new pcode mailbox during startup until it reports that this handshaking is complete.
The bspec doesn't give guidance on how long we may need to wait for this handshaking to complete. For now, let's just set a really long timeout; if we still don't get a completion status by the end of that timeout, we'll just continue on and hope for the best.
v2 (Lucas): Rename macros to make clear the relation between command and result (requested by José)
Bspec: 52065 Cc: Clinton Taylor Clinton.A.Taylor@intel.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Radhakrishna Sripada radhakrishna.sripada@intel.com Signed-off-by: Matt Roper matthew.d.roper@intel.com Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com Reviewed-by: José Roberto de Souza jose.souza@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20201001063917.3133475-2-lucas... Signed-off-by: Henning Schild henning.schild@siemens.com --- drivers/gpu/drm/i915/i915_drv.c | 3 +++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_sideband.c | 15 +++++++++++++++ drivers/gpu/drm/i915/intel_sideband.h | 2 ++ 4 files changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 382cf048eefe..f72e3bb4ee9a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -84,6 +84,7 @@ #include "intel_gvt.h" #include "intel_memory_region.h" #include "intel_pm.h" +#include "intel_sideband.h" #include "vlv_suspend.h"
static struct drm_driver driver; @@ -614,6 +615,8 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) */ intel_dram_detect(dev_priv);
+ intel_pcode_init(dev_priv); + intel_bw_init_hw(dev_priv);
return 0; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 04157d8ced32..728a46489f9c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9235,6 +9235,9 @@ enum { #define GEN9_SAGV_DISABLE 0x0 #define GEN9_SAGV_IS_DISABLED 0x1 #define GEN9_SAGV_ENABLE 0x3 +#define DG1_PCODE_STATUS 0x7E +#define DG1_UNCORE_GET_INIT_STATUS 0x0 +#define DG1_UNCORE_INIT_STATUS_COMPLETE 0x1 #define GEN12_PCODE_READ_SAGV_BLOCK_TIME_US 0x23 #define GEN6_PCODE_DATA _MMIO(0x138128) #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 5b3279262123..02ebf5a04a9b 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -555,3 +555,18 @@ int skl_pcode_request(struct drm_i915_private *i915, u32 mbox, u32 request, return ret ? ret : status; #undef COND } + +void intel_pcode_init(struct drm_i915_private *i915) +{ + int ret; + + if (!IS_DGFX(i915)) + return; + + ret = skl_pcode_request(i915, DG1_PCODE_STATUS, + DG1_UNCORE_GET_INIT_STATUS, + DG1_UNCORE_INIT_STATUS_COMPLETE, + DG1_UNCORE_INIT_STATUS_COMPLETE, 50); + if (ret) + drm_err(&i915->drm, "Pcode did not report uncore initialization completion!\n"); +} diff --git a/drivers/gpu/drm/i915/intel_sideband.h b/drivers/gpu/drm/i915/intel_sideband.h index 7fb95745a444..094c7b19c5d4 100644 --- a/drivers/gpu/drm/i915/intel_sideband.h +++ b/drivers/gpu/drm/i915/intel_sideband.h @@ -138,4 +138,6 @@ int sandybridge_pcode_write_timeout(struct drm_i915_private *i915, u32 mbox, int skl_pcode_request(struct drm_i915_private *i915, u32 mbox, u32 request, u32 reply_mask, u32 reply, int timeout_base_ms);
+void intel_pcode_init(struct drm_i915_private *i915); + #endif /* _INTEL_SIDEBAND_H */
From: José Roberto de Souza jose.souza@intel.com
[ Upstream commit 5d0c938ec9cc96fc7b8abcff0ca8b2a084e9c90c ]
Up to now we were reading some DRAM information from MCHBAR register and from pcode what is already not good but some GEN12(TGL-H and ADL-S) platforms have MCHBAR DRAM information in different offsets.
This was notified to HW team that decided that the best alternative is always apply the 16gb_dimm watermark adjustment for GEN12+ platforms and read the remaning DRAM information needed to other display programming from pcode.
So here moving the DRAM pcode function to intel_dram.c, removing the duplicated fields from intel_qgv_info, setting and using information from dram_info.
v2: - bring back num_points to intel_qgv_info as num_qgv_point can be overwritten in icl_get_qgv_points() - add gen12_get_dram_info() and simplify gen11_get_dram_info()
Reviewed-by: Lucas De Marchi lucas.demarchi@intel.com Signed-off-by: José Roberto de Souza jose.souza@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210128164312.91160-2-jose.so... Signed-off-by: Henning Schild henning.schild@siemens.com --- drivers/gpu/drm/i915/display/intel_bw.c | 80 +++--------------------- drivers/gpu/drm/i915/i915_drv.c | 5 +- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_dram.c | 82 ++++++++++++++++++++++++- 4 files changed, 93 insertions(+), 75 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index bd060404d249..4b5a30ac84bc 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -20,76 +20,9 @@ struct intel_qgv_point { struct intel_qgv_info { struct intel_qgv_point points[I915_NUM_QGV_POINTS]; u8 num_points; - u8 num_channels; u8 t_bl; - enum intel_dram_type dram_type; };
-static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv, - struct intel_qgv_info *qi) -{ - u32 val = 0; - int ret; - - ret = sandybridge_pcode_read(dev_priv, - ICL_PCODE_MEM_SUBSYSYSTEM_INFO | - ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, - &val, NULL); - if (ret) - return ret; - - if (IS_GEN(dev_priv, 12)) { - switch (val & 0xf) { - case 0: - qi->dram_type = INTEL_DRAM_DDR4; - break; - case 3: - qi->dram_type = INTEL_DRAM_LPDDR4; - break; - case 4: - qi->dram_type = INTEL_DRAM_DDR3; - break; - case 5: - qi->dram_type = INTEL_DRAM_LPDDR3; - break; - default: - MISSING_CASE(val & 0xf); - break; - } - } else if (IS_GEN(dev_priv, 11)) { - switch (val & 0xf) { - case 0: - qi->dram_type = INTEL_DRAM_DDR4; - break; - case 1: - qi->dram_type = INTEL_DRAM_DDR3; - break; - case 2: - qi->dram_type = INTEL_DRAM_LPDDR3; - break; - case 3: - qi->dram_type = INTEL_DRAM_LPDDR4; - break; - default: - MISSING_CASE(val & 0xf); - break; - } - } else { - MISSING_CASE(INTEL_GEN(dev_priv)); - qi->dram_type = INTEL_DRAM_LPDDR3; /* Conservative default */ - } - - qi->num_channels = (val & 0xf0) >> 4; - qi->num_points = (val & 0xf00) >> 8; - - if (IS_GEN(dev_priv, 12)) - qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 16; - else if (IS_GEN(dev_priv, 11)) - qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 8; - - return 0; -} - static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, struct intel_qgv_point *sp, int point) @@ -139,11 +72,15 @@ int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, static int icl_get_qgv_points(struct drm_i915_private *dev_priv, struct intel_qgv_info *qi) { + const struct dram_info *dram_info = &dev_priv->dram_info; int i, ret;
- ret = icl_pcode_read_mem_global_info(dev_priv, qi); - if (ret) - return ret; + qi->num_points = dram_info->num_qgv_points; + + if (IS_GEN(dev_priv, 12)) + qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 16; + else if (IS_GEN(dev_priv, 11)) + qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8;
if (drm_WARN_ON(&dev_priv->drm, qi->num_points > ARRAY_SIZE(qi->points))) @@ -209,7 +146,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel { struct intel_qgv_info qi = {}; bool is_y_tile = true; /* assume y tile may be used */ - int num_channels; + int num_channels = dev_priv->dram_info.num_channels; int deinterleave; int ipqdepth, ipqdepthpch; int dclk_max; @@ -222,7 +159,6 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel "Failed to get memory subsystem information, ignoring bandwidth limits"); return ret; } - num_channels = qi.num_channels;
deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); dclk_max = icl_sagv_max_dclk(&qi); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f72e3bb4ee9a..c72a26af181c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -609,14 +609,15 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) goto err_msi;
intel_opregion_setup(dev_priv); + + intel_pcode_init(dev_priv); + /* * Fill the dram structure to get the system raw bandwidth and * dram info. This will be used for memory latency calculation. */ intel_dram_detect(dev_priv);
- intel_pcode_init(dev_priv); - intel_bw_init_hw(dev_priv);
return 0; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6909901b3551..a8b65bab82c8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1148,6 +1148,7 @@ struct drm_i915_private { INTEL_DRAM_LPDDR3, INTEL_DRAM_LPDDR4 } type; + u8 num_qgv_points; } dram_info;
struct intel_bw_info { diff --git a/drivers/gpu/drm/i915/intel_dram.c b/drivers/gpu/drm/i915/intel_dram.c index 8aa12cad93ce..26e109c64984 100644 --- a/drivers/gpu/drm/i915/intel_dram.c +++ b/drivers/gpu/drm/i915/intel_dram.c @@ -5,6 +5,7 @@
#include "i915_drv.h" #include "intel_dram.h" +#include "intel_sideband.h"
struct dram_dimm_info { u8 size, width, ranks; @@ -433,6 +434,81 @@ static int bxt_get_dram_info(struct drm_i915_private *i915) return 0; }
+static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv) +{ + struct dram_info *dram_info = &dev_priv->dram_info; + u32 val = 0; + int ret; + + ret = sandybridge_pcode_read(dev_priv, + ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, + &val, NULL); + if (ret) + return ret; + + if (IS_GEN(dev_priv, 12)) { + switch (val & 0xf) { + case 0: + dram_info->type = INTEL_DRAM_DDR4; + break; + case 3: + dram_info->type = INTEL_DRAM_LPDDR4; + break; + case 4: + dram_info->type = INTEL_DRAM_DDR3; + break; + case 5: + dram_info->type = INTEL_DRAM_LPDDR3; + break; + default: + MISSING_CASE(val & 0xf); + return -1; + } + } else { + switch (val & 0xf) { + case 0: + dram_info->type = INTEL_DRAM_DDR4; + break; + case 1: + dram_info->type = INTEL_DRAM_DDR3; + break; + case 2: + dram_info->type = INTEL_DRAM_LPDDR3; + break; + case 3: + dram_info->type = INTEL_DRAM_LPDDR4; + break; + default: + MISSING_CASE(val & 0xf); + return -1; + } + } + + dram_info->num_channels = (val & 0xf0) >> 4; + dram_info->num_qgv_points = (val & 0xf00) >> 8; + + return 0; +} + +static int gen11_get_dram_info(struct drm_i915_private *i915) +{ + int ret = skl_get_dram_info(i915); + + if (ret) + return ret; + + return icl_pcode_read_mem_global_info(i915); +} + +static int gen12_get_dram_info(struct drm_i915_private *i915) +{ + /* Always needed for GEN12+ */ + i915->dram_info.is_16gb_dimm = true; + + return icl_pcode_read_mem_global_info(i915); +} + void intel_dram_detect(struct drm_i915_private *i915) { struct dram_info *dram_info = &i915->dram_info; @@ -448,7 +524,11 @@ void intel_dram_detect(struct drm_i915_private *i915) if (INTEL_GEN(i915) < 9 || !HAS_DISPLAY(i915)) return;
- if (IS_GEN9_LP(i915)) + if (INTEL_GEN(i915) >= 12) + ret = gen12_get_dram_info(i915); + else if (INTEL_GEN(i915) >= 11) + ret = gen11_get_dram_info(i915); + else if (IS_GEN9_LP(i915)) ret = bxt_get_dram_info(i915); else ret = skl_get_dram_info(i915);
On Thu, Jun 15, 2023 at 01:39:07PM +0200, Henning Schild wrote:
changes since v1:
- added my Signed-Offs
- removed additional "From"s
- change cover letter to motivate need for patch1
This fixes the following problem which was seen on a Tigerlake running Debian 10 with a 5.10 kernel. The fix is in the second patch while the first patch just makes sure the latter one does apply.
Now queued up, thanks.
greg k-h
linux-stable-mirror@lists.linaro.org