diff options
68 files changed, 5268 insertions, 4316 deletions
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 201dcd3c2e9d..3bf810ec75b1 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -4201,17 +4201,21 @@ int num_ioctls;</synopsis> </sect2> </sect1> <sect1> - <title>GuC-based Command Submission</title> + <title>GuC</title> <sect2> - <title>GuC</title> + <title>GuC-specific firmware loader</title> !Pdrivers/gpu/drm/i915/intel_guc_loader.c GuC-specific firmware loader !Idrivers/gpu/drm/i915/intel_guc_loader.c </sect2> <sect2> - <title>GuC Client</title> -!Pdrivers/gpu/drm/i915/i915_guc_submission.c GuC-based command submissison + <title>GuC-based command submission</title> +!Pdrivers/gpu/drm/i915/i915_guc_submission.c GuC-based command submission !Idrivers/gpu/drm/i915/i915_guc_submission.c </sect2> + <sect2> + <title>GuC Firmware Layout</title> +!Pdrivers/gpu/drm/i915/intel_guc_fwif.h GuC Firmware Layout + </sect2> </sect1> <sect1> diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index db9a675e751b..bca14c899137 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -547,6 +547,7 @@ static const struct pci_device_id intel_stolen_ids[] __initconst = { INTEL_CHV_IDS(&chv_stolen_funcs), INTEL_SKL_IDS(&gen9_stolen_funcs), INTEL_BXT_IDS(&gen9_stolen_funcs), + INTEL_KBL_IDS(&gen9_stolen_funcs), }; static void __init intel_graphics_stolen(int num, int slot, int func) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 051eab33e4c7..fcd77b27514d 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -10,6 +10,7 @@ config DRM_I915 # the shmem_readpage() which depends upon tmpfs select SHMEM select TMPFS + select STOP_MACHINE select DRM_KMS_HELPER select DRM_PANEL select DRM_MIPI_DSI diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 44d290ae1999..0851de07bd13 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -77,6 +77,7 @@ i915-y += dvo_ch7017.o \ dvo_tfp410.o \ intel_crt.o \ intel_ddi.o \ + intel_dp_link_training.o \ intel_dp_mst.o \ intel_dp.o \ intel_dsi.o \ diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 0e2c1b9648a7..13dea4263554 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h @@ -32,7 +32,8 @@ struct intel_dvo_device { const char *name; int type; /* DVOA/B/C output register */ - u32 dvo_reg; + i915_reg_t dvo_reg; + i915_reg_t dvo_srcdim_reg; /* GPIO register used for i2c bus to control this device */ u32 gpio; int slave_addr; diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index db58c8d664c2..814d894ed925 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -407,14 +407,14 @@ static const struct drm_i915_cmd_table hsw_blt_ring_cmds[] = { * LRI. */ struct drm_i915_reg_descriptor { - u32 addr; + i915_reg_t addr; u32 mask; u32 value; }; /* Convenience macro for adding 32-bit registers. */ -#define REG32(address, ...) \ - { .addr = address, __VA_ARGS__ } +#define REG32(_reg, ...) \ + { .addr = (_reg), __VA_ARGS__ } /* * Convenience macro for adding 64-bit registers. @@ -423,8 +423,13 @@ struct drm_i915_reg_descriptor { * access commands only allow 32-bit accesses. Hence, we have to include * entries for both halves of the 64-bit registers. */ -#define REG64(addr) \ - REG32(addr), REG32(addr + sizeof(u32)) +#define REG64(_reg) \ + { .addr = _reg }, \ + { .addr = _reg ## _UDW } + +#define REG64_IDX(_reg, idx) \ + { .addr = _reg(idx) }, \ + { .addr = _reg ## _UDW(idx) } static const struct drm_i915_reg_descriptor gen7_render_regs[] = { REG64(GPGPU_THREADS_DISPATCHED), @@ -451,14 +456,14 @@ static const struct drm_i915_reg_descriptor gen7_render_regs[] = { REG32(GEN7_GPGPU_DISPATCHDIMX), REG32(GEN7_GPGPU_DISPATCHDIMY), REG32(GEN7_GPGPU_DISPATCHDIMZ), - REG64(GEN7_SO_NUM_PRIMS_WRITTEN(0)), - REG64(GEN7_SO_NUM_PRIMS_WRITTEN(1)), - REG64(GEN7_SO_NUM_PRIMS_WRITTEN(2)), - REG64(GEN7_SO_NUM_PRIMS_WRITTEN(3)), - REG64(GEN7_SO_PRIM_STORAGE_NEEDED(0)), - REG64(GEN7_SO_PRIM_STORAGE_NEEDED(1)), - REG64(GEN7_SO_PRIM_STORAGE_NEEDED(2)), - REG64(GEN7_SO_PRIM_STORAGE_NEEDED(3)), + REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 0), + REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 1), + REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 2), + REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 3), + REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 0), + REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 1), + REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 2), + REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 3), REG32(GEN7_SO_WRITE_OFFSET(0)), REG32(GEN7_SO_WRITE_OFFSET(1)), REG32(GEN7_SO_WRITE_OFFSET(2)), @@ -592,7 +597,7 @@ static bool check_sorted(int ring_id, bool ret = true; for (i = 0; i < reg_count; i++) { - u32 curr = reg_table[i].addr; + u32 curr = i915_mmio_reg_offset(reg_table[i].addr); if (curr < previous) { DRM_ERROR("CMD: table not sorted ring=%d entry=%d reg=0x%08X prev=0x%08X\n", @@ -847,7 +852,7 @@ find_reg(const struct drm_i915_reg_descriptor *table, int i; for (i = 0; i < count; i++) { - if (table[i].addr == addr) + if (i915_mmio_reg_offset(table[i].addr) == addr) return &table[i]; } } @@ -1023,7 +1028,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, * to the register. Hence, limit OACONTROL writes to * only MI_LOAD_REGISTER_IMM commands. */ - if (reg_addr == OACONTROL) { + if (reg_addr == i915_mmio_reg_offset(OACONTROL)) { if (desc->cmd.value == MI_LOAD_REGISTER_MEM) { DRM_DEBUG_DRIVER("CMD: Rejected LRM to OACONTROL\n"); return false; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a3b22bdacd44..411a9c68b4ee 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1252,18 +1252,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused) max_freq = (IS_BROXTON(dev) ? rp_state_cap >> 0 : rp_state_cap >> 16) & 0xff; - max_freq *= (IS_SKYLAKE(dev) ? GEN9_FREQ_SCALER : 1); + max_freq *= (IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ? + GEN9_FREQ_SCALER : 1); seq_printf(m, "Lowest (RPN) frequency: %dMHz\n", intel_gpu_freq(dev_priv, max_freq)); max_freq = (rp_state_cap & 0xff00) >> 8; - max_freq *= (IS_SKYLAKE(dev) ? GEN9_FREQ_SCALER : 1); + max_freq *= (IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ? + GEN9_FREQ_SCALER : 1); seq_printf(m, "Nominal (RP1) frequency: %dMHz\n", intel_gpu_freq(dev_priv, max_freq)); max_freq = (IS_BROXTON(dev) ? rp_state_cap >> 16 : rp_state_cap >> 0) & 0xff; - max_freq *= (IS_SKYLAKE(dev) ? GEN9_FREQ_SCALER : 1); + max_freq *= (IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ? + GEN9_FREQ_SCALER : 1); seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", intel_gpu_freq(dev_priv, max_freq)); seq_printf(m, "Max overclocked frequency: %dMHz\n", @@ -1523,7 +1526,7 @@ static int gen6_drpc_info(struct seq_file *m) seq_printf(m, "RC information accurate: %s\n", yesno(count < 51)); } - gt_core_status = readl(dev_priv->regs + GEN6_GT_CORE_STATUS); + gt_core_status = I915_READ_FW(GEN6_GT_CORE_STATUS); trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4, true); rpmodectl1 = I915_READ(GEN6_RP_CONTROL); @@ -1640,7 +1643,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused) seq_puts(m, "FBC enabled\n"); else seq_printf(m, "FBC disabled: %s\n", - intel_no_fbc_reason_str(dev_priv->fbc.no_fbc_reason)); + dev_priv->fbc.no_fbc_reason); if (INTEL_INFO(dev_priv)->gen >= 7) seq_printf(m, "Compressing: %s\n", @@ -1801,7 +1804,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) if (ret) goto out; - if (IS_SKYLAKE(dev)) { + if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { /* Convert GT frequency to 50 HZ units */ min_gpu_freq = dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER; @@ -1821,7 +1824,8 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) &ia_freq); seq_printf(m, "%d\t\t%d\t\t\t\t%d\n", intel_gpu_freq(dev_priv, (gpu_freq * - (IS_SKYLAKE(dev) ? GEN9_FREQ_SCALER : 1))), + (IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ? + GEN9_FREQ_SCALER : 1))), ((ia_freq >> 0) & 0xff) * 100, ((ia_freq >> 8) & 0xff) * 100); } @@ -1873,17 +1877,19 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) struct drm_i915_private *dev_priv = dev->dev_private; ifbdev = dev_priv->fbdev; - fb = to_intel_framebuffer(ifbdev->helper.fb); - - seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", - fb->base.width, - fb->base.height, - fb->base.depth, - fb->base.bits_per_pixel, - fb->base.modifier[0], - atomic_read(&fb->base.refcount.refcount)); - describe_obj(m, fb->obj); - seq_putc(m, '\n'); + if (ifbdev) { + fb = to_intel_framebuffer(ifbdev->helper.fb); + + seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", + fb->base.width, + fb->base.height, + fb->base.depth, + fb->base.bits_per_pixel, + fb->base.modifier[0], + atomic_read(&fb->base.refcount.refcount)); + describe_obj(m, fb->obj); + seq_putc(m, '\n'); + } #endif mutex_lock(&dev->mode_config.fb_lock); @@ -2402,6 +2408,12 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data) guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted); seq_printf(m, "\tversion found: %d.%d\n", guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found); + seq_printf(m, "\theader: offset is %d; size = %d\n", + guc_fw->header_offset, guc_fw->header_size); + seq_printf(m, "\tuCode: offset is %d; size = %d\n", + guc_fw->ucode_offset, guc_fw->ucode_size); + seq_printf(m, "\tRSA: offset is %d; size = %d\n", + guc_fw->rsa_offset, guc_fw->rsa_size); tmp = I915_READ(GUC_STATUS); @@ -2550,7 +2562,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) yesno(work_busy(&dev_priv->psr.work.work))); if (HAS_DDI(dev)) - enabled = I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE; + enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE; else { for_each_pipe(dev_priv, pipe) { stat[pipe] = I915_READ(VLV_PSRSTAT(pipe)) & @@ -2572,7 +2584,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) /* CHV PSR has no kind of performance counter */ if (HAS_DDI(dev)) { - psrperf = I915_READ(EDP_PSR_PERF_CNT(dev)) & + psrperf = I915_READ(EDP_PSR_PERF_CNT) & EDP_PSR_PERF_CNT_MASK; seq_printf(m, "Performance_Counter: %u\n", psrperf); @@ -2696,24 +2708,16 @@ static const char *power_domain_str(enum intel_display_power_domain domain) return "TRANSCODER_C"; case POWER_DOMAIN_TRANSCODER_EDP: return "TRANSCODER_EDP"; - case POWER_DOMAIN_PORT_DDI_A_2_LANES: - return "PORT_DDI_A_2_LANES"; - case POWER_DOMAIN_PORT_DDI_A_4_LANES: - return "PORT_DDI_A_4_LANES"; - case POWER_DOMAIN_PORT_DDI_B_2_LANES: - return "PORT_DDI_B_2_LANES"; - case POWER_DOMAIN_PORT_DDI_B_4_LANES: - return "PORT_DDI_B_4_LANES"; - case POWER_DOMAIN_PORT_DDI_C_2_LANES: - return "PORT_DDI_C_2_LANES"; - case POWER_DOMAIN_PORT_DDI_C_4_LANES: - return "PORT_DDI_C_4_LANES"; - case POWER_DOMAIN_PORT_DDI_D_2_LANES: - return "PORT_DDI_D_2_LANES"; - case POWER_DOMAIN_PORT_DDI_D_4_LANES: - return "PORT_DDI_D_4_LANES"; - case POWER_DOMAIN_PORT_DDI_E_2_LANES: - return "PORT_DDI_E_2_LANES"; + case POWER_DOMAIN_PORT_DDI_A_LANES: + return "PORT_DDI_A_LANES"; + case POWER_DOMAIN_PORT_DDI_B_LANES: + return "PORT_DDI_B_LANES"; + case POWER_DOMAIN_PORT_DDI_C_LANES: + return "PORT_DDI_C_LANES"; + case POWER_DOMAIN_PORT_DDI_D_LANES: + return "PORT_DDI_D_LANES"; + case POWER_DOMAIN_PORT_DDI_E_LANES: + return "PORT_DDI_E_LANES"; case POWER_DOMAIN_PORT_DSI: return "PORT_DSI"; case POWER_DOMAIN_PORT_CRT: @@ -2734,6 +2738,10 @@ static const char *power_domain_str(enum intel_display_power_domain domain) return "AUX_C"; case POWER_DOMAIN_AUX_D: return "AUX_D"; + case POWER_DOMAIN_GMBUS: + return "GMBUS"; + case POWER_DOMAIN_MODESET: + return "MODESET"; case POWER_DOMAIN_INIT: return "INIT"; default: @@ -2777,6 +2785,51 @@ static int i915_power_domain_info(struct seq_file *m, void *unused) return 0; } +static int i915_dmc_info(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_csr *csr; + + if (!HAS_CSR(dev)) { + seq_puts(m, "not supported\n"); + return 0; + } + + csr = &dev_priv->csr; + + intel_runtime_pm_get(dev_priv); + + seq_printf(m, "fw loaded: %s\n", yesno(csr->dmc_payload != NULL)); + seq_printf(m, "path: %s\n", csr->fw_path); + + if (!csr->dmc_payload) + goto out; + + seq_printf(m, "version: %d.%d\n", CSR_VERSION_MAJOR(csr->version), + CSR_VERSION_MINOR(csr->version)); + + if (IS_SKYLAKE(dev) && csr->version >= CSR_VERSION(1, 6)) { + seq_printf(m, "DC3 -> DC5 count: %d\n", + I915_READ(SKL_CSR_DC3_DC5_COUNT)); + seq_printf(m, "DC5 -> DC6 count: %d\n", + I915_READ(SKL_CSR_DC5_DC6_COUNT)); + } else if (IS_BROXTON(dev) && csr->version >= CSR_VERSION(1, 4)) { + seq_printf(m, "DC3 -> DC5 count: %d\n", + I915_READ(BXT_CSR_DC3_DC5_COUNT)); + } + +out: + seq_printf(m, "program base: 0x%08x\n", I915_READ(CSR_PROGRAM(0))); + seq_printf(m, "ssp base: 0x%08x\n", I915_READ(CSR_SSP_BASE)); + seq_printf(m, "htp: 0x%08x\n", I915_READ(CSR_HTP_SKL)); + + intel_runtime_pm_put(dev_priv); + + return 0; +} + static void intel_seq_print_mode(struct seq_file *m, int tabs, struct drm_display_mode *mode) { @@ -2944,6 +2997,107 @@ static bool cursor_position(struct drm_device *dev, int pipe, int *x, int *y) return cursor_active(dev, pipe); } +static const char *plane_type(enum drm_plane_type type) +{ + switch (type) { + case DRM_PLANE_TYPE_OVERLAY: + return "OVL"; + case DRM_PLANE_TYPE_PRIMARY: + return "PRI"; + case DRM_PLANE_TYPE_CURSOR: + return "CUR"; + /* + * Deliberately omitting default: to generate compiler warnings + * when a new drm_plane_type gets added. + */ + } + + return "unknown"; +} + +static const char *plane_rotation(unsigned int rotation) +{ + static char buf[48]; + /* + * According to doc only one DRM_ROTATE_ is allowed but this + * will print them all to visualize if the values are misused + */ + snprintf(buf, sizeof(buf), + "%s%s%s%s%s%s(0x%08x)", + (rotation & BIT(DRM_ROTATE_0)) ? "0 " : "", + (rotation & BIT(DRM_ROTATE_90)) ? "90 " : "", + (rotation & BIT(DRM_ROTATE_180)) ? "180 " : "", + (rotation & BIT(DRM_ROTATE_270)) ? "270 " : "", + (rotation & BIT(DRM_REFLECT_X)) ? "FLIPX " : "", + (rotation & BIT(DRM_REFLECT_Y)) ? "FLIPY " : "", + rotation); + + return buf; +} + +static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc) +{ + struct drm_info_node *node = m->private; + struct drm_device *dev = node->minor->dev; + struct intel_plane *intel_plane; + + for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { + struct drm_plane_state *state; + struct drm_plane *plane = &intel_plane->base; + + if (!plane->state) { + seq_puts(m, "plane->state is NULL!\n"); + continue; + } |
