Re: [PATCH v1 06/10] drm/mediatek: add ETHDR support for MT8195

2021-07-21 Thread CK Hu
Hi, Nancy:

On Thu, 2021-07-22 at 09:32 +0800, Nancy.Lin wrote:
> Hi Chun-Kuang,
> 
> On Mon, 2021-07-19 at 07:56 +0800, Chun-Kuang Hu wrote:
> > Hi, Nancy:
> > 
> > Nancy.Lin  於 2021年7月17日 週六 下午5:04寫道:
> > > 
> > > Add ETHDR module files:
> > > ETHDR is designed for HDR video and graphics conversion in the
> > > external
> > > display path. It handles multiple HDR input types and performs tone
> > > mapping, color space/color format conversion, and then combines
> > > different layers, output the required HDR or SDR signal to the
> > > subsequent display path.
> > > 
> > > Signed-off-by: Nancy.Lin 
> > > ---
> > >  drivers/gpu/drm/mediatek/Makefile   |   3 +-
> > >  drivers/gpu/drm/mediatek/mtk_disp_drv.h |   8 +
> > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  11 +
> > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> > >  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   4 +
> > >  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   1 +
> > >  drivers/gpu/drm/mediatek/mtk_ethdr.c| 537
> > > 
> > >  drivers/gpu/drm/mediatek/mtk_ethdr.h|  20 +
> > >  8 files changed, 584 insertions(+), 1 deletion(-)
> > >  create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
> > >  create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h
> > > 
> > > +
> > > +void mtk_ethdr_layer_on(struct device *dev, unsigned int idx,
> > > +   struct cmdq_pkt *cmdq_pkt)
> > > +{
> > > +   struct mtk_ethdr *priv = dev_get_drvdata(dev);
> > > +   struct mtk_ethdr_comp *mixer = 
> > > >ethdr_comp[ETHDR_MIXER];
> > > +
> > > +   dev_dbg(dev, "%s+ idx:%d", __func__, idx);
> > > +
> > > +   if (idx < 4)
> > > +   mtk_ddp_write_mask(cmdq_pkt, BIT(idx), 
> > > >cmdq_base,
> > > +  mixer->regs, MIX_SRC_CON,
> > > BIT(idx));
> > > +}
> > > +
> > > +void mtk_ethdr_layer_off(struct device *dev, unsigned int idx,
> > > +struct cmdq_pkt *cmdq_pkt)
> > > +{
> > > +   struct mtk_ethdr *priv = dev_get_drvdata(dev);
> > > +   struct mtk_ethdr_comp *mixer = 
> > > >ethdr_comp[ETHDR_MIXER];
> > > +
> > > +   dev_dbg(dev, "%s+ idx:%d", __func__, idx);
> > > +
> > > +   switch (idx) {
> > > +   case 0:
> > > +   mtk_ddp_write_mask(cmdq_pkt, 0, >cmdq_base,
> > > +  mixer->regs, MIX_L0_SRC_SIZE,
> > > ~0);
> > > +   break;
> > > +   case 1:
> > > +   mtk_ddp_write_mask(cmdq_pkt, 0, >cmdq_base,
> > > +  mixer->regs, MIX_L1_SRC_SIZE,
> > > ~0);
> > > +   break;
> > > +   case 2:
> > > +   mtk_ddp_write_mask(cmdq_pkt, 0, >cmdq_base,
> > > +  mixer->regs, MIX_L2_SRC_SIZE,
> > > ~0);
> > > +   break;
> > > +   case 3:
> > > +   mtk_ddp_write_mask(cmdq_pkt, 0, >cmdq_base,
> > > +  mixer->regs, MIX_L3_SRC_SIZE,
> > > ~0);
> > > +   break;
> > > +   default:
> > > +   dev_dbg(dev, "%s Wrong layer ID\n", __func__);
> > > +   break;
> > > +   }
> > 
> > Why not just
> > 
> >mtk_ddp_write_mask(cmdq_pkt, 0, >cmdq_base,
> >   mixer->regs, MIX_SRC_CON,
> > BIT(idx));
> > 
> 
> There are two modes in Mixer.
> 1. Background relay mode: all layers off
> 2. Normal mix mode: at least one layer on
> The timing of the two modes is different, so keep using the normal mix
> mode.
> Just set the layer region to 0 when the layer off.

layer_on() and layer_off() does different things. Comparing before turn
on a layer with after turn on->off a layer, the register setting are
different. I would like just restore the register. 

Regards,
CK

> 
> > > +}
> > > +




Re: [Intel-gfx] [PATCH 3/4] drm/i915/gt: rename legacy engine->hw_id to engine->gen6_hw_id

2021-07-21 Thread Lucas De Marchi
On Wed, Jul 21, 2021 at 3:51 PM Matt Roper  wrote:
>
> On Tue, Jul 20, 2021 at 04:20:13PM -0700, Lucas De Marchi wrote:
> > We kept adding new engines and for that increasing hw_id unnecessarily:
> > it's not used since GRAPHICS_VER == 8. Prepend "gen6" to the field and
> > try to pack it in the structs to give a hint this field is actually not
> > used in recent platforms.
> >
> > Signed-off-by: Lucas De Marchi 
>
> Reviewed-by: Matt Roper 
>
> although if we apply patch #4 we could probably drop this intermediate

I was not so confident people would agree with that patch. Adding the macros to
the header as suggested helps it being more palatable though.

thanks
Lucas De Marchi

> step.
>
>
> Matt
>
> > ---
> >  drivers/gpu/drm/i915/gt/intel_engine_cs.c| 12 ++--
> >  drivers/gpu/drm/i915/gt/intel_engine_types.h |  2 +-
> >  drivers/gpu/drm/i915/i915_reg.h  |  2 +-
> >  3 files changed, 8 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > index a11f69f2e46e..508221de411c 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > @@ -42,7 +42,7 @@
> >
> >  #define MAX_MMIO_BASES 3
> >  struct engine_info {
> > - unsigned int hw_id;
> > + u8 gen6_hw_id;
> >   u8 class;
> >   u8 instance;
> >   /* mmio bases table *must* be sorted in reverse graphics_ver order */
> > @@ -54,7 +54,7 @@ struct engine_info {
> >
> >  static const struct engine_info intel_engines[] = {
> >   [RCS0] = {
> > - .hw_id = RCS0_HW,
> > + .gen6_hw_id = RCS0_HW,
> >   .class = RENDER_CLASS,
> >   .instance = 0,
> >   .mmio_bases = {
> > @@ -62,7 +62,7 @@ static const struct engine_info intel_engines[] = {
> >   },
> >   },
> >   [BCS0] = {
> > - .hw_id = BCS0_HW,
> > + .gen6_hw_id = BCS0_HW,
> >   .class = COPY_ENGINE_CLASS,
> >   .instance = 0,
> >   .mmio_bases = {
> > @@ -70,7 +70,7 @@ static const struct engine_info intel_engines[] = {
> >   },
> >   },
> >   [VCS0] = {
> > - .hw_id = VCS0_HW,
> > + .gen6_hw_id = VCS0_HW,
> >   .class = VIDEO_DECODE_CLASS,
> >   .instance = 0,
> >   .mmio_bases = {
> > @@ -102,7 +102,7 @@ static const struct engine_info intel_engines[] = {
> >   },
> >   },
> >   [VECS0] = {
> > - .hw_id = VECS0_HW,
> > + .gen6_hw_id = VECS0_HW,
> >   .class = VIDEO_ENHANCEMENT_CLASS,
> >   .instance = 0,
> >   .mmio_bases = {
> > @@ -290,7 +290,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
> > intel_engine_id id)
> >   engine->i915 = i915;
> >   engine->gt = gt;
> >   engine->uncore = gt->uncore;
> > - engine->hw_id = info->hw_id;
> > + engine->gen6_hw_id = info->gen6_hw_id;
> >   guc_class = engine_class_to_guc_class(info->class);
> >   engine->guc_id = MAKE_GUC_ID(guc_class, info->instance);
> >   engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases);
> > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
> > b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > index a107eb58ffa2..266422d8d1b1 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > @@ -264,11 +264,11 @@ struct intel_engine_cs {
> >   enum intel_engine_id id;
> >   enum intel_engine_id legacy_idx;
> >
> > - unsigned int hw_id;
> >   unsigned int guc_id;
> >
> >   intel_engine_mask_t mask;
> >
> > + u8 gen6_hw_id;
> >   u8 class;
> >   u8 instance;
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h 
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index 943fe485c662..8750ffce9d61 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -2572,7 +2572,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
> >  #define   ARB_MODE_BWGTLB_DISABLE (1 << 9)
> >  #define   ARB_MODE_SWIZZLE_BDW   (1 << 1)
> >  #define RENDER_HWS_PGA_GEN7  _MMIO(0x04080)
> > -#define RING_FAULT_REG(engine)   _MMIO(0x4094 + 0x100 * 
> > (engine)->hw_id)
> > +#define RING_FAULT_REG(engine)   _MMIO(0x4094 + 0x100 * 
> > (engine)->gen6_hw_id)
> >  #define GEN8_RING_FAULT_REG  _MMIO(0x4094)
> >  #define GEN12_RING_FAULT_REG _MMIO(0xcec4)
> >  #define   GEN8_RING_FAULT_ENGINE_ID(x)   (((x) >> 12) & 0x7)
> > --
> > 2.31.1
> >
>
> --
> Matt Roper
> Graphics Software Engineer
> VTT-OSGC Platform Enablement
> Intel Corporation
> (916) 356-2795
> ___
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [PATCH 33/51] drm/i915/guc: Provide mmio list to be saved/restored on engine reset

2021-07-21 Thread Matthew Brost
On Fri, Jul 16, 2021 at 01:17:06PM -0700, Matthew Brost wrote:
> From: John Harrison 
> 
> The driver must provide GuC with a list of mmio registers
> that should be saved/restored during a GuC-based engine reset.
> Unfortunately, the list must be dynamically allocated as its size is
> variable. That means the driver must generate the list twice - once to
> work out the size and a second time to actually save it.
> 
> v2:
>  (Alan / CI)
>   - GEN7_GT_MODE -> GEN6_GT_MODE to fix WA selftest failure
> 
> Signed-off-by: John Harrison 
> Signed-off-by: Fernando Pacheco 
> Signed-off-by: Matthew Brost 

Everything looks structurally correct. Feel confident on my below RB but
W/A are not my area of expertise. If any one else wanted to give it a
look, I wouldn't mind.

With that:
Reviewed-by: Matthew Brost 


> Cc: Daniele Ceraolo Spurio 
> Cc: Tvrtko Ursulin 
> ---
>  drivers/gpu/drm/i915/gt/intel_workarounds.c   |  46 ++--
>  .../gpu/drm/i915/gt/intel_workarounds_types.h |   1 +
>  drivers/gpu/drm/i915/gt/uc/intel_guc.h|   1 +
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 199 +-
>  drivers/gpu/drm/i915/i915_reg.h   |   1 +
>  5 files changed, 222 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
> b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> index 72562c233ad2..34738ccab8bd 100644
> --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
> +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> @@ -150,13 +150,14 @@ static void _wa_add(struct i915_wa_list *wal, const 
> struct i915_wa *wa)
>  }
>  
>  static void wa_add(struct i915_wa_list *wal, i915_reg_t reg,
> -u32 clear, u32 set, u32 read_mask)
> +u32 clear, u32 set, u32 read_mask, bool masked_reg)
>  {
>   struct i915_wa wa = {
>   .reg  = reg,
>   .clr  = clear,
>   .set  = set,
>   .read = read_mask,
> + .masked_reg = masked_reg,
>   };
>  
>   _wa_add(wal, );
> @@ -165,7 +166,7 @@ static void wa_add(struct i915_wa_list *wal, i915_reg_t 
> reg,
>  static void
>  wa_write_clr_set(struct i915_wa_list *wal, i915_reg_t reg, u32 clear, u32 
> set)
>  {
> - wa_add(wal, reg, clear, set, clear);
> + wa_add(wal, reg, clear, set, clear, false);
>  }
>  
>  static void
> @@ -200,20 +201,20 @@ wa_write_clr(struct i915_wa_list *wal, i915_reg_t reg, 
> u32 clr)
>  static void
>  wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
>  {
> - wa_add(wal, reg, 0, _MASKED_BIT_ENABLE(val), val);
> + wa_add(wal, reg, 0, _MASKED_BIT_ENABLE(val), val, true);
>  }
>  
>  static void
>  wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
>  {
> - wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val);
> + wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val, true);
>  }
>  
>  static void
>  wa_masked_field_set(struct i915_wa_list *wal, i915_reg_t reg,
>   u32 mask, u32 val)
>  {
> - wa_add(wal, reg, 0, _MASKED_FIELD(mask, val), mask);
> + wa_add(wal, reg, 0, _MASKED_FIELD(mask, val), mask, true);
>  }
>  
>  static void gen6_ctx_workarounds_init(struct intel_engine_cs *engine,
> @@ -583,10 +584,10 @@ static void icl_ctx_workarounds_init(struct 
> intel_engine_cs *engine,
>GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC);
>  
>   /* WaEnableFloatBlendOptimization:icl */
> - wa_write_clr_set(wal,
> -  GEN10_CACHE_MODE_SS,
> -  0, /* write-only, so skip validation */
> -  _MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE));
> + wa_add(wal, GEN10_CACHE_MODE_SS, 0,
> +_MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE),
> +0 /* write-only, so skip validation */,
> +true);
>  
>   /* WaDisableGPGPUMidThreadPreemption:icl */
>   wa_masked_field_set(wal, GEN8_CS_CHICKEN1,
> @@ -631,7 +632,7 @@ static void gen12_ctx_gt_tuning_init(struct 
> intel_engine_cs *engine,
>  FF_MODE2,
>  FF_MODE2_TDS_TIMER_MASK,
>  FF_MODE2_TDS_TIMER_128,
> -0);
> +0, false);
>  }
>  
>  static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine,
> @@ -669,7 +670,7 @@ static void gen12_ctx_workarounds_init(struct 
> intel_engine_cs *engine,
>  FF_MODE2,
>  FF_MODE2_GS_TIMER_MASK,
>  FF_MODE2_GS_TIMER_224,
> -0);
> +0, false);
>  
>   /*
>* Wa_14012131227:dg1
> @@ -847,7 +848,7 @@ hsw_gt_workarounds_init(struct drm_i915_private *i915, 
> struct i915_wa_list *wal)
>   wa_add(wal,
>  HSW_ROW_CHICKEN3, 0,
>  _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE),
> - 0 /* XXX does this reg exist? */);
> +0 /* XXX does this reg exist? */, true);
>  
>   /* WaVSRefCountFullforceMissDisable:hsw */
>   wa_write_clr(wal, 

[PATCH] drivers/firmware: fix sysfb depends to prevent build failures

2021-07-21 Thread Javier Martinez Canillas
The Generic System Framebuffers support is built when the COMPILE_TEST
option is enabled. But this wrongly assumes that all the architectures
declare a struct screen_info.

This is true for most architectures, but at least the following do not:
arc, m68k, microblaze, openrisc, parisc and s390.

By attempting to make this compile testeable on all architectures, it
leads to linking errors as reported by the kernel test robot for parisc:

  All errors (new ones prefixed by >>):

 hppa-linux-ld: drivers/firmware/sysfb.o: in function `sysfb_init':
 (.init.text+0x24): undefined reference to `screen_info'
  >> hppa-linux-ld: (.init.text+0x28): undefined reference to `screen_info'

To prevent these errors only allow sysfb to be built on systems that are
going to need it, which are x86 BIOS and EFI.

The EFI Kconfig symbol is used instead of (ARM || ARM64 || RISC) because
some of these architectures only declare a struct screen_info if EFI is
enabled. And also, because the sysfb code is only used for EFI on these
architectures. For !EFI the "simple-framebuffer" device is registered by
OF when parsing the Device Tree Blob (if a DT node for this is defined).

Reported-by: kernel test robot 
Signed-off-by: Javier Martinez Canillas 
---

 drivers/firmware/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index af6719cc576..897f5f25c64 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -254,7 +254,7 @@ config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
 config SYSFB
bool
default y
-   depends on X86 || ARM || ARM64 || RISCV || COMPILE_TEST
+   depends on X86 || EFI
 
 config SYSFB_SIMPLEFB
bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
-- 
2.31.1



[PATCH v2 1/2] drm/msm/dsi: update dsi register header file for tpg

2021-07-21 Thread Abhinav Kumar
Update the DSI controller header XML file to add registers
and bitfields to support rectangular checkered pattern
generator.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/dsi/dsi.xml.h | 94 +++
 1 file changed, 75 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h 
b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index eadbcc7..ae299b7 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -8,25 +8,8 @@ This file was generated by the rules-ng-ng headergen tool in 
this git repository
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml 
  (981 bytes, from 2021-06-05 21:37:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml 
  (   1572 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml
  (  20912 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml  
  (   2849 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml
  (  37461 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml 
  (  15291 bytes, from 2021-06-15 22:36:13)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml  
  (   3236 bytes, from 2021-06-05 21:37:42)
-- 
/home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml 
(   4935 bytes, from 2021-05-21 19:18:08)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml
  (   7004 bytes, from 2021-05-21 19:18:08)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml
  (   3712 bytes, from 2021-05-21 19:18:08)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml
  (   5381 bytes, from 2021-05-21 19:18:08)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml
  (   4499 bytes, from 2021-05-21 19:18:08)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml 
  (  10953 bytes, from 2021-05-21 19:18:08)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml 
  (  10900 bytes, from 2021-05-21 19:18:08)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml
  (602 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml 
  (   1686 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml 
  (600 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml   
  (  41874 bytes, from 2021-02-18 16:45:44)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml 
  (  10416 bytes, from 2021-02-18 16:45:44)
+- 
/local/mnt2/workspace2/abhinav/mesa_tool/mesa/src/freedreno/registers/dsi/dsi.xml
 (  17500 bytes, from 2021-07-22 02:35:56)
+- 
/local/mnt2/workspace2/abhinav/mesa_tool/mesa/src/freedreno/registers/freedreno_copyright.xml
 (   1572 bytes, from 2021-07-13 18:03:11)
 
 Copyright (C) 2013-2021 by the following authors:
 - Rob Clark  (robclark)
@@ -105,6 +88,32 @@ enum dsi_lane_swap {
LANE_SWAP_3210 = 7,
 };
 
+enum video_config_bpp {
+   VIDEO_CONFIG_18BPP = 0,
+   VIDEO_CONFIG_24BPP = 1,
+};
+
+enum video_pattern_sel {
+   VID_PRBS = 0,
+   VID_INCREMENTAL = 1,
+   VID_FIXED = 2,
+   VID_MDSS_GENERAL_PATTERN = 3,
+};
+
+enum cmd_mdp_stream0_pattern_sel {
+   CMD_MDP_PRBS = 0,
+   CMD_MDP_INCREMENTAL = 1,
+   CMD_MDP_FIXED = 2,
+   CMD_MDP_MDSS_GENERAL_PATTERN = 3,
+};
+
+enum cmd_dma_pattern_sel {
+   CMD_DMA_PRBS = 0,
+   CMD_DMA_INCREMENTAL = 1,
+   CMD_DMA_FIXED = 2,
+   CMD_DMA_CUSTOM_PATTERN_DMA_FIFO = 3,
+};
+
 #define DSI_IRQ_CMD_DMA_DONE   0x0001
 #define DSI_IRQ_MASK_CMD_DMA_DONE  0x0002
 #define DSI_IRQ_CMD_MDP_DONE   0x0100
@@ -564,6 +573,53 @@ static inline uint32_t 
DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(enum dsi_lane_swap val)
 #define REG_DSI_PHY_RESET  0x0128
 #define DSI_PHY_RESET_RESET0x0001
 
+#define REG_DSI_TEST_PATTERN_GEN_VIDEO_INIT_VAL
0x0160
+
+#define REG_DSI_TPG_MAIN_CONTROL   0x0198
+#define DSI_TPG_MAIN_CONTROL_CHECKERED_RECTANGLE_PATTERN   0x0100
+
+#define REG_DSI_TPG_VIDEO_CONFIG   0x01a0
+#define DSI_TPG_VIDEO_CONFIG_BPP__MASK 0x0003
+#define DSI_TPG_VIDEO_CONFIG_BPP__SHIFT 

[PATCH v2 2/2] drm/msm/dsi: add support for dsi test pattern generator

2021-07-21 Thread Abhinav Kumar
During board bringups its useful to have a DSI test pattern
generator to isolate a DPU vs a DSI issue and focus on the relevant
hardware block.

To facilitate this, add an API which triggers the DSI controller
test pattern. The expected output is a rectangular checkered pattern.

This has been validated on a single DSI video mode panel by calling it
right after drm_panel_enable() which is also the ideal location to use
this as the DSI host and the panel have been initialized by then.

Further validation on dual DSI and command mode panel is pending.
If there are any fix ups needed for those, it shall be applied on top
of this change.

Changes in v2:
 - generate the new dsi.xml.h and update the bitfield names

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/dsi/dsi.h |  3 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c| 61 +++
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 13 
 3 files changed, 77 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 9b8e9b0..663ccbd 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -84,6 +84,7 @@ void msm_dsi_manager_setup_encoder(int id);
 int msm_dsi_manager_register(struct msm_dsi *msm_dsi);
 void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi);
 bool msm_dsi_manager_validate_current_config(u8 id);
+void msm_dsi_manager_tpg_enable(void);
 
 /* msm dsi */
 static inline bool msm_dsi_device_connected(struct msm_dsi *msm_dsi)
@@ -148,6 +149,8 @@ int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
 int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi);
 int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi);
 void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct 
mipi_dsi_host *host);
+void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
+
 /* dsi phy */
 struct msm_dsi_phy;
 struct msm_dsi_phy_shared_timings {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index ed504fe..e0a3581 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2495,3 +2495,64 @@ void msm_dsi_host_snapshot(struct msm_disp_state 
*disp_state, struct mipi_dsi_ho
 
pm_runtime_put_sync(_host->pdev->dev);
 }
+
+static void msm_dsi_host_video_test_pattern_setup(struct msm_dsi_host 
*msm_host)
+{
+   u32 reg;
+
+   reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL);
+
+   dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_VIDEO_INIT_VAL, 0xff);
+   /* draw checkered rectangle pattern */
+   dsi_write(msm_host, REG_DSI_TPG_MAIN_CONTROL,
+   DSI_TPG_MAIN_CONTROL_CHECKERED_RECTANGLE_PATTERN);
+   /* use 24-bit RGB test pttern */
+   dsi_write(msm_host, REG_DSI_TPG_VIDEO_CONFIG,
+   DSI_TPG_VIDEO_CONFIG_BPP(VIDEO_CONFIG_24BPP) |
+   DSI_TPG_VIDEO_CONFIG_RGB);
+
+   reg |= 
DSI_TEST_PATTERN_GEN_CTRL_VIDEO_PATTERN_SEL(VID_MDSS_GENERAL_PATTERN);
+   dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, reg);
+
+   DBG("Video test pattern setup done\n");
+}
+
+static void msm_dsi_host_cmd_test_pattern_setup(struct msm_dsi_host *msm_host)
+{
+   u32 reg;
+
+   reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL);
+
+   /* initial value for test pattern */
+   dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0, 0xff);
+
+   reg |= 
DSI_TEST_PATTERN_GEN_CTRL_CMD_MDP_STREAM0_PATTERN_SEL(CMD_MDP_MDSS_GENERAL_PATTERN);
+
+   dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, reg);
+   /* draw checkered rectangle pattern */
+   dsi_write(msm_host, REG_DSI_TPG_MAIN_CONTROL2,
+   
DSI_TPG_MAIN_CONTROL2_CMD_MDP0_CHECKERED_RECTANGLE_PATTERN);
+
+   DBG("Cmd test pattern setup done\n");
+}
+
+void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+   bool is_video_mode = !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO);
+   u32 reg;
+
+   if (is_video_mode)
+   msm_dsi_host_video_test_pattern_setup(msm_host);
+   else
+   msm_dsi_host_cmd_test_pattern_setup(msm_host);
+
+   reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL);
+   /* enable the test pattern generator */
+   dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, (reg | 
DSI_TEST_PATTERN_GEN_CTRL_EN));
+
+   /* for command mode need to trigger one frame from tpg */
+   if (!is_video_mode)
+   dsi_write(msm_host, 
REG_DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER,
+   
DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER_SW_TRIGGER);
+}
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 4ebfedc..db80de6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -441,6 +441,19 @@ static void 

[PATCH] drm/msm/dp: Initialize the INTF_CONFIG register

2021-07-21 Thread Bjorn Andersson
Some bootloaders set the widebus enable bit in the INTF_CONFIG register,
but configuration of widebus isn't yet supported ensure that the
register has a known value, with widebus disabled.

Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/dp/dp_catalog.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 23458b0ddc37..37cb1102a0ca 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -747,6 +747,7 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog 
*dp_catalog)
dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY,
dp_catalog->width_blanking);
dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active);
+   dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0);
return 0;
 }
 
-- 
2.29.2



[PATCH 5/5] drm/msm/dp: Allow sub-regions to be specified in DT

2021-07-21 Thread Bjorn Andersson
Not all platforms has P0 at an offset of 0x1000 from the base address,
so add support for specifying each sub-region in DT. The code falls back
to the predefined offsets in the case that only a single reg is
specified, in order to support existing DT.

Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/dp/dp_parser.c | 49 +++---
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 1a10901ae574..fc8a6452f641 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -63,18 +63,45 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
return PTR_ERR(dss->ahb);
}
 
-   if (dss->ahb_len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
-   DRM_ERROR("legacy memory region not large enough\n");
-   return -EINVAL;
-   }
+   dss->aux = dp_ioremap(pdev, 1, >aux_len);
+   if (IS_ERR(dss->aux)) {
+   /*
+* The initial binding had a single reg, but in order to
+* support variation in the sub-region sizes this was split.
+* dp_ioremap() will fail with -ENODEV here if only a single
+* reg is specified, so fill in the sub-region offsets and
+* lengths based on this single region.
+*/
+   if (PTR_ERR(dss->aux) == -ENODEV) {
+   if (dss->ahb_len < DP_DEFAULT_P0_OFFSET + 
DP_DEFAULT_P0_SIZE) {
+   DRM_ERROR("legacy memory region not large 
enough\n");
+   return -EINVAL;
+   }
+
+   dss->ahb_len = DP_DEFAULT_AHB_SIZE;
+   dss->aux = dss->ahb + DP_DEFAULT_AUX_OFFSET;
+   dss->aux_len = DP_DEFAULT_AUX_SIZE;
+   dss->link = dss->ahb + DP_DEFAULT_LINK_OFFSET;
+   dss->link_len = DP_DEFAULT_LINK_SIZE;
+   dss->p0 = dss->ahb + DP_DEFAULT_P0_OFFSET;
+   dss->p0_len = DP_DEFAULT_P0_SIZE;
+   } else {
+   DRM_ERROR("unable to remap aux region: %pe\n", 
dss->aux);
+   return PTR_ERR(dss->aux);
+   }
+   } else {
+   dss->link = dp_ioremap(pdev, 2, >link_len);
+   if (IS_ERR(dss->link)) {
+   DRM_ERROR("unable to remap link region: %pe\n", 
dss->link);
+   return PTR_ERR(dss->link);
+   }
 
-   dss->ahb_len = DP_DEFAULT_AHB_SIZE;
-   dss->aux = dss->ahb + DP_DEFAULT_AUX_OFFSET;
-   dss->aux_len = DP_DEFAULT_AUX_SIZE;
-   dss->link = dss->ahb + DP_DEFAULT_LINK_OFFSET;
-   dss->link_len = DP_DEFAULT_LINK_SIZE;
-   dss->p0 = dss->ahb + DP_DEFAULT_P0_OFFSET;
-   dss->p0_len = DP_DEFAULT_P0_SIZE;
+   dss->p0 = dp_ioremap(pdev, 3, >p0_len);
+   if (IS_ERR(dss->p0)) {
+   DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0);
+   return PTR_ERR(dss->p0);
+   }
+   }
 
io->phy = devm_phy_get(>dev, "dp");
if (IS_ERR(io->phy))
-- 
2.29.2



[PATCH 4/5] drm/msm/dp: Store each subblock in the io region

2021-07-21 Thread Bjorn Andersson
Not all platforms has DP_P0 at offset 0x1000 from the beginning of the
DP block. So dss_io_data into representing each of the sub-regions, to
make it possible in the next patch to specify each of the sub-regions
individually.

Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/dp/dp_catalog.c | 64 +
 drivers/gpu/drm/msm/dp/dp_parser.c  | 30 --
 drivers/gpu/drm/msm/dp/dp_parser.h  | 10 -
 3 files changed, 54 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index ca96e3514790..23458b0ddc37 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -24,15 +24,6 @@
 #define DP_INTERRUPT_STATUS_ACK_SHIFT  1
 #define DP_INTERRUPT_STATUS_MASK_SHIFT 2
 
-#define MSM_DP_CONTROLLER_AHB_OFFSET   0x
-#define MSM_DP_CONTROLLER_AHB_SIZE 0x0200
-#define MSM_DP_CONTROLLER_AUX_OFFSET   0x0200
-#define MSM_DP_CONTROLLER_AUX_SIZE 0x0200
-#define MSM_DP_CONTROLLER_LINK_OFFSET  0x0400
-#define MSM_DP_CONTROLLER_LINK_SIZE0x0C00
-#define MSM_DP_CONTROLLER_P0_OFFSET0x1000
-#define MSM_DP_CONTROLLER_P0_SIZE  0x0400
-
 #define DP_INTERRUPT_STATUS1 \
(DP_INTR_AUX_I2C_DONE| \
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
@@ -66,82 +57,77 @@ void dp_catalog_snapshot(struct dp_catalog *dp_catalog, 
struct msm_disp_state *d
 {
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);
+   struct dss_io_data *dss = >io->dp_controller;
 
-   msm_disp_snapshot_add_block(disp_state, catalog->io->dp_controller.len,
-   catalog->io->dp_controller.base, "dp_ctrl");
+   msm_disp_snapshot_add_block(disp_state, dss->ahb_len, dss->ahb, 
"dp_ahb");
+   msm_disp_snapshot_add_block(disp_state, dss->aux_len, dss->aux, 
"dp_aux");
+   msm_disp_snapshot_add_block(disp_state, dss->link_len, dss->link, 
"dp_link");
+   msm_disp_snapshot_add_block(disp_state, dss->p0_len, dss->p0, "dp_p0");
 }
 
 static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_AUX_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.aux + offset);
 }
 
 static inline void dp_write_aux(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_AUX_OFFSET;
/*
 * To make sure aux reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.aux + offset);
 }
 
 static inline u32 dp_read_ahb(struct dp_catalog_private *catalog, u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_AHB_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.ahb + offset);
 }
 
 static inline void dp_write_ahb(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_AHB_OFFSET;
/*
 * To make sure phy reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.ahb + offset);
 }
 
 static inline void dp_write_p0(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_P0_OFFSET;
/*
 * To make sure interface reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.p0 + offset);
 }
 
 static inline u32 dp_read_p0(struct dp_catalog_private *catalog,
   u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_P0_OFFSET;
/*
 * To make sure interface reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.p0 + offset);
 }
 
 static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_LINK_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.link + offset);
 }
 
 static inline void dp_write_link(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_LINK_OFFSET;
   

[PATCH 2/5] drm/msm/dp: Use devres for ioremap()

2021-07-21 Thread Bjorn Andersson
The non-devres version of ioremap is used, which requires manual
cleanup. But the code paths leading here is mixed with other devres
users, so rely on this for ioremap as well to simplify the code.

Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/dp/dp_parser.c | 29 -
 1 file changed, 4 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 0519dd3ac3c3..c064ced78278 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -32,7 +32,7 @@ static int msm_dss_ioremap(struct platform_device *pdev,
}
 
io_data->len = (u32)resource_size(res);
-   io_data->base = ioremap(res->start, io_data->len);
+   io_data->base = devm_ioremap(>dev, res->start, io_data->len);
if (!io_data->base) {
DRM_ERROR("%pS->%s: ioremap failed\n",
__builtin_return_address(0), __func__);
@@ -42,22 +42,6 @@ static int msm_dss_ioremap(struct platform_device *pdev,
return 0;
 }
 
-static void msm_dss_iounmap(struct dss_io_data *io_data)
-{
-   if (io_data->base) {
-   iounmap(io_data->base);
-   io_data->base = NULL;
-   }
-   io_data->len = 0;
-}
-
-static void dp_parser_unmap_io_resources(struct dp_parser *parser)
-{
-   struct dp_io *io = >io;
-
-   msm_dss_iounmap(>dp_controller);
-}
-
 static int dp_parser_ctrl_res(struct dp_parser *parser)
 {
int rc = 0;
@@ -67,19 +51,14 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
rc = msm_dss_ioremap(pdev, >dp_controller);
if (rc) {
DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc);
-   goto err;
+   return rc;
}
 
io->phy = devm_phy_get(>dev, "dp");
-   if (IS_ERR(io->phy)) {
-   rc = PTR_ERR(io->phy);
-   goto err;
-   }
+   if (IS_ERR(io->phy))
+   return PTR_ERR(io->phy);
 
return 0;
-err:
-   dp_parser_unmap_io_resources(parser);
-   return rc;
 }
 
 static int dp_parser_misc(struct dp_parser *parser)
-- 
2.29.2



[PATCH 1/5] dt-bindings: msm/dp: Change reg definition

2021-07-21 Thread Bjorn Andersson
reg was defined as one region covering the entire DP block, but the
memory map is actually split in 4 regions and obviously the size of
these regions differs between platforms.

Switch the reg to require that all four regions are specified instead.
It is expected that the implementation will handle existing DTBs, even
though the schema defines the new layout.

Signed-off-by: Bjorn Andersson 
---
 .../bindings/display/msm/dp-controller.yaml   | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 64d8d9e5e47a..a6e41be038fc 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -19,7 +19,11 @@ properties:
   - qcom,sc7180-dp
 
   reg:
-maxItems: 1
+items:
+  - description: ahb register block
+  - description: aux register block
+  - description: link register block
+  - description: p0 register block
 
   interrupts:
 maxItems: 1
@@ -100,7 +104,10 @@ examples:
 
 displayport-controller@ae9 {
 compatible = "qcom,sc7180-dp";
-reg = <0xae9 0x1400>;
+reg = <0xae9 0x200>,
+  <0xae90200 0x200>,
+  <0xae90400 0xc00>,
+  <0xae91000 0x400>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
2.29.2



[PATCH 3/5] drm/msm/dp: Refactor ioremap wrapper

2021-07-21 Thread Bjorn Andersson
In order to deal with multiple memory ranges in the following commit
change the ioremap wrapper to not poke directly into the dss_io_data
struct.

Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/dp/dp_parser.c | 28 ++--
 drivers/gpu/drm/msm/dp/dp_parser.h |  2 +-
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index c064ced78278..e68dacef547c 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -19,39 +19,39 @@ static const struct dp_regulator_cfg sdm845_dp_reg_cfg = {
},
 };
 
-static int msm_dss_ioremap(struct platform_device *pdev,
-   struct dss_io_data *io_data)
+static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t 
*len)
 {
struct resource *res = NULL;
+   void __iomem *base;
 
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   res = platform_get_resource(pdev, IORESOURCE_MEM, idx);
if (!res) {
DRM_ERROR("%pS->%s: msm_dss_get_res failed\n",
__builtin_return_address(0), __func__);
-   return -ENODEV;
+   return ERR_PTR(-ENODEV);
}
 
-   io_data->len = (u32)resource_size(res);
-   io_data->base = devm_ioremap(>dev, res->start, io_data->len);
-   if (!io_data->base) {
+   base = devm_ioremap_resource(>dev, res);
+   if (!base) {
DRM_ERROR("%pS->%s: ioremap failed\n",
__builtin_return_address(0), __func__);
-   return -EIO;
+   return ERR_PTR(-EIO);
}
 
-   return 0;
+   *len = resource_size(res);
+   return base;
 }
 
 static int dp_parser_ctrl_res(struct dp_parser *parser)
 {
-   int rc = 0;
struct platform_device *pdev = parser->pdev;
struct dp_io *io = >io;
+   struct dss_io_data *dss = >dp_controller;
 
-   rc = msm_dss_ioremap(pdev, >dp_controller);
-   if (rc) {
-   DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc);
-   return rc;
+   dss->base = dp_ioremap(pdev, 0, >len);
+   if (IS_ERR(dss->base)) {
+   DRM_ERROR("unable to remap dp io region: %pe\n", dss->base);
+   return PTR_ERR(dss->base);
}
 
io->phy = devm_phy_get(>dev, "dp");
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h 
b/drivers/gpu/drm/msm/dp/dp_parser.h
index 34b49628bbaf..dc62e70b1640 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -26,7 +26,7 @@ enum dp_pm_type {
 };
 
 struct dss_io_data {
-   u32 len;
+   size_t len;
void __iomem *base;
 };
 
-- 
2.29.2



[PATCH 0/5] drm/msm/dp: Allow variation in register regions

2021-07-21 Thread Bjorn Andersson
It turns out that sc8180x (among others) doesn't have the same internal layout
of the 4 subblocks. This series therefor modifies the binding to require all
four regions to be described individually and then extends the driver to read
these four regions. The driver will fall back to read the old single-reg format
and apply the original offsets and sizes.

Bjorn Andersson (5):
  dt-bindings: msm/dp: Change reg definition
  drm/msm/dp: Use devres for ioremap()
  drm/msm/dp: Refactor ioremap wrapper
  drm/msm/dp: Store each subblock in the io region
  drm/msm/dp: Allow sub-regions to be specified in DT

 .../bindings/display/msm/dp-controller.yaml   |  11 +-
 drivers/gpu/drm/msm/dp/dp_catalog.c   |  64 ---
 drivers/gpu/drm/msm/dp/dp_parser.c| 102 +++---
 drivers/gpu/drm/msm/dp/dp_parser.h|  10 +-
 4 files changed, 102 insertions(+), 85 deletions(-)

-- 
2.29.2



Re: [PATCH 06/14] drm/i915/guc/slpc: Enable SLPC and add related H2G events

2021-07-21 Thread kernel test robot
Hi Vinay,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next 
tegra-drm/drm/tegra/for-next drm/drm-next v5.14-rc2 next-20210721]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-rhel-8.3-kselftests (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
# 
https://github.com/0day-ci/linux/commit/14352081e4f18759e70413f3be4151d623c97b8c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528
git checkout 14352081e4f18759e70413f3be4151d623c97b8c
# save the attached .config to linux build tree
make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:217:5: warning: no previous 
>> prototype for 'slpc_decode_min_freq' [-Wmissing-prototypes]
 217 | u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
 | ^~~~
>> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:229:5: warning: no previous 
>> prototype for 'slpc_decode_max_freq' [-Wmissing-prototypes]
 229 | u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
 | ^~~~


vim +/slpc_decode_min_freq +217 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c

   216  
 > 217  u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
   218  {
   219  struct slpc_shared_data *data = slpc->vaddr;
   220  
   221  GEM_BUG_ON(!slpc->vma);
   222  
   223  return  DIV_ROUND_CLOSEST(
   224  REG_FIELD_GET(SLPC_MIN_UNSLICE_FREQ_MASK,
   225  data->task_state_data.freq) *
   226  GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER);
   227  }
   228  
 > 229  u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
   230  {
   231  struct slpc_shared_data *data = slpc->vaddr;
   232  
   233  GEM_BUG_ON(!slpc->vma);
   234  
   235  return  DIV_ROUND_CLOSEST(
   236  REG_FIELD_GET(SLPC_MAX_UNSLICE_FREQ_MASK,
   237  data->task_state_data.freq) *
   238  GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER);
   239  }
   240  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel compatibles

2021-07-21 Thread Rob Herring
On Wed, Jul 21, 2021 at 04:03:40PM +0200, Maxime Ripard wrote:
> The binding mentions that all the drivers using that driver must use a
> vendor-specific compatible but never enforces it, nor documents the
> vendor-specific compatibles.
> 
> Let's make we document all of them, and that the binding will create an
> error if we add one that isn't.
> 
> Cc: dri-devel@lists.freedesktop.org
> Cc: Laurent Pinchart 
> Cc: Sam Ravnborg 
> Cc: Thierry Reding 
> Signed-off-by: Maxime Ripard 
> ---
>  .../bindings/display/panel/lvds.yaml   | 18 --
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml 
> b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> index 49460c9dceea..d1513111eb48 100644
> --- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> @@ -31,12 +31,18 @@ allOf:
>  
>  properties:
>compatible:
> -contains:
> -  const: panel-lvds
> -description:
> -  Shall contain "panel-lvds" in addition to a mandatory panel-specific
> -  compatible string defined in individual panel bindings. The 
> "panel-lvds"
> -  value shall never be used on its own.
> +items:
> +  - enum:
> +  - advantech,idk-1110wr

At least this one is documented elsewhere. You can add 'minItems: 2' if 
you want to just enforce having 2 compatibles. Or do:

items:
  - {}
  - const: panel-lvds

Which also enforces the order.

> +  - advantech,idk-2121wr
> +  - auo,b101ew05
> +  - innolux,ee101ia-01d
> +  - mitsubishi,aa104xd12
> +  - mitsubishi,aa121td01
> +  - sgd,gktw70sdae4se
> +  - sharp,lq150x1lg11
> +  - tbs,a711-panel
> +  - const: panel-lvds
>  
>data-mapping:
>  enum:
> -- 
> 2.31.1
> 
> 


Re: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel compatibles

2021-07-21 Thread Rob Herring
On Wed, 21 Jul 2021 16:03:40 +0200, Maxime Ripard wrote:
> The binding mentions that all the drivers using that driver must use a
> vendor-specific compatible but never enforces it, nor documents the
> vendor-specific compatibles.
> 
> Let's make we document all of them, and that the binding will create an
> error if we add one that isn't.
> 
> Cc: dri-devel@lists.freedesktop.org
> Cc: Laurent Pinchart 
> Cc: Sam Ravnborg 
> Cc: Thierry Reding 
> Signed-off-by: Maxime Ripard 
> ---
>  .../bindings/display/panel/lvds.yaml   | 18 --
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml:
 panel: compatible: ['sharp,lq150x1lg11'] is too short
From schema: 
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml:
 panel: 'data-mapping' is a required property
From schema: 
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml:
 panel: 'width-mm' is a required property
From schema: 
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml:
 panel: 'height-mm' is a required property
From schema: 
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml:
 panel: 'panel-timing' is a required property
From schema: 
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml:
 panel: 'oneOf' conditional failed, one must be fixed:
'port' is a required property
'ports' is a required property
From schema: 
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml
\ndoc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1508254

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



Re: [PATCH v2 3/3] drm/panel: Add ilitek ili9341 panel driver

2021-07-21 Thread Dillon Min
Hi Noralf

Thanks for your time to review my patch.

On Thu, 22 Jul 2021 at 01:42, Noralf Trønnes  wrote:
>
>
>
> Den 21.07.2021 09.41, skrev dillon.min...@gmail.com:
> > From: Dillon Min 
> >
> > This driver combine tiny/ili9341.c mipi_dbi_interface driver
> > with mipi_dpi_interface driver, can support ili9341 with serial
> > mode or parallel rgb interface mode by register configuration.
> >
> > Cc: Linus Walleij 
> > Signed-off-by: Dillon Min 
> > ---
>
> > +static const struct of_device_id ili9341_of_match[] = {
> > + {
> > + .compatible = "st,sf-tc240t-9370-t",
> > + .data = _stm32f429_disco_data,
> > + },
> > + {
> > + /* porting from tiny/ili9341.c
> > +  * for original mipi dbi compitable
> > +  */
> > + .compatible = "adafruit,yx240qv29",
>
> I don't understand this, now there will be 2 drivers that support the
> same display?

There is no reason to create two drivers to support the same display.

To support only-dbi and dbi+dpi panel at drm/panel or drm/tiny both
fine with me.

>
> AFAICT drm/tiny/ili9341.c is just copied into this driver, is the plan
> to remove the tiny/ driver? If so I couldn't see this mentioned anywhere.

Yes, I'd like to merge the code from drm/tiny/ili9341.c to this driver
(to make a single driver to support different bus).

I have two purpose to extend the feature drm/tiny/ili9341.c

- keep compatible = "adafruit,yx240qv29", add bus mode dts bindings (panel_bus)
  to define the interface which host wants to use. such as
panel_bus="dbi" or "rgb"
  or "i80" for this case, i will add dpi code to drm/tiny/ili9341.c.

- merge tiny/ili9341.c to this driver,remove drm/tiny/ili9341.c, add
new dts compatible
  string to support other interfaces. just like what i'm doing now.

I have no idea about your plan on drm/tiny drivers, actually some of
these panels under
the diny folder can support both dbi and dbi+dpi (much faster, need
more pins). no
doubt the requirement to support dpi is always there.

What is your preference?

Thanks & Regards
Dillon

>
> Noralf.
>
> > + .data = NULL,
> > + },
> > +};
> > +MODULE_DEVICE_TABLE(of, ili9341_of_match);


[PATCH v4] drm/mediatek: Fix cursor plane didn't update

2021-07-21 Thread jason-jh . lin
The cursor plane should use the current plane state in atomic_async_update
because it would not be the new plane state in the global atomic state
since _swap_state happened when those hook are run.

Fix cursor plane issue by below modification:
1. Remove plane_helper_funcs->atomic_update(plane, state) in
   mtk_drm_crtc_async_update.
2. Add mtk_drm_update_new_state in to mtk_plane_atomic_async_update to
   update the cursor plane by current plane state hook and update
   others plane by the new_state.

Fixes: 37418bf14c13 ("drm: Use state helper instead of the plane state pointer")
Signed-off-by: jason-jh.lin 
Tested-by: Enric Balletbo i Serra 
---
  Change in v4:
  - Fix compile warning:
../drivers/gpu/drm/mediatek/mtk_drm_crtc.c:578:39: warning: unused
variable ‘plane_helper_funcs’ [-Wunused-variable
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |  3 --
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 60 ++--
 2 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 40df2c823187..515315505e3b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -532,13 +532,10 @@ void mtk_drm_crtc_async_update(struct drm_crtc *crtc, 
struct drm_plane *plane,
   struct drm_atomic_state *state)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-   const struct drm_plane_helper_funcs *plane_helper_funcs =
-   plane->helper_private;
 
if (!mtk_crtc->enabled)
return;
 
-   plane_helper_funcs->atomic_update(plane, state);
mtk_drm_crtc_update_config(mtk_crtc, false);
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c 
b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index b5582dcf564c..e6dcb34d3052 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -110,6 +110,35 @@ static int mtk_plane_atomic_async_check(struct drm_plane 
*plane,
   true, true);
 }
 
+static void mtk_plane_update_new_state(struct drm_plane_state *new_state,
+  struct mtk_plane_state *mtk_plane_state)
+{
+   struct drm_framebuffer *fb = new_state->fb;
+   struct drm_gem_object *gem;
+   struct mtk_drm_gem_obj *mtk_gem;
+   unsigned int pitch, format;
+   dma_addr_t addr;
+
+   gem = fb->obj[0];
+   mtk_gem = to_mtk_gem_obj(gem);
+   addr = mtk_gem->dma_addr;
+   pitch = fb->pitches[0];
+   format = fb->format->format;
+
+   addr += (new_state->src.x1 >> 16) * fb->format->cpp[0];
+   addr += (new_state->src.y1 >> 16) * pitch;
+
+   mtk_plane_state->pending.enable = true;
+   mtk_plane_state->pending.pitch = pitch;
+   mtk_plane_state->pending.format = format;
+   mtk_plane_state->pending.addr = addr;
+   mtk_plane_state->pending.x = new_state->dst.x1;
+   mtk_plane_state->pending.y = new_state->dst.y1;
+   mtk_plane_state->pending.width = drm_rect_width(_state->dst);
+   mtk_plane_state->pending.height = drm_rect_height(_state->dst);
+   mtk_plane_state->pending.rotation = new_state->rotation;
+}
+
 static void mtk_plane_atomic_async_update(struct drm_plane *plane,
  struct drm_atomic_state *state)
 {
@@ -126,8 +155,10 @@ static void mtk_plane_atomic_async_update(struct drm_plane 
*plane,
plane->state->src_h = new_state->src_h;
plane->state->src_w = new_state->src_w;
swap(plane->state->fb, new_state->fb);
-   new_plane_state->pending.async_dirty = true;
 
+   mtk_plane_update_new_state(new_state, new_plane_state);
+   wmb(); /* Make sure the above parameters are set before update */
+   new_plane_state->pending.async_dirty = true;
mtk_drm_crtc_async_update(new_state->crtc, plane, state);
 }
 
@@ -189,14 +220,8 @@ static void mtk_plane_atomic_update(struct drm_plane 
*plane,
struct drm_plane_state *new_state = 
drm_atomic_get_new_plane_state(state,
   
plane);
struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(new_state);
-   struct drm_crtc *crtc = new_state->crtc;
-   struct drm_framebuffer *fb = new_state->fb;
-   struct drm_gem_object *gem;
-   struct mtk_drm_gem_obj *mtk_gem;
-   unsigned int pitch, format;
-   dma_addr_t addr;
 
-   if (!crtc || WARN_ON(!fb))
+   if (!new_state->crtc || WARN_ON(!new_state->fb))
return;
 
if (!new_state->visible) {
@@ -204,24 +229,7 @@ static void mtk_plane_atomic_update(struct drm_plane 
*plane,
return;
}
 
-   gem = fb->obj[0];
-   mtk_gem = to_mtk_gem_obj(gem);
-   addr = mtk_gem->dma_addr;
-   pitch = fb->pitches[0];
-   format = fb->format->format;
-
- 

Re: [PATCH 09/14] drm/i915/guc/slpc: Add debugfs for SLPC info

2021-07-21 Thread kernel test robot
Hi Vinay,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next 
tegra-drm/drm/tegra/for-next drm/drm-next v5.14-rc2 next-20210721]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-a016-20210720 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 
c781eb153bfbd1b52b03efe34f56bbeccbb8aba6)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# 
https://github.com/0day-ci/linux/commit/1c6f8cf3c2757db7a87fceef08834f4e0e14f2f9
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528
git checkout 1c6f8cf3c2757db7a87fceef08834f4e0e14f2f9
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c:67:6: warning: no previous 
>> prototype for function 'intel_eval_slpc_support' [-Wmissing-prototypes]
   bool intel_eval_slpc_support(void *data)
^
   drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c:67:1: note: declare 'static' 
if the function is not intended to be used outside of this translation unit
   bool intel_eval_slpc_support(void *data)
   ^
   static 
   1 warning generated.
--
   drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:238:5: warning: no previous 
prototype for function 'slpc_decode_min_freq' [-Wmissing-prototypes]
   u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
   ^
   drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:238:1: note: declare 'static' if 
the function is not intended to be used outside of this translation unit
   u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
   ^
   static 
   drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:250:5: warning: no previous 
prototype for function 'slpc_decode_max_freq' [-Wmissing-prototypes]
   u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
   ^
   drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:250:1: note: declare 'static' if 
the function is not intended to be used outside of this translation unit
   u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
   ^
   static 
>> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:445:17: warning: variable 'data' 
>> is uninitialized when used here [-Wuninitialized]
   slpc_tasks = >task_state_data;
 ^~~~
   drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:436:31: note: initialize the 
variable 'data' to silence this warning
   struct slpc_shared_data *data;
^
 = NULL
   3 warnings generated.


vim +/intel_eval_slpc_support +67 drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c

66  
  > 67  bool intel_eval_slpc_support(void *data)
68  {
69  struct intel_guc *guc;
70  
71  guc = (struct intel_guc *)data;
72  return intel_guc_slpc_is_used(guc);
73  }
74  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH 02/14] drm/i915/guc/slpc: Initial definitions for SLPC

2021-07-21 Thread Belgaumkar, Vinay




On 7/21/2021 10:24 AM, Michal Wajdeczko wrote:



On 21.07.2021 18:11, Vinay Belgaumkar wrote:

Add macros to check for SLPC support. This feature is currently supported
for Gen12+ and enabled whenever GuC submission is enabled/selected.

Include templates for SLPC init/fini and enable.

v2: Move SLPC helper functions to intel_guc_slpc.c/.h. Define basic
template for SLPC structure in intel_guc_slpc_types.h. Fix copyright (Michal W)

Signed-off-by: Vinay Belgaumkar 
Signed-off-by: Sundaresan Sujaritha 
Signed-off-by: Daniele Ceraolo Spurio 

drm/i915/guc/slpc: Lay out slpc init/enable/fini

Declare init/fini and enable function templates.

v2: Rebase

Signed-off-by: Vinay Belgaumkar 
Signed-off-by: Sundaresan Sujaritha 
---
  drivers/gpu/drm/i915/Makefile |  1 +
  drivers/gpu/drm/i915/gt/uc/intel_guc.c|  2 +
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|  4 ++
  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 63 +++
  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h   | 33 ++
  .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h | 15 +
  drivers/gpu/drm/i915/gt/uc/intel_uc.c |  6 +-
  drivers/gpu/drm/i915/gt/uc/intel_uc.h |  2 +
  8 files changed, 124 insertions(+), 2 deletions(-)
  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index ab7679957623..d8eac4468df9 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -186,6 +186,7 @@ i915-y += gt/uc/intel_uc.o \
  gt/uc/intel_guc_fw.o \
  gt/uc/intel_guc_log.o \
  gt/uc/intel_guc_log_debugfs.o \
+ gt/uc/intel_guc_slpc.o \
  gt/uc/intel_guc_submission.o \
  gt/uc/intel_huc.o \
  gt/uc/intel_huc_debugfs.o \
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 979128e28372..39bc3c16057b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -7,6 +7,7 @@
  #include "gt/intel_gt_irq.h"
  #include "gt/intel_gt_pm_irq.h"
  #include "intel_guc.h"
+#include "intel_guc_slpc.h"
  #include "intel_guc_ads.h"
  #include "intel_guc_submission.h"
  #include "i915_drv.h"
@@ -157,6 +158,7 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_ct_init_early(>ct);
intel_guc_log_init_early(>log);
intel_guc_submission_init_early(guc);
+   intel_guc_slpc_init_early(>slpc);
  
  	mutex_init(>send_mutex);

spin_lock_init(>irq_lock);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 9c62c68fb132..8cecfad9d7b1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -15,6 +15,7 @@
  #include "intel_guc_ct.h"
  #include "intel_guc_log.h"
  #include "intel_guc_reg.h"
+#include "intel_guc_slpc_types.h"
  #include "intel_uc_fw.h"
  #include "i915_utils.h"
  #include "i915_vma.h"
@@ -30,6 +31,7 @@ struct intel_guc {
struct intel_uc_fw fw;
struct intel_guc_log log;
struct intel_guc_ct ct;
+   struct intel_guc_slpc slpc;
  
  	/* Global engine used to submit requests to GuC */

struct i915_sched_engine *sched_engine;
@@ -57,6 +59,8 @@ struct intel_guc {
  
  	bool submission_supported;

bool submission_selected;
+   bool slpc_supported;
+   bool slpc_selected;
  
  	struct i915_vma *ads_vma;

struct __guc_ads_blob *ads_blob;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
new file mode 100644
index ..d9feb430ce35
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "intel_guc_slpc.h"
+#include "gt/intel_gt.h"
+
+static inline struct intel_guc *slpc_to_guc(struct intel_guc_slpc *slpc)
+{
+   return container_of(slpc, struct intel_guc, slpc);
+}
+
+static bool __detect_slpc_supported(struct intel_guc *guc)
+{
+   /* GuC SLPC is unavailable for pre-Gen12 */
+   return guc->submission_supported &&
+   GRAPHICS_VER(guc_to_gt(guc)->i915) >= 12;
+}
+
+static bool __guc_slpc_selected(struct intel_guc *guc)
+{
+   if (!intel_guc_slpc_is_supported(guc))
+   return false;
+
+   return guc->submission_selected;
+}
+
+void intel_guc_slpc_init_early(struct intel_guc_slpc *slpc)
+{
+   struct intel_guc *guc = slpc_to_guc(slpc);
+
+   guc->slpc_supported = __detect_slpc_supported(guc);
+   guc->slpc_selected = __guc_slpc_selected(guc);
+}
+
+int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
+{
+   return 0;
+}
+
+/*
+ * intel_guc_slpc_enable() - Start SLPC
+ * @slpc: pointer to 

Re: [PATCH] drm/mediatek: dpi: fix NULL dereference in mtk_dpi_bridge_atomic_check

2021-07-21 Thread Chun-Kuang Hu
Hi, Frank:

Frank Wunderlich  於 2021年7月12日 週一 下午4:08寫道:
>
> From: Frank Wunderlich 
>
> bridge->driver_private is not set (NULL) so use bridge_to_dpi(bridge)
> like it's done in bridge_atomic_get_output_bus_fmts

Applied to mediatek-drm-fixes [1], thanks.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-fixes

Regards,
Chun-Kuang.

>
> Fixes: ec8747c52434 ("drm/mediatek: dpi: Add bus format negotiation")
> Signed-off-by: Frank Wunderlich 
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index bced555648b0..a2eca1f66984 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -605,7 +605,7 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge 
> *bridge,
>struct drm_crtc_state *crtc_state,
>struct drm_connector_state *conn_state)
>  {
> -   struct mtk_dpi *dpi = bridge->driver_private;
> +   struct mtk_dpi *dpi = bridge_to_dpi(bridge);
> unsigned int out_bus_format;
>
> out_bus_format = bridge_state->output_bus_cfg.format;
> --
> 2.25.1
>
>
> ___
> Linux-mediatek mailing list
> linux-media...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


Re: [PATCH 06/18] drm/i915/guc: Implement GuC context operations for new inteface

2021-07-21 Thread Daniele Ceraolo Spurio




On 7/20/2021 6:51 PM, John Harrison wrote:

On 7/20/2021 15:39, Matthew Brost wrote:

Implement GuC context operations which includes GuC specific operations
alloc, pin, unpin, and destroy.

v2:
  (Daniel Vetter)
   - Use msleep_interruptible rather than cond_resched in busy loop
  (Michal)
   - Remove C++ style comment
v3:
  (Matthew Brost)
   - Drop GUC_ID_START
  (John Harrison)
   - Fix a bunch of typos
   - Use drm_err rather than drm_dbg for G2H errors
  (Daniele)
   - Fix ;; typo
   - Clean up sched state functions
   - Add lockdep for guc_id functions
   - Don't call __release_guc_id when guc_id is invalid
   - Use MISSING_CASE
   - Add comment in guc_context_pin
   - Use shorter path to rpm
  (Daniele / CI)
   - Don't call release_guc_id on an invalid guc_id in destroy

Signed-off-by: John Harrison 
Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/intel_context.c   |   5 +
  drivers/gpu/drm/i915/gt/intel_context_types.h |  22 +-
  drivers/gpu/drm/i915/gt/intel_lrc_reg.h   |   1 -
  drivers/gpu/drm/i915/gt/uc/intel_guc.h    |  40 ++
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   4 +
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 667 --
  drivers/gpu/drm/i915/i915_reg.h   |   1 +
  drivers/gpu/drm/i915/i915_request.c   |   1 +
  8 files changed, 686 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c

index bd63813c8a80..32fd6647154b 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -384,6 +384,11 @@ intel_context_init(struct intel_context *ce, 
struct intel_engine_cs *engine)

    mutex_init(>pin_mutex);
  +    spin_lock_init(>guc_state.lock);
+
+    ce->guc_id = GUC_INVALID_LRC_ID;
+    INIT_LIST_HEAD(>guc_id_link);
+
  i915_active_init(>active,
   __intel_context_active, __intel_context_retire, 0);
  }
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h

index 6d99631d19b9..606c480aec26 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -96,6 +96,7 @@ struct intel_context {
  #define CONTEXT_BANNED    6
  #define CONTEXT_FORCE_SINGLE_SUBMISSION    7
  #define CONTEXT_NOPREEMPT    8
+#define CONTEXT_LRCA_DIRTY    9
    struct {
  u64 timeout_us;
@@ -138,14 +139,29 @@ struct intel_context {
    u8 wa_bb_page; /* if set, page num reserved for context 
workarounds */

  +    struct {
+    /** lock: protects everything in guc_state */
+    spinlock_t lock;
+    /**
+ * sched_state: scheduling state of this context using GuC
+ * submission
+ */
+    u8 sched_state;
+    } guc_state;
+
  /* GuC scheduling state flags that do not require a lock. */
  atomic_t guc_sched_state_no_lock;
  +    /* GuC LRC descriptor ID */
+    u16 guc_id;
+
+    /* GuC LRC descriptor reference count */
+    atomic_t guc_id_ref;
+
  /*
- * GuC LRC descriptor ID - Not assigned in this patch but future 
patches

- * in the series will.
+ * GuC ID link - in list when unpinned but guc_id still valid in 
GuC

   */
-    u16 guc_id;
+    struct list_head guc_id_link;
  };
    #endif /* __INTEL_CONTEXT_TYPES__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h 
b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h

index 41e5350a7a05..49d4857ad9b7 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
+++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
@@ -87,7 +87,6 @@
  #define GEN11_CSB_WRITE_PTR_MASK    (GEN11_CSB_PTR_MASK << 0)
    #define MAX_CONTEXT_HW_ID    (1 << 21) /* exclusive */
-#define MAX_GUC_CONTEXT_HW_ID    (1 << 20) /* exclusive */
  #define GEN11_MAX_CONTEXT_HW_ID    (1 << 11) /* exclusive */
  /* in Gen12 ID 0x7FF is reserved to indicate idle */
  #define GEN12_MAX_CONTEXT_HW_ID    (GEN11_MAX_CONTEXT_HW_ID - 1)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h

index 8c7b92f699f1..30773cd699f5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -7,6 +7,7 @@
  #define _INTEL_GUC_H_
    #include 
+#include 
    #include "intel_uncore.h"
  #include "intel_guc_fw.h"
@@ -44,6 +45,14 @@ struct intel_guc {
  void (*disable)(struct intel_guc *guc);
  } interrupts;
  +    /*
+ * contexts_lock protects the pool of free guc ids and a linked 
list of

+ * guc ids available to be stolen
+ */
+    spinlock_t contexts_lock;
+    struct ida guc_ids;
+    struct list_head guc_id_list;
+
  bool submission_selected;
    struct i915_vma *ads_vma;
@@ -101,6 +110,34 @@ intel_guc_send_and_receive(struct intel_guc 
*guc, const u32 *action, u32 len,

   response_buf, response_buf_size, 0);
  }
  +static inline int intel_guc_send_busy_loop(struct intel_guc* guc,
+   

Re: [PATCH 06/51] drm/i915/guc: Implement GuC context operations for new inteface

2021-07-21 Thread Daniele Ceraolo Spurio




On 7/19/2021 9:04 PM, Matthew Brost wrote:

On Mon, Jul 19, 2021 at 05:51:46PM -0700, Daniele Ceraolo Spurio wrote:


On 7/16/2021 1:16 PM, Matthew Brost wrote:

Implement GuC context operations which includes GuC specific operations
alloc, pin, unpin, and destroy.

v2:
   (Daniel Vetter)
- Use msleep_interruptible rather than cond_resched in busy loop
   (Michal)
- Remove C++ style comment

Signed-off-by: John Harrison 
Signed-off-by: Matthew Brost 
---
   drivers/gpu/drm/i915/gt/intel_context.c   |   5 +
   drivers/gpu/drm/i915/gt/intel_context_types.h |  22 +-
   drivers/gpu/drm/i915/gt/intel_lrc_reg.h   |   1 -
   drivers/gpu/drm/i915/gt/uc/intel_guc.h|  40 ++
   drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   4 +
   .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 666 --
   drivers/gpu/drm/i915/i915_reg.h   |   1 +
   drivers/gpu/drm/i915/i915_request.c   |   1 +
   8 files changed, 685 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index bd63813c8a80..32fd6647154b 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -384,6 +384,11 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
mutex_init(>pin_mutex);
+   spin_lock_init(>guc_state.lock);
+
+   ce->guc_id = GUC_INVALID_LRC_ID;
+   INIT_LIST_HEAD(>guc_id_link);
+
i915_active_init(>active,
 __intel_context_active, __intel_context_retire, 0);
   }
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 6d99631d19b9..606c480aec26 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -96,6 +96,7 @@ struct intel_context {
   #define CONTEXT_BANNED   6
   #define CONTEXT_FORCE_SINGLE_SUBMISSION  7
   #define CONTEXT_NOPREEMPT8
+#define CONTEXT_LRCA_DIRTY 9
struct {
u64 timeout_us;
@@ -138,14 +139,29 @@ struct intel_context {
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
+   struct {
+   /** lock: protects everything in guc_state */
+   spinlock_t lock;
+   /**
+* sched_state: scheduling state of this context using GuC
+* submission
+*/
+   u8 sched_state;
+   } guc_state;
+
/* GuC scheduling state flags that do not require a lock. */
atomic_t guc_sched_state_no_lock;
+   /* GuC LRC descriptor ID */
+   u16 guc_id;
+
+   /* GuC LRC descriptor reference count */
+   atomic_t guc_id_ref;
+
/*
-* GuC LRC descriptor ID - Not assigned in this patch but future patches
-* in the series will.
+* GuC ID link - in list when unpinned but guc_id still valid in GuC
 */
-   u16 guc_id;
+   struct list_head guc_id_link;
   };
   #endif /* __INTEL_CONTEXT_TYPES__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h 
b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
index 41e5350a7a05..49d4857ad9b7 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
+++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
@@ -87,7 +87,6 @@
   #define GEN11_CSB_WRITE_PTR_MASK (GEN11_CSB_PTR_MASK << 0)
   #define MAX_CONTEXT_HW_ID(1 << 21) /* exclusive */
-#define MAX_GUC_CONTEXT_HW_ID  (1 << 20) /* exclusive */
   #define GEN11_MAX_CONTEXT_HW_ID  (1 << 11) /* exclusive */
   /* in Gen12 ID 0x7FF is reserved to indicate idle */
   #define GEN12_MAX_CONTEXT_HW_ID  (GEN11_MAX_CONTEXT_HW_ID - 1)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 8c7b92f699f1..30773cd699f5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -7,6 +7,7 @@
   #define _INTEL_GUC_H_
   #include 
+#include 
   #include "intel_uncore.h"
   #include "intel_guc_fw.h"
@@ -44,6 +45,14 @@ struct intel_guc {
void (*disable)(struct intel_guc *guc);
} interrupts;
+   /*
+* contexts_lock protects the pool of free guc ids and a linked list of
+* guc ids available to be stolen
+*/
+   spinlock_t contexts_lock;
+   struct ida guc_ids;
+   struct list_head guc_id_list;
+
bool submission_selected;
struct i915_vma *ads_vma;
@@ -101,6 +110,34 @@ intel_guc_send_and_receive(struct intel_guc *guc, const 
u32 *action, u32 len,
 response_buf, response_buf_size, 0);
   }
+static inline int intel_guc_send_busy_loop(struct intel_guc* guc,
+  const u32 *action,
+  u32 len,
+  bool loop)
+{
+   int err;
+   unsigned int sleep_period_ms = 1;

Re: [PATCH 06/14] drm/i915/guc/slpc: Enable SLPC and add related H2G events

2021-07-21 Thread kernel test robot
Hi Vinay,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next 
tegra-drm/drm/tegra/for-next drm/drm-next v5.14-rc2 next-20210721]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-a016-20210720 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 
c781eb153bfbd1b52b03efe34f56bbeccbb8aba6)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# 
https://github.com/0day-ci/linux/commit/14352081e4f18759e70413f3be4151d623c97b8c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528
git checkout 14352081e4f18759e70413f3be4151d623c97b8c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:217:5: warning: no previous 
>> prototype for function 'slpc_decode_min_freq' [-Wmissing-prototypes]
   u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
   ^
   drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:217:1: note: declare 'static' if 
the function is not intended to be used outside of this translation unit
   u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
   ^
   static 
>> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:229:5: warning: no previous 
>> prototype for function 'slpc_decode_max_freq' [-Wmissing-prototypes]
   u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
   ^
   drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:229:1: note: declare 'static' if 
the function is not intended to be used outside of this translation unit
   u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
   ^
   static 
   2 warnings generated.


vim +/slpc_decode_min_freq +217 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c

   216  
 > 217  u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
   218  {
   219  struct slpc_shared_data *data = slpc->vaddr;
   220  
   221  GEM_BUG_ON(!slpc->vma);
   222  
   223  return  DIV_ROUND_CLOSEST(
   224  REG_FIELD_GET(SLPC_MIN_UNSLICE_FREQ_MASK,
   225  data->task_state_data.freq) *
   226  GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER);
   227  }
   228  
 > 229  u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
   230  {
   231  struct slpc_shared_data *data = slpc->vaddr;
   232  
   233  GEM_BUG_ON(!slpc->vma);
   234  
   235  return  DIV_ROUND_CLOSEST(
   236  REG_FIELD_GET(SLPC_MAX_UNSLICE_FREQ_MASK,
   237  data->task_state_data.freq) *
   238  GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER);
   239  }
   240  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH v2 3/3] drm/panel: Add ilitek ili9341 panel driver

2021-07-21 Thread Dillon Min
Hi Sam,

Thanks for your time on my code review.

On Thu, 22 Jul 2021 at 00:56, Sam Ravnborg  wrote:
>
> Hi Dillon,
>
> On Wed, Jul 21, 2021 at 03:41:28PM +0800, dillon.min...@gmail.com wrote:
> > From: Dillon Min 
> >
> > This driver combine tiny/ili9341.c mipi_dbi_interface driver
> > with mipi_dpi_interface driver, can support ili9341 with serial
> > mode or parallel rgb interface mode by register configuration.
> >
> > Cc: Linus Walleij 
> > Signed-off-by: Dillon Min 
>
> I have not looked at the driver before, sorry for being late.
> A few nits in the following.

That's fine. thanks.

>
> Sam
>
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
>
> Spaces between blocks of includes.
> So linux/* goes in one block, video/* in next block, drm/* in the last
> block.
> Sort alphabetically in each block.

I will add this change to v3. thanks.

>
> > +
> > +/**
> > + * struct ili9341_config - the system specific ILI9341 configuration
> > + * @max_spi_speed: 1000
> > + */
> Unless you plan to pull this into our kernel-doc there is really no need
> for a kernel-doc marker. On the other hand W=1 builds will tell if you
> missed something. So there are arguments both ways.

This driver was following the drm/panel/panel-ilitek-ili9322.c style,
I didn't realize the /** ... */ is the kernel-doc marker before. just because
W=1 report some warnings, so i add all this marker to struct ili9341_config

I will remove all the kernel-doc markers, and try to build with W=1
again, thanks.

>
> > +struct ili9341_config {
> > + u32 max_spi_speed;
> > + /** @mode: the drm display mode */
> > + const struct drm_display_mode mode;
> > + /** @ca: TODO: need comments for this register */
> > + u8 ca[ILI9341_CA_LEN];
> > + /** @power_b: TODO: need comments for this register */
> > + u8 power_b[ILI9341_POWER_B_LEN];
> > + /** @power_seq: TODO: need comments for this register */
> > + u8 power_seq[ILI9341_POWER_SEQ_LEN];
> > + /** @dtca: TODO: need comments for this register */
> > + u8 dtca[ILI9341_DTCA_LEN];
> > + /** @dtcb: TODO: need comments for this register */
> > + u8 dtcb[ILI9341_DTCB_LEN];
> > + /** @power_a: TODO: need comments for this register */
> > + u8 power_a[ILI9341_POWER_A_LEN];
> > + /** @frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
> > + u8 frc[ILI9341_FRC_LEN];
> > + /** @prc: TODO: need comments for this register */
> > + u8 prc;
> > + /** @dfc_1: B6h DISCTRL (Display Function Control) */
> > + u8 dfc_1[ILI9341_DFC_1_LEN];
> > + /** @power_1: Power Control 1 (C0h) */
> > + u8 power_1;
> > + /** @power_2: Power Control 2 (C1h) */
> > + u8 power_2;
> > + /** @vcom_1: VCOM Control 1(C5h) */
> > + u8 vcom_1[ILI9341_VCOM_1_LEN];
> > + /** @vcom_2: VCOM Control 2(C7h) */
> > + u8 vcom_2;
> > + /** @address_mode: Memory Access Control (36h) */
> > + u8 address_mode;
> > + /** @g3amma_en: TODO: need comments for this register */
> > + u8 g3amma_en;
> > + /** @rgb_interface: RGB Interface Signal Control (B0h) */
> > + u8 rgb_interface;
> > + /** @dfc_2: refer to dfc_1 */
> > + u8 dfc_2[ILI9341_DFC_2_LEN];
> > + /** @column_addr: Column Address Set (2Ah) */
> > + u8 column_addr[ILI9341_COLUMN_ADDR_LEN];
> > + /** @page_addr: Page Address Set (2Bh) */
> > + u8 page_addr[ILI9341_PAGE_ADDR_LEN];
> > + /** @interface: Interface Control (F6h) */
> > + u8 interface[ILI9341_INTERFACE_LEN];
> > + /** @pixel_format: This command sets the pixel format for the RGB */
> > + /* image data used by
> > +  */
> > + u8 pixel_format;
> > + /** @gamma_curve: This command is used to select the desired Gamma */
> > + /* curve for the
> > +  */
> Make this a single comment block.

Okay.

>
> > + u8 gamma_curve;
> > + /** @pgamma: Positive Gamma Correction (E0h) */
> > + u8 pgamma[ILI9341_PGAMMA_LEN];
> > + /** @ngamma: Negative Gamma Correction (E1h) */
> > + u8 ngamma[ILI9341_NGAMMA_LEN];
> > +};
> > +
> > +struct ili9341 {
> > + struct device *dev;
> We will have struct device * both in drm_panel and in ili9341.
> You could brop the one in ili9341.

Okay, I will use the dev from 'struct drm_panel'.

>
> > + const struct ili9341_config *conf;
> > + struct drm_panel panel;
> > + struct gpio_desc *reset_gpio;
> > + struct gpio_desc *dc_gpio;
> > + struct mipi_dbi *dbi;
> > + u32 max_spi_speed;
> > + struct regulator_bulk_data supplies[3];
> > +};
> > +
> > +/*
> > + * The Stm32f429-disco board has a panel ili9341 connected to ltdc 
> > controller
> > + */
> > +static const struct ili9341_config ili9341_stm32f429_disco_data = {
> > + 

[PATCH v4] drm/msm/dp: add logs across DP driver for ease of debugging

2021-07-21 Thread maitreye
From: Maitreyee Rao 

Add trace points across the MSM DP driver to help debug
interop issues.

Changes in v4:
 - Changed goto statement and used if else-if

Signed-off-by: Maitreyee Rao 
---
 drivers/gpu/drm/msm/dp/dp_catalog.c |  8 ++--
 drivers/gpu/drm/msm/dp/dp_ctrl.c|  5 -
 drivers/gpu/drm/msm/dp/dp_display.c | 14 ++
 drivers/gpu/drm/msm/dp/dp_link.c| 35 ++-
 drivers/gpu/drm/msm/dp/dp_power.c   |  3 +++
 5 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 32f3575..958d3fa3 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -372,6 +372,7 @@ void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog 
*dp_catalog,
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);
 
+   DRM_DEBUG_DP("enable=%d\n", enable);
if (enable) {
/*
 * To make sure link reg writes happens before other operation,
@@ -580,6 +581,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog 
*dp_catalog,
 
config = (en ? config | intr_mask : config & ~intr_mask);
 
+   DRM_DEBUG_DP("intr_mask=%#x config=%#x\n", intr_mask, config);
dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK,
config & DP_DP_HPD_INT_MASK);
 }
@@ -610,6 +612,7 @@ u32 dp_catalog_link_is_connected(struct dp_catalog 
*dp_catalog)
u32 status;
 
status = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
+   DRM_DEBUG_DP("aux status: %#x\n", status);
status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT;
status &= DP_DP_HPD_STATE_STATUS_BITS_MASK;
 
@@ -685,6 +688,7 @@ void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog 
*dp_catalog,
/* Make sure to clear the current pattern before starting a new one */
dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0);
 
+   DRM_DEBUG_DP("pattern: %#x\n", pattern);
switch (pattern) {
case DP_PHY_TEST_PATTERN_D10_2:
dp_write_link(catalog, REG_DP_STATE_CTRL,
@@ -745,7 +749,7 @@ void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog 
*dp_catalog,
DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
break;
default:
-   DRM_DEBUG_DP("No valid test pattern requested:0x%x\n", pattern);
+   DRM_DEBUG_DP("No valid test pattern requested: %#x\n", pattern);
break;
}
 }
@@ -928,7 +932,7 @@ void dp_catalog_audio_config_acr(struct dp_catalog 
*dp_catalog)
select = dp_catalog->audio_data;
acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14);
 
-   DRM_DEBUG_DP("select = 0x%x, acr_ctrl = 0x%x\n", select, acr_ctrl);
+   DRM_DEBUG_DP("select: %#x, acr_ctrl: %#x\n", select, acr_ctrl);
 
dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 2a8955c..72de71a 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -122,7 +122,7 @@ void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl)
IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES))
pr_warn("PUSH_IDLE pattern timedout\n");
 
-   pr_debug("mainlink off done\n");
+   DRM_DEBUG_DP("mainlink off done\n");
 }
 
 static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl)
@@ -1013,6 +1013,8 @@ static int dp_ctrl_update_vx_px(struct dp_ctrl_private 
*ctrl)
u32 voltage_swing_level = link->phy_params.v_level;
u32 pre_emphasis_level = link->phy_params.p_level;
 
+   DRM_DEBUG_DP("voltage level: %d emphasis level: %d\n", 
voltage_swing_level,
+   pre_emphasis_level);
ret = dp_catalog_ctrl_update_vx_px(ctrl->catalog,
voltage_swing_level, pre_emphasis_level);
 
@@ -1384,6 +1386,7 @@ int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, 
bool reset)
if (reset)
dp_catalog_ctrl_reset(ctrl->catalog);
 
+   DRM_DEBUG_DP("flip=%d\n", flip);
dp_catalog_ctrl_phy_reset(ctrl->catalog);
phy_init(phy);
dp_catalog_ctrl_enable_irq(ctrl->catalog, true);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index cf9c645..f0a81f7 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -275,6 +275,8 @@ static bool dp_display_is_ds_bridge(struct dp_panel *panel)
 
 static bool dp_display_is_sink_count_zero(struct dp_display_private *dp)
 {
+   DRM_DEBUG_DP("present=%#x sink_count=%d\n", 
dp->panel->dpcd[DP_DOWNSTREAMPORT_PRESENT],
+   dp->link->sink_count);
return dp_display_is_ds_bridge(dp->panel) &&
(dp->link->sink_count == 0);
 }
@@ -320,6 +322,7 @@ static int 

Re: [PATCH 2/4] drm/i915/gt: nuke unused legacy engine hw_id

2021-07-21 Thread Lucas De Marchi

On Wed, Jul 21, 2021 at 03:47:22PM -0700, Matt Roper wrote:

On Tue, Jul 20, 2021 at 04:20:12PM -0700, Lucas De Marchi wrote:

The engine hw_id is only used by RING_FAULT_REG(), which is not used
since GRAPHICS_VER == 8. We tend to keep adding new defines just to be
consistent, but let's try to remove them and let them defined to 0 when
not used.


s/when not used/for engines that only exist on gen8+ platforms/

Reviewed-by: Matt Roper 

For historical reference, we did use hw_id on gen8+ platforms too until
relatively recently --- it was used to set the engine's guc_id as well
up until:

   commit c784e5249e773689e38d2bc1749f08b986621a26
   Author: John Harrison 
   Date:   Wed Oct 28 07:58:24 2020 -0700

   drm/i915/guc: Update to use firmware v49.0.1


thanks for digging this, I will add that to the commit message as well.

Lucas De Marchi


Re: [PATCH v2 3/3] drm/panel: Add ilitek ili9341 panel driver

2021-07-21 Thread Dillon Min
Hi Jagan

Thanks for your time to review my code.

On Wed, 21 Jul 2021 at 23:48, Jagan Teki  wrote:
>
> On Wed, Jul 21, 2021 at 1:11 PM  wrote:
> >
> > From: Dillon Min 
> >
> > This driver combine tiny/ili9341.c mipi_dbi_interface driver
> > with mipi_dpi_interface driver, can support ili9341 with serial
> > mode or parallel rgb interface mode by register configuration.
> >
> > Cc: Linus Walleij 
> > Signed-off-by: Dillon Min 
> > ---
> > changes in v2:
> > - replace vcc regulator to three bulk regulators(vci, vddi, vddi-led)
> >   according to linus suggestion, thanks.
> >
> >  drivers/gpu/drm/panel/Kconfig|  12 +
> >  drivers/gpu/drm/panel/Makefile   |   1 +
> >  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 778 
> > +++
> >  3 files changed, 791 insertions(+)
> >  create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> >
> > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> > index ef87d92cdf49..eb34b8d1b19a 100644
> > --- a/drivers/gpu/drm/panel/Kconfig
> > +++ b/drivers/gpu/drm/panel/Kconfig
> > @@ -124,6 +124,18 @@ config DRM_PANEL_ILITEK_IL9322
> >   Say Y here if you want to enable support for Ilitek IL9322
> >   QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
> >
> > +config DRM_PANEL_ILITEK_ILI9341
> > +   tristate "Ilitek ILI9341 240x320 QVGA panels"
> > +   depends on OF && SPI
> > +   depends on DRM_KMS_HELPER
> > +   depends on DRM_KMS_CMA_HELPER
> > +   depends on BACKLIGHT_CLASS_DEVICE
> > +   select DRM_MIPI_DBI
> > +   help
> > + Say Y here if you want to enable support for Ilitek IL9341
> > + QVGA (240x320) RGB panels. support serial & parallel rgb
> > + interface.
> > +
> >  config DRM_PANEL_ILITEK_ILI9881C
> > tristate "Ilitek ILI9881C-based panels"
> > depends on OF
> > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> > index cae4d976c069..0ecde184665d 100644
> > --- a/drivers/gpu/drm/panel/Makefile
> > +++ b/drivers/gpu/drm/panel/Makefile
> > @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += 
> > panel-elida-kd35t133.o
> >  obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
> >  obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += 
> > panel-feiyang-fy07024di26a30d.o
> >  obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
> > +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
> >  obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
> >  obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
> >  obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
> > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c 
> > b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> > new file mode 100644
> > index ..717b0b930e2f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> > @@ -0,0 +1,778 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Ilitek ILI9341 TFT LCD drm_panel driver.
> > + *
> > + * This panel can be configured to support:
> > + * - 16-bit parallel RGB interface
> > + * - 18-bit parallel RGB interface
> > + * - 4-line serial spi interface
> > + *
> > + * Copyright (C) 2021 Dillon Min 
> > + * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c
> > + * the reuse of DBI abstraction part referred from Linus's patch
> > + * "drm/panel: s6e63m0: Switch to DBI abstraction for SPI"
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
> > +#define ILI9341_FRC0xb1   /* Frame Rate Control register */
> > +#define ILI9341_DFC0xb6   /* Display Function Control register 
> > */
> > +#define ILI9341_POWER1 0xc0   /* Power Control 1 register */
> > +#define ILI9341_POWER2 0xc1   /* Power Control 2 register */
> > +#define ILI9341_VCOM1  0xc5   /* VCOM Control 1 register */
> > +#define ILI9341_VCOM2  0xc7   /* VCOM Control 2 register */
> > +#define ILI9341_POWERA 0xcb   /* Power control A register */
> > +#define ILI9341_POWERB 0xcf   /* Power control B register */
> > +#define ILI9341_PGAMMA 0xe0   /* Positive Gamma Correction 
> > register */
> > +#define ILI9341_NGAMMA 0xe1   /* Negative Gamma Correction 
> > register */
> > +#define ILI9341_DTCA   0xe8   /* Driver timing control A */
> > +#define ILI9341_DTCB   0xea   /* Driver timing control B */
> > +#define ILI9341_POWER_SEQ  0xed   /* Power on sequence register */
> > +#define ILI9341_3GAMMA_EN  0xf2   /* 3 Gamma enable register */
> > +#define 

Re: [PATCH 4/4] drm/i915/gt: nuke gen6_hw_id

2021-07-21 Thread Matt Roper
On Tue, Jul 20, 2021 at 04:20:14PM -0700, Lucas De Marchi wrote:
> This is only used by GRAPHICS_VER == 6 and GRAPHICS_VER == 7. All other
> recent platforms do not depend on this field, so it doesn't make much
> sense to keep it generic like that. Instead, just do a mapping from
> engine class to HW ID in the single place that is needed.
> 
> Signed-off-by: Lucas De Marchi 
> ---
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c| 6 --
>  drivers/gpu/drm/i915/gt/intel_engine_types.h | 8 
>  drivers/gpu/drm/i915/i915_reg.h  | 4 +++-
>  3 files changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index 508221de411c..0a04e8d90e9e 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -42,7 +42,6 @@
>  
>  #define MAX_MMIO_BASES 3
>  struct engine_info {
> - u8 gen6_hw_id;
>   u8 class;
>   u8 instance;
>   /* mmio bases table *must* be sorted in reverse graphics_ver order */
> @@ -54,7 +53,6 @@ struct engine_info {
>  
>  static const struct engine_info intel_engines[] = {
>   [RCS0] = {
> - .gen6_hw_id = RCS0_HW,
>   .class = RENDER_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -62,7 +60,6 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [BCS0] = {
> - .gen6_hw_id = BCS0_HW,
>   .class = COPY_ENGINE_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -70,7 +67,6 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VCS0] = {
> - .gen6_hw_id = VCS0_HW,
>   .class = VIDEO_DECODE_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -102,7 +98,6 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VECS0] = {
> - .gen6_hw_id = VECS0_HW,
>   .class = VIDEO_ENHANCEMENT_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -290,7 +285,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
> intel_engine_id id)
>   engine->i915 = i915;
>   engine->gt = gt;
>   engine->uncore = gt->uncore;
> - engine->gen6_hw_id = info->gen6_hw_id;
>   guc_class = engine_class_to_guc_class(info->class);
>   engine->guc_id = MAKE_GUC_ID(guc_class, info->instance);
>   engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases);
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
> b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> index 266422d8d1b1..64330bfb7641 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> @@ -28,13 +28,6 @@
>  #include "intel_wakeref.h"
>  #include "intel_workarounds_types.h"
>  
> -/* Legacy HW Engine ID */
> -
> -#define RCS0_HW  0
> -#define VCS0_HW  1
> -#define BCS0_HW  2
> -#define VECS0_HW 3
> -
>  /* Gen11+ HW Engine class + instance */
>  #define RENDER_CLASS 0
>  #define VIDEO_DECODE_CLASS   1
> @@ -268,7 +261,6 @@ struct intel_engine_cs {
>  
>   intel_engine_mask_t mask;
>  
> - u8 gen6_hw_id;
>   u8 class;
>   u8 instance;
>  
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 8750ffce9d61..d91386f4828e 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2572,7 +2572,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
>  #define   ARB_MODE_BWGTLB_DISABLE (1 << 9)
>  #define   ARB_MODE_SWIZZLE_BDW   (1 << 1)
>  #define RENDER_HWS_PGA_GEN7  _MMIO(0x04080)
> -#define RING_FAULT_REG(engine)   _MMIO(0x4094 + 0x100 * 
> (engine)->gen6_hw_id)
> +
> +#define _GEN6_ENGINE_CLASS_TO_ID(class) _PICK((class), 0, 1, 3, 2)
> +#define RING_FAULT_REG(engine)   _MMIO(0x4094 + 0x100 * 
> _GEN6_ENGINE_CLASS_TO_ID((engine)->class))

If you want to make this more clear to someone reading it down the road,
you could always do something explicit like:

  #define _RING_FAULT_REG_RCS0x4094
  #define _RING_FAULT_REG_VCS0x4194
  #define _RING_FAULT_REG_BCS0x4294
  #define _RING_FAULT_REG_VECS   0x4394
  #define RING_FAULT_REG(engine) _MMIO(_PICK((engine)->class, \
 _RING_FAULT_REG_RCS, \
 _RING_FAULT_REG_VCS, \
 _RING_FAULT_REG_VECS, \
 _RING_FAULT_REG_BCS))

But in general,

Reviewed-by: Matt Roper 


>  #define GEN8_RING_FAULT_REG  _MMIO(0x4094)
>  #define GEN12_RING_FAULT_REG _MMIO(0xcec4)
>  #define   GEN8_RING_FAULT_ENGINE_ID(x)   (((x) >> 12) & 0x7)
> -- 
> 2.31.1
> 

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC 

Re: [PATCH 3/4] drm/i915/gt: rename legacy engine->hw_id to engine->gen6_hw_id

2021-07-21 Thread Matt Roper
On Tue, Jul 20, 2021 at 04:20:13PM -0700, Lucas De Marchi wrote:
> We kept adding new engines and for that increasing hw_id unnecessarily:
> it's not used since GRAPHICS_VER == 8. Prepend "gen6" to the field and
> try to pack it in the structs to give a hint this field is actually not
> used in recent platforms.
> 
> Signed-off-by: Lucas De Marchi 

Reviewed-by: Matt Roper 

although if we apply patch #4 we could probably drop this intermediate
step.


Matt

> ---
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c| 12 ++--
>  drivers/gpu/drm/i915/gt/intel_engine_types.h |  2 +-
>  drivers/gpu/drm/i915/i915_reg.h  |  2 +-
>  3 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index a11f69f2e46e..508221de411c 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -42,7 +42,7 @@
>  
>  #define MAX_MMIO_BASES 3
>  struct engine_info {
> - unsigned int hw_id;
> + u8 gen6_hw_id;
>   u8 class;
>   u8 instance;
>   /* mmio bases table *must* be sorted in reverse graphics_ver order */
> @@ -54,7 +54,7 @@ struct engine_info {
>  
>  static const struct engine_info intel_engines[] = {
>   [RCS0] = {
> - .hw_id = RCS0_HW,
> + .gen6_hw_id = RCS0_HW,
>   .class = RENDER_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -62,7 +62,7 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [BCS0] = {
> - .hw_id = BCS0_HW,
> + .gen6_hw_id = BCS0_HW,
>   .class = COPY_ENGINE_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -70,7 +70,7 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VCS0] = {
> - .hw_id = VCS0_HW,
> + .gen6_hw_id = VCS0_HW,
>   .class = VIDEO_DECODE_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -102,7 +102,7 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VECS0] = {
> - .hw_id = VECS0_HW,
> + .gen6_hw_id = VECS0_HW,
>   .class = VIDEO_ENHANCEMENT_CLASS,
>   .instance = 0,
>   .mmio_bases = {
> @@ -290,7 +290,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
> intel_engine_id id)
>   engine->i915 = i915;
>   engine->gt = gt;
>   engine->uncore = gt->uncore;
> - engine->hw_id = info->hw_id;
> + engine->gen6_hw_id = info->gen6_hw_id;
>   guc_class = engine_class_to_guc_class(info->class);
>   engine->guc_id = MAKE_GUC_ID(guc_class, info->instance);
>   engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases);
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
> b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> index a107eb58ffa2..266422d8d1b1 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> @@ -264,11 +264,11 @@ struct intel_engine_cs {
>   enum intel_engine_id id;
>   enum intel_engine_id legacy_idx;
>  
> - unsigned int hw_id;
>   unsigned int guc_id;
>  
>   intel_engine_mask_t mask;
>  
> + u8 gen6_hw_id;
>   u8 class;
>   u8 instance;
>  
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 943fe485c662..8750ffce9d61 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2572,7 +2572,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
>  #define   ARB_MODE_BWGTLB_DISABLE (1 << 9)
>  #define   ARB_MODE_SWIZZLE_BDW   (1 << 1)
>  #define RENDER_HWS_PGA_GEN7  _MMIO(0x04080)
> -#define RING_FAULT_REG(engine)   _MMIO(0x4094 + 0x100 * (engine)->hw_id)
> +#define RING_FAULT_REG(engine)   _MMIO(0x4094 + 0x100 * 
> (engine)->gen6_hw_id)
>  #define GEN8_RING_FAULT_REG  _MMIO(0x4094)
>  #define GEN12_RING_FAULT_REG _MMIO(0xcec4)
>  #define   GEN8_RING_FAULT_ENGINE_ID(x)   (((x) >> 12) & 0x7)
> -- 
> 2.31.1
> 

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795


Re: [PATCH 2/4] drm/i915/gt: nuke unused legacy engine hw_id

2021-07-21 Thread Matt Roper
On Tue, Jul 20, 2021 at 04:20:12PM -0700, Lucas De Marchi wrote:
> The engine hw_id is only used by RING_FAULT_REG(), which is not used
> since GRAPHICS_VER == 8. We tend to keep adding new defines just to be
> consistent, but let's try to remove them and let them defined to 0 when
> not used.

s/when not used/for engines that only exist on gen8+ platforms/

Reviewed-by: Matt Roper 

For historical reference, we did use hw_id on gen8+ platforms too until
relatively recently --- it was used to set the engine's guc_id as well
up until:

commit c784e5249e773689e38d2bc1749f08b986621a26
Author: John Harrison 
Date:   Wed Oct 28 07:58:24 2020 -0700

drm/i915/guc: Update to use firmware v49.0.1


Matt

> 
> Signed-off-by: Lucas De Marchi 
> ---
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c| 4 
>  drivers/gpu/drm/i915/gt/intel_engine_types.h | 4 
>  2 files changed, 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index d561573ed98c..a11f69f2e46e 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -80,7 +80,6 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VCS1] = {
> - .hw_id = VCS1_HW,
>   .class = VIDEO_DECODE_CLASS,
>   .instance = 1,
>   .mmio_bases = {
> @@ -89,7 +88,6 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VCS2] = {
> - .hw_id = VCS2_HW,
>   .class = VIDEO_DECODE_CLASS,
>   .instance = 2,
>   .mmio_bases = {
> @@ -97,7 +95,6 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VCS3] = {
> - .hw_id = VCS3_HW,
>   .class = VIDEO_DECODE_CLASS,
>   .instance = 3,
>   .mmio_bases = {
> @@ -114,7 +111,6 @@ static const struct engine_info intel_engines[] = {
>   },
>   },
>   [VECS1] = {
> - .hw_id = VECS1_HW,
>   .class = VIDEO_ENHANCEMENT_CLASS,
>   .instance = 1,
>   .mmio_bases = {
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
> b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> index 1cb9c3b70b29..a107eb58ffa2 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> @@ -34,10 +34,6 @@
>  #define VCS0_HW  1
>  #define BCS0_HW  2
>  #define VECS0_HW 3
> -#define VCS1_HW  4
> -#define VCS2_HW  6
> -#define VCS3_HW  7
> -#define VECS1_HW 12
>  
>  /* Gen11+ HW Engine class + instance */
>  #define RENDER_CLASS 0
> -- 
> 2.31.1
> 

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795


Re: [v2 3/3] drm/msm/dsi: Add DSI support for SC7280

2021-07-21 Thread Stephen Boyd
Quoting Rajeev Nandan (2021-06-22 05:42:28)
> Add support for v2.5.0 DSI block in the SC7280 SoC.
>
> Signed-off-by: Rajeev Nandan 
> Reviewed-by: Dmitry Baryshkov 
> ---

Reviewed-by: Stephen Boyd 


Re: [v2 2/3] drm/msm/dsi: Add PHY configuration for SC7280

2021-07-21 Thread Stephen Boyd
Quoting Rajeev Nandan (2021-06-22 05:42:27)
> The SC7280 SoC uses the 7nm (V4.1) DSI PHY driver with
> different enable|disable regulator loads.
>
> Signed-off-by: Rajeev Nandan 
> Reviewed-by: Dmitry Baryshkov 
> ---

Reviewed-by: Stephen Boyd 


Re: [v2 1/3] dt-bindings: msm/dsi: Add sc7280 7nm dsi phy

2021-07-21 Thread Stephen Boyd
Quoting Rajeev Nandan (2021-06-22 05:42:26)
> The SC7280 SoC uses the 7nm (V4.1) DSI PHY driver.
>
> Signed-off-by: Rajeev Nandan 
> ---

Reviewed-by: Stephen Boyd 


Re: [PATCH 1/4] drm/i915/gt: fix platform prefix

2021-07-21 Thread Matt Roper
On Tue, Jul 20, 2021 at 04:20:11PM -0700, Lucas De Marchi wrote:
> gen8_clear_engine_error_register() is actually not used by
> GRAPHICS_VER >= 8, since for those we are using another register that is
> not engine-dependent. Fix the platform prefix, to make clear we are not
> using any GEN6_RING_FAULT_REG_* one GRAPHICS_VER >= 8.
> 
> Signed-off-by: Lucas De Marchi 

Reviewed-by: Matt Roper 

> ---
>  drivers/gpu/drm/i915/gt/intel_gt.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
> b/drivers/gpu/drm/i915/gt/intel_gt.c
> index e714e21c0a4d..a8efdd44e9cf 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -205,7 +205,7 @@ static void clear_register(struct intel_uncore *uncore, 
> i915_reg_t reg)
>   intel_uncore_rmw(uncore, reg, 0, 0);
>  }
>  
> -static void gen8_clear_engine_error_register(struct intel_engine_cs *engine)
> +static void gen6_clear_engine_error_register(struct intel_engine_cs *engine)
>  {
>   GEN6_RING_FAULT_REG_RMW(engine, RING_FAULT_VALID, 0);
>   GEN6_RING_FAULT_REG_POSTING_READ(engine);
> @@ -251,7 +251,7 @@ intel_gt_clear_error_registers(struct intel_gt *gt,
>   enum intel_engine_id id;
>  
>   for_each_engine_masked(engine, gt, engine_mask, id)
> - gen8_clear_engine_error_register(engine);
> + gen6_clear_engine_error_register(engine);
>   }
>  }
>  
> -- 
> 2.31.1
> 

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795


[PATCH][next] drm: Fix space indentations, replace with tabs

2021-07-21 Thread Colin King
From: Colin Ian King 

A couple of statements are indented with spaces, clean this up
by replacing spaces with tabs.

Signed-off-by: Colin Ian King 
---
 drivers/gpu/drm/drm_ioctl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index f454e0424086..c023da67ca7a 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -834,8 +834,8 @@ long drm_ioctl(struct file *filp,
if (drm_dev_is_unplugged(dev))
return -ENODEV;
 
-   if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE)
-   return -ENOTTY;
+   if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE)
+   return -ENOTTY;
 
is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;
 
-- 
2.31.1



Re: [PATCH v3] drm/msm/dp: add logs across DP driver for ease of debugging

2021-07-21 Thread maitreye

Hello Stephen,
Thanks again for the review comments



On 2021-07-20 22:31, Stephen Boyd wrote:

Quoting maitreye (2021-07-20 15:39:30)
diff --git a/drivers/gpu/drm/msm/dp/dp_link.c 
b/drivers/gpu/drm/msm/dp/dp_link.c

index be986da..316e8e6 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -1036,43 +1036,46 @@ int dp_link_process_request(struct dp_link 
*dp_link)


if (link->request.test_requested == DP_TEST_LINK_EDID_READ) {
dp_link->sink_request |= DP_TEST_LINK_EDID_READ;
-   return ret;
+   goto out;
}

ret = dp_link_process_ds_port_status_change(link);
if (!ret) {
dp_link->sink_request |= DS_PORT_STATUS_CHANGED;
-   return ret;
+   goto out;
}

ret = dp_link_process_link_training_request(link);
if (!ret) {
dp_link->sink_request |= DP_TEST_LINK_TRAINING;
-   return ret;
+   goto out;
}

ret = dp_link_process_phy_test_pattern_request(link);
if (!ret) {
dp_link->sink_request |= 
DP_TEST_LINK_PHY_TEST_PATTERN;

-   return ret;
+   goto out;
}

ret = dp_link_process_link_status_update(link);


if ret == 0 we go into the if below and goto out.


if (!ret) {
dp_link->sink_request |= DP_LINK_STATUS_UPDATED;
-   return ret;
+   goto out;
}


At this point ret != 0 due to the goto above.



if (dp_link_is_video_pattern_requested(link)) {
-   ret = 0;


And now we've removed the ret = 0 assignment from here.


dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN;
+   goto out;


And then we goto out. Isn't this a behavior change? Still feels like we
should be using if/else-if logic here instead of this goto maze.


}

if (dp_link_is_audio_pattern_requested(link)) {
dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN;
-   return -EINVAL;
+   ret = -EINVAL;
+   goto out;
}

+out:
+   DRM_DEBUG_DP("sink request=%#x", dp_link->sink_request);
return ret;
 }



Thank you. I see what you are saying, and yes it makes sense, I'll 
change it to if else-if logic.


[pull] amdgpu drm-fixes-5.14

2021-07-21 Thread Alex Deucher
Hi Dave, Daniel,

Updates for 5.14.  Mostly fixes for new asics added in 5.14.

The following changes since commit 876d98e5511d8cfd12fc617a6717e7a8ea07be17:

  Merge tag 'drm-intel-fixes-2021-07-15' of 
git://anongit.freedesktop.org/drm/drm-intel into drm-fixes (2021-07-16 10:53:02 
+1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-5.14-2021-07-21

for you to fetch changes up to d80cded9cc25f841d5250d2e94a7b42be1e81c97:

  drm/amdgpu - Corrected the video codecs array name for yellow carp 
(2021-07-21 17:47:28 -0400)


amd-drm-fixes-5.14-2021-07-21:

amdgpu:
- Yellow Carp updates
- Add some Yellow Carp DIDs
- Beige Goby updates
- CIK 10bit 4K regression fix
- GFX10 golden settings updates
- eDP panel regression fix
- Misc display fixes
- Aldebaran fix


Aaron Liu (2):
  drm/amdgpu: update yellow carp external rev_id handling
  drm/amdgpu: add yellow carp pci id (v2)

Bindu Ramamurthy (2):
  drm/amd/display: Populate socclk entries for dcn3.02/3.03
  drm/amd/display: Populate dtbclk entries for dcn3.02/3.03

Camille Cho (1):
  drm/amd/display: Only set default brightness for OLED

Eric Yang (2):
  drm/amd/display: implement workaround for riommu related hang
  drm/amd/display: change zstate allow msg condition

Lijo Lazar (1):
  drm/amd/pm: Support board calibration on aldebaran

Likun Gao (1):
  drm/amdgpu: update golden setting for sienna_cichlid

Liviu Dudau (1):
  drm/amd/display: Fix 10bit 4K display on CIK GPUs

Mikita Lipski (1):
  drm/amd/display: Remove MALL function from DCN3.1

Nevenko Stupar (1):
  drm/amd/display: Line Buffer changes

Nicholas Kazlauskas (3):
  drm/amd/display: Fix max vstartup calculation for modes with borders
  drm/amd/display: Query VCO frequency from register for DCN3.1
  drm/amd/display: Update bounding box for DCN3.1

Stylon Wang (1):
  drm/amd/display: Fix ASSR regression on embedded panels

Tao Zhou (2):
  drm/amdgpu: update gc golden setting for dimgrey_cavefish
  drm/amd/pm: update DRIVER_IF_VERSION for beige_goby

Veerabadhran Gopalakrishnan (3):
  amdgpu/nv.c - Added video codec support for Yellow Carp
  amdgpu/nv.c - Optimize code for video codec support structure
  drm/amdgpu - Corrected the video codecs array name for yellow carp

Victor Lu (1):
  drm/amd/display: Fix comparison error in dcn21 DML

Xiaojian Du (1):
  drm/amdgpu: update the golden setting for vangogh

 drivers/gpu/drm/amd/amdgpu/amdgpu.h|   7 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|   4 +
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |   3 +
 drivers/gpu/drm/amd/amdgpu/nv.c| 248 +
 drivers/gpu/drm/amd/amdgpu/soc15.c | 176 ++-
 .../amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c   |   4 +
 .../amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c   |  59 -
 .../amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h   |  54 -
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |  12 +-
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c  |   2 +-
 drivers/gpu/drm/amd/display/dc/dc.h|  10 +-
 drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h |   4 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c  |   7 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c  |  50 +++--
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c   |  16 --
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h   |   3 +-
 .../drm/amd/display/dc/dcn302/dcn302_resource.c|  13 +-
 .../drm/amd/display/dc/dcn303/dcn303_resource.c|  13 +-
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c |  18 ++
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h |   1 +
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c  |   3 +-
 .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c  |   4 +
 .../amd/display/dc/dml/dcn21/display_mode_vba_21.c |   2 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/transform.h  |   3 +
 .../drm/amd/display/dc/inc/hw_sequencer_private.h  |   1 +
 drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h   |   3 +-
 drivers/gpu/drm/amd/pm/inc/smu_types.h |   3 +-
 drivers/gpu/drm/amd/pm/inc/smu_v11_0.h |   2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c |  46 +++-
 29 files changed, 288 insertions(+), 483 deletions(-)


[PATCH 18/18] drm/i915: Add intel_context tracing

2021-07-21 Thread Matthew Brost
Add intel_context tracing. These trace points are particular helpful
when debugging the GuC firmware and can be enabled via
CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS kernel config option.

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |   6 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  14 ++
 drivers/gpu/drm/i915/i915_trace.h | 145 ++
 3 files changed, 165 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 91349d071e0e..251ff7eea22d 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -8,6 +8,7 @@
 
 #include "i915_drv.h"
 #include "i915_globals.h"
+#include "i915_trace.h"
 
 #include "intel_context.h"
 #include "intel_engine.h"
@@ -28,6 +29,7 @@ static void rcu_context_free(struct rcu_head *rcu)
 {
struct intel_context *ce = container_of(rcu, typeof(*ce), rcu);
 
+   trace_intel_context_free(ce);
kmem_cache_free(global.slab_ce, ce);
 }
 
@@ -46,6 +48,7 @@ intel_context_create(struct intel_engine_cs *engine)
return ERR_PTR(-ENOMEM);
 
intel_context_init(ce, engine);
+   trace_intel_context_create(ce);
return ce;
 }
 
@@ -268,6 +271,8 @@ int __intel_context_do_pin_ww(struct intel_context *ce,
 
GEM_BUG_ON(!intel_context_is_pinned(ce)); /* no overflow! */
 
+   trace_intel_context_do_pin(ce);
+
 err_unlock:
mutex_unlock(>pin_mutex);
 err_post_unpin:
@@ -323,6 +328,7 @@ void __intel_context_do_unpin(struct intel_context *ce, int 
sub)
 */
intel_context_get(ce);
intel_context_active_release(ce);
+   trace_intel_context_do_unpin(ce);
intel_context_put(ce);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index d47a8358c831..26aadad10b12 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -344,6 +344,7 @@ static int guc_add_request(struct intel_guc *guc, struct 
i915_request *rq)
 
err = intel_guc_send_nb(guc, action, len, g2h_len_dw);
if (!enabled && !err) {
+   trace_intel_context_sched_enable(ce);
atomic_inc(>outstanding_submission_g2h);
set_context_enabled(ce);
} else if (!enabled) {
@@ -815,6 +816,8 @@ static int register_context(struct intel_context *ce)
u32 offset = intel_guc_ggtt_offset(guc, guc->lrc_desc_pool) +
ce->guc_id * sizeof(struct guc_lrc_desc);
 
+   trace_intel_context_register(ce);
+
return __guc_action_register_context(guc, ce->guc_id, offset);
 }
 
@@ -835,6 +838,8 @@ static int deregister_context(struct intel_context *ce, u32 
guc_id)
 {
struct intel_guc *guc = ce_to_guc(ce);
 
+   trace_intel_context_deregister(ce);
+
return __guc_action_deregister_context(guc, guc_id);
 }
 
@@ -908,6 +913,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce)
 * registering this context.
 */
if (context_registered) {
+   trace_intel_context_steal_guc_id(ce);
set_context_wait_for_deregister_to_register(ce);
intel_context_get(ce);
 
@@ -971,6 +977,7 @@ static void __guc_context_sched_disable(struct intel_guc 
*guc,
 
GEM_BUG_ON(guc_id == GUC_INVALID_LRC_ID);
 
+   trace_intel_context_sched_disable(ce);
intel_context_get(ce);
 
guc_submission_send_busy_loop(guc, action, ARRAY_SIZE(action),
@@ -1133,6 +1140,9 @@ static void __guc_signal_context_fence(struct 
intel_context *ce)
 
lockdep_assert_held(>guc_state.lock);
 
+   if (!list_empty(>guc_state.fences))
+   trace_intel_context_fence_release(ce);
+
list_for_each_entry(rq, >guc_state.fences, guc_fence_link)
i915_sw_fence_complete(>submit);
 
@@ -1538,6 +1548,8 @@ int intel_guc_deregister_done_process_msg(struct 
intel_guc *guc,
if (unlikely(!ce))
return -EPROTO;
 
+   trace_intel_context_deregister_done(ce);
+
if (context_wait_for_deregister_to_register(ce)) {
struct intel_runtime_pm *runtime_pm =
>engine->gt->i915->runtime_pm;
@@ -1589,6 +1601,8 @@ int intel_guc_sched_done_process_msg(struct intel_guc 
*guc,
return -EPROTO;
}
 
+   trace_intel_context_sched_done(ce);
+
if (context_pending_enable(ce)) {
clr_context_pending_enable(ce);
} else if (context_pending_disable(ce)) {
diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index 478f5427531d..68b70626c3e2 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -895,6 +895,91 @@ TRACE_EVENT(i915_request_out,
  __entry->ctx, 

[PATCH 15/18] drm/i915/guc: Update intel_gt_wait_for_idle to work with GuC

2021-07-21 Thread Matthew Brost
When running the GuC the GPU can't be considered idle if the GuC still
has contexts pinned. As such, a call has been added in
intel_gt_wait_for_idle to idle the UC and in turn the GuC by waiting for
the number of unpinned contexts to go to zero.

v2: rtimeout -> remaining_timeout
v3: Drop unnecessary includes, guc_submission_busy_loop ->
guc_submission_send_busy_loop, drop negatie timeout trick, move a
refactor of guc_context_unpin to earlier path (John H)
v4: Add stddef.h back into intel_gt_requests.h, sort circuit idle
function if not in GuC submission mode

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  |  3 +-
 drivers/gpu/drm/i915/gt/intel_gt.c| 19 
 drivers/gpu/drm/i915/gt/intel_gt.h|  2 +
 drivers/gpu/drm/i915/gt/intel_gt_requests.c   | 21 ++---
 drivers/gpu/drm/i915/gt/intel_gt_requests.h   |  9 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h |  4 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 88 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |  5 ++
 drivers/gpu/drm/i915/i915_gem_evict.c |  1 +
 .../gpu/drm/i915/selftests/igt_live_test.c|  2 +-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  3 +-
 13 files changed, 134 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 2f3b7dc7b0e6..5130e8ed9564 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -645,7 +645,8 @@ mmap_offset_attach(struct drm_i915_gem_object *obj,
goto insert;
 
/* Attempt to reap some mmap space from dead objects */
-   err = intel_gt_retire_requests_timeout(>gt, MAX_SCHEDULE_TIMEOUT);
+   err = intel_gt_retire_requests_timeout(>gt, MAX_SCHEDULE_TIMEOUT,
+  NULL);
if (err)
goto err;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index e714e21c0a4d..acfdd53b2678 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -585,6 +585,25 @@ static void __intel_gt_disable(struct intel_gt *gt)
GEM_BUG_ON(intel_gt_pm_is_awake(gt));
 }
 
+int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
+{
+   long remaining_timeout;
+
+   /* If the device is asleep, we have no requests outstanding */
+   if (!intel_gt_pm_is_awake(gt))
+   return 0;
+
+   while ((timeout = intel_gt_retire_requests_timeout(gt, timeout,
+  _timeout)) 
> 0) {
+   cond_resched();
+   if (signal_pending(current))
+   return -EINTR;
+   }
+
+   return timeout ? timeout : intel_uc_wait_for_idle(>uc,
+ remaining_timeout);
+}
+
 int intel_gt_init(struct intel_gt *gt)
 {
int err;
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index e7aabe0cc5bf..74e771871a9b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -48,6 +48,8 @@ void intel_gt_driver_release(struct intel_gt *gt);
 
 void intel_gt_driver_late_release(struct intel_gt *gt);
 
+int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout);
+
 void intel_gt_check_and_clear_faults(struct intel_gt *gt);
 void intel_gt_clear_error_registers(struct intel_gt *gt,
intel_engine_mask_t engine_mask);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.c 
b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
index 647eca9d867a..edb881d75630 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
@@ -130,7 +130,8 @@ void intel_engine_fini_retire(struct intel_engine_cs 
*engine)
GEM_BUG_ON(engine->retire);
 }
 
-long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
+long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout,
+ long *remaining_timeout)
 {
struct intel_gt_timelines *timelines = >timelines;
struct intel_timeline *tl, *tn;
@@ -195,22 +196,10 @@ out_active:   spin_lock(>lock);
if (flush_submission(gt, timeout)) /* Wait, there's more! */
active_count++;
 
-   return active_count ? timeout : 0;
-}
-
-int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
-{
-   /* If the device is asleep, we have no requests outstanding */
-   if (!intel_gt_pm_is_awake(gt))
-   return 0;
-
-   while ((timeout = intel_gt_retire_requests_timeout(gt, timeout)) > 0) {
-   cond_resched();
-   if (signal_pending(current))
-   

[PATCH 16/18] drm/i915/guc: Update GuC debugfs to support new GuC

2021-07-21 Thread Matthew Brost
Update GuC debugfs to support the new GuC structures.

v2:
 (John Harrison)
  - Remove intel_lrc_reg.h include from i915_debugfs.c
 (Michal)
  - Rename GuC debugfs functions

Signed-off-by: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 22 
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h |  3 +
 .../gpu/drm/i915/gt/uc/intel_guc_debugfs.c| 23 +++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 55 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.h |  5 ++
 5 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index b6bbbdb4c689..8bb6b1bbcea1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1174,3 +1174,25 @@ void intel_guc_ct_event_handler(struct intel_guc_ct *ct)
 
ct_try_receive_message(ct);
 }
+
+void intel_guc_ct_print_info(struct intel_guc_ct *ct,
+struct drm_printer *p)
+{
+   drm_printf(p, "CT %s\n", enableddisabled(ct->enabled));
+
+   if (!ct->enabled)
+   return;
+
+   drm_printf(p, "H2G Space: %u\n",
+  atomic_read(>ctbs.send.space) * 4);
+   drm_printf(p, "Head: %u\n",
+  ct->ctbs.send.desc->head);
+   drm_printf(p, "Tail: %u\n",
+  ct->ctbs.send.desc->tail);
+   drm_printf(p, "G2H Space: %u\n",
+  atomic_read(>ctbs.recv.space) * 4);
+   drm_printf(p, "Head: %u\n",
+  ct->ctbs.recv.desc->head);
+   drm_printf(p, "Tail: %u\n",
+  ct->ctbs.recv.desc->tail);
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
index 2758ee849a59..f709a19c7e21 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
@@ -16,6 +16,7 @@
 
 struct i915_vma;
 struct intel_guc;
+struct drm_printer;
 
 /**
  * DOC: Command Transport (CT).
@@ -114,4 +115,6 @@ int intel_guc_ct_send(struct intel_guc_ct *ct, const u32 
*action, u32 len,
  u32 *response_buf, u32 response_buf_size, u32 flags);
 void intel_guc_ct_event_handler(struct intel_guc_ct *ct);
 
+void intel_guc_ct_print_info(struct intel_guc_ct *ct, struct drm_printer *p);
+
 #endif /* _INTEL_GUC_CT_H_ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
index fe7cb7b29a1e..7a454c91a736 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
@@ -9,6 +9,8 @@
 #include "intel_guc.h"
 #include "intel_guc_debugfs.h"
 #include "intel_guc_log_debugfs.h"
+#include "gt/uc/intel_guc_ct.h"
+#include "gt/uc/intel_guc_submission.h"
 
 static int guc_info_show(struct seq_file *m, void *data)
 {
@@ -22,16 +24,35 @@ static int guc_info_show(struct seq_file *m, void *data)
drm_puts(, "\n");
intel_guc_log_info(>log, );
 
-   /* Add more as required ... */
+   if (!intel_guc_submission_is_used(guc))
+   return 0;
+
+   intel_guc_ct_print_info(>ct, );
+   intel_guc_submission_print_info(guc, );
 
return 0;
 }
 DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_info);
 
+static int guc_registered_contexts_show(struct seq_file *m, void *data)
+{
+   struct intel_guc *guc = m->private;
+   struct drm_printer p = drm_seq_file_printer(m);
+
+   if (!intel_guc_submission_is_used(guc))
+   return -ENODEV;
+
+   intel_guc_submission_print_context_info(guc, );
+
+   return 0;
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_registered_contexts);
+
 void intel_guc_debugfs_register(struct intel_guc *guc, struct dentry *root)
 {
static const struct debugfs_gt_file files[] = {
{ "guc_info", _info_fops, NULL },
+   { "guc_registered_contexts", _registered_contexts_fops, 
NULL },
};
 
if (!intel_guc_is_supported(guc))
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index e4ce21c9b7ef..e6e5364beb1c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1609,3 +1609,58 @@ int intel_guc_sched_done_process_msg(struct intel_guc 
*guc,
 
return 0;
 }
+
+void intel_guc_submission_print_info(struct intel_guc *guc,
+struct drm_printer *p)
+{
+   struct i915_sched_engine *sched_engine = guc->sched_engine;
+   struct rb_node *rb;
+   unsigned long flags;
+
+   if (!sched_engine)
+   return;
+
+   drm_printf(p, "GuC Number Outstanding Submission G2H: %u\n",
+  atomic_read(>outstanding_submission_g2h));
+   drm_printf(p, "GuC tasklet count: %u\n\n",
+  atomic_read(_engine->tasklet.count));
+
+   

[PATCH 11/18] drm/i915: Disable preempt busywait when using GuC scheduling

2021-07-21 Thread Matthew Brost
Disable preempt busywait when using GuC scheduling. This isn't needed as
the GuC controls preemption when scheduling.

v2:
 (John H):
  - Fix commit message

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index a69f5c438c72..b29eb9fd0009 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -506,7 +506,8 @@ gen8_emit_fini_breadcrumb_tail(struct i915_request *rq, u32 
*cs)
*cs++ = MI_USER_INTERRUPT;
 
*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
-   if (intel_engine_has_semaphores(rq->engine))
+   if (intel_engine_has_semaphores(rq->engine) &&
+   !intel_uc_uses_guc_submission(>engine->gt->uc))
cs = emit_preempt_busywait(rq, cs);
 
rq->tail = intel_ring_offset(rq, cs);
@@ -598,7 +599,8 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
*cs++ = MI_USER_INTERRUPT;
 
*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
-   if (intel_engine_has_semaphores(rq->engine))
+   if (intel_engine_has_semaphores(rq->engine) &&
+   !intel_uc_uses_guc_submission(>engine->gt->uc))
cs = gen12_emit_preempt_busywait(rq, cs);
 
rq->tail = intel_ring_offset(rq, cs);
-- 
2.28.0



[PATCH 05/18] drm/i915/guc: Add bypass tasklet submission path to GuC

2021-07-21 Thread Matthew Brost
Add bypass tasklet submission path to GuC. The tasklet is only used if H2G
channel has backpresure.

Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 37 +++
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ca0717166a27..53b4a5eb4a85 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -172,6 +172,12 @@ static int guc_add_request(struct intel_guc *guc, struct 
i915_request *rq)
return err;
 }
 
+static inline void guc_set_lrc_tail(struct i915_request *rq)
+{
+   rq->context->lrc_reg_state[CTX_RING_TAIL] =
+   intel_ring_set_tail(rq->ring, rq->tail);
+}
+
 static inline int rq_prio(const struct i915_request *rq)
 {
return rq->sched.attr.priority;
@@ -215,8 +221,7 @@ static int guc_dequeue_one_context(struct intel_guc *guc)
}
 done:
if (submit) {
-   last->context->lrc_reg_state[CTX_RING_TAIL] =
-   intel_ring_set_tail(last->ring, last->tail);
+   guc_set_lrc_tail(last);
 resubmit:
/*
 * We only check for -EBUSY here even though it is possible for
@@ -496,20 +501,36 @@ static inline void queue_request(struct i915_sched_engine 
*sched_engine,
set_bit(I915_FENCE_FLAG_PQUEUE, >fence.flags);
 }
 
+static int guc_bypass_tasklet_submit(struct intel_guc *guc,
+struct i915_request *rq)
+{
+   int ret;
+
+   __i915_request_submit(rq);
+
+   trace_i915_request_in(rq, 0);
+
+   guc_set_lrc_tail(rq);
+   ret = guc_add_request(guc, rq);
+   if (ret == -EBUSY)
+   guc->stalled_request = rq;
+
+   return ret;
+}
+
 static void guc_submit_request(struct i915_request *rq)
 {
struct i915_sched_engine *sched_engine = rq->engine->sched_engine;
+   struct intel_guc *guc = >engine->gt->uc.guc;
unsigned long flags;
 
/* Will be called from irq-context when using foreign fences. */
spin_lock_irqsave(_engine->lock, flags);
 
-   queue_request(sched_engine, rq, rq_prio(rq));
-
-   GEM_BUG_ON(i915_sched_engine_is_empty(sched_engine));
-   GEM_BUG_ON(list_empty(>sched.link));
-
-   tasklet_hi_schedule(_engine->tasklet);
+   if (guc->stalled_request || !i915_sched_engine_is_empty(sched_engine))
+   queue_request(sched_engine, rq, rq_prio(rq));
+   else if (guc_bypass_tasklet_submit(guc, rq) == -EBUSY)
+   tasklet_hi_schedule(_engine->tasklet);
 
spin_unlock_irqrestore(_engine->lock, flags);
 }
-- 
2.28.0



[PATCH 13/18] drm/i915/guc: Disable semaphores when using GuC scheduling

2021-07-21 Thread Matthew Brost
Semaphores are an optimization and not required for basic GuC submission
to work properly. Disable until we have time to do the implementation to
enable semaphores and tune them for performance. Also long direction is
just to delete semaphores from the i915 so another reason to not enable
these for GuC submission.

This patch fixes an existing bugs where I915_ENGINE_HAS_SEMAPHORES was
not honored correctly.

v2: Reword commit message
v3:
 (John H)
  - Add text to commit indicating this also fixing an existing bug
v4:
 (John H)
  - s/bug/bugs

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 7d6f52d8a801..64659802d4df 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -799,7 +799,8 @@ static int intel_context_set_gem(struct intel_context *ce,
}
 
if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
-   intel_engine_has_timeslices(ce->engine))
+   intel_engine_has_timeslices(ce->engine) &&
+   intel_engine_has_semaphores(ce->engine))
__set_bit(CONTEXT_USE_SEMAPHORES, >flags);
 
if (IS_ACTIVE(CONFIG_DRM_I915_REQUEST_TIMEOUT) &&
@@ -1778,7 +1779,8 @@ static void __apply_priority(struct intel_context *ce, 
void *arg)
if (!intel_engine_has_timeslices(ce->engine))
return;
 
-   if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
+   if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
+   intel_engine_has_semaphores(ce->engine))
intel_context_set_use_semaphores(ce);
else
intel_context_clear_use_semaphores(ce);
-- 
2.28.0



[PATCH 14/18] drm/i915/guc: Ensure G2H response has space in buffer

2021-07-21 Thread Matthew Brost
Ensure G2H response has space in the buffer before sending H2G CTB as
the GuC can't handle any backpressure on the G2H interface.

v2:
 (Matthew)
  - s/INTEL_GUC_SEND/INTEL_GUC_CT_SEND
v3:
 (Matthew)
  - Add G2H credit accounting to blocking path, add g2h_release_space
helper
 (John H)
  - CTB_G2H_BUFFER_SIZE / 4 == G2H_ROOM_BUFFER_SIZE

Signed-off-by: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  8 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 94 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 11 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  4 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 13 ++-
 5 files changed, 104 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 4d470ebeda95..451797c62b41 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -96,10 +96,11 @@ inline int intel_guc_send(struct intel_guc *guc, const u32 
*action, u32 len)
 }
 
 static
-inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 len)
+inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 len,
+u32 g2h_len_dw)
 {
return intel_guc_ct_send(>ct, action, len, NULL, 0,
-INTEL_GUC_CT_SEND_NB);
+MAKE_SEND_FLAGS(g2h_len_dw));
 }
 
 static inline int
@@ -113,6 +114,7 @@ intel_guc_send_and_receive(struct intel_guc *guc, const u32 
*action, u32 len,
 static inline int intel_guc_send_busy_loop(struct intel_guc *guc,
   const u32 *action,
   u32 len,
+  u32 g2h_len_dw,
   bool loop)
 {
int err;
@@ -130,7 +132,7 @@ static inline int intel_guc_send_busy_loop(struct intel_guc 
*guc,
might_sleep_if(loop && not_atomic);
 
 retry:
-   err = intel_guc_send_nb(guc, action, len);
+   err = intel_guc_send_nb(guc, action, len, g2h_len_dw);
if (unlikely(err == -EBUSY && loop)) {
if (likely(not_atomic)) {
if (msleep_interruptible(sleep_period_ms))
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index 019b25ff1888..75f69c28056e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -73,6 +73,7 @@ static inline struct drm_device *ct_to_drm(struct 
intel_guc_ct *ct)
 #define CTB_DESC_SIZE  ALIGN(sizeof(struct guc_ct_buffer_desc), SZ_2K)
 #define CTB_H2G_BUFFER_SIZE(SZ_4K)
 #define CTB_G2H_BUFFER_SIZE(4 * CTB_H2G_BUFFER_SIZE)
+#define G2H_ROOM_BUFFER_SIZE   (CTB_G2H_BUFFER_SIZE / 4)
 
 struct ct_request {
struct list_head link;
@@ -129,23 +130,27 @@ static void guc_ct_buffer_desc_init(struct 
guc_ct_buffer_desc *desc)
 
 static void guc_ct_buffer_reset(struct intel_guc_ct_buffer *ctb)
 {
+   u32 space;
+
ctb->broken = false;
ctb->tail = 0;
ctb->head = 0;
-   ctb->space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size);
+   space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size) - ctb->resv_space;
+   atomic_set(>space, space);
 
guc_ct_buffer_desc_init(ctb->desc);
 }
 
 static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb,
   struct guc_ct_buffer_desc *desc,
-  u32 *cmds, u32 size_in_bytes)
+  u32 *cmds, u32 size_in_bytes, u32 resv_space)
 {
GEM_BUG_ON(size_in_bytes % 4);
 
ctb->desc = desc;
ctb->cmds = cmds;
ctb->size = size_in_bytes / 4;
+   ctb->resv_space = resv_space / 4;
 
guc_ct_buffer_reset(ctb);
 }
@@ -226,6 +231,7 @@ int intel_guc_ct_init(struct intel_guc_ct *ct)
struct guc_ct_buffer_desc *desc;
u32 blob_size;
u32 cmds_size;
+   u32 resv_space;
void *blob;
u32 *cmds;
int err;
@@ -250,19 +256,23 @@ int intel_guc_ct_init(struct intel_guc_ct *ct)
desc = blob;
cmds = blob + 2 * CTB_DESC_SIZE;
cmds_size = CTB_H2G_BUFFER_SIZE;
-   CT_DEBUG(ct, "%s desc %#tx cmds %#tx size %u\n", "send",
-ptrdiff(desc, blob), ptrdiff(cmds, blob), cmds_size);
+   resv_space = 0;
+   CT_DEBUG(ct, "%s desc %#tx cmds %#tx size %u/%u\n", "send",
+ptrdiff(desc, blob), ptrdiff(cmds, blob), cmds_size,
+resv_space);
 
-   guc_ct_buffer_init(>ctbs.send, desc, cmds, cmds_size);
+   guc_ct_buffer_init(>ctbs.send, desc, cmds, cmds_size, resv_space);
 
/* store pointers to desc and cmds for recv ctb */
desc = blob + CTB_DESC_SIZE;
cmds = blob + 2 * CTB_DESC_SIZE + CTB_H2G_BUFFER_SIZE;
cmds_size = 

[PATCH 10/18] drm/i915/guc: Extend deregistration fence to schedule disable

2021-07-21 Thread Matthew Brost
Extend the deregistration context fence to fence whne a GuC context has
scheduling disable pending.

v2:
 (John H)
  - Update comment why we check the pin count within spin lock

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 40 +++
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 2f393d9dba0d..fc0b36ab1e68 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -930,7 +930,22 @@ static void guc_context_sched_disable(struct intel_context 
*ce)
goto unpin;
 
spin_lock_irqsave(>guc_state.lock, flags);
+
+   /*
+* We have to check if the context has been pinned again as another pin
+* operation is allowed to pass this function. Checking the pin count,
+* within ce->guc_state.lock, synchronizes this function with
+* guc_request_alloc ensuring a request doesn't slip through the
+* 'context_pending_disable' fence. Checking within the spin lock (can't
+* sleep) ensures another process doesn't pin this context and generate
+* a request before we set the 'context_pending_disable' flag here.
+*/
+   if (unlikely(atomic_add_unless(>pin_count, -2, 2))) {
+   spin_unlock_irqrestore(>guc_state.lock, flags);
+   return;
+   }
guc_id = prep_context_pending_disable(ce);
+
spin_unlock_irqrestore(>guc_state.lock, flags);
 
with_intel_runtime_pm(runtime_pm, wakeref)
@@ -1135,19 +1150,22 @@ static int guc_request_alloc(struct i915_request *rq)
 out:
/*
 * We block all requests on this context if a G2H is pending for a
-* context deregistration as the GuC will fail a context registration
-* while this G2H is pending. Once a G2H returns, the fence is released
-* that is blocking these requests (see guc_signal_context_fence).
+* schedule disable or context deregistration as the GuC will fail a
+* schedule enable or context registration if either G2H is pending
+* respectfully. Once a G2H returns, the fence is released that is
+* blocking these requests (see guc_signal_context_fence).
 *
-* We can safely check the below field outside of the lock as it isn't
-* possible for this field to transition from being clear to set but
+* We can safely check the below fields outside of the lock as it isn't
+* possible for these fields to transition from being clear to set but
 * converse is possible, hence the need for the check within the lock.
 */
-   if (likely(!context_wait_for_deregister_to_register(ce)))
+   if (likely(!context_wait_for_deregister_to_register(ce) &&
+  !context_pending_disable(ce)))
return 0;
 
spin_lock_irqsave(>guc_state.lock, flags);
-   if (context_wait_for_deregister_to_register(ce)) {
+   if (context_wait_for_deregister_to_register(ce) ||
+   context_pending_disable(ce)) {
i915_sw_fence_await(>submit);
 
list_add_tail(>guc_fence_link, >guc_state.fences);
@@ -1491,10 +1509,18 @@ int intel_guc_sched_done_process_msg(struct intel_guc 
*guc,
if (context_pending_enable(ce)) {
clr_context_pending_enable(ce);
} else if (context_pending_disable(ce)) {
+   /*
+* Unpin must be done before __guc_signal_context_fence,
+* otherwise a race exists between the requests getting
+* submitted + retired before this unpin completes resulting in
+* the pin_count going to zero and the context still being
+* enabled.
+*/
intel_context_sched_disable_unpin(ce);
 
spin_lock_irqsave(>guc_state.lock, flags);
clr_context_pending_disable(ce);
+   __guc_signal_context_fence(ce);
spin_unlock_irqrestore(>guc_state.lock, flags);
}
 
-- 
2.28.0



[PATCH 17/18] drm/i915/guc: Add trace point for GuC submit

2021-07-21 Thread Matthew Brost
Add trace point for GuC submit. Extended existing request trace points
to include submit fence value,, guc_id, and ring tail value.

v2: Fix white space alignment in i915_request_add trace point
v3: Delete dep_from , dep_to (Tvrtko)

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  3 +++
 drivers/gpu/drm/i915/i915_trace.h | 23 +++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index e6e5364beb1c..d47a8358c831 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -418,6 +418,7 @@ static int guc_dequeue_one_context(struct intel_guc *guc)
guc->stalled_request = last;
return false;
}
+   trace_i915_request_guc_submit(last);
}
 
guc->stalled_request = NULL;
@@ -638,6 +639,8 @@ static int guc_bypass_tasklet_submit(struct intel_guc *guc,
ret = guc_add_request(guc, rq);
if (ret == -EBUSY)
guc->stalled_request = rq;
+   else
+   trace_i915_request_guc_submit(rq);
 
return ret;
 }
diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index 6778ad2a14a4..478f5427531d 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -794,30 +794,40 @@ DECLARE_EVENT_CLASS(i915_request,
TP_STRUCT__entry(
 __field(u32, dev)
 __field(u64, ctx)
+__field(u32, guc_id)
 __field(u16, class)
 __field(u16, instance)
 __field(u32, seqno)
+__field(u32, tail)
 ),
 
TP_fast_assign(
   __entry->dev = rq->engine->i915->drm.primary->index;
   __entry->class = rq->engine->uabi_class;
   __entry->instance = rq->engine->uabi_instance;
+  __entry->guc_id = rq->context->guc_id;
   __entry->ctx = rq->fence.context;
   __entry->seqno = rq->fence.seqno;
+  __entry->tail = rq->tail;
   ),
 
-   TP_printk("dev=%u, engine=%u:%u, ctx=%llu, seqno=%u",
+   TP_printk("dev=%u, engine=%u:%u, guc_id=%u, ctx=%llu, seqno=%u, 
tail=%u",
  __entry->dev, __entry->class, __entry->instance,
- __entry->ctx, __entry->seqno)
+ __entry->guc_id, __entry->ctx, __entry->seqno,
+ __entry->tail)
 );
 
 DEFINE_EVENT(i915_request, i915_request_add,
-   TP_PROTO(struct i915_request *rq),
-   TP_ARGS(rq)
+TP_PROTO(struct i915_request *rq),
+TP_ARGS(rq)
 );
 
 #if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS)
+DEFINE_EVENT(i915_request, i915_request_guc_submit,
+TP_PROTO(struct i915_request *rq),
+TP_ARGS(rq)
+);
+
 DEFINE_EVENT(i915_request, i915_request_submit,
 TP_PROTO(struct i915_request *rq),
 TP_ARGS(rq)
@@ -887,6 +897,11 @@ TRACE_EVENT(i915_request_out,
 
 #else
 #if !defined(TRACE_HEADER_MULTI_READ)
+static inline void
+trace_i915_request_guc_submit(struct i915_request *rq)
+{
+}
+
 static inline void
 trace_i915_request_submit(struct i915_request *rq)
 {
-- 
2.28.0



[PATCH 07/18] drm/i915/guc: Insert fence on context when deregistering

2021-07-21 Thread Matthew Brost
Sometimes during context pinning a context with the same guc_id is
registered with the GuC. In this a case deregister must be done before
the context can be registered. A fence is inserted on all requests while
the deregister is in flight. Once the G2H is received indicating the
deregistration is complete the context is registered and the fence is
released.

v2:
 (John H)
  - Fix commit message

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  1 +
 drivers/gpu/drm/i915/gt/intel_context_types.h |  5 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 51 ++-
 drivers/gpu/drm/i915/i915_request.h   |  8 +++
 4 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 32fd6647154b..ad7197c5910f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -385,6 +385,7 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
mutex_init(>pin_mutex);
 
spin_lock_init(>guc_state.lock);
+   INIT_LIST_HEAD(>guc_state.fences);
 
ce->guc_id = GUC_INVALID_LRC_ID;
INIT_LIST_HEAD(>guc_id_link);
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 606c480aec26..e0e3a937f709 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -147,6 +147,11 @@ struct intel_context {
 * submission
 */
u8 sched_state;
+   /*
+* fences: maintains of list of requests that have a submit
+* fence related to GuC submission
+*/
+   struct list_head fences;
} guc_state;
 
/* GuC scheduling state flags that do not require a lock. */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 463613a414d2..a0871b800153 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -935,6 +935,30 @@ static const struct intel_context_ops guc_context_ops = {
.destroy = guc_context_destroy,
 };
 
+static void __guc_signal_context_fence(struct intel_context *ce)
+{
+   struct i915_request *rq;
+
+   lockdep_assert_held(>guc_state.lock);
+
+   list_for_each_entry(rq, >guc_state.fences, guc_fence_link)
+   i915_sw_fence_complete(>submit);
+
+   INIT_LIST_HEAD(>guc_state.fences);
+}
+
+static void guc_signal_context_fence(struct intel_context *ce)
+{
+   unsigned long flags;
+
+   GEM_BUG_ON(!context_wait_for_deregister_to_register(ce));
+
+   spin_lock_irqsave(>guc_state.lock, flags);
+   clr_context_wait_for_deregister_to_register(ce);
+   __guc_signal_context_fence(ce);
+   spin_unlock_irqrestore(>guc_state.lock, flags);
+}
+
 static bool context_needs_register(struct intel_context *ce, bool new_guc_id)
 {
return new_guc_id || test_bit(CONTEXT_LRCA_DIRTY, >flags) ||
@@ -945,6 +969,7 @@ static int guc_request_alloc(struct i915_request *rq)
 {
struct intel_context *ce = rq->context;
struct intel_guc *guc = ce_to_guc(ce);
+   unsigned long flags;
int ret;
 
GEM_BUG_ON(!intel_context_is_pinned(rq->context));
@@ -989,7 +1014,7 @@ static int guc_request_alloc(struct i915_request *rq)
 * increment (in pin_guc_id) is needed to seal a race with unpin_guc_id.
 */
if (atomic_add_unless(>guc_id_ref, 1, 0))
-   return 0;
+   goto out;
 
ret = pin_guc_id(guc, ce);  /* returns 1 if new guc_id assigned */
if (unlikely(ret < 0))
@@ -1005,6 +1030,28 @@ static int guc_request_alloc(struct i915_request *rq)
 
clear_bit(CONTEXT_LRCA_DIRTY, >flags);
 
+out:
+   /*
+* We block all requests on this context if a G2H is pending for a
+* context deregistration as the GuC will fail a context registration
+* while this G2H is pending. Once a G2H returns, the fence is released
+* that is blocking these requests (see guc_signal_context_fence).
+*
+* We can safely check the below field outside of the lock as it isn't
+* possible for this field to transition from being clear to set but
+* converse is possible, hence the need for the check within the lock.
+*/
+   if (likely(!context_wait_for_deregister_to_register(ce)))
+   return 0;
+
+   spin_lock_irqsave(>guc_state.lock, flags);
+   if (context_wait_for_deregister_to_register(ce)) {
+   i915_sw_fence_await(>submit);
+
+   list_add_tail(>guc_fence_link, >guc_state.fences);
+   }
+   spin_unlock_irqrestore(>guc_state.lock, flags);
+
return 0;
 }
 
@@ 

[PATCH 03/18] drm/i915/guc: Add LRC descriptor context lookup array

2021-07-21 Thread Matthew Brost
Add LRC descriptor context lookup array which can resolve the
intel_context from the LRC descriptor index. In addition to lookup, it
can determine if the LRC descriptor context is currently registered with
the GuC by checking if an entry for a descriptor index is present.
Future patches in the series will make use of this array.

v2:
 (Michal)
  - "linux/xarray.h" -> 
  - s/lrc/LRC
 (John H)
  - Fix commit message

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  5 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 32 +--
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2625d2d5959f..35783558d261 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -6,6 +6,8 @@
 #ifndef _INTEL_GUC_H_
 #define _INTEL_GUC_H_
 
+#include 
+
 #include "intel_uncore.h"
 #include "intel_guc_fw.h"
 #include "intel_guc_fwif.h"
@@ -46,6 +48,9 @@ struct intel_guc {
struct i915_vma *lrc_desc_pool;
void *lrc_desc_pool_vaddr;
 
+   /* guc_id to intel_context lookup */
+   struct xarray context_lookup;
+
/* Control params for fw initialization */
u32 params[GUC_CTL_MAX_DWORDS];
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ed5d8ab3624f..23a94a896a0b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -65,8 +65,6 @@ static inline struct i915_priolist *to_priolist(struct 
rb_node *rb)
return rb_entry(rb, struct i915_priolist, node);
 }
 
-/* Future patches will use this function */
-__maybe_unused
 static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc *guc, u32 index)
 {
struct guc_lrc_desc *base = guc->lrc_desc_pool_vaddr;
@@ -76,6 +74,15 @@ static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc 
*guc, u32 index)
return [index];
 }
 
+static inline struct intel_context *__get_context(struct intel_guc *guc, u32 
id)
+{
+   struct intel_context *ce = xa_load(>context_lookup, id);
+
+   GEM_BUG_ON(id >= GUC_MAX_LRC_DESCRIPTORS);
+
+   return ce;
+}
+
 static int guc_lrc_desc_pool_create(struct intel_guc *guc)
 {
u32 size;
@@ -96,6 +103,25 @@ static void guc_lrc_desc_pool_destroy(struct intel_guc *guc)
i915_vma_unpin_and_release(>lrc_desc_pool, I915_VMA_RELEASE_MAP);
 }
 
+static inline void reset_lrc_desc(struct intel_guc *guc, u32 id)
+{
+   struct guc_lrc_desc *desc = __get_lrc_desc(guc, id);
+
+   memset(desc, 0, sizeof(*desc));
+   xa_erase_irq(>context_lookup, id);
+}
+
+static inline bool lrc_desc_registered(struct intel_guc *guc, u32 id)
+{
+   return __get_context(guc, id);
+}
+
+static inline void set_lrc_desc_registered(struct intel_guc *guc, u32 id,
+  struct intel_context *ce)
+{
+   xa_store_irq(>context_lookup, id, ce, GFP_ATOMIC);
+}
+
 static void guc_add_request(struct intel_guc *guc, struct i915_request *rq)
 {
/* Leaving stub as this function will be used in future patches */
@@ -400,6 +426,8 @@ int intel_guc_submission_init(struct intel_guc *guc)
 */
GEM_BUG_ON(!guc->lrc_desc_pool);
 
+   xa_init_flags(>context_lookup, XA_FLAGS_LOCK_IRQ);
+
return 0;
 }
 
-- 
2.28.0



[PATCH 06/18] drm/i915/guc: Implement GuC context operations for new inteface

2021-07-21 Thread Matthew Brost
Implement GuC context operations which includes GuC specific operations
alloc, pin, unpin, and destroy.

v2:
 (Daniel Vetter)
  - Use msleep_interruptible rather than cond_resched in busy loop
 (Michal)
  - Remove C++ style comment
v3:
 (Matthew Brost)
  - Drop GUC_ID_START
 (John Harrison)
  - Fix a bunch of typos
  - Use drm_err rather than drm_dbg for G2H errors
 (Daniele)
  - Fix ;; typo
  - Clean up sched state functions
  - Add lockdep for guc_id functions
  - Don't call __release_guc_id when guc_id is invalid
  - Use MISSING_CASE
  - Add comment in guc_context_pin
  - Use shorter path to rpm
 (Daniele / CI)
  - Don't call release_guc_id on an invalid guc_id in destroy
v4:
 (Daniel Vetter)
  - Add FIXME comment

Signed-off-by: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |   5 +
 drivers/gpu/drm/i915/gt/intel_context_types.h |  22 +-
 drivers/gpu/drm/i915/gt/intel_lrc_reg.h   |   1 -
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  47 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   4 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 670 --
 drivers/gpu/drm/i915/i915_reg.h   |   1 +
 drivers/gpu/drm/i915/i915_request.c   |   1 +
 8 files changed, 696 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index bd63813c8a80..32fd6647154b 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -384,6 +384,11 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
 
mutex_init(>pin_mutex);
 
+   spin_lock_init(>guc_state.lock);
+
+   ce->guc_id = GUC_INVALID_LRC_ID;
+   INIT_LIST_HEAD(>guc_id_link);
+
i915_active_init(>active,
 __intel_context_active, __intel_context_retire, 0);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 6d99631d19b9..606c480aec26 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -96,6 +96,7 @@ struct intel_context {
 #define CONTEXT_BANNED 6
 #define CONTEXT_FORCE_SINGLE_SUBMISSION7
 #define CONTEXT_NOPREEMPT  8
+#define CONTEXT_LRCA_DIRTY 9
 
struct {
u64 timeout_us;
@@ -138,14 +139,29 @@ struct intel_context {
 
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
 
+   struct {
+   /** lock: protects everything in guc_state */
+   spinlock_t lock;
+   /**
+* sched_state: scheduling state of this context using GuC
+* submission
+*/
+   u8 sched_state;
+   } guc_state;
+
/* GuC scheduling state flags that do not require a lock. */
atomic_t guc_sched_state_no_lock;
 
+   /* GuC LRC descriptor ID */
+   u16 guc_id;
+
+   /* GuC LRC descriptor reference count */
+   atomic_t guc_id_ref;
+
/*
-* GuC LRC descriptor ID - Not assigned in this patch but future patches
-* in the series will.
+* GuC ID link - in list when unpinned but guc_id still valid in GuC
 */
-   u16 guc_id;
+   struct list_head guc_id_link;
 };
 
 #endif /* __INTEL_CONTEXT_TYPES__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h 
b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
index 41e5350a7a05..49d4857ad9b7 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
+++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
@@ -87,7 +87,6 @@
 #define GEN11_CSB_WRITE_PTR_MASK   (GEN11_CSB_PTR_MASK << 0)
 
 #define MAX_CONTEXT_HW_ID  (1 << 21) /* exclusive */
-#define MAX_GUC_CONTEXT_HW_ID  (1 << 20) /* exclusive */
 #define GEN11_MAX_CONTEXT_HW_ID(1 << 11) /* exclusive */
 /* in Gen12 ID 0x7FF is reserved to indicate idle */
 #define GEN12_MAX_CONTEXT_HW_ID(GEN11_MAX_CONTEXT_HW_ID - 1)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 8c7b92f699f1..7fd6c3e343e4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -7,6 +7,7 @@
 #define _INTEL_GUC_H_
 
 #include 
+#include 
 
 #include "intel_uncore.h"
 #include "intel_guc_fw.h"
@@ -44,6 +45,14 @@ struct intel_guc {
void (*disable)(struct intel_guc *guc);
} interrupts;
 
+   /*
+* contexts_lock protects the pool of free guc ids and a linked list of
+* guc ids available to be stolen
+*/
+   spinlock_t contexts_lock;
+   struct ida guc_ids;
+   struct list_head guc_id_list;
+
bool submission_selected;
 
struct i915_vma *ads_vma;
@@ -101,6 +110,41 @@ intel_guc_send_and_receive(struct intel_guc *guc, const 
u32 *action, u32 len,
 

[PATCH 08/18] drm/i915/guc: Defer context unpin until scheduling is disabled

2021-07-21 Thread Matthew Brost
With GuC scheduling, it isn't safe to unpin a context while scheduling
is enabled for that context as the GuC may touch some of the pinned
state (e.g. LRC). To ensure scheduling isn't enabled when an unpin is
done, a call back is added to intel_context_unpin when pin count == 1
to disable scheduling for that context. When the response CTB is
received it is safe to do the final unpin.

Future patches may add a heuristic / delay to schedule the disable
call back to avoid thrashing on schedule enable / disable.

v2:
 (John H)
  - s/drm_dbg/drm_err
 (Daneiel)
  - Clean up sched state function

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |   4 +-
 drivers/gpu/drm/i915/gt/intel_context.h   |  27 +++-
 drivers/gpu/drm/i915/gt/intel_context_types.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   3 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 146 +-
 6 files changed, 180 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index ad7197c5910f..3d5b4116617f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -306,9 +306,9 @@ int __intel_context_do_pin(struct intel_context *ce)
return err;
 }
 
-void intel_context_unpin(struct intel_context *ce)
+void __intel_context_do_unpin(struct intel_context *ce, int sub)
 {
-   if (!atomic_dec_and_test(>pin_count))
+   if (!atomic_sub_and_test(sub, >pin_count))
return;
 
CE_TRACE(ce, "unpin\n");
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index b10cbe8fee99..974ef85320c2 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -113,7 +113,32 @@ static inline void __intel_context_pin(struct 
intel_context *ce)
atomic_inc(>pin_count);
 }
 
-void intel_context_unpin(struct intel_context *ce);
+void __intel_context_do_unpin(struct intel_context *ce, int sub);
+
+static inline void intel_context_sched_disable_unpin(struct intel_context *ce)
+{
+   __intel_context_do_unpin(ce, 2);
+}
+
+static inline void intel_context_unpin(struct intel_context *ce)
+{
+   if (!ce->ops->sched_disable) {
+   __intel_context_do_unpin(ce, 1);
+   } else {
+   /*
+* Move ownership of this pin to the scheduling disable which is
+* an async operation. When that operation completes the above
+* intel_context_sched_disable_unpin is called potentially
+* unpinning the context.
+*/
+   while (!atomic_add_unless(>pin_count, -1, 1)) {
+   if (atomic_cmpxchg(>pin_count, 1, 2) == 1) {
+   ce->ops->sched_disable(ce);
+   break;
+   }
+   }
+   }
+}
 
 void intel_context_enter_engine(struct intel_context *ce);
 void intel_context_exit_engine(struct intel_context *ce);
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index e0e3a937f709..4a5518d295c2 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -43,6 +43,8 @@ struct intel_context_ops {
void (*enter)(struct intel_context *ce);
void (*exit)(struct intel_context *ce);
 
+   void (*sched_disable)(struct intel_context *ce);
+
void (*reset)(struct intel_context *ce);
void (*destroy)(struct kref *kref);
 };
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 7fd6c3e343e4..4d470ebeda95 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -248,6 +248,8 @@ int intel_guc_reset_engine(struct intel_guc *guc,
 
 int intel_guc_deregister_done_process_msg(struct intel_guc *guc,
  const u32 *msg, u32 len);
+int intel_guc_sched_done_process_msg(struct intel_guc *guc,
+const u32 *msg, u32 len);
 
 void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p);
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index 28ff82c5be45..019b25ff1888 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -932,6 +932,9 @@ static int ct_process_request(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
ret = intel_guc_deregister_done_process_msg(guc, payload,
len);
break;
+   case INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE:
+   ret = intel_guc_sched_done_process_msg(guc, payload, 

[PATCH 09/18] drm/i915/guc: Disable engine barriers with GuC during unpin

2021-07-21 Thread Matthew Brost
Disable engine barriers for unpinning with GuC. This feature isn't
needed with the GuC as it disables context scheduling before unpinning
which guarantees the HW will not reference the context. Hence it is
not necessary to defer unpinning until a kernel context request
completes on each engine in the context engine mask.

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context.c|  2 +-
 drivers/gpu/drm/i915/gt/selftest_context.c | 10 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 3d5b4116617f..91349d071e0e 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -80,7 +80,7 @@ static int intel_context_active_acquire(struct intel_context 
*ce)
 
__i915_active_acquire(>active);
 
-   if (intel_context_is_barrier(ce))
+   if (intel_context_is_barrier(ce) || intel_engine_uses_guc(ce->engine))
return 0;
 
/* Preallocate tracking nodes */
diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c 
b/drivers/gpu/drm/i915/gt/selftest_context.c
index 26685b927169..fa7b99a671dd 100644
--- a/drivers/gpu/drm/i915/gt/selftest_context.c
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -209,7 +209,13 @@ static int __live_active_context(struct intel_engine_cs 
*engine)
 * This test makes sure that the context is kept alive until a
 * subsequent idle-barrier (emitted when the engine wakeref hits 0
 * with no more outstanding requests).
+*
+* In GuC submission mode we don't use idle barriers and we instead
+* get a message from the GuC to signal that it is safe to unpin the
+* context from memory.
 */
+   if (intel_engine_uses_guc(engine))
+   return 0;
 
if (intel_engine_pm_is_awake(engine)) {
pr_err("%s is awake before starting %s!\n",
@@ -357,7 +363,11 @@ static int __live_remote_context(struct intel_engine_cs 
*engine)
 * on the context image remotely (intel_context_prepare_remote_request),
 * which inserts foreign fences into intel_context.active, does not
 * clobber the idle-barrier.
+*
+* In GuC submission mode we don't use idle barriers.
 */
+   if (intel_engine_uses_guc(engine))
+   return 0;
 
if (intel_engine_pm_is_awake(engine)) {
pr_err("%s is awake before starting %s!\n",
-- 
2.28.0



[PATCH 12/18] drm/i915/guc: Ensure request ordering via completion fences

2021-07-21 Thread Matthew Brost
If two requests are on the same ring, they are explicitly ordered by the
HW. So, a submission fence is sufficient to ensure ordering when using
the new GuC submission interface. Conversely, if two requests share a
timeline and are on the same physical engine but different context this
doesn't ensure ordering on the new GuC submission interface. So, a
completion fence needs to be used to ensure ordering.

v2:
 (Daniele)
  - Don't delete spin lock
v3:
 (Daniele)
  - Delete forward dec

Signed-off-by: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/i915_request.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index ef26724fe980..c55dea0edb09 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -432,6 +432,7 @@ void i915_request_retire_upto(struct i915_request *rq)
 
do {
tmp = list_first_entry(>requests, typeof(*tmp), link);
+   GEM_BUG_ON(!i915_request_completed(tmp));
} while (i915_request_retire(tmp) && tmp != rq);
 }
 
@@ -1463,7 +1464,8 @@ i915_request_await_request(struct i915_request *to, 
struct i915_request *from)
return ret;
}
 
-   if (is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask)))
+   if (!intel_engine_uses_guc(to->engine) &&
+   is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask)))
ret = await_request_submit(to, from);
else
ret = emit_semaphore_wait(to, from, I915_FENCE_GFP);
@@ -1622,6 +1624,8 @@ __i915_request_add_to_timeline(struct i915_request *rq)
prev = to_request(__i915_active_fence_set(>last_request,
  >fence));
if (prev && !__i915_request_is_complete(prev)) {
+   bool uses_guc = intel_engine_uses_guc(rq->engine);
+
/*
 * The requests are supposed to be kept in order. However,
 * we need to be wary in case the timeline->last_request
@@ -1632,7 +1636,9 @@ __i915_request_add_to_timeline(struct i915_request *rq)
   i915_seqno_passed(prev->fence.seqno,
 rq->fence.seqno));
 
-   if (is_power_of_2(READ_ONCE(prev->engine)->mask | 
rq->engine->mask))
+   if ((!uses_guc &&
+is_power_of_2(READ_ONCE(prev->engine)->mask | 
rq->engine->mask)) ||
+   (uses_guc && prev->context == rq->context))
i915_sw_fence_await_sw_fence(>submit,
 >submit,
 >submitq);
-- 
2.28.0



[PATCH 04/18] drm/i915/guc: Implement GuC submission tasklet

2021-07-21 Thread Matthew Brost
Implement GuC submission tasklet for new interface. The new GuC
interface uses H2G to submit contexts to the GuC. Since H2G use a single
channel, a single tasklet is used for the submission path.

Also the per engine interrupt handler has been updated to disable the
rescheduling of the physical engine tasklet, when using GuC scheduling,
as the physical engine tasklet is no longer used.

In this patch the field, guc_id, has been added to intel_context and is
not assigned. Patches later in the series will assign this value.

v2:
 (John Harrison)
  - Clean up some comments
v3:
 (John Harrison)
  - More comment cleanups

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context_types.h |   9 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 231 +-
 3 files changed, 127 insertions(+), 117 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 90026c177105..6d99631d19b9 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -137,6 +137,15 @@ struct intel_context {
struct intel_sseu sseu;
 
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
+
+   /* GuC scheduling state flags that do not require a lock. */
+   atomic_t guc_sched_state_no_lock;
+
+   /*
+* GuC LRC descriptor ID - Not assigned in this patch but future patches
+* in the series will.
+*/
+   u16 guc_id;
 };
 
 #endif /* __INTEL_CONTEXT_TYPES__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 35783558d261..8c7b92f699f1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -30,6 +30,10 @@ struct intel_guc {
struct intel_guc_log log;
struct intel_guc_ct ct;
 
+   /* Global engine used to submit requests to GuC */
+   struct i915_sched_engine *sched_engine;
+   struct i915_request *stalled_request;
+
/* intel_guc_recv interrupt related state */
spinlock_t irq_lock;
unsigned int msg_enabled_mask;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 23a94a896a0b..ca0717166a27 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -60,6 +60,31 @@
 
 #define GUC_REQUEST_SIZE 64 /* bytes */
 
+/*
+ * Below is a set of functions which control the GuC scheduling state which do
+ * not require a lock as all state transitions are mutually exclusive. i.e. It
+ * is not possible for the context pinning code and submission, for the same
+ * context, to be executing simultaneously. We still need an atomic as it is
+ * possible for some of the bits to changing at the same time though.
+ */
+#define SCHED_STATE_NO_LOCK_ENABLEDBIT(0)
+static inline bool context_enabled(struct intel_context *ce)
+{
+   return (atomic_read(>guc_sched_state_no_lock) &
+   SCHED_STATE_NO_LOCK_ENABLED);
+}
+
+static inline void set_context_enabled(struct intel_context *ce)
+{
+   atomic_or(SCHED_STATE_NO_LOCK_ENABLED, >guc_sched_state_no_lock);
+}
+
+static inline void clr_context_enabled(struct intel_context *ce)
+{
+   atomic_and((u32)~SCHED_STATE_NO_LOCK_ENABLED,
+  >guc_sched_state_no_lock);
+}
+
 static inline struct i915_priolist *to_priolist(struct rb_node *rb)
 {
return rb_entry(rb, struct i915_priolist, node);
@@ -122,37 +147,29 @@ static inline void set_lrc_desc_registered(struct 
intel_guc *guc, u32 id,
xa_store_irq(>context_lookup, id, ce, GFP_ATOMIC);
 }
 
-static void guc_add_request(struct intel_guc *guc, struct i915_request *rq)
+static int guc_add_request(struct intel_guc *guc, struct i915_request *rq)
 {
-   /* Leaving stub as this function will be used in future patches */
-}
+   int err;
+   struct intel_context *ce = rq->context;
+   u32 action[3];
+   int len = 0;
+   bool enabled = context_enabled(ce);
 
-/*
- * When we're doing submissions using regular execlists backend, writing to
- * ELSP from CPU side is enough to make sure that writes to ringbuffer pages
- * pinned in mappable aperture portion of GGTT are visible to command streamer.
- * Writes done by GuC on our behalf are not guaranteeing such ordering,
- * therefore, to ensure the flush, we're issuing a POSTING READ.
- */
-static void flush_ggtt_writes(struct i915_vma *vma)
-{
-   if (i915_vma_is_map_and_fenceable(vma))
-   intel_uncore_posting_read_fw(vma->vm->gt->uncore,
-GUC_STATUS);
-}
+   if (!enabled) {
+   action[len++] = INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_SET;
+   action[len++] = ce->guc_id;
+  

[PATCH 01/18] drm/i915/guc: Add new GuC interface defines and structures

2021-07-21 Thread Matthew Brost
Add new GuC interface defines and structures while maintaining old ones
in parallel.

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  | 14 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   | 42 +++
 2 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
index 2d6198e63ebe..57e18babdf4b 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
@@ -124,10 +124,24 @@ enum intel_guc_action {
INTEL_GUC_ACTION_FORCE_LOG_BUFFER_FLUSH = 0x302,
INTEL_GUC_ACTION_ENTER_S_STATE = 0x501,
INTEL_GUC_ACTION_EXIT_S_STATE = 0x502,
+   INTEL_GUC_ACTION_GLOBAL_SCHED_POLICY_CHANGE = 0x506,
+   INTEL_GUC_ACTION_SCHED_CONTEXT = 0x1000,
+   INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_SET = 0x1001,
+   INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE = 0x1002,
+   INTEL_GUC_ACTION_SCHED_ENGINE_MODE_SET = 0x1003,
+   INTEL_GUC_ACTION_SCHED_ENGINE_MODE_DONE = 0x1004,
+   INTEL_GUC_ACTION_SET_CONTEXT_PRIORITY = 0x1005,
+   INTEL_GUC_ACTION_SET_CONTEXT_EXECUTION_QUANTUM = 0x1006,
+   INTEL_GUC_ACTION_SET_CONTEXT_PREEMPTION_TIMEOUT = 0x1007,
+   INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION = 0x1008,
+   INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION = 0x1009,
INTEL_GUC_ACTION_SLPC_REQUEST = 0x3003,
INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
+   INTEL_GUC_ACTION_REGISTER_CONTEXT = 0x4502,
+   INTEL_GUC_ACTION_DEREGISTER_CONTEXT = 0x4503,
INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER = 0x4505,
INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
+   INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
INTEL_GUC_ACTION_LIMIT
 };
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
index 617ec601648d..3e060d5958cc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -17,6 +17,9 @@
 #include "abi/guc_communication_ctb_abi.h"
 #include "abi/guc_messages_abi.h"
 
+#define GUC_CONTEXT_DISABLE0
+#define GUC_CONTEXT_ENABLE 1
+
 #define GUC_CLIENT_PRIORITY_KMD_HIGH   0
 #define GUC_CLIENT_PRIORITY_HIGH   1
 #define GUC_CLIENT_PRIORITY_KMD_NORMAL 2
@@ -26,6 +29,9 @@
 #define GUC_MAX_STAGE_DESCRIPTORS  1024
 #defineGUC_INVALID_STAGE_IDGUC_MAX_STAGE_DESCRIPTORS
 
+#define GUC_MAX_LRC_DESCRIPTORS65535
+#defineGUC_INVALID_LRC_ID  GUC_MAX_LRC_DESCRIPTORS
+
 #define GUC_RENDER_ENGINE  0
 #define GUC_VIDEO_ENGINE   1
 #define GUC_BLITTER_ENGINE 2
@@ -237,6 +243,42 @@ struct guc_stage_desc {
u64 desc_private;
 } __packed;
 
+#define CONTEXT_REGISTRATION_FLAG_KMD  BIT(0)
+
+#define CONTEXT_POLICY_DEFAULT_EXECUTION_QUANTUM_US 100
+#define CONTEXT_POLICY_DEFAULT_PREEMPTION_TIME_US 50
+
+/* Preempt to idle on quantum expiry */
+#define CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLEBIT(0)
+
+/*
+ * GuC Context registration descriptor.
+ * FIXME: This is only required to exist during context registration.
+ * The current 1:1 between guc_lrc_desc and LRCs for the lifetime of the LRC
+ * is not required.
+ */
+struct guc_lrc_desc {
+   u32 hw_context_desc;
+   u32 slpm_perf_mode_hint;/* SPLC v1 only */
+   u32 slpm_freq_hint;
+   u32 engine_submit_mask; /* In logical space */
+   u8 engine_class;
+   u8 reserved0[3];
+   u32 priority;
+   u32 process_desc;
+   u32 wq_addr;
+   u32 wq_size;
+   u32 context_flags;  /* CONTEXT_REGISTRATION_* */
+   /* Time for one workload to execute. (in micro seconds) */
+   u32 execution_quantum;
+   /* Time to wait for a preemption request to complete before issuing a
+* reset. (in micro seconds).
+*/
+   u32 preemption_timeout;
+   u32 policy_flags;   /* CONTEXT_POLICY_* */
+   u32 reserved1[19];
+} __packed;
+
 #define GUC_POWER_UNSPECIFIED  0
 #define GUC_POWER_D0   1
 #define GUC_POWER_D1   2
-- 
2.28.0



[PATCH 00/18] Series to merge a subset of GuC submission

2021-07-21 Thread Matthew Brost
The first 18 patches [1] are basically ready to merge.

v2: Address NITs, add missing RBs, fix checkpatch warnings

Signed-off-by: Matthew Brost 

[1] https://patchwork.freedesktop.org/series/91840/


Matthew Brost (18):
  drm/i915/guc: Add new GuC interface defines and structures
  drm/i915/guc: Remove GuC stage descriptor, add LRC descriptor
  drm/i915/guc: Add LRC descriptor context lookup array
  drm/i915/guc: Implement GuC submission tasklet
  drm/i915/guc: Add bypass tasklet submission path to GuC
  drm/i915/guc: Implement GuC context operations for new inteface
  drm/i915/guc: Insert fence on context when deregistering
  drm/i915/guc: Defer context unpin until scheduling is disabled
  drm/i915/guc: Disable engine barriers with GuC during unpin
  drm/i915/guc: Extend deregistration fence to schedule disable
  drm/i915: Disable preempt busywait when using GuC scheduling
  drm/i915/guc: Ensure request ordering via completion fences
  drm/i915/guc: Disable semaphores when using GuC scheduling
  drm/i915/guc: Ensure G2H response has space in buffer
  drm/i915/guc: Update intel_gt_wait_for_idle to work with GuC
  drm/i915/guc: Update GuC debugfs to support new GuC
  drm/i915/guc: Add trace point for GuC submit
  drm/i915: Add intel_context tracing

 drivers/gpu/drm/i915/gem/i915_gem_context.c   |6 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  |3 +-
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |6 +-
 drivers/gpu/drm/i915/gt/intel_context.c   |   18 +-
 drivers/gpu/drm/i915/gt/intel_context.h   |   27 +-
 drivers/gpu/drm/i915/gt/intel_context_types.h |   32 +
 drivers/gpu/drm/i915/gt/intel_gt.c|   19 +
 drivers/gpu/drm/i915/gt/intel_gt.h|2 +
 drivers/gpu/drm/i915/gt/intel_gt_requests.c   |   21 +-
 drivers/gpu/drm/i915/gt/intel_gt_requests.h   |9 +-
 drivers/gpu/drm/i915/gt/intel_lrc_reg.h   |1 -
 drivers/gpu/drm/i915/gt/selftest_context.c|   10 +
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   14 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   72 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  124 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h |   18 +-
 .../gpu/drm/i915/gt/uc/intel_guc_debugfs.c|   23 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |   89 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 1290 ++---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.h |5 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |5 +
 drivers/gpu/drm/i915/i915_gem_evict.c |1 +
 drivers/gpu/drm/i915/i915_reg.h   |1 +
 drivers/gpu/drm/i915/i915_request.c   |   11 +-
 drivers/gpu/drm/i915/i915_request.h   |8 +
 drivers/gpu/drm/i915/i915_trace.h |  168 ++-
 .../gpu/drm/i915/selftests/igt_live_test.c|2 +-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |3 +-
 28 files changed, 1707 insertions(+), 281 deletions(-)

-- 
2.28.0



[PATCH 02/18] drm/i915/guc: Remove GuC stage descriptor, add LRC descriptor

2021-07-21 Thread Matthew Brost
Remove old GuC stage descriptor, add LRC descriptor which will be used
by the new GuC interface implemented in this patch series.

v2:
 (John Harrison)
  - s/lrc/LRC/g

Cc: John Harrison 
Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  4 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   | 65 -
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 72 ++-
 3 files changed, 25 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 72e4653222e2..2625d2d5959f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -43,8 +43,8 @@ struct intel_guc {
struct i915_vma *ads_vma;
struct __guc_ads_blob *ads_blob;
 
-   struct i915_vma *stage_desc_pool;
-   void *stage_desc_pool_vaddr;
+   struct i915_vma *lrc_desc_pool;
+   void *lrc_desc_pool_vaddr;
 
/* Control params for fw initialization */
u32 params[GUC_CTL_MAX_DWORDS];
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
index 3e060d5958cc..3489b390ae77 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -26,9 +26,6 @@
 #define GUC_CLIENT_PRIORITY_NORMAL 3
 #define GUC_CLIENT_PRIORITY_NUM4
 
-#define GUC_MAX_STAGE_DESCRIPTORS  1024
-#defineGUC_INVALID_STAGE_IDGUC_MAX_STAGE_DESCRIPTORS
-
 #define GUC_MAX_LRC_DESCRIPTORS65535
 #defineGUC_INVALID_LRC_ID  GUC_MAX_LRC_DESCRIPTORS
 
@@ -181,68 +178,6 @@ struct guc_process_desc {
u32 reserved[30];
 } __packed;
 
-/* engine id and context id is packed into guc_execlist_context.context_id*/
-#define GUC_ELC_CTXID_OFFSET   0
-#define GUC_ELC_ENGINE_OFFSET  29
-
-/* The execlist context including software and HW information */
-struct guc_execlist_context {
-   u32 context_desc;
-   u32 context_id;
-   u32 ring_status;
-   u32 ring_lrca;
-   u32 ring_begin;
-   u32 ring_end;
-   u32 ring_next_free_location;
-   u32 ring_current_tail_pointer_value;
-   u8 engine_state_submit_value;
-   u8 engine_state_wait_value;
-   u16 pagefault_count;
-   u16 engine_submit_queue_count;
-} __packed;
-
-/*
- * This structure describes a stage set arranged for a particular communication
- * between uKernel (GuC) and Driver (KMD). Technically, this is known as a
- * "GuC Context descriptor" in the specs, but we use the term "stage 
descriptor"
- * to avoid confusion with all the other things already named "context" in the
- * driver. A static pool of these descriptors are stored inside a GEM object
- * (stage_desc_pool) which is held for the entire lifetime of our interaction
- * with the GuC, being allocated before the GuC is loaded with its firmware.
- */
-struct guc_stage_desc {
-   u32 sched_common_area;
-   u32 stage_id;
-   u32 pas_id;
-   u8 engines_used;
-   u64 db_trigger_cpu;
-   u32 db_trigger_uk;
-   u64 db_trigger_phy;
-   u16 db_id;
-
-   struct guc_execlist_context lrc[GUC_MAX_ENGINES_NUM];
-
-   u8 attribute;
-
-   u32 priority;
-
-   u32 wq_sampled_tail_offset;
-   u32 wq_total_submit_enqueues;
-
-   u32 process_desc;
-   u32 wq_addr;
-   u32 wq_size;
-
-   u32 engine_presence;
-
-   u8 engine_suspended;
-
-   u8 reserved0[3];
-   u64 reserved1[1];
-
-   u64 desc_private;
-} __packed;
-
 #define CONTEXT_REGISTRATION_FLAG_KMD  BIT(0)
 
 #define CONTEXT_POLICY_DEFAULT_EXECUTION_QUANTUM_US 100
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index e9c237b18692..ed5d8ab3624f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -65,57 +65,35 @@ static inline struct i915_priolist *to_priolist(struct 
rb_node *rb)
return rb_entry(rb, struct i915_priolist, node);
 }
 
-static struct guc_stage_desc *__get_stage_desc(struct intel_guc *guc, u32 id)
+/* Future patches will use this function */
+__maybe_unused
+static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc *guc, u32 index)
 {
-   struct guc_stage_desc *base = guc->stage_desc_pool_vaddr;
+   struct guc_lrc_desc *base = guc->lrc_desc_pool_vaddr;
 
-   return [id];
-}
-
-static int guc_stage_desc_pool_create(struct intel_guc *guc)
-{
-   u32 size = PAGE_ALIGN(sizeof(struct guc_stage_desc) *
- GUC_MAX_STAGE_DESCRIPTORS);
+   GEM_BUG_ON(index >= GUC_MAX_LRC_DESCRIPTORS);
 
-   return intel_guc_allocate_and_map_vma(guc, size, >stage_desc_pool,
- >stage_desc_pool_vaddr);
+   return [index];
 }
 
-static void guc_stage_desc_pool_destroy(struct 

Re: [PATCH 12/18] drm/i915/guc: Ensure request ordering via completion fences

2021-07-21 Thread Daniele Ceraolo Spurio




On 7/20/2021 3:39 PM, Matthew Brost wrote:

If two requests are on the same ring, they are explicitly ordered by the
HW. So, a submission fence is sufficient to ensure ordering when using
the new GuC submission interface. Conversely, if two requests share a
timeline and are on the same physical engine but different context this
doesn't ensure ordering on the new GuC submission interface. So, a
completion fence needs to be used to ensure ordering.

v2:
  (Daniele)
   - Don't delete spin lock

Signed-off-by: John Harrison 
Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/i915_request.c | 12 ++--
  1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index ef26724fe980..3ecdc9180d8f 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -432,6 +432,7 @@ void i915_request_retire_upto(struct i915_request *rq)
  
  	do {

tmp = list_first_entry(>requests, typeof(*tmp), link);
+   GEM_BUG_ON(!i915_request_completed(tmp));
} while (i915_request_retire(tmp) && tmp != rq);
  }
  
@@ -1380,6 +1381,9 @@ i915_request_await_external(struct i915_request *rq, struct dma_fence *fence)

return err;
  }
  
+static int

+i915_request_await_request(struct i915_request *to, struct i915_request *from);
+


I missed it in the previous rev, but this forward decl seems unneeded.
With it dropped:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


  int
  i915_request_await_execution(struct i915_request *rq,
 struct dma_fence *fence)
@@ -1463,7 +1467,8 @@ i915_request_await_request(struct i915_request *to, 
struct i915_request *from)
return ret;
}
  
-	if (is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask)))

+   if (!intel_engine_uses_guc(to->engine) &&
+   is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask)))
ret = await_request_submit(to, from);
else
ret = emit_semaphore_wait(to, from, I915_FENCE_GFP);
@@ -1622,6 +1627,8 @@ __i915_request_add_to_timeline(struct i915_request *rq)
prev = to_request(__i915_active_fence_set(>last_request,
  >fence));
if (prev && !__i915_request_is_complete(prev)) {
+   bool uses_guc = intel_engine_uses_guc(rq->engine);
+
/*
 * The requests are supposed to be kept in order. However,
 * we need to be wary in case the timeline->last_request
@@ -1632,7 +1639,8 @@ __i915_request_add_to_timeline(struct i915_request *rq)
   i915_seqno_passed(prev->fence.seqno,
 rq->fence.seqno));
  
-		if (is_power_of_2(READ_ONCE(prev->engine)->mask | rq->engine->mask))

+   if ((!uses_guc && is_power_of_2(READ_ONCE(prev->engine)->mask | 
rq->engine->mask)) ||
+   (uses_guc && prev->context == rq->context))
i915_sw_fence_await_sw_fence(>submit,
 >submit,
 >submitq);




Re: [PATCH v5 09/15] drm/i915/pxp: Implement PXP irq handler

2021-07-21 Thread Daniele Ceraolo Spurio




On 7/21/2021 11:59 AM, Rodrigo Vivi wrote:

On Thu, Jul 15, 2021 at 09:10:28PM -0700, Daniele Ceraolo Spurio wrote:

From: "Huang, Sean Z" 

The HW will generate a teardown interrupt when session termination is
required, which requires i915 to submit a terminating batch. Once the HW
is done with the termination it will generate another interrupt, at
which point it is safe to re-create the session.

Since the termination and re-creation flow is something we want to
trigger from the driver as well, use a common work function that can be
called both from the irq handler and from the driver set-up flows, which
has the addded benefit of allowing us to skip any extra locks because
the work itself serializes the operations.

v2: use struct completion instead of bool (Chris)
v3: drop locks, clean up functions and improve comments (Chris),
 move to common work function.
v4: improve comments, simplify wait logic (Rodrigo)
v5: unconditionally set interrupts,

I didn't find this... this looks the same as v4


It's a very minor change in intel_pxp_irq_enable, the regs were set 
inside the if statement before in this patch and moved outside in a 
later patch, now they're outside to begin.





rename state_attacked var (Rodrigo)

thanks




Signed-off-by: Huang, Sean Z 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Cc: Rodrigo Vivi 
Reviewed-by: Rodrigo Vivi  #v4

anyway, this patch looks good to me...

Reviewed-by: Rodrigo Vivi 



Thanks!

Daniele






---
  drivers/gpu/drm/i915/Makefile|  1 +
  drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  7 ++
  drivers/gpu/drm/i915/i915_reg.h  |  1 +
  drivers/gpu/drm/i915/pxp/intel_pxp.c | 66 +++--
  drivers/gpu/drm/i915/pxp/intel_pxp.h |  8 ++
  drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 99 
  drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 32 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++-
  drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  5 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c |  8 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_types.h   | 18 
  11 files changed, 283 insertions(+), 16 deletions(-)
  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 44d3a2bcb64c..1714089a10f0 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -279,6 +279,7 @@ i915-y += i915_perf.o
  i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp.o \
pxp/intel_pxp_cmd.o \
+   pxp/intel_pxp_irq.o \
pxp/intel_pxp_session.o \
pxp/intel_pxp_tee.o
  
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c

index c13462274fe8..96f0e9172a09 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -13,6 +13,7 @@
  #include "intel_lrc_reg.h"
  #include "intel_uncore.h"
  #include "intel_rps.h"
+#include "pxp/intel_pxp_irq.h"
  
  static void guc_irq_handler(struct intel_guc *guc, u16 iir)

  {
@@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 
instance,
if (instance == OTHER_GTPM_INSTANCE)
return gen11_rps_irq_handler(>rps, iir);
  
+	if (instance == OTHER_KCR_INSTANCE)

+   return intel_pxp_irq_handler(>pxp, iir);
+
WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
  instance, iir);
  }
@@ -190,6 +194,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
+
+   intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0);
+   intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~0);
  }
  
  void gen11_gt_irq_postinstall(struct intel_gt *gt)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 943fe485c662..2c583f2d410d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8051,6 +8051,7 @@ enum {
  /* irq instances for OTHER_CLASS */
  #define OTHER_GUC_INSTANCE0
  #define OTHER_GTPM_INSTANCE   1
+#define OTHER_KCR_INSTANCE 4
  
  #define GEN11_INTR_IDENTITY_REG(x)	_MMIO(0x190060 + ((x) * 4))
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c

index 26176d43a02d..b0c7edc10cc3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -2,7 +2,9 @@
  /*
   * Copyright(c) 2020 Intel Corporation.
   */
+#include 
  #include "intel_pxp.h"
+#include "intel_pxp_irq.h"
  #include "intel_pxp_session.h"
  #include "intel_pxp_tee.h"
  #include "gt/intel_context.h"
@@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
  
  	mutex_init(>tee_mutex);
 

Re: [RESEND PATCH v6 07/14] drm/etnaviv: Change buffer dump checks to target syslog

2021-07-21 Thread Lucas Stach
Am Mittwoch, dem 21.07.2021 um 13:55 -0400 schrieb Sean Paul:
> From: Sean Paul 
> 
> Since the logs protected by these checks specifically target syslog,
> use the new drm_debug_syslog_enabled() call to avoid triggering
> these prints when only trace is enabled.
> 
> Signed-off-by: Sean Paul 

Acked-by: Lucas Stach 

> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-8-s...@poorly.run
>  #v5
> 
> Changes in v5:
> -Added to the set
> Changes in v6:
> -None
> ---
>  drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c 
> b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
> index 76d38561c910..7713474800e8 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
> @@ -353,7 +353,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 
> exec_state,
>  
>   lockdep_assert_held(>lock);
>  
> - if (drm_debug_enabled(DRM_UT_DRIVER))
> + if (drm_debug_syslog_enabled(DRM_UT_DRIVER))
>   etnaviv_buffer_dump(gpu, buffer, 0, 0x50);
>  
>   link_target = etnaviv_cmdbuf_get_va(cmdbuf,
> @@ -509,13 +509,13 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 
> exec_state,
>etnaviv_cmdbuf_get_va(buffer, 
> >mmu_context->cmdbuf_mapping)
>+ buffer->user_size - 4);
>  
> - if (drm_debug_enabled(DRM_UT_DRIVER))
> + if (drm_debug_syslog_enabled(DRM_UT_DRIVER))
>   pr_info("stream link to 0x%08x @ 0x%08x %p\n",
>   return_target,
>   etnaviv_cmdbuf_get_va(cmdbuf, 
> >mmu_context->cmdbuf_mapping),
>   cmdbuf->vaddr);
>  
> - if (drm_debug_enabled(DRM_UT_DRIVER)) {
> + if (drm_debug_syslog_enabled(DRM_UT_DRIVER)) {
>   print_hex_dump(KERN_INFO, "cmd ", DUMP_PREFIX_OFFSET, 16, 4,
>  cmdbuf->vaddr, cmdbuf->size, 0);
>  
> @@ -534,6 +534,6 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 
> exec_state,
>   VIV_FE_LINK_HEADER_PREFETCH(link_dwords),
>   link_target);
>  
> - if (drm_debug_enabled(DRM_UT_DRIVER))
> + if (drm_debug_syslog_enabled(DRM_UT_DRIVER))
>   etnaviv_buffer_dump(gpu, buffer, 0, 0x50);
>  }




Re: [Intel-gfx] [PATCH 5/7] drm/i915/gem/ttm: Respect the objection region in placement_from_obj

2021-07-21 Thread Daniel Vetter
On Wed, Jul 21, 2021 at 10:11 PM Jason Ekstrand  wrote:
>
> On Mon, Jul 19, 2021 at 8:35 AM Matthew Auld
>  wrote:
> >
> > On Fri, 16 Jul 2021 at 20:49, Jason Ekstrand  wrote:
> > >
> > > On Fri, Jul 16, 2021 at 1:45 PM Matthew Auld
> > >  wrote:
> > > >
> > > > On Fri, 16 Jul 2021 at 18:39, Jason Ekstrand  
> > > > wrote:
> > > > >
> > > > > On Fri, Jul 16, 2021 at 11:00 AM Matthew Auld
> > > > >  wrote:
> > > > > >
> > > > > > On Fri, 16 Jul 2021 at 16:52, Matthew Auld
> > > > > >  wrote:
> > > > > > >
> > > > > > > On Fri, 16 Jul 2021 at 15:10, Jason Ekstrand 
> > > > > > >  wrote:
> > > > > > > >
> > > > > > > > On Fri, Jul 16, 2021 at 8:54 AM Matthew Auld
> > > > > > > >  wrote:
> > > > > > > > >
> > > > > > > > > On Thu, 15 Jul 2021 at 23:39, Jason Ekstrand 
> > > > > > > > >  wrote:
> > > > > > > > > >
> > > > > > > > > > Whenever we had a user object (n_placements > 0), we were 
> > > > > > > > > > ignoring
> > > > > > > > > > obj->mm.region and always putting obj->placements[0] as the 
> > > > > > > > > > requested
> > > > > > > > > > region.  For LMEM+SMEM objects, this was causing them to 
> > > > > > > > > > get shoved into
> > > > > > > > > > LMEM on every i915_ttm_get_pages() even when SMEM was 
> > > > > > > > > > requested by, say,
> > > > > > > > > > i915_gem_object_migrate().
> > > > > > > > >
> > > > > > > > > i915_ttm_migrate calls i915_ttm_place_from_region() directly 
> > > > > > > > > with the
> > > > > > > > > requested region, so there shouldn't be an issue with 
> > > > > > > > > migration right?
> > > > > > > > > Do you have some more details?
> > > > > > > >
> > > > > > > > With i915_ttm_migrate directly, no.  But, in the last patch in 
> > > > > > > > the
> > > > > > > > series, we're trying to migrate LMEM+SMEM buffers into SMEM on
> > > > > > > > attach() and pin it there.  This blows up in a very unexpected 
> > > > > > > > (IMO)
> > > > > > > > way.  The flow goes something like this:
> > > > > > > >
> > > > > > > >  - Client attempts a dma-buf import from another device
> > > > > > > >  - In attach() we call i915_gem_object_migrate() which calls
> > > > > > > > i915_ttm_migrate() which migrates as requested.
> > > > > > > >  - Once the migration is complete, we call 
> > > > > > > > i915_gem_object_pin_pages()
> > > > > > > > which calls i915_ttm_get_pages() which depends on
> > > > > > > > i915_ttm_placement_from_obj() and so migrates it right back to 
> > > > > > > > LMEM.
> > > > > > >
> > > > > > > The mm.pages must be NULL here, otherwise it would just increment 
> > > > > > > the
> > > > > > > pages_pin_count?
> > > > >
> > > > > Given that the test is using the four_underscores version, it
> > > > > doesn't have that check.  However, this executes after we've done the
> > > > > dma-buf import which pinned pages.  So we should definitely have
> > > > > pages.
> > > >
> > > > We shouldn't call four_underscores() if we might already have
> > > > pages though. Under non-TTM that would leak the pages, and in TTM we
> > > > might hit the WARN_ON(mm->pages) in __i915_ttm_get_pages(), if for
> > > > example nothing was moved. I take it we can't just call pin_pages()?
> > > > Four scary underscores usually means "don't call this in normal code".
> > >
> > > I've switched the four_underscores call to a __two_underscores in
> > > the selftests and it had no effect, good or bad.  But, still, probably
> > > better to call that one.
> > >
> > > > >
> > > > > > > >
> > > > > > > > Maybe the problem here is actually that our TTM code isn't 
> > > > > > > > respecting
> > > > > > > > obj->mm.pages_pin_count?
> > > > > > >
> > > > > > > I think if the resource is moved, we always nuke the mm.pages 
> > > > > > > after
> > > > > > > being notified of the move. Also TTM is also not allowed to move
> > > > > > > pinned buffers.
> > > > > > >
> > > > > > > I guess if we are evicted/swapped, so assuming we are not holding 
> > > > > > > the
> > > > > > > object lock, and it's not pinned, the future call to get_pages() 
> > > > > > > will
> > > > > > > see mm.pages = NULL, even though the ttm_resource is still there, 
> > > > > > > and
> > > > > > > because we prioritise the placements[0], instead of mm.region we 
> > > > > > > end
> > > > > > > up moving it for no good reason. But in your case you are holding 
> > > > > > > the
> > > > > > > lock, or it's pinned? Also is this just with the selftest, or
> > > > > > > something real?
> > > > > >
> > > > > > Or at least in the selftest I see i915_gem_object_get_pages()
> > > > > > which doesn't even consider the mm.pages AFAIK.
> > > > >
> > > > > The bogus migration is happening as part of the
> > > > > __i915_gem_object_get_pages() (2 __underscores) call in
> > > > > i915_gem_dmabuf_attach (see last patch).  That code is attempting to
> > > > > migrate the BO to SMEM and then pin it there using the obvious calls
> > > > > to do so.  However, in the pin_pages call, it gets implicitly migrated
> > > > > back to LMEM thanks 

Re: [PATCH 3/4] drm/i915/userptr: Probe existence of backing struct pages upon creation

2021-07-21 Thread Jason Ekstrand
On Thu, Jul 15, 2021 at 5:16 AM Matthew Auld  wrote:
>
> From: Chris Wilson 
>
> Jason Ekstrand requested a more efficient method than userptr+set-domain
> to determine if the userptr object was backed by a complete set of pages
> upon creation. To be more efficient than simply populating the userptr
> using get_user_pages() (as done by the call to set-domain or execbuf),
> we can walk the tree of vm_area_struct and check for gaps or vma not
> backed by struct page (VM_PFNMAP). The question is how to handle
> VM_MIXEDMAP which may be either struct page or pfn backed...
>
> With discrete are going to drop support for set_domain(), so offering a
> way to probe the pages, without having to resort to dummy batches has
> been requested.
>
> v2:
> - add new query param for the PROPBE flag, so userspace can easily
>   check if the kernel supports it(Jason).
> - use mmap_read_{lock, unlock}.
> - add some kernel-doc.
>
> Testcase: igt/gem_userptr_blits/probe
> Signed-off-by: Chris Wilson 
> Signed-off-by: Matthew Auld 
> Cc: Thomas Hellström 
> Cc: Maarten Lankhorst 
> Cc: Tvrtko Ursulin 
> Cc: Jordan Justen 
> Cc: Kenneth Graunke 
> Cc: Jason Ekstrand 
> Cc: Daniel Vetter 
> Cc: Ramalingam C 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 40 -
>  drivers/gpu/drm/i915/i915_getparam.c|  3 ++
>  include/uapi/drm/i915_drm.h | 18 ++
>  3 files changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> index 56edfeff8c02..fd6880328596 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> @@ -422,6 +422,33 @@ static const struct drm_i915_gem_object_ops 
> i915_gem_userptr_ops = {
>
>  #endif
>
> +static int
> +probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
> +{
> +   const unsigned long end = addr + len;
> +   struct vm_area_struct *vma;
> +   int ret = -EFAULT;
> +
> +   mmap_read_lock(mm);
> +   for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
> +   if (vma->vm_start > addr)

Why isn't this > end?  Are we somehow guaranteed that one vma covers
the entire range?

> +   break;
> +
> +   if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
> +   break;
> +
> +   if (vma->vm_end >= end) {
> +   ret = 0;
> +   break;
> +   }
> +
> +   addr = vma->vm_end;
> +   }
> +   mmap_read_unlock(mm);
> +
> +   return ret;
> +}
> +
>  /*
>   * Creates a new mm object that wraps some normal memory from the process
>   * context - user memory.
> @@ -477,7 +504,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
> }
>
> if (args->flags & ~(I915_USERPTR_READ_ONLY |
> -   I915_USERPTR_UNSYNCHRONIZED))
> +   I915_USERPTR_UNSYNCHRONIZED |
> +   I915_USERPTR_PROBE))
> return -EINVAL;
>
> if (i915_gem_object_size_2big(args->user_size))
> @@ -504,6 +532,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
> return -ENODEV;
> }
>
> +   if (args->flags & I915_USERPTR_PROBE) {
> +   /*
> +* Check that the range pointed to represents real struct
> +* pages and not iomappings (at this moment in time!)
> +*/
> +   ret = probe_range(current->mm, args->user_ptr, 
> args->user_size);
> +   if (ret)
> +   return ret;
> +   }
> +
>  #ifdef CONFIG_MMU_NOTIFIER
> obj = i915_gem_object_alloc();
> if (obj == NULL)
> diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
> b/drivers/gpu/drm/i915/i915_getparam.c
> index 24e18219eb50..d6d2e1a10d14 100644
> --- a/drivers/gpu/drm/i915/i915_getparam.c
> +++ b/drivers/gpu/drm/i915/i915_getparam.c
> @@ -163,6 +163,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void 
> *data,
> case I915_PARAM_PERF_REVISION:
> value = i915_perf_ioctl_version();
> break;
> +   case I915_PARAM_HAS_USERPTR_PROBE:
> +   value = true;
> +   break;
> default:
> DRM_DEBUG("Unknown parameter %d\n", param->param);
> return -EINVAL;
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index e20eeeca7a1c..2e4112bf4d38 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -674,6 +674,9 @@ typedef struct drm_i915_irq_wait {
>   */
>  #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
>
> +/* Query if the kernel supports the I915_USERPTR_PROBE flag. */
> +#define I915_PARAM_HAS_USERPTR_PROBE 56
> +
>  /* Must be kept compact -- no holes and well documented */
>
>  typedef struct drm_i915_getparam {
> @@ -2178,12 +2181,27 

Re: [PATCH] drm/i915: Ditch i915 globals shrink infrastructure

2021-07-21 Thread Daniel Vetter
On Wed, Jul 21, 2021 at 10:17 PM Jason Ekstrand  wrote:
>
> On Wed, Jul 21, 2021 at 1:32 PM Daniel Vetter  wrote:
> >
> > This essentially reverts
> >
> > commit 84a1074920523430f9dc30ff907f4801b4820072
> > Author: Chris Wilson 
> > Date:   Wed Jan 24 11:36:08 2018 +
> >
> > drm/i915: Shrink the GEM kmem_caches upon idling
> >
> > mm/vmscan.c:do_shrink_slab() is a thing, if there's an issue with it
> > then we need to fix that there, not hand-roll our own slab shrinking
> > code in i915.
> >
> > Noticed while reviewing a patch set from Jason to fix up some issues
> > in our i915_init() and i915_exit() module load/cleanup code. Now that
> > i915_globals.c isn't any different than normal init/exit functions, we
> > should convert them over to one unified table and remove
> > i915_globals.[hc] entirely.
>
> Mind throwing in a comment somewhere about how i915 is one of only two
> users of kmem_cache_shrink() in the entire kernel?  That also seems to
> be pretty good evidence that it's not useful.

I missed one, there's also on in kunit (I think just got in, it's from
this year at least per commit). That one seems actually legit, it's a
selftest for some statistics around slabs I think, so has a legit
reason to carefully control the state and trim anything that just
hangs around.

I'll add something and push when CI approves.

> Reviewed-by: Jason Ekstrand 
>
> Feel free to land at-will and I'll deal with merge conflicts on my end.

I think if we can land this, then yours, then I type the conversion to
explicit init/exit and we're done.
-Daniel

>
> > Cc: David Airlie 
> > Cc: Jason Ekstrand 
> > Signed-off-by: Daniel Vetter 
> > ---
> >  drivers/gpu/drm/i915/gem/i915_gem_context.c |  6 --
> >  drivers/gpu/drm/i915/gem/i915_gem_object.c  |  6 --
> >  drivers/gpu/drm/i915/gt/intel_context.c |  6 --
> >  drivers/gpu/drm/i915/gt/intel_gt_pm.c   |  4 -
> >  drivers/gpu/drm/i915/i915_active.c  |  6 --
> >  drivers/gpu/drm/i915/i915_globals.c | 95 -
> >  drivers/gpu/drm/i915/i915_globals.h |  3 -
> >  drivers/gpu/drm/i915/i915_request.c |  7 --
> >  drivers/gpu/drm/i915/i915_scheduler.c   |  7 --
> >  drivers/gpu/drm/i915/i915_vma.c |  6 --
> >  10 files changed, 146 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> > b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > index 7d6f52d8a801..bf2a2319353a 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > @@ -2280,18 +2280,12 @@ i915_gem_engines_iter_next(struct 
> > i915_gem_engines_iter *it)
> >  #include "selftests/i915_gem_context.c"
> >  #endif
> >
> > -static void i915_global_gem_context_shrink(void)
> > -{
> > -   kmem_cache_shrink(global.slab_luts);
> > -}
> > -
> >  static void i915_global_gem_context_exit(void)
> >  {
> > kmem_cache_destroy(global.slab_luts);
> >  }
> >
> >  static struct i915_global_gem_context global = { {
> > -   .shrink = i915_global_gem_context_shrink,
> > .exit = i915_global_gem_context_exit,
> >  } };
> >
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
> > b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > index 9da7b288b7ed..5c21cff33199 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > @@ -664,18 +664,12 @@ void i915_gem_init__objects(struct drm_i915_private 
> > *i915)
> > INIT_WORK(>mm.free_work, __i915_gem_free_work);
> >  }
> >
> > -static void i915_global_objects_shrink(void)
> > -{
> > -   kmem_cache_shrink(global.slab_objects);
> > -}
> > -
> >  static void i915_global_objects_exit(void)
> >  {
> > kmem_cache_destroy(global.slab_objects);
> >  }
> >
> >  static struct i915_global_object global = { {
> > -   .shrink = i915_global_objects_shrink,
> > .exit = i915_global_objects_exit,
> >  } };
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
> > b/drivers/gpu/drm/i915/gt/intel_context.c
> > index bd63813c8a80..c1338441cc1d 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_context.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> > @@ -398,18 +398,12 @@ void intel_context_fini(struct intel_context *ce)
> > i915_active_fini(>active);
> >  }
> >
> > -static void i915_global_context_shrink(void)
> > -{
> > -   kmem_cache_shrink(global.slab_ce);
> > -}
> > -
> >  static void i915_global_context_exit(void)
> >  {
> > kmem_cache_destroy(global.slab_ce);
> >  }
> >
> >  static struct i915_global_context global = { {
> > -   .shrink = i915_global_context_shrink,
> > .exit = i915_global_context_exit,
> >  } };
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
> > b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> > index aef3084e8b16..d86825437516 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> > @@ -67,8 +67,6 @@ static int 

Re: [PATCH] drm/i915: Ditch i915 globals shrink infrastructure

2021-07-21 Thread Jason Ekstrand
On Wed, Jul 21, 2021 at 1:32 PM Daniel Vetter  wrote:
>
> This essentially reverts
>
> commit 84a1074920523430f9dc30ff907f4801b4820072
> Author: Chris Wilson 
> Date:   Wed Jan 24 11:36:08 2018 +
>
> drm/i915: Shrink the GEM kmem_caches upon idling
>
> mm/vmscan.c:do_shrink_slab() is a thing, if there's an issue with it
> then we need to fix that there, not hand-roll our own slab shrinking
> code in i915.
>
> Noticed while reviewing a patch set from Jason to fix up some issues
> in our i915_init() and i915_exit() module load/cleanup code. Now that
> i915_globals.c isn't any different than normal init/exit functions, we
> should convert them over to one unified table and remove
> i915_globals.[hc] entirely.

Mind throwing in a comment somewhere about how i915 is one of only two
users of kmem_cache_shrink() in the entire kernel?  That also seems to
be pretty good evidence that it's not useful.

Reviewed-by: Jason Ekstrand 

Feel free to land at-will and I'll deal with merge conflicts on my end.

> Cc: David Airlie 
> Cc: Jason Ekstrand 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c |  6 --
>  drivers/gpu/drm/i915/gem/i915_gem_object.c  |  6 --
>  drivers/gpu/drm/i915/gt/intel_context.c |  6 --
>  drivers/gpu/drm/i915/gt/intel_gt_pm.c   |  4 -
>  drivers/gpu/drm/i915/i915_active.c  |  6 --
>  drivers/gpu/drm/i915/i915_globals.c | 95 -
>  drivers/gpu/drm/i915/i915_globals.h |  3 -
>  drivers/gpu/drm/i915/i915_request.c |  7 --
>  drivers/gpu/drm/i915/i915_scheduler.c   |  7 --
>  drivers/gpu/drm/i915/i915_vma.c |  6 --
>  10 files changed, 146 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 7d6f52d8a801..bf2a2319353a 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -2280,18 +2280,12 @@ i915_gem_engines_iter_next(struct 
> i915_gem_engines_iter *it)
>  #include "selftests/i915_gem_context.c"
>  #endif
>
> -static void i915_global_gem_context_shrink(void)
> -{
> -   kmem_cache_shrink(global.slab_luts);
> -}
> -
>  static void i915_global_gem_context_exit(void)
>  {
> kmem_cache_destroy(global.slab_luts);
>  }
>
>  static struct i915_global_gem_context global = { {
> -   .shrink = i915_global_gem_context_shrink,
> .exit = i915_global_gem_context_exit,
>  } };
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index 9da7b288b7ed..5c21cff33199 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> @@ -664,18 +664,12 @@ void i915_gem_init__objects(struct drm_i915_private 
> *i915)
> INIT_WORK(>mm.free_work, __i915_gem_free_work);
>  }
>
> -static void i915_global_objects_shrink(void)
> -{
> -   kmem_cache_shrink(global.slab_objects);
> -}
> -
>  static void i915_global_objects_exit(void)
>  {
> kmem_cache_destroy(global.slab_objects);
>  }
>
>  static struct i915_global_object global = { {
> -   .shrink = i915_global_objects_shrink,
> .exit = i915_global_objects_exit,
>  } };
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
> b/drivers/gpu/drm/i915/gt/intel_context.c
> index bd63813c8a80..c1338441cc1d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -398,18 +398,12 @@ void intel_context_fini(struct intel_context *ce)
> i915_active_fini(>active);
>  }
>
> -static void i915_global_context_shrink(void)
> -{
> -   kmem_cache_shrink(global.slab_ce);
> -}
> -
>  static void i915_global_context_exit(void)
>  {
> kmem_cache_destroy(global.slab_ce);
>  }
>
>  static struct i915_global_context global = { {
> -   .shrink = i915_global_context_shrink,
> .exit = i915_global_context_exit,
>  } };
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
> b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> index aef3084e8b16..d86825437516 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> @@ -67,8 +67,6 @@ static int __gt_unpark(struct intel_wakeref *wf)
>
> GT_TRACE(gt, "\n");
>
> -   i915_globals_unpark();
> -
> /*
>  * It seems that the DMC likes to transition between the DC states a 
> lot
>  * when there are no connected displays (no active power domains) 
> during
> @@ -116,8 +114,6 @@ static int __gt_park(struct intel_wakeref *wf)
> GEM_BUG_ON(!wakeref);
> intel_display_power_put_async(i915, POWER_DOMAIN_GT_IRQ, wakeref);
>
> -   i915_globals_park();
> -
> return 0;
>  }
>
> diff --git a/drivers/gpu/drm/i915/i915_active.c 
> b/drivers/gpu/drm/i915/i915_active.c
> index b1aa1c482c32..91723123ae9f 100644
> --- a/drivers/gpu/drm/i915/i915_active.c
> +++ b/drivers/gpu/drm/i915/i915_active.c
> 

Re: [Intel-gfx] [PATCH 6/6] drm/i915: Make the kmem slab for i915_buddy_block a global

2021-07-21 Thread Jason Ekstrand
On Wed, Jul 21, 2021 at 1:56 PM Daniel Vetter  wrote:
>
> On Wed, Jul 21, 2021 at 05:25:41PM +0100, Matthew Auld wrote:
> > On 21/07/2021 16:23, Jason Ekstrand wrote:
> > > There's no reason that I can tell why this should be per-i915_buddy_mm
> > > and doing so causes KMEM_CACHE to throw dmesg warnings because it tries
> > > to create a debugfs entry with the name i915_buddy_block multiple times.
> > > We could handle this by carefully giving each slab its own name but that
> > > brings its own pain because then we have to store that string somewhere
> > > and manage the lifetimes of the different slabs.  The most likely
> > > outcome would be a global atomic which we increment to get a new name or
> > > something like that.
> > >
> > > The much easier solution is to use the i915_globals system like we do
> > > for every other slab in i915.  This ensures that we have exactly one of
> > > them for each i915 driver load and it gets neatly created on module load
> > > and destroyed on module unload.  Using the globals system also means
> > > that its now tied into the shrink handler so we can properly respond to
> > > low-memory situations.
> > >
> > > Signed-off-by: Jason Ekstrand 
> > > Fixes: 88be9a0a06b7 ("drm/i915/ttm: add ttm_buddy_man")
> > > Cc: Matthew Auld 
> > > Cc: Christian König 
> >
> > It was intentionally ripped it out with the idea that we would be moving the
> > buddy stuff into ttm, and so part of that was trying to get rid of the some
> > of the i915 specifics, like this globals thing.
> >
> > Reviewed-by: Matthew Auld 
>
> I just sent out a patch to put i915_globals on a diet, so maybe we can
> hold this patch here a bit when there's other reasons for why this is
> special?

This is required to get rid of the dmesg warnings.

> Or at least no make this use the i915_globals stuff and instead just link
> up the init/exit function calls directly into Jason's new table, so that
> we don't have a merge conflict here?

I'm happy to deal with merge conflicts however they land.

--Jason

> -Daniel
>
> >
> > > ---
> > >   drivers/gpu/drm/i915/i915_buddy.c   | 44 ++---
> > >   drivers/gpu/drm/i915/i915_buddy.h   |  3 +-
> > >   drivers/gpu/drm/i915/i915_globals.c |  2 ++
> > >   3 files changed, 38 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/i915_buddy.c 
> > > b/drivers/gpu/drm/i915/i915_buddy.c
> > > index 29dd7d0310c1f..911feedad4513 100644
> > > --- a/drivers/gpu/drm/i915/i915_buddy.c
> > > +++ b/drivers/gpu/drm/i915/i915_buddy.c
> > > @@ -8,8 +8,14 @@
> > >   #include "i915_buddy.h"
> > >   #include "i915_gem.h"
> > > +#include "i915_globals.h"
> > >   #include "i915_utils.h"
> > > +static struct i915_global_buddy {
> > > +   struct i915_global base;
> > > +   struct kmem_cache *slab_blocks;
> > > +} global;
> > > +
> > >   static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_mm 
> > > *mm,
> > >  struct i915_buddy_block 
> > > *parent,
> > >  unsigned int order,
> > > @@ -19,7 +25,7 @@ static struct i915_buddy_block *i915_block_alloc(struct 
> > > i915_buddy_mm *mm,
> > > GEM_BUG_ON(order > I915_BUDDY_MAX_ORDER);
> > > -   block = kmem_cache_zalloc(mm->slab_blocks, GFP_KERNEL);
> > > +   block = kmem_cache_zalloc(global.slab_blocks, GFP_KERNEL);
> > > if (!block)
> > > return NULL;
> > > @@ -34,7 +40,7 @@ static struct i915_buddy_block *i915_block_alloc(struct 
> > > i915_buddy_mm *mm,
> > >   static void i915_block_free(struct i915_buddy_mm *mm,
> > > struct i915_buddy_block *block)
> > >   {
> > > -   kmem_cache_free(mm->slab_blocks, block);
> > > +   kmem_cache_free(global.slab_blocks, block);
> > >   }
> > >   static void mark_allocated(struct i915_buddy_block *block)
> > > @@ -85,15 +91,11 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 
> > > size, u64 chunk_size)
> > > GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER);
> > > -   mm->slab_blocks = KMEM_CACHE(i915_buddy_block, SLAB_HWCACHE_ALIGN);
> > > -   if (!mm->slab_blocks)
> > > -   return -ENOMEM;
> > > -
> > > mm->free_list = kmalloc_array(mm->max_order + 1,
> > >   sizeof(struct list_head),
> > >   GFP_KERNEL);
> > > if (!mm->free_list)
> > > -   goto out_destroy_slab;
> > > +   return -ENOMEM;
> > > for (i = 0; i <= mm->max_order; ++i)
> > > INIT_LIST_HEAD(>free_list[i]);
> > > @@ -145,8 +147,6 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 
> > > size, u64 chunk_size)
> > > kfree(mm->roots);
> > >   out_free_list:
> > > kfree(mm->free_list);
> > > -out_destroy_slab:
> > > -   kmem_cache_destroy(mm->slab_blocks);
> > > return -ENOMEM;
> > >   }
> > > @@ -161,7 +161,6 @@ void i915_buddy_fini(struct i915_buddy_mm *mm)
> > > kfree(mm->roots);
> > > kfree(mm->free_list);
> > > -   

[PATCH 7/7] drm/i915/gem: Migrate to system at dma-buf attach time (v7)

2021-07-21 Thread Jason Ekstrand
From: Thomas Hellström 

Until we support p2p dma or as a complement to that, migrate data
to system memory at dma-buf attach time if possible.

v2:
- Rebase on dynamic exporter. Update the igt_dmabuf_import_same_driver
  selftest to migrate if we are LMEM capable.
v3:
- Migrate also in the pin() callback.
v4:
- Migrate in attach
v5: (jason)
- Lock around the migration
v6: (jason)
- Move the can_migrate check outside the lock
- Rework the selftests to test more migration conditions.  In
  particular, SMEM, LMEM, and LMEM+SMEM are all checked.
v7: (mauld)
- Misc style nits

Signed-off-by: Thomas Hellström 
Signed-off-by: Michael J. Ruhl 
Reported-by: kernel test robot 
Signed-off-by: Jason Ekstrand 
Reviewed-by: Jason Ekstrand 
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 23 -
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 87 ++-
 2 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 59dc56ae14d6b..afa34111de02e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -164,8 +164,29 @@ static int i915_gem_dmabuf_attach(struct dma_buf *dmabuf,
  struct dma_buf_attachment *attach)
 {
struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf);
+   struct i915_gem_ww_ctx ww;
+   int err;
+
+   if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM))
+   return -EOPNOTSUPP;
+
+   for_i915_gem_ww(, err, true) {
+   err = i915_gem_object_lock(obj, );
+   if (err)
+   continue;
+
+   err = i915_gem_object_migrate(obj, , INTEL_REGION_SMEM);
+   if (err)
+   continue;
 
-   return i915_gem_object_pin_pages_unlocked(obj);
+   err = i915_gem_object_wait_migration(obj, 0);
+   if (err)
+   continue;
+
+   err = i915_gem_object_pin_pages(obj);
+   }
+
+   return err;
 }
 
 static void i915_gem_dmabuf_detach(struct dma_buf *dmabuf,
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
index d4ce01e6ee854..ffae7df5e4d7d 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
@@ -85,9 +85,63 @@ static int igt_dmabuf_import_self(void *arg)
return err;
 }
 
-static int igt_dmabuf_import_same_driver(void *arg)
+static int igt_dmabuf_import_same_driver_lmem(void *arg)
 {
struct drm_i915_private *i915 = arg;
+   struct intel_memory_region *lmem = i915->mm.regions[INTEL_REGION_LMEM];
+   struct drm_i915_gem_object *obj;
+   struct drm_gem_object *import;
+   struct dma_buf *dmabuf;
+   int err;
+
+   if (!lmem)
+   return 0;
+
+   force_different_devices = true;
+
+   obj = __i915_gem_object_create_user(i915, PAGE_SIZE, , 1);
+   if (IS_ERR(obj)) {
+   pr_err("__i915_gem_object_create_user failed with err=%ld\n",
+  PTR_ERR(dmabuf));
+   err = PTR_ERR(obj);
+   goto out_ret;
+   }
+
+   dmabuf = i915_gem_prime_export(>base, 0);
+   if (IS_ERR(dmabuf)) {
+   pr_err("i915_gem_prime_export failed with err=%ld\n",
+  PTR_ERR(dmabuf));
+   err = PTR_ERR(dmabuf);
+   goto out;
+   }
+
+   /*
+* We expect an import of an LMEM-only object to fail with
+* -EOPNOTSUPP because it can't be migrated to SMEM.
+*/
+   import = i915_gem_prime_import(>drm, dmabuf);
+   if (!IS_ERR(import)) {
+   drm_gem_object_put(import);
+   pr_err("i915_gem_prime_import succeeded when it shouldn't 
have\n");
+   err = -EINVAL;
+   } else if (PTR_ERR(import) != -EOPNOTSUPP) {
+   pr_err("i915_gem_prime_import failed with the wrong err=%ld\n",
+  PTR_ERR(import));
+   err = PTR_ERR(import);
+   }
+
+   dma_buf_put(dmabuf);
+out:
+   i915_gem_object_put(obj);
+out_ret:
+   force_different_devices = false;
+   return err;
+}
+
+static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
+struct intel_memory_region **regions,
+unsigned int num_regions)
+{
struct drm_i915_gem_object *obj, *import_obj;
struct drm_gem_object *import;
struct dma_buf *dmabuf;
@@ -97,8 +151,12 @@ static int igt_dmabuf_import_same_driver(void *arg)
int err;
 
force_different_devices = true;
-   obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
+
+   obj = __i915_gem_object_create_user(i915, PAGE_SIZE,
+   regions, num_regions);
if 

[PATCH 6/7] drm/i915/gem: Correct the locking and pin pattern for dma-buf (v8)

2021-07-21 Thread Jason Ekstrand
From: Thomas Hellström 

If our exported dma-bufs are imported by another instance of our driver,
that instance will typically have the imported dma-bufs locked during
dma_buf_map_attachment(). But the exporter also locks the same reservation
object in the map_dma_buf() callback, which leads to recursive locking.

So taking the lock inside _pin_pages_unlocked() is incorrect.

Additionally, the current pinning code path is contrary to the defined
way that pinning should occur.

Remove the explicit pin/unpin from the map/umap functions and move them
to the attach/detach allowing correct locking to occur, and to match
the static dma-buf drm_prime pattern.

Add a live selftest to exercise both dynamic and non-dynamic
exports.

v2:
- Extend the selftest with a fake dynamic importer.
- Provide real pin and unpin callbacks to not abuse the interface.
v3: (ruhl)
- Remove the dynamic export support and move the pinning into the
  attach/detach path.
v4: (ruhl)
- Put pages does not need to assert on the dma-resv
v5: (jason)
- Lock around dma_buf_unmap_attachment() when emulating a dynamic
  importer in the subtests.
- Use pin_pages_unlocked
v6: (jason)
- Use dma_buf_attach instead of dma_buf_attach_dynamic in the selftests
v7: (mauld)
- Use __i915_gem_object_get_pages (2 __underscores) instead of the
  4 underscore version in the selftests
v8: (mauld)
- Drop the kernel doc from the static i915_gem_dmabuf_attach function
- Add missing "err = PTR_ERR()" to a bunch of selftest error cases

Reported-by: Michael J. Ruhl 
Signed-off-by: Thomas Hellström 
Signed-off-by: Michael J. Ruhl 
Signed-off-by: Jason Ekstrand 
Reviewed-by: Jason Ekstrand 
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  37 --
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 109 +-
 2 files changed, 132 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 616c3a2f1baf0..59dc56ae14d6b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -12,6 +12,8 @@
 #include "i915_gem_object.h"
 #include "i915_scatterlist.h"
 
+I915_SELFTEST_DECLARE(static bool force_different_devices;)
+
 static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
 {
return to_intel_bo(buf->priv);
@@ -25,15 +27,11 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
dma_buf_attachment *attachme
struct scatterlist *src, *dst;
int ret, i;
 
-   ret = i915_gem_object_pin_pages_unlocked(obj);
-   if (ret)
-   goto err;
-
/* Copy sg so that we make an independent mapping */
st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
if (st == NULL) {
ret = -ENOMEM;
-   goto err_unpin_pages;
+   goto err;
}
 
ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
@@ -58,8 +56,6 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
dma_buf_attachment *attachme
sg_free_table(st);
 err_free:
kfree(st);
-err_unpin_pages:
-   i915_gem_object_unpin_pages(obj);
 err:
return ERR_PTR(ret);
 }
@@ -68,13 +64,9 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment 
*attachment,
   struct sg_table *sg,
   enum dma_data_direction dir)
 {
-   struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
-
dma_unmap_sgtable(attachment->dev, sg, dir, DMA_ATTR_SKIP_CPU_SYNC);
sg_free_table(sg);
kfree(sg);
-
-   i915_gem_object_unpin_pages(obj);
 }
 
 static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map 
*map)
@@ -168,7 +160,25 @@ static int i915_gem_end_cpu_access(struct dma_buf 
*dma_buf, enum dma_data_direct
return err;
 }
 
+static int i915_gem_dmabuf_attach(struct dma_buf *dmabuf,
+ struct dma_buf_attachment *attach)
+{
+   struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf);
+
+   return i915_gem_object_pin_pages_unlocked(obj);
+}
+
+static void i915_gem_dmabuf_detach(struct dma_buf *dmabuf,
+  struct dma_buf_attachment *attach)
+{
+   struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf);
+
+   i915_gem_object_unpin_pages(obj);
+}
+
 static const struct dma_buf_ops i915_dmabuf_ops =  {
+   .attach = i915_gem_dmabuf_attach,
+   .detach = i915_gem_dmabuf_detach,
.map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
@@ -204,6 +214,8 @@ static int i915_gem_object_get_pages_dmabuf(struct 
drm_i915_gem_object *obj)
struct sg_table *pages;
unsigned int sg_page_sizes;
 
+   assert_object_held(obj);
+
pages = dma_buf_map_attachment(obj->base.import_attach,
   DMA_BIDIRECTIONAL);
if 

[PATCH 5/7] drm/i915/gem/ttm: Respect the objection region in placement_from_obj

2021-07-21 Thread Jason Ekstrand
Whenever we had a user object (n_placements > 0), we were ignoring
obj->mm.region and always putting obj->placements[0] as the requested
region.  For LMEM+SMEM objects, this was causing them to get shoved into
LMEM on every i915_ttm_get_pages() even when SMEM was requested by, say,
i915_gem_object_migrate().

Signed-off-by: Jason Ekstrand 
Cc: Thomas Hellström 
Cc: Matthew Auld 
Cc: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index f253b11e9e367..b76bdd978a5cc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -150,8 +150,7 @@ i915_ttm_placement_from_obj(const struct 
drm_i915_gem_object *obj,
unsigned int i;
 
placement->num_placement = 1;
-   i915_ttm_place_from_region(num_allowed ? obj->mm.placements[0] :
-  obj->mm.region, requested, flags);
+   i915_ttm_place_from_region(obj->mm.region, requested, flags);
 
/* Cache this on object? */
placement->num_busy_placement = num_allowed;
-- 
2.31.1



[PATCH 4/7] drm/i915/gem: Unify user object creation (v3)

2021-07-21 Thread Jason Ekstrand
Instead of hand-rolling the same three calls in each function, pull them
into an i915_gem_object_create_user helper.  Apart from re-ordering of
the placements array ENOMEM check, there should be no functional change.

v2 (Matthew Auld):
 - Add the call to i915_gem_flush_free_objects() from
   i915_gem_dumb_create() in a separate patch
 - Move i915_gem_object_alloc() below the simple error checks
v3 (Matthew Auld):
 - Add __ to i915_gem_object_create_user and kerneldoc which warns the
   caller that it's not validating anything.

Signed-off-by: Jason Ekstrand 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 119 ++---
 drivers/gpu/drm/i915/gem/i915_gem_object.h |   4 +
 2 files changed, 58 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index adcce37c04b8d..23fee13a33844 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -11,13 +11,14 @@
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
 
-static u32 object_max_page_size(struct drm_i915_gem_object *obj)
+static u32 object_max_page_size(struct intel_memory_region **placements,
+   unsigned int n_placements)
 {
u32 max_page_size = 0;
int i;
 
-   for (i = 0; i < obj->mm.n_placements; i++) {
-   struct intel_memory_region *mr = obj->mm.placements[i];
+   for (i = 0; i < n_placements; i++) {
+   struct intel_memory_region *mr = placements[i];
 
GEM_BUG_ON(!is_power_of_2(mr->min_page_size));
max_page_size = max_t(u32, max_page_size, mr->min_page_size);
@@ -81,22 +82,46 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
return 0;
 }
 
-static int
-i915_gem_setup(struct drm_i915_gem_object *obj, u64 size)
+/**
+ * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
+ * @i915: i915 private
+ * @size: size of the buffer, in bytes
+ * @placements: possible placement regions, in priority order
+ * @n_placements: number of possible placement regions
+ *
+ * This function is exposed primarily for selftests and does very little
+ * error checking.  It is assumed that the set of placement regions has
+ * already been verified to be valid.
+ */
+struct drm_i915_gem_object *
+__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
+ struct intel_memory_region **placements,
+ unsigned int n_placements)
 {
-   struct intel_memory_region *mr = obj->mm.placements[0];
+   struct intel_memory_region *mr = placements[0];
+   struct drm_i915_gem_object *obj;
unsigned int flags;
int ret;
 
-   size = round_up(size, object_max_page_size(obj));
+   i915_gem_flush_free_objects(i915);
+
+   size = round_up(size, object_max_page_size(placements, n_placements));
if (size == 0)
-   return -EINVAL;
+   return ERR_PTR(-EINVAL);
 
/* For most of the ABI (e.g. mmap) we think in system pages */
GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE));
 
if (i915_gem_object_size_2big(size))
-   return -E2BIG;
+   return ERR_PTR(-E2BIG);
+
+   obj = i915_gem_object_alloc();
+   if (!obj)
+   return ERR_PTR(-ENOMEM);
+
+   ret = object_set_placements(obj, placements, n_placements);
+   if (ret)
+   goto object_free;
 
/*
 * I915_BO_ALLOC_USER will make sure the object is cleared before
@@ -106,12 +131,18 @@ i915_gem_setup(struct drm_i915_gem_object *obj, u64 size)
 
ret = mr->ops->init_object(mr, obj, size, 0, flags);
if (ret)
-   return ret;
+   goto object_free;
 
GEM_BUG_ON(size != obj->base.size);
 
trace_i915_gem_object_create(obj);
-   return 0;
+   return obj;
+
+object_free:
+   if (obj->mm.n_placements > 1)
+   kfree(obj->mm.placements);
+   i915_gem_object_free(obj);
+   return ERR_PTR(ret);
 }
 
 int
@@ -124,7 +155,6 @@ i915_gem_dumb_create(struct drm_file *file,
enum intel_memory_type mem_type;
int cpp = DIV_ROUND_UP(args->bpp, 8);
u32 format;
-   int ret;
 
switch (cpp) {
case 1:
@@ -151,32 +181,19 @@ i915_gem_dumb_create(struct drm_file *file,
if (args->pitch < args->width)
return -EINVAL;
 
-   i915_gem_flush_free_objects(i915);
-
args->size = mul_u32_u32(args->pitch, args->height);
 
mem_type = INTEL_MEMORY_SYSTEM;
if (HAS_LMEM(to_i915(dev)))
mem_type = INTEL_MEMORY_LOCAL;
 
-   obj = i915_gem_object_alloc();
-   if (!obj)
-   return -ENOMEM;
-
mr = intel_memory_region_by_type(to_i915(dev), mem_type);
-   ret = object_set_placements(obj, , 1);
-   if (ret)
-   goto 

[PATCH 3/7] drm/i915/gem: Call i915_gem_flush_free_objects() in i915_gem_dumb_create()

2021-07-21 Thread Jason Ekstrand
This doesn't really fix anything serious since the chances of a client
creating and destroying a mass of dumb BOs is pretty low.  However, it
is called by the other two create IOCTLs to garbage collect old objects.
Call it here too for consistency.

Signed-off-by: Jason Ekstrand 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index aa687b10dcd45..adcce37c04b8d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -151,6 +151,8 @@ i915_gem_dumb_create(struct drm_file *file,
if (args->pitch < args->width)
return -EINVAL;
 
+   i915_gem_flush_free_objects(i915);
+
args->size = mul_u32_u32(args->pitch, args->height);
 
mem_type = INTEL_MEMORY_SYSTEM;
-- 
2.31.1



[PATCH 2/7] drm/i915/gem: Refactor placement setup for i915_gem_object_create* (v2)

2021-07-21 Thread Jason Ekstrand
Since we don't allow changing the set of regions after creation, we can
make ext_set_placements() build up the region set directly in the
create_ext and assign it to the object later.  This is similar to what
we did for contexts with the proto-context only simpler because there's
no funny object shuffling.  This will be used in the next patch to allow
us to de-duplicate a bunch of code.  Also, since we know the maximum
number of regions up-front, we can use a fixed-size temporary array for
the regions.  This simplifies memory management a bit for this new
delayed approach.

v2 (Matthew Auld):
 - Get rid of MAX_N_PLACEMENTS
 - Drop kfree(placements) from set_placements()
v3 (Matthew Auld):
 - Properly set ext_data->n_placements

Signed-off-by: Jason Ekstrand 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 82 --
 1 file changed, 46 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 51f92e4b1a69d..aa687b10dcd45 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -27,10 +27,13 @@ static u32 object_max_page_size(struct drm_i915_gem_object 
*obj)
return max_page_size;
 }
 
-static void object_set_placements(struct drm_i915_gem_object *obj,
- struct intel_memory_region **placements,
- unsigned int n_placements)
+static int object_set_placements(struct drm_i915_gem_object *obj,
+struct intel_memory_region **placements,
+unsigned int n_placements)
 {
+   struct intel_memory_region **arr;
+   unsigned int i;
+
GEM_BUG_ON(!n_placements);
 
/*
@@ -44,9 +47,20 @@ static void object_set_placements(struct drm_i915_gem_object 
*obj,
obj->mm.placements = >mm.regions[mr->id];
obj->mm.n_placements = 1;
} else {
-   obj->mm.placements = placements;
+   arr = kmalloc_array(n_placements,
+   sizeof(struct intel_memory_region *),
+   GFP_KERNEL);
+   if (!arr)
+   return -ENOMEM;
+
+   for (i = 0; i < n_placements; i++)
+   arr[i] = placements[i];
+
+   obj->mm.placements = arr;
obj->mm.n_placements = n_placements;
}
+
+   return 0;
 }
 
 static int i915_gem_publish(struct drm_i915_gem_object *obj,
@@ -148,7 +162,9 @@ i915_gem_dumb_create(struct drm_file *file,
return -ENOMEM;
 
mr = intel_memory_region_by_type(to_i915(dev), mem_type);
-   object_set_placements(obj, , 1);
+   ret = object_set_placements(obj, , 1);
+   if (ret)
+   goto object_free;
 
ret = i915_gem_setup(obj, args->size);
if (ret)
@@ -184,7 +200,9 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
return -ENOMEM;
 
mr = intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM);
-   object_set_placements(obj, , 1);
+   ret = object_set_placements(obj, , 1);
+   if (ret)
+   goto object_free;
 
ret = i915_gem_setup(obj, args->size);
if (ret)
@@ -199,7 +217,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 
 struct create_ext {
struct drm_i915_private *i915;
-   struct drm_i915_gem_object *vanilla_object;
+   struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
+   unsigned int n_placements;
 };
 
 static void repr_placements(char *buf, size_t size,
@@ -230,8 +249,7 @@ static int set_placements(struct 
drm_i915_gem_create_ext_memory_regions *args,
struct drm_i915_private *i915 = ext_data->i915;
struct drm_i915_gem_memory_class_instance __user *uregions =
u64_to_user_ptr(args->regions);
-   struct drm_i915_gem_object *obj = ext_data->vanilla_object;
-   struct intel_memory_region **placements;
+   struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
u32 mask;
int i, ret = 0;
 
@@ -245,6 +263,8 @@ static int set_placements(struct 
drm_i915_gem_create_ext_memory_regions *args,
ret = -EINVAL;
}
 
+   BUILD_BUG_ON(ARRAY_SIZE(i915->mm.regions) != ARRAY_SIZE(placements));
+   BUILD_BUG_ON(ARRAY_SIZE(ext_data->placements) != 
ARRAY_SIZE(placements));
if (args->num_regions > ARRAY_SIZE(i915->mm.regions)) {
drm_dbg(>drm, "num_regions is too large\n");
ret = -EINVAL;
@@ -253,21 +273,13 @@ static int set_placements(struct 
drm_i915_gem_create_ext_memory_regions *args,
if (ret)
return ret;
 
-   placements = kmalloc_array(args->num_regions,
-  sizeof(struct intel_memory_region *),
-  GFP_KERNEL);
- 

[PATCH 1/7] drm/i915/gem: Check object_can_migrate from object_migrate

2021-07-21 Thread Jason Ekstrand
We don't roll them together entirely because there are still a couple
cases where we want a separate can_migrate check.  For instance, the
display code checks that you can migrate a buffer to LMEM before it
accepts it in fb_create.  The dma-buf import code also uses it to do an
early check and return a different error code if someone tries to attach
a LMEM-only dma-buf to another driver.

However, no one actually wants to call object_migrate when can_migrate
has failed.  The stated intention is for self-tests but none of those
actually take advantage of this unsafe migration.

Signed-off-by: Jason Ekstrand 
Cc: Daniel Vetter 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c| 13 ++---
 .../gpu/drm/i915/gem/selftests/i915_gem_migrate.c | 15 ---
 2 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 9da7b288b7ede..f2244ae09a613 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -584,12 +584,6 @@ bool i915_gem_object_can_migrate(struct 
drm_i915_gem_object *obj,
  * completed yet, and to accomplish that, i915_gem_object_wait_migration()
  * must be called.
  *
- * This function is a bit more permissive than i915_gem_object_can_migrate()
- * to allow for migrating objects where the caller knows exactly what is
- * happening. For example within selftests. More specifically this
- * function allows migrating I915_BO_ALLOC_USER objects to regions
- * that are not in the list of allowable regions.
- *
  * Note: the @ww parameter is not used yet, but included to make sure
  * callers put some effort into obtaining a valid ww ctx if one is
  * available.
@@ -616,11 +610,8 @@ int i915_gem_object_migrate(struct drm_i915_gem_object 
*obj,
if (obj->mm.region == mr)
return 0;
 
-   if (!i915_gem_object_evictable(obj))
-   return -EBUSY;
-
-   if (!obj->ops->migrate)
-   return -EOPNOTSUPP;
+   if (!i915_gem_object_can_migrate(obj, id))
+   return -EINVAL;
 
return obj->ops->migrate(obj, mr);
 }
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
index 0b7144d2991ca..28a700f08b49a 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
@@ -61,11 +61,6 @@ static int igt_create_migrate(struct intel_gt *gt, enum 
intel_region_id src,
if (err)
continue;
 
-   if (!i915_gem_object_can_migrate(obj, dst)) {
-   err = -EINVAL;
-   continue;
-   }
-
err = i915_gem_object_migrate(obj, , dst);
if (err)
continue;
@@ -114,11 +109,6 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx 
*ww,
return err;
 
if (i915_gem_object_is_lmem(obj)) {
-   if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM)) {
-   pr_err("object can't migrate to smem.\n");
-   return -EINVAL;
-   }
-
err = i915_gem_object_migrate(obj, ww, INTEL_REGION_SMEM);
if (err) {
pr_err("Object failed migration to smem\n");
@@ -137,11 +127,6 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx 
*ww,
}
 
} else {
-   if (!i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM)) {
-   pr_err("object can't migrate to lmem.\n");
-   return -EINVAL;
-   }
-
err = i915_gem_object_migrate(obj, ww, INTEL_REGION_LMEM);
if (err) {
pr_err("Object failed migration to lmem\n");
-- 
2.31.1



[PATCH 0/7] drm/i915: Migrate memory to SMEM when imported cross-device (v8)

2021-07-21 Thread Jason Ekstrand
This patch series fixes an issue with discrete graphics on Intel where we
allowed dma-buf import while leaving the object in local memory.  This
breaks down pretty badly if the import happened on a different physical
device.

v7:
 - Drop "drm/i915/gem/ttm: Place new BOs in the requested region"
 - Add a new "drm/i915/gem: Call i915_gem_flush_free_objects() in 
i915_gem_dumb_create()"
 - Misc. review feedback from Matthew Auld
v8:
 - Misc. review feedback from Matthew Auld

Jason Ekstrand (5):
  drm/i915/gem: Check object_can_migrate from object_migrate
  drm/i915/gem: Refactor placement setup for i915_gem_object_create*
(v2)
  drm/i915/gem: Call i915_gem_flush_free_objects() in
i915_gem_dumb_create()
  drm/i915/gem: Unify user object creation (v3)
  drm/i915/gem/ttm: Respect the objection region in placement_from_obj

Thomas Hellström (2):
  drm/i915/gem: Correct the locking and pin pattern for dma-buf (v8)
  drm/i915/gem: Migrate to system at dma-buf attach time (v7)

 drivers/gpu/drm/i915/gem/i915_gem_create.c| 177 
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  58 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   4 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   |   3 +-
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 190 +-
 .../drm/i915/gem/selftests/i915_gem_migrate.c |  15 --
 7 files changed, 330 insertions(+), 130 deletions(-)

-- 
2.31.1



Re: [PATCH 5/7] drm/i915/gem/ttm: Respect the objection region in placement_from_obj

2021-07-21 Thread Jason Ekstrand
On Mon, Jul 19, 2021 at 8:35 AM Matthew Auld
 wrote:
>
> On Fri, 16 Jul 2021 at 20:49, Jason Ekstrand  wrote:
> >
> > On Fri, Jul 16, 2021 at 1:45 PM Matthew Auld
> >  wrote:
> > >
> > > On Fri, 16 Jul 2021 at 18:39, Jason Ekstrand  wrote:
> > > >
> > > > On Fri, Jul 16, 2021 at 11:00 AM Matthew Auld
> > > >  wrote:
> > > > >
> > > > > On Fri, 16 Jul 2021 at 16:52, Matthew Auld
> > > > >  wrote:
> > > > > >
> > > > > > On Fri, 16 Jul 2021 at 15:10, Jason Ekstrand  
> > > > > > wrote:
> > > > > > >
> > > > > > > On Fri, Jul 16, 2021 at 8:54 AM Matthew Auld
> > > > > > >  wrote:
> > > > > > > >
> > > > > > > > On Thu, 15 Jul 2021 at 23:39, Jason Ekstrand 
> > > > > > > >  wrote:
> > > > > > > > >
> > > > > > > > > Whenever we had a user object (n_placements > 0), we were 
> > > > > > > > > ignoring
> > > > > > > > > obj->mm.region and always putting obj->placements[0] as the 
> > > > > > > > > requested
> > > > > > > > > region.  For LMEM+SMEM objects, this was causing them to get 
> > > > > > > > > shoved into
> > > > > > > > > LMEM on every i915_ttm_get_pages() even when SMEM was 
> > > > > > > > > requested by, say,
> > > > > > > > > i915_gem_object_migrate().
> > > > > > > >
> > > > > > > > i915_ttm_migrate calls i915_ttm_place_from_region() directly 
> > > > > > > > with the
> > > > > > > > requested region, so there shouldn't be an issue with migration 
> > > > > > > > right?
> > > > > > > > Do you have some more details?
> > > > > > >
> > > > > > > With i915_ttm_migrate directly, no.  But, in the last patch in the
> > > > > > > series, we're trying to migrate LMEM+SMEM buffers into SMEM on
> > > > > > > attach() and pin it there.  This blows up in a very unexpected 
> > > > > > > (IMO)
> > > > > > > way.  The flow goes something like this:
> > > > > > >
> > > > > > >  - Client attempts a dma-buf import from another device
> > > > > > >  - In attach() we call i915_gem_object_migrate() which calls
> > > > > > > i915_ttm_migrate() which migrates as requested.
> > > > > > >  - Once the migration is complete, we call 
> > > > > > > i915_gem_object_pin_pages()
> > > > > > > which calls i915_ttm_get_pages() which depends on
> > > > > > > i915_ttm_placement_from_obj() and so migrates it right back to 
> > > > > > > LMEM.
> > > > > >
> > > > > > The mm.pages must be NULL here, otherwise it would just increment 
> > > > > > the
> > > > > > pages_pin_count?
> > > >
> > > > Given that the test is using the four_underscores version, it
> > > > doesn't have that check.  However, this executes after we've done the
> > > > dma-buf import which pinned pages.  So we should definitely have
> > > > pages.
> > >
> > > We shouldn't call four_underscores() if we might already have
> > > pages though. Under non-TTM that would leak the pages, and in TTM we
> > > might hit the WARN_ON(mm->pages) in __i915_ttm_get_pages(), if for
> > > example nothing was moved. I take it we can't just call pin_pages()?
> > > Four scary underscores usually means "don't call this in normal code".
> >
> > I've switched the four_underscores call to a __two_underscores in
> > the selftests and it had no effect, good or bad.  But, still, probably
> > better to call that one.
> >
> > > >
> > > > > > >
> > > > > > > Maybe the problem here is actually that our TTM code isn't 
> > > > > > > respecting
> > > > > > > obj->mm.pages_pin_count?
> > > > > >
> > > > > > I think if the resource is moved, we always nuke the mm.pages after
> > > > > > being notified of the move. Also TTM is also not allowed to move
> > > > > > pinned buffers.
> > > > > >
> > > > > > I guess if we are evicted/swapped, so assuming we are not holding 
> > > > > > the
> > > > > > object lock, and it's not pinned, the future call to get_pages() 
> > > > > > will
> > > > > > see mm.pages = NULL, even though the ttm_resource is still there, 
> > > > > > and
> > > > > > because we prioritise the placements[0], instead of mm.region we end
> > > > > > up moving it for no good reason. But in your case you are holding 
> > > > > > the
> > > > > > lock, or it's pinned? Also is this just with the selftest, or
> > > > > > something real?
> > > > >
> > > > > Or at least in the selftest I see i915_gem_object_get_pages()
> > > > > which doesn't even consider the mm.pages AFAIK.
> > > >
> > > > The bogus migration is happening as part of the
> > > > __i915_gem_object_get_pages() (2 __underscores) call in
> > > > i915_gem_dmabuf_attach (see last patch).  That code is attempting to
> > > > migrate the BO to SMEM and then pin it there using the obvious calls
> > > > to do so.  However, in the pin_pages call, it gets implicitly migrated
> > > > back to LMEM thanks to i915_ttm_get_pages().  Why is _get_pages()
> > > > migrating things at all?
> > >
> > > Not sure yet, but __two_underscores() checks if
> > > i915_gem_object_has_pages() before actually calling into
> > > i915_ttm_get_pages(), so the mm.pages would have to be NULL here for
> > > some reason, so best guess is something to 

Re: [PATCH] backlight: pwm_bl: Avoid backlight flicker if backlight control GPIO is input

2021-07-21 Thread Marek Vasut

On 7/21/21 9:01 PM, Marek Vasut wrote:

[...]

@@ -486,18 +500,6 @@ static int pwm_backlight_probe(struct 
platform_device *pdev)

   goto err_alloc;
   }
-    /*
- * If the GPIO is not known to be already configured as output, 
that
- * is, if gpiod_get_direction returns either 1 or -EINVAL, 
change the

- * direction to output and set the GPIO as active.
- * Do not force the GPIO to active when it was already output 
as it
- * could cause backlight flickering or we would enable the 
backlight too
- * early. Leave the decision of the initial backlight state for 
later.

- */
-    if (pb->enable_gpio &&
-    gpiod_get_direction(pb->enable_gpio) != 0)
-    gpiod_direction_output(pb->enable_gpio, 1);


pwm_backlight_initial_power_state() is still called after 
pwm_apply_state()

in pwm_backlight_probe(), so that might still be too late, no ?


The initial pwm_apply_state() is essentially a nop or, perhaps, a sanity
check if you prefer to think if it that way.

It can change the PWM period in some (non-DT) cases but only if the PWM
is not already running... and the change of period should not start it
running.


All right, let me give this a try.


ACK, for this case I have here, this works too. Can you submit a proper 
patch, including my AB/TB and I think also the Fixes tag ?


Re: [PATCH 3/4] drm/i915/userptr: Probe existence of backing struct pages upon creation

2021-07-21 Thread Kenneth Graunke
Thanks!  Series is:

Acked-by: Kenneth Graunke 

https://gitlab.freedesktop.org/kwg/mesa/-/commits/iris-userptr-probe
is an untested Mesa branch that makes use of the new probe uAPI.

On Thursday, July 15, 2021 3:15:35 AM PDT Matthew Auld wrote:
> From: Chris Wilson 
> 
> Jason Ekstrand requested a more efficient method than userptr+set-domain
> to determine if the userptr object was backed by a complete set of pages
> upon creation. To be more efficient than simply populating the userptr
> using get_user_pages() (as done by the call to set-domain or execbuf),
> we can walk the tree of vm_area_struct and check for gaps or vma not
> backed by struct page (VM_PFNMAP). The question is how to handle
> VM_MIXEDMAP which may be either struct page or pfn backed...
> 
> With discrete are going to drop support for set_domain(), so offering a
> way to probe the pages, without having to resort to dummy batches has
> been requested.
> 
> v2:
> - add new query param for the PROPBE flag, so userspace can easily
>   check if the kernel supports it(Jason).
> - use mmap_read_{lock, unlock}.
> - add some kernel-doc.
> 
> Testcase: igt/gem_userptr_blits/probe
> Signed-off-by: Chris Wilson 
> Signed-off-by: Matthew Auld 
> Cc: Thomas Hellström 
> Cc: Maarten Lankhorst 
> Cc: Tvrtko Ursulin 
> Cc: Jordan Justen 
> Cc: Kenneth Graunke 
> Cc: Jason Ekstrand 
> Cc: Daniel Vetter 
> Cc: Ramalingam C 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 40 -
>  drivers/gpu/drm/i915/i915_getparam.c|  3 ++
>  include/uapi/drm/i915_drm.h | 18 ++
>  3 files changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> index 56edfeff8c02..fd6880328596 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> @@ -422,6 +422,33 @@ static const struct drm_i915_gem_object_ops 
> i915_gem_userptr_ops = {
>  
>  #endif
>  
> +static int
> +probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
> +{
> + const unsigned long end = addr + len;
> + struct vm_area_struct *vma;
> + int ret = -EFAULT;
> +
> + mmap_read_lock(mm);
> + for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
> + if (vma->vm_start > addr)
> + break;
> +
> + if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
> + break;
> +
> + if (vma->vm_end >= end) {
> + ret = 0;
> + break;
> + }
> +
> + addr = vma->vm_end;
> + }
> + mmap_read_unlock(mm);
> +
> + return ret;
> +}
> +
>  /*
>   * Creates a new mm object that wraps some normal memory from the process
>   * context - user memory.
> @@ -477,7 +504,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
>   }
>  
>   if (args->flags & ~(I915_USERPTR_READ_ONLY |
> - I915_USERPTR_UNSYNCHRONIZED))
> + I915_USERPTR_UNSYNCHRONIZED |
> + I915_USERPTR_PROBE))
>   return -EINVAL;
>  
>   if (i915_gem_object_size_2big(args->user_size))
> @@ -504,6 +532,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
>   return -ENODEV;
>   }
>  
> + if (args->flags & I915_USERPTR_PROBE) {
> + /*
> +  * Check that the range pointed to represents real struct
> +  * pages and not iomappings (at this moment in time!)
> +  */
> + ret = probe_range(current->mm, args->user_ptr, args->user_size);
> + if (ret)
> + return ret;
> + }
> +
>  #ifdef CONFIG_MMU_NOTIFIER
>   obj = i915_gem_object_alloc();
>   if (obj == NULL)
> diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
> b/drivers/gpu/drm/i915/i915_getparam.c
> index 24e18219eb50..d6d2e1a10d14 100644
> --- a/drivers/gpu/drm/i915/i915_getparam.c
> +++ b/drivers/gpu/drm/i915/i915_getparam.c
> @@ -163,6 +163,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void 
> *data,
>   case I915_PARAM_PERF_REVISION:
>   value = i915_perf_ioctl_version();
>   break;
> + case I915_PARAM_HAS_USERPTR_PROBE:
> + value = true;
> + break;
>   default:
>   DRM_DEBUG("Unknown parameter %d\n", param->param);
>   return -EINVAL;
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index e20eeeca7a1c..2e4112bf4d38 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -674,6 +674,9 @@ typedef struct drm_i915_irq_wait {
>   */
>  #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
>  
> +/* Query if the kernel supports the I915_USERPTR_PROBE flag. */
> +#define I915_PARAM_HAS_USERPTR_PROBE 56
> +
>  /* Must be kept compact -- no holes and well documented */
>  
>  typedef struct 

Re: [PATCH 3/4] drm/i915/userptr: Probe existence of backing struct pages upon creation

2021-07-21 Thread Kenneth Graunke
Thanks for this!  Series is:

Acked-by: Kenneth Graunke 

https://gitlab.freedesktop.org/kwg/mesa/-/commits/iris-userptr-probe
is an untested branch that uses the new probe API in Mesa.

On Thursday, July 15, 2021 3:15:35 AM PDT Matthew Auld wrote:
> From: Chris Wilson 
> 
> Jason Ekstrand requested a more efficient method than userptr+set-domain
> to determine if the userptr object was backed by a complete set of pages
> upon creation. To be more efficient than simply populating the userptr
> using get_user_pages() (as done by the call to set-domain or execbuf),
> we can walk the tree of vm_area_struct and check for gaps or vma not
> backed by struct page (VM_PFNMAP). The question is how to handle
> VM_MIXEDMAP which may be either struct page or pfn backed...
> 
> With discrete are going to drop support for set_domain(), so offering a
> way to probe the pages, without having to resort to dummy batches has
> been requested.
> 
> v2:
> - add new query param for the PROPBE flag, so userspace can easily
>   check if the kernel supports it(Jason).
> - use mmap_read_{lock, unlock}.
> - add some kernel-doc.
> 
> Testcase: igt/gem_userptr_blits/probe
> Signed-off-by: Chris Wilson 
> Signed-off-by: Matthew Auld 
> Cc: Thomas Hellström 
> Cc: Maarten Lankhorst 
> Cc: Tvrtko Ursulin 
> Cc: Jordan Justen 
> Cc: Kenneth Graunke 
> Cc: Jason Ekstrand 
> Cc: Daniel Vetter 
> Cc: Ramalingam C 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 40 -
>  drivers/gpu/drm/i915/i915_getparam.c|  3 ++
>  include/uapi/drm/i915_drm.h | 18 ++
>  3 files changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> index 56edfeff8c02..fd6880328596 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> @@ -422,6 +422,33 @@ static const struct drm_i915_gem_object_ops 
> i915_gem_userptr_ops = {
>  
>  #endif
>  
> +static int
> +probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
> +{
> + const unsigned long end = addr + len;
> + struct vm_area_struct *vma;
> + int ret = -EFAULT;
> +
> + mmap_read_lock(mm);
> + for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
> + if (vma->vm_start > addr)
> + break;
> +
> + if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
> + break;
> +
> + if (vma->vm_end >= end) {
> + ret = 0;
> + break;
> + }
> +
> + addr = vma->vm_end;
> + }
> + mmap_read_unlock(mm);
> +
> + return ret;
> +}
> +
>  /*
>   * Creates a new mm object that wraps some normal memory from the process
>   * context - user memory.
> @@ -477,7 +504,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
>   }
>  
>   if (args->flags & ~(I915_USERPTR_READ_ONLY |
> - I915_USERPTR_UNSYNCHRONIZED))
> + I915_USERPTR_UNSYNCHRONIZED |
> + I915_USERPTR_PROBE))
>   return -EINVAL;
>  
>   if (i915_gem_object_size_2big(args->user_size))
> @@ -504,6 +532,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
>   return -ENODEV;
>   }
>  
> + if (args->flags & I915_USERPTR_PROBE) {
> + /*
> +  * Check that the range pointed to represents real struct
> +  * pages and not iomappings (at this moment in time!)
> +  */
> + ret = probe_range(current->mm, args->user_ptr, args->user_size);
> + if (ret)
> + return ret;
> + }
> +
>  #ifdef CONFIG_MMU_NOTIFIER
>   obj = i915_gem_object_alloc();
>   if (obj == NULL)
> diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
> b/drivers/gpu/drm/i915/i915_getparam.c
> index 24e18219eb50..d6d2e1a10d14 100644
> --- a/drivers/gpu/drm/i915/i915_getparam.c
> +++ b/drivers/gpu/drm/i915/i915_getparam.c
> @@ -163,6 +163,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void 
> *data,
>   case I915_PARAM_PERF_REVISION:
>   value = i915_perf_ioctl_version();
>   break;
> + case I915_PARAM_HAS_USERPTR_PROBE:
> + value = true;
> + break;
>   default:
>   DRM_DEBUG("Unknown parameter %d\n", param->param);
>   return -EINVAL;
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index e20eeeca7a1c..2e4112bf4d38 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -674,6 +674,9 @@ typedef struct drm_i915_irq_wait {
>   */
>  #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
>  
> +/* Query if the kernel supports the I915_USERPTR_PROBE flag. */
> +#define I915_PARAM_HAS_USERPTR_PROBE 56
> +
>  /* Must be kept compact -- no holes and well documented */
>  
>  typedef struct 

Re: [Linaro-mm-sig] [PATCH] drm/msm: Add fence->wait() op

2021-07-21 Thread Daniel Vetter
On Wed, Jul 21, 2021 at 09:34:43AM -0700, Rob Clark wrote:
> On Wed, Jul 21, 2021 at 12:59 AM Daniel Vetter  wrote:
> >
> > On Wed, Jul 21, 2021 at 12:32 AM Rob Clark  wrote:
> > >
> > > On Tue, Jul 20, 2021 at 1:55 PM Daniel Vetter  wrote:
> > > >
> > > > On Tue, Jul 20, 2021 at 8:26 PM Rob Clark  wrote:
> > > > >
> > > > > On Tue, Jul 20, 2021 at 11:03 AM Christian König
> > > > >  wrote:
> > > > > >
> > > > > > Hi Rob,
> > > > > >
> > > > > > Am 20.07.21 um 17:07 schrieb Rob Clark:
> > > > > > > From: Rob Clark 
> > > > > > >
> > > > > > > Somehow we had neither ->wait() nor dma_fence_signal() calls, and 
> > > > > > > no
> > > > > > > one noticed.  Oops.
> > > > > >
> > > > > >
> > > > > > I'm not sure if that is a good idea.
> > > > > >
> > > > > > The dma_fence->wait() callback is pretty much deprecated and should 
> > > > > > not
> > > > > > be used any more.
> > > > > >
> > > > > > What exactly do you need that for?
> > > > >
> > > > > Well, the alternative is to track the set of fences which have
> > > > > signalling enabled, and then figure out which ones to signal, which
> > > > > seems like a lot more work, vs just re-purposing the wait
> > > > > implementation we already have for non-dma_fence cases ;-)
> > > > >
> > > > > Why is the ->wait() callback (pretty much) deprecated?
> > > >
> > > > Because if you need it that means for your driver dma_fence_add_cb is
> > > > broken, which means a _lot_ of things don't work. Like dma_buf poll
> > > > (compositors have patches to start using that), and I think
> > > > drm/scheduler also becomes rather unhappy.
> > >
> > > I'm starting to page back in how this works.. fence cb's aren't broken
> > > (which is also why dma_fence_wait() was not completely broken),
> > > because in retire_submits() we call
> > > dma_fence_is_signaled(submit->hw_fence).
> > >
> > > But the reason that the custom wait function cleans up a tiny bit of
> > > jank is that the wait_queue_head_t gets signaled earlier, before we
> > > start iterating the submits and doing all that retire_submit() stuff
> > > (unpin/unref bo's, etc).  I suppose I could just split things up to
> > > call dma_fence_signal() earlier, and *then* do the retire_submits()
> > > stuff.
> >
> > Yeah reducing the latency there sounds like a good idea.
> > -Daniel
> >
> 
> Hmm, no, turns out that isn't the problem.. or, well, it is probably a
> good idea to call drm_fence_signal() earlier.  But it seems like
> waking up from wait_event_* is faster than wake_up_state(wait->task,
> TASK_NORMAL).  I suppose the wake_up_state() approach still needs for
> the scheduler to get around to schedule the runnable task.
> 
> So for now, I'm going back to my own wait function (plus earlier
> drm_fence_signal())
> 
> Before removing dma_fence_opps::wait(), I guess we want to re-think
> dma_fence_default_wait().. but I think that would require a
> dma_fence_context base class (rather than just a raw integer).

Uh that's not great ... can't we fix this instead of papering over it in
drivers? Aside from maybe different wakeup flags it all is supposed to
work exactly the same underneath, and whether using a wait queue or not
really shouldn't matter.
-Daniel

> 
> BR,
> -R
> 
> > >
> > > BR,
> > > -R
> > >
> > > > It essentially exists only for old drivers where ->enable_signalling
> > > > is unreliable and we paper over that with a retry loop in ->wait and
> > > > pray no one notices that it's too butchered. The proper fix is to have
> > > > a driver thread to guarantee that ->enable_signalling works reliable,
> > > > so you don't need a ->wait.
> > > >
> > > > Can you type up a kerneldoc patch for dma_fence_ops->wait to hammer
> > > > this in please?
> > > > -Daniel
> > > >
> > > > >
> > > > > BR,
> > > > > -R
> > > > >
> > > > > > Regards,
> > > > > > Christian.
> > > > > >
> > > > > > >
> > > > > > > Note that this removes the !timeout case, which has not been used 
> > > > > > > in
> > > > > > > a long time.
> > > > > >
> > > > > >
> > > > > > >
> > > > > > > Signed-off-by: Rob Clark 
> > > > > > > ---
> > > > > > >   drivers/gpu/drm/msm/msm_fence.c | 59 
> > > > > > > +++--
> > > > > > >   1 file changed, 34 insertions(+), 25 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/gpu/drm/msm/msm_fence.c 
> > > > > > > b/drivers/gpu/drm/msm/msm_fence.c
> > > > > > > index cd59a5918038..8ee96b90ded6 100644
> > > > > > > --- a/drivers/gpu/drm/msm/msm_fence.c
> > > > > > > +++ b/drivers/gpu/drm/msm/msm_fence.c
> > > > > > > @@ -38,11 +38,10 @@ static inline bool fence_completed(struct 
> > > > > > > msm_fence_context *fctx, uint32_t fenc
> > > > > > >   return (int32_t)(fctx->completed_fence - fence) >= 0;
> > > > > > >   }
> > > > > > >
> > > > > > > -/* legacy path for WAIT_FENCE ioctl: */
> > > > > > > -int msm_wait_fence(struct msm_fence_context *fctx, uint32_t 
> > > > > > > fence,
> > > > > > > - ktime_t *timeout, bool interruptible)
> > > > > > > +static signed long 

Re: [PATCH] backlight: pwm_bl: Avoid backlight flicker if backlight control GPIO is input

2021-07-21 Thread Marek Vasut

On 7/21/21 6:43 PM, Daniel Thompson wrote:

On Wed, Jul 21, 2021 at 05:09:57PM +0200, Marek Vasut wrote:

On 7/21/21 12:49 PM, Daniel Thompson wrote:

However, on the basis of making things less fragile, I think the
underlying problem here is the assumption that it is safe to modify
enable_gpio before the driver has imposed state upon the PWM (this
assumption has always been made and, in addition to systems where the BL
has a phandle will also risks flicker problems on systems where
power_pwm_on_delay is not zero).


It is safe to modify the GPIO into defined state, but that defined state is
not always out/enabled, that defined state depends on the hardware.


It is only safe to do this once we know what the initial value should be
and I'm not sure that value can comes exclusively from reading the pin.


I agree, it is far from perfect, but so is the current code.


Agreed. Current handling of enable pin isn't right.



However, see below regarding the floating backlight enable pin.


This patch does not change the assumption that we can configure the
GPIO before we modify the PWM state. This means it won't fix the problem
for cases there the pin is HiZ by default but whose GPIOD_ASIS state is
neither input nor output.


That is correct, for pin that is floating, we lost. But then I would argue
that if your backlight-enable GPIO is floating, the hardware is buggy, I
would expect some pull resistor to keep the backlight off on power on on
that GPIO.


I didn't say that the pin was floating. I said that the pin was in a HiZ
state meaning it could still be subject to pull up/down.

However there are cases, such as when the regulator is off, where I
think it is entirely legitimate for the enable pin to be floating. The
current driver does the wrong thing here if the pin is set as input
since if the regulator is off the initial enable_gpio value should be 0.


Oh, right, that's a valid point.

So if the pin is input, we can basically toss a coin.


I don't think it is quite as bad as that: if the PWM and regulator
are enabled then it is not okay for this pin to be floating.


So then we would have to check the regulator and pwm state, however 
Linux driver for those can reinit both the regulator and pwm block, so 
we are growing more and more heuristics.



[...]
I think a reasonably elegant approach can be reached by making
pwm_backlight_initial_power_state() responsible for ensuring enable_gpio
matches the observed hardware state (taking into account both the pin
state and the regulator). I think this will fix both your flicker
concerns whilst permitting the legitimate cases for a floating pin.

Something like:


I think we are getting closer, but there is extra problem to this.


diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index e48fded3e414..8d8959a70e44 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -409,6 +409,33 @@ static bool pwm_backlight_is_linear(struct 
platform_pwm_backlight_data *data)
   static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
   {
struct device_node *node = pb->dev->of_node;
+   bool active = true;
+
+   /*
+* If the enable GPIO is present, observable (either as input
+* or output) and off then the backlight is not currently active.
+* */
+   if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
+   active = false;


This will fail on iMX GPIO controller, where if the GPIO is output, you can
read its state, but by default that state is what you wrote into the GPIO
output value register, not what is the actual value on the pin (i.e.
consider you have a strong pull resistor that overpowers the driver).

To have a GPIO which is output and sample the actual pin value, you have to
tweak the pinmux and enable the SION bit, then you get the actual value. But
that is specific to the iMX GPIO controller/pinmux.


You're describing a situation where we own a GPIO output pin and the
value we believe we are driving into the pin is not being achieved due
to some additional factor.


E.g. disabled PWM or regulator.


Do we need to care about that? It sounds like
the backlight driver won't work properly in this case since whatever
value we set the enable_gpio then it will stay at the same value.


Possibly.


[...]
@@ -486,18 +500,6 @@ static int pwm_backlight_probe(struct platform_device 
*pdev)
goto err_alloc;
}
-   /*
-* If the GPIO is not known to be already configured as output, that
-* is, if gpiod_get_direction returns either 1 or -EINVAL, change the
-* direction to output and set the GPIO as active.
-* Do not force the GPIO to active when it was already output as it
-* could cause backlight flickering or we would enable the backlight too
-* early. Leave the decision of the initial backlight state for later.
-*/
-   if 

Re: [PATCH v5 09/15] drm/i915/pxp: Implement PXP irq handler

2021-07-21 Thread Rodrigo Vivi
On Thu, Jul 15, 2021 at 09:10:28PM -0700, Daniele Ceraolo Spurio wrote:
> From: "Huang, Sean Z" 
> 
> The HW will generate a teardown interrupt when session termination is
> required, which requires i915 to submit a terminating batch. Once the HW
> is done with the termination it will generate another interrupt, at
> which point it is safe to re-create the session.
> 
> Since the termination and re-creation flow is something we want to
> trigger from the driver as well, use a common work function that can be
> called both from the irq handler and from the driver set-up flows, which
> has the addded benefit of allowing us to skip any extra locks because
> the work itself serializes the operations.
> 
> v2: use struct completion instead of bool (Chris)
> v3: drop locks, clean up functions and improve comments (Chris),
> move to common work function.
> v4: improve comments, simplify wait logic (Rodrigo)
> v5: unconditionally set interrupts,

I didn't find this... this looks the same as v4

> rename state_attacked var (Rodrigo)

thanks



> 
> Signed-off-by: Huang, Sean Z 
> Signed-off-by: Daniele Ceraolo Spurio 
> Cc: Chris Wilson 
> Cc: Rodrigo Vivi 
> Reviewed-by: Rodrigo Vivi  #v4

anyway, this patch looks good to me...

Reviewed-by: Rodrigo Vivi 



> ---
>  drivers/gpu/drm/i915/Makefile|  1 +
>  drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  7 ++
>  drivers/gpu/drm/i915/i915_reg.h  |  1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp.c | 66 +++--
>  drivers/gpu/drm/i915/pxp/intel_pxp.h |  8 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 99 
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 32 +++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++-
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  5 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c |  8 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h   | 18 
>  11 files changed, 283 insertions(+), 16 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 44d3a2bcb64c..1714089a10f0 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -279,6 +279,7 @@ i915-y += i915_perf.o
>  i915-$(CONFIG_DRM_I915_PXP) += \
>   pxp/intel_pxp.o \
>   pxp/intel_pxp_cmd.o \
> + pxp/intel_pxp_irq.o \
>   pxp/intel_pxp_session.o \
>   pxp/intel_pxp_tee.o
>  
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c 
> b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> index c13462274fe8..96f0e9172a09 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> @@ -13,6 +13,7 @@
>  #include "intel_lrc_reg.h"
>  #include "intel_uncore.h"
>  #include "intel_rps.h"
> +#include "pxp/intel_pxp_irq.h"
>  
>  static void guc_irq_handler(struct intel_guc *guc, u16 iir)
>  {
> @@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 
> instance,
>   if (instance == OTHER_GTPM_INSTANCE)
>   return gen11_rps_irq_handler(>rps, iir);
>  
> + if (instance == OTHER_KCR_INSTANCE)
> + return intel_pxp_irq_handler(>pxp, iir);
> +
>   WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
> instance, iir);
>  }
> @@ -190,6 +194,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
>   intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
>   intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
>   intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
> +
> + intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0);
> + intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~0);
>  }
>  
>  void gen11_gt_irq_postinstall(struct intel_gt *gt)
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 943fe485c662..2c583f2d410d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8051,6 +8051,7 @@ enum {
>  /* irq instances for OTHER_CLASS */
>  #define OTHER_GUC_INSTANCE   0
>  #define OTHER_GTPM_INSTANCE  1
> +#define OTHER_KCR_INSTANCE   4
>  
>  #define GEN11_INTR_IDENTITY_REG(x)   _MMIO(0x190060 + ((x) * 4))
>  
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
> b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index 26176d43a02d..b0c7edc10cc3 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -2,7 +2,9 @@
>  /*
>   * Copyright(c) 2020 Intel Corporation.
>   */
> +#include 
>  #include "intel_pxp.h"
> +#include "intel_pxp_irq.h"
>  #include "intel_pxp_session.h"
>  #include "intel_pxp_tee.h"
>  #include "gt/intel_context.h"
> @@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
>  
>   mutex_init(>tee_mutex);
>  
> + /*
> +  * we'll use the completion to check if there is a termination pending,

Re: [Intel-gfx] [PATCH 6/6] drm/i915: Make the kmem slab for i915_buddy_block a global

2021-07-21 Thread Daniel Vetter
On Wed, Jul 21, 2021 at 05:25:41PM +0100, Matthew Auld wrote:
> On 21/07/2021 16:23, Jason Ekstrand wrote:
> > There's no reason that I can tell why this should be per-i915_buddy_mm
> > and doing so causes KMEM_CACHE to throw dmesg warnings because it tries
> > to create a debugfs entry with the name i915_buddy_block multiple times.
> > We could handle this by carefully giving each slab its own name but that
> > brings its own pain because then we have to store that string somewhere
> > and manage the lifetimes of the different slabs.  The most likely
> > outcome would be a global atomic which we increment to get a new name or
> > something like that.
> > 
> > The much easier solution is to use the i915_globals system like we do
> > for every other slab in i915.  This ensures that we have exactly one of
> > them for each i915 driver load and it gets neatly created on module load
> > and destroyed on module unload.  Using the globals system also means
> > that its now tied into the shrink handler so we can properly respond to
> > low-memory situations.
> > 
> > Signed-off-by: Jason Ekstrand 
> > Fixes: 88be9a0a06b7 ("drm/i915/ttm: add ttm_buddy_man")
> > Cc: Matthew Auld 
> > Cc: Christian König 
> 
> It was intentionally ripped it out with the idea that we would be moving the
> buddy stuff into ttm, and so part of that was trying to get rid of the some
> of the i915 specifics, like this globals thing.
> 
> Reviewed-by: Matthew Auld 

I just sent out a patch to put i915_globals on a diet, so maybe we can
hold this patch here a bit when there's other reasons for why this is
special?

Or at least no make this use the i915_globals stuff and instead just link
up the init/exit function calls directly into Jason's new table, so that
we don't have a merge conflict here?
-Daniel

> 
> > ---
> >   drivers/gpu/drm/i915/i915_buddy.c   | 44 ++---
> >   drivers/gpu/drm/i915/i915_buddy.h   |  3 +-
> >   drivers/gpu/drm/i915/i915_globals.c |  2 ++
> >   3 files changed, 38 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_buddy.c 
> > b/drivers/gpu/drm/i915/i915_buddy.c
> > index 29dd7d0310c1f..911feedad4513 100644
> > --- a/drivers/gpu/drm/i915/i915_buddy.c
> > +++ b/drivers/gpu/drm/i915/i915_buddy.c
> > @@ -8,8 +8,14 @@
> >   #include "i915_buddy.h"
> >   #include "i915_gem.h"
> > +#include "i915_globals.h"
> >   #include "i915_utils.h"
> > +static struct i915_global_buddy {
> > +   struct i915_global base;
> > +   struct kmem_cache *slab_blocks;
> > +} global;
> > +
> >   static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_mm *mm,
> >  struct i915_buddy_block 
> > *parent,
> >  unsigned int order,
> > @@ -19,7 +25,7 @@ static struct i915_buddy_block *i915_block_alloc(struct 
> > i915_buddy_mm *mm,
> > GEM_BUG_ON(order > I915_BUDDY_MAX_ORDER);
> > -   block = kmem_cache_zalloc(mm->slab_blocks, GFP_KERNEL);
> > +   block = kmem_cache_zalloc(global.slab_blocks, GFP_KERNEL);
> > if (!block)
> > return NULL;
> > @@ -34,7 +40,7 @@ static struct i915_buddy_block *i915_block_alloc(struct 
> > i915_buddy_mm *mm,
> >   static void i915_block_free(struct i915_buddy_mm *mm,
> > struct i915_buddy_block *block)
> >   {
> > -   kmem_cache_free(mm->slab_blocks, block);
> > +   kmem_cache_free(global.slab_blocks, block);
> >   }
> >   static void mark_allocated(struct i915_buddy_block *block)
> > @@ -85,15 +91,11 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, 
> > u64 chunk_size)
> > GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER);
> > -   mm->slab_blocks = KMEM_CACHE(i915_buddy_block, SLAB_HWCACHE_ALIGN);
> > -   if (!mm->slab_blocks)
> > -   return -ENOMEM;
> > -
> > mm->free_list = kmalloc_array(mm->max_order + 1,
> >   sizeof(struct list_head),
> >   GFP_KERNEL);
> > if (!mm->free_list)
> > -   goto out_destroy_slab;
> > +   return -ENOMEM;
> > for (i = 0; i <= mm->max_order; ++i)
> > INIT_LIST_HEAD(>free_list[i]);
> > @@ -145,8 +147,6 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, 
> > u64 chunk_size)
> > kfree(mm->roots);
> >   out_free_list:
> > kfree(mm->free_list);
> > -out_destroy_slab:
> > -   kmem_cache_destroy(mm->slab_blocks);
> > return -ENOMEM;
> >   }
> > @@ -161,7 +161,6 @@ void i915_buddy_fini(struct i915_buddy_mm *mm)
> > kfree(mm->roots);
> > kfree(mm->free_list);
> > -   kmem_cache_destroy(mm->slab_blocks);
> >   }
> >   static int split_block(struct i915_buddy_mm *mm,
> > @@ -410,3 +409,28 @@ int i915_buddy_alloc_range(struct i915_buddy_mm *mm,
> >   #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> >   #include "selftests/i915_buddy.c"
> >   #endif
> > +
> > +static void i915_global_buddy_shrink(void)
> > +{
> > +   kmem_cache_shrink(global.slab_blocks);
> > +}
> 

Re: [PATCH v5 03/15] drm/i915/pxp: define PXP device flag and kconfig

2021-07-21 Thread Rodrigo Vivi
On Thu, Jul 15, 2021 at 09:10:22PM -0700, Daniele Ceraolo Spurio wrote:
> Ahead of the PXP implementation, define the relevant define flag and
> kconfig option.
> 
> v2: flip kconfig default to N. Some machines have IFWIs that do not
> support PXP, so we need it to be an opt-in until we add support to query
> the caps from the mei device.

ack

> 
> Signed-off-by: Daniele Ceraolo Spurio 
> Reviewed-by: Rodrigo Vivi  #v1

rvb still valid

> ---
>  drivers/gpu/drm/i915/Kconfig | 11 +++
>  drivers/gpu/drm/i915/i915_drv.h  |  4 
>  drivers/gpu/drm/i915/intel_device_info.h |  1 +
>  3 files changed, 16 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index f960f5d7664e..5987c3d5d9fb 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -131,6 +131,17 @@ config DRM_I915_GVT_KVMGT
> Choose this option if you want to enable KVMGT support for
> Intel GVT-g.
>  
> +config DRM_I915_PXP
> + bool "Enable Intel PXP support for Intel Gen12+ platform"
> + depends on DRM_I915
> + depends on INTEL_MEI && INTEL_MEI_PXP
> + default n
> + help
> +   PXP (Protected Xe Path) is an i915 component, available on GEN12+
> +   GPUs, that helps to establish the hardware protected session and
> +   manage the status of the alive software session, as well as its life
> +   cycle.
> +
>  menu "drm/i915 Debugging"
>  depends on DRM_I915
>  depends on EXPERT
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c4747f4407ef..772f9f0b6ddb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1752,6 +1752,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>  
>  #define HAS_VRR(i915)(GRAPHICS_VER(i915) >= 12)
>  
> +#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
> +INTEL_INFO(dev_priv)->has_pxp) && \
> +VDBOX_MASK(_priv->gt)
> +
>  /* Only valid when HAS_DISPLAY() is true */
>  #define INTEL_DISPLAY_ENABLED(dev_priv) \
>   (drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), 
> !(dev_priv)->params.disable_display)
> diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
> b/drivers/gpu/drm/i915/intel_device_info.h
> index bd83004c78b6..8e9597008b8a 100644
> --- a/drivers/gpu/drm/i915/intel_device_info.h
> +++ b/drivers/gpu/drm/i915/intel_device_info.h
> @@ -129,6 +129,7 @@ enum intel_ppgtt_type {
>   func(has_logical_ring_elsq); \
>   func(has_master_unit_irq); \
>   func(has_pooled_eu); \
> + func(has_pxp); \
>   func(has_rc6); \
>   func(has_rc6p); \
>   func(has_rps); \
> -- 
> 2.32.0
> 


Re: [PATCH v5 07/15] drm/i915/pxp: Create the arbitrary session after boot

2021-07-21 Thread Rodrigo Vivi
On Thu, Jul 15, 2021 at 09:10:26PM -0700, Daniele Ceraolo Spurio wrote:
> From: "Huang, Sean Z" 
> 
> Create the arbitrary session, with the fixed session id 0xf, after
> system boot, for the case that application allocates the protected
> buffer without establishing any protection session. Because the
> hardware requires at least one alive session for protected buffer
> creation. This arbitrary session will need to be re-created after
> teardown or power event because hardware encryption key won't be
> valid after such cases.
> 
> The session ID is exposed as part of the uapi so it can be used as part
> of userspace commands.
> 
> v2: use gt->uncore->rpm (Chris)
> v3: s/arb_is_in_play/arb_is_valid (Chris), move set-up to the new
> init_hw function
> v4: move interface defs to separate header, set arb_is valid to false
> on fini (Rodrigo)
> v5: handle async component binding
> 
> Signed-off-by: Huang, Sean Z 
> Signed-off-by: Daniele Ceraolo Spurio 
> Cc: Chris Wilson 
> Cc: Rodrigo Vivi 
> Reviewed-by: Rodrigo Vivi  #v4
> ---
>  drivers/gpu/drm/i915/Makefile |  1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp.c  |  7 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h  |  5 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 74 
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.h  | 15 
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 87 +++
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.h  |  3 +
>  .../drm/i915/pxp/intel_pxp_tee_interface.h| 37 
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h| 12 +++
>  include/uapi/drm/i915_drm.h   |  3 +
>  10 files changed, 244 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.h
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 05eb6b7753cc..946b56cff9cf 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -278,6 +278,7 @@ i915-y += i915_perf.o
>  # Protected execution platform (PXP) support
>  i915-$(CONFIG_DRM_I915_PXP) += \
>   pxp/intel_pxp.o \
> + pxp/intel_pxp_session.o \
>   pxp/intel_pxp_tee.o
>  
>  # Post-mortem debug and GPU hang state capture
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
> b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index 66a98feb33ab..e1370f323126 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -3,6 +3,7 @@
>   * Copyright(c) 2020 Intel Corporation.
>   */
>  #include "intel_pxp.h"
> +#include "intel_pxp_session.h"
>  #include "intel_pxp_tee.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
> @@ -65,6 +66,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>   if (!HAS_PXP(gt->i915))
>   return;
>  
> + mutex_init(>tee_mutex);
> +
>   ret = create_vcs_context(pxp);
>   if (ret)
>   return;
> @@ -86,6 +89,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>   if (!intel_pxp_is_enabled(pxp))
>   return;
>  
> + pxp->arb_is_valid = false;
> +
>   intel_pxp_tee_component_fini(pxp);
>  
>   destroy_vcs_context(pxp);
> @@ -94,6 +99,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>  void intel_pxp_init_hw(struct intel_pxp *pxp)
>  {
>   kcr_pxp_enable(pxp_to_gt(pxp));
> +
> + intel_pxp_create_arb_session(pxp);
>  }
>  
>  void intel_pxp_fini_hw(struct intel_pxp *pxp)
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 5427c3b28aa9..8eeb65af78b1 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -19,6 +19,11 @@ static inline bool intel_pxp_is_enabled(const struct 
> intel_pxp *pxp)
>   return pxp->ce;
>  }
>  
> +static inline bool intel_pxp_is_active(const struct intel_pxp *pxp)
> +{
> + return pxp->arb_is_valid;
> +}
> +
>  #ifdef CONFIG_DRM_I915_PXP
>  void intel_pxp_init(struct intel_pxp *pxp);
>  void intel_pxp_fini(struct intel_pxp *pxp);
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
> b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> new file mode 100644
> index ..3331868f354c
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2020, Intel Corporation. All rights reserved.
> + */
> +
> +#include "drm/i915_drm.h"
> +#include "i915_drv.h"
> +
> +#include "intel_pxp.h"
> +#include "intel_pxp_session.h"
> +#include "intel_pxp_tee.h"
> +#include "intel_pxp_types.h"
> +
> +#define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define 
> */
> +
> +#define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */
> +
> +static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
> +{
> + struct intel_gt *gt = 

Re: [PATCH v5 05/15] drm/i915/pxp: Implement funcs to create the TEE channel

2021-07-21 Thread Rodrigo Vivi
On Thu, Jul 15, 2021 at 09:10:24PM -0700, Daniele Ceraolo Spurio wrote:
> From: "Huang, Sean Z" 
> 
> Implement the funcs to create the TEE channel, so kernel can
> send the TEE commands directly to TEE for creating the arbitrary
> (default) session.
> 
> v2: fix locking, don't pollute dev_priv (Chris)
> 
> v3: wait for mei PXP component to be bound.
> 
> v4: drop the wait, as the component might be bound after i915 load
> completes. We'll instead check when sending a tee message.

ack

> 
> Signed-off-by: Huang, Sean Z 
> Signed-off-by: Daniele Ceraolo Spurio 
> Cc: Chris Wilson 
> Reviewed-by: Rodrigo Vivi  #v2

rvb still valid

> ---
>  drivers/gpu/drm/i915/Makefile  |  3 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp.c   | 13 
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c   | 77 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.h   | 14 
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  3 +
>  5 files changed, 109 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index fe054918837d..05eb6b7753cc 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -277,7 +277,8 @@ i915-y += i915_perf.o
>  
>  # Protected execution platform (PXP) support
>  i915-$(CONFIG_DRM_I915_PXP) += \
> - pxp/intel_pxp.o
> + pxp/intel_pxp.o \
> + pxp/intel_pxp_tee.o
>  
>  # Post-mortem debug and GPU hang state capture
>  i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
> b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index 7b2053902146..400deaea2d8a 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -3,6 +3,7 @@
>   * Copyright(c) 2020 Intel Corporation.
>   */
>  #include "intel_pxp.h"
> +#include "intel_pxp_tee.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
>  
> @@ -50,7 +51,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
>   if (ret)
>   return;
>  
> + ret = intel_pxp_tee_component_init(pxp);
> + if (ret)
> + goto out_context;
> +
>   drm_info(>i915->drm, "Protected Xe Path (PXP) protected content 
> support initialized\n");
> +
> + return;
> +
> +out_context:
> + destroy_vcs_context(pxp);
>  }
>  
>  void intel_pxp_fini(struct intel_pxp *pxp)
> @@ -58,5 +68,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>   if (!intel_pxp_is_enabled(pxp))
>   return;
>  
> + intel_pxp_tee_component_fini(pxp);
> +
>   destroy_vcs_context(pxp);
> +
>  }
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
> b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> new file mode 100644
> index ..21916ec0f6ff
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2020 Intel Corporation.
> + */
> +
> +#include 
> +#include "drm/i915_pxp_tee_interface.h"
> +#include "drm/i915_component.h"
> +#include "i915_drv.h"
> +#include "intel_pxp.h"
> +#include "intel_pxp_tee.h"
> +
> +static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
> +{
> + return _to_i915(i915_kdev)->gt.pxp;
> +}
> +
> +/**
> + * i915_pxp_tee_component_bind - bind function to pass the function pointers 
> to pxp_tee
> + * @i915_kdev: pointer to i915 kernel device
> + * @tee_kdev: pointer to tee kernel device
> + * @data: pointer to pxp_tee_master containing the function pointers
> + *
> + * This bind function is called during the system boot or resume from system 
> sleep.
> + *
> + * Return: return 0 if successful.
> + */
> +static int i915_pxp_tee_component_bind(struct device *i915_kdev,
> +struct device *tee_kdev, void *data)
> +{
> + struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
> +
> + pxp->pxp_component = data;
> + pxp->pxp_component->tee_dev = tee_kdev;
> +
> + return 0;
> +}
> +
> +static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
> +   struct device *tee_kdev, void *data)
> +{
> + struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
> +
> + pxp->pxp_component = NULL;
> +}
> +
> +static const struct component_ops i915_pxp_tee_component_ops = {
> + .bind   = i915_pxp_tee_component_bind,
> + .unbind = i915_pxp_tee_component_unbind,
> +};
> +
> +int intel_pxp_tee_component_init(struct intel_pxp *pxp)
> +{
> + int ret;
> + struct intel_gt *gt = pxp_to_gt(pxp);
> + struct drm_i915_private *i915 = gt->i915;
> +
> + ret = component_add_typed(i915->drm.dev, _pxp_tee_component_ops,
> +   I915_COMPONENT_PXP);
> + if (ret < 0) {
> + drm_err(>drm, "Failed to add PXP component (%d)\n", ret);
> + return ret;
> + }
> +
> + 

Re: [PATCH] backlight: pwm_bl: Avoid backlight flicker if backlight control GPIO is input

2021-07-21 Thread Marek Vasut

On 7/21/21 6:12 PM, Daniel Thompson wrote:

On Wed, Jul 21, 2021 at 05:09:57PM +0200, Marek Vasut wrote:

On 7/21/21 12:49 PM, Daniel Thompson wrote:

I'm not sure that's correct, we can simply say that any new uses of the
pwm-backlight should specify the initial GPIO configuration, and for the
legacy ones, use whatever is in the code now.


I'm not 100% against the idea... however if we still have to get the
code to read state from the hardware right for legacy cases that means
we have to do the same work but with fewer people testing it.


We can do something like this:

if (of_property_read_bool(np, "enable-active-high"))
   gpiod_direction_output(pb->enable_gpio, 1);
else if (of_property_read_bool(np, "enable-active-low"))
   gpiod_direction_output(pb->enable_gpio, 0);
else {
   WARN_ON_ONCE("Fix your DT"); // or some such notification
   ... legacy code path ...
}

Note that I picked the same DT prop names as drivers/gpio/gpiolib-of.c
of_gpio_flags_quirks() uses, because we are headed into similar mess here
I'm afraid.


I don't quite understand what you mean here. We are using gpiolib so
for us there is no concept of active-high or active-low. The only
concept for us is whether enable_gpio is asserted or not.


It would look the same -- just substitute in "enable-on-boot" and 
"disable-on-boot" DT property.



What the DT property would be describing is purely whether the
bootloader left the backlight on or off.


Rather, it would simply control what is the default state of the 
backlight enable GPIO (enabled/disabled).



This sails very close to the
edge of what is in-scope for DT (at least it does it we can read
the inherited state directly from the hardware).


The problem with reading it out of hardware is that the hardware might 
be in undefined state and expects Linux to define that state, so that 
does not always work. Hence my initial suggestion to add a DT property 
to define the state up front, instead of using these fragile heuristics.



What it also means decisions about the DT bindings are more about
whether, if the backlight is lit up, the bootloader should also disclose
what it thinks it has established as the PWM duty cycle as well.


Please also consider the case where bootloader configures total minimum 
of the hardware to start Linux as soon as possible, i.e. it puts Linux 
in DRAM and jumps to Linux.



Overall I have fairly grave concerns that this simply moves
fragility into the bootloader rather then reducing it.


Wait a minute, I think we disconnected somewhere. I would rather prefer 
to remove the fragility and bootloader dependency altogether, exactly to 
avoid depending on the state the bootloader left the hardware in.


Re: [Intel-gfx] [PATCH 4/4] drm/i915/gt: nuke gen6_hw_id

2021-07-21 Thread Lucas De Marchi

On Wed, Jul 21, 2021 at 10:25:59AM +0100, Tvrtko Ursulin wrote:


On 21/07/2021 00:20, Lucas De Marchi wrote:

This is only used by GRAPHICS_VER == 6 and GRAPHICS_VER == 7. All other
recent platforms do not depend on this field, so it doesn't make much
sense to keep it generic like that. Instead, just do a mapping from
engine class to HW ID in the single place that is needed.

Signed-off-by: Lucas De Marchi 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c| 6 --
 drivers/gpu/drm/i915/gt/intel_engine_types.h | 8 
 drivers/gpu/drm/i915/i915_reg.h  | 4 +++-
 3 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 508221de411c..0a04e8d90e9e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -42,7 +42,6 @@
 #define MAX_MMIO_BASES 3
 struct engine_info {
-   u8 gen6_hw_id;
u8 class;
u8 instance;
/* mmio bases table *must* be sorted in reverse graphics_ver order */
@@ -54,7 +53,6 @@ struct engine_info {
 static const struct engine_info intel_engines[] = {
[RCS0] = {
-   .gen6_hw_id = RCS0_HW,
.class = RENDER_CLASS,
.instance = 0,
.mmio_bases = {
@@ -62,7 +60,6 @@ static const struct engine_info intel_engines[] = {
},
},
[BCS0] = {
-   .gen6_hw_id = BCS0_HW,
.class = COPY_ENGINE_CLASS,
.instance = 0,
.mmio_bases = {
@@ -70,7 +67,6 @@ static const struct engine_info intel_engines[] = {
},
},
[VCS0] = {
-   .gen6_hw_id = VCS0_HW,
.class = VIDEO_DECODE_CLASS,
.instance = 0,
.mmio_bases = {
@@ -102,7 +98,6 @@ static const struct engine_info intel_engines[] = {
},
},
[VECS0] = {
-   .gen6_hw_id = VECS0_HW,
.class = VIDEO_ENHANCEMENT_CLASS,
.instance = 0,
.mmio_bases = {
@@ -290,7 +285,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
intel_engine_id id)
engine->i915 = i915;
engine->gt = gt;
engine->uncore = gt->uncore;
-   engine->gen6_hw_id = info->gen6_hw_id;
guc_class = engine_class_to_guc_class(info->class);
engine->guc_id = MAKE_GUC_ID(guc_class, info->instance);
engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 266422d8d1b1..64330bfb7641 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -28,13 +28,6 @@
 #include "intel_wakeref.h"
 #include "intel_workarounds_types.h"
-/* Legacy HW Engine ID */
-
-#define RCS0_HW0
-#define VCS0_HW1
-#define BCS0_HW2
-#define VECS0_HW   3
-
 /* Gen11+ HW Engine class + instance */
 #define RENDER_CLASS   0
 #define VIDEO_DECODE_CLASS 1
@@ -268,7 +261,6 @@ struct intel_engine_cs {
intel_engine_mask_t mask;
-   u8 gen6_hw_id;
u8 class;
u8 instance;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8750ffce9d61..d91386f4828e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2572,7 +2572,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 #define   ARB_MODE_BWGTLB_DISABLE (1 << 9)
 #define   ARB_MODE_SWIZZLE_BDW (1 << 1)
 #define RENDER_HWS_PGA_GEN7_MMIO(0x04080)
-#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * (engine)->gen6_hw_id)
+
+#define _GEN6_ENGINE_CLASS_TO_ID(class) _PICK((class), 0, 1, 3, 2)
+#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * 
_GEN6_ENGINE_CLASS_TO_ID((engine)->class))


Makes sense to me.

Maybe HW_ID and HW_CLASS in the macro name? Not sure.


I can do that... I think I avoided it because it makes the macro
very big. Anyway, this should be called in just one place, so it doesn't
matter much... I can add it.



Only open I have is why the "Gen11+ HW Engine class + instance" 
comment and now we would tie that, allegedly Gen11 concept, with 
Gen6-7. Care to do some digging?


Not sure. This comes from 3d7b3039741d ("drm/i915: Move engine IDs out of 
i915_reg.h")
that I reviewed :-o

Cc'ing  Daniele. I don't see "class" as a Gen11+ thing. Is it just that
those numbers started to make sense for gen11?  Since

a) we are using the class even for GRAPHICS_VER < 11
b) the legacy HW IDs shouldn't be used anywhere else anymore


we could

1) move the legacy defines back to i915_reg.h
2) use them in the macro above (IMO would slightly improve the
readability of that _PICK() call)
3) Remove the "Gen11+" comment in the _CLASS macros to avoid
misunderstandings


Thoughts?

thanks
Lucas De Marchi



[PATCH] drm/i915: Ditch i915 globals shrink infrastructure

2021-07-21 Thread Daniel Vetter
This essentially reverts

commit 84a1074920523430f9dc30ff907f4801b4820072
Author: Chris Wilson 
Date:   Wed Jan 24 11:36:08 2018 +

drm/i915: Shrink the GEM kmem_caches upon idling

mm/vmscan.c:do_shrink_slab() is a thing, if there's an issue with it
then we need to fix that there, not hand-roll our own slab shrinking
code in i915.

Noticed while reviewing a patch set from Jason to fix up some issues
in our i915_init() and i915_exit() module load/cleanup code. Now that
i915_globals.c isn't any different than normal init/exit functions, we
should convert them over to one unified table and remove
i915_globals.[hc] entirely.

Cc: David Airlie 
Cc: Jason Ekstrand 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c |  6 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c  |  6 --
 drivers/gpu/drm/i915/gt/intel_context.c |  6 --
 drivers/gpu/drm/i915/gt/intel_gt_pm.c   |  4 -
 drivers/gpu/drm/i915/i915_active.c  |  6 --
 drivers/gpu/drm/i915/i915_globals.c | 95 -
 drivers/gpu/drm/i915/i915_globals.h |  3 -
 drivers/gpu/drm/i915/i915_request.c |  7 --
 drivers/gpu/drm/i915/i915_scheduler.c   |  7 --
 drivers/gpu/drm/i915/i915_vma.c |  6 --
 10 files changed, 146 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 7d6f52d8a801..bf2a2319353a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -2280,18 +2280,12 @@ i915_gem_engines_iter_next(struct i915_gem_engines_iter 
*it)
 #include "selftests/i915_gem_context.c"
 #endif
 
-static void i915_global_gem_context_shrink(void)
-{
-   kmem_cache_shrink(global.slab_luts);
-}
-
 static void i915_global_gem_context_exit(void)
 {
kmem_cache_destroy(global.slab_luts);
 }
 
 static struct i915_global_gem_context global = { {
-   .shrink = i915_global_gem_context_shrink,
.exit = i915_global_gem_context_exit,
 } };
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 9da7b288b7ed..5c21cff33199 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -664,18 +664,12 @@ void i915_gem_init__objects(struct drm_i915_private *i915)
INIT_WORK(>mm.free_work, __i915_gem_free_work);
 }
 
-static void i915_global_objects_shrink(void)
-{
-   kmem_cache_shrink(global.slab_objects);
-}
-
 static void i915_global_objects_exit(void)
 {
kmem_cache_destroy(global.slab_objects);
 }
 
 static struct i915_global_object global = { {
-   .shrink = i915_global_objects_shrink,
.exit = i915_global_objects_exit,
 } };
 
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index bd63813c8a80..c1338441cc1d 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -398,18 +398,12 @@ void intel_context_fini(struct intel_context *ce)
i915_active_fini(>active);
 }
 
-static void i915_global_context_shrink(void)
-{
-   kmem_cache_shrink(global.slab_ce);
-}
-
 static void i915_global_context_exit(void)
 {
kmem_cache_destroy(global.slab_ce);
 }
 
 static struct i915_global_context global = { {
-   .shrink = i915_global_context_shrink,
.exit = i915_global_context_exit,
 } };
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index aef3084e8b16..d86825437516 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -67,8 +67,6 @@ static int __gt_unpark(struct intel_wakeref *wf)
 
GT_TRACE(gt, "\n");
 
-   i915_globals_unpark();
-
/*
 * It seems that the DMC likes to transition between the DC states a lot
 * when there are no connected displays (no active power domains) during
@@ -116,8 +114,6 @@ static int __gt_park(struct intel_wakeref *wf)
GEM_BUG_ON(!wakeref);
intel_display_power_put_async(i915, POWER_DOMAIN_GT_IRQ, wakeref);
 
-   i915_globals_park();
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_active.c 
b/drivers/gpu/drm/i915/i915_active.c
index b1aa1c482c32..91723123ae9f 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -1176,18 +1176,12 @@ struct i915_active *i915_active_create(void)
 #include "selftests/i915_active.c"
 #endif
 
-static void i915_global_active_shrink(void)
-{
-   kmem_cache_shrink(global.slab_cache);
-}
-
 static void i915_global_active_exit(void)
 {
kmem_cache_destroy(global.slab_cache);
 }
 
 static struct i915_global_active global = { {
-   .shrink = i915_global_active_shrink,
.exit = i915_global_active_exit,
 } };
 
diff --git a/drivers/gpu/drm/i915/i915_globals.c 
b/drivers/gpu/drm/i915/i915_globals.c
index 77f1911c463b..7fe2e503897b 100644
--- 

Re: [PATCH 2/7] drm/i915/gem: Refactor placement setup for i915_gem_object_create* (v2)

2021-07-21 Thread Jason Ekstrand
On Wed, Jul 21, 2021 at 3:32 AM Matthew Auld
 wrote:
>
> On Tue, 20 Jul 2021 at 23:07, Jason Ekstrand  wrote:
> >
> > On Mon, Jul 19, 2021 at 3:18 AM Matthew Auld
> >  wrote:
> > >
> > > On Fri, 16 Jul 2021 at 15:14, Jason Ekstrand  wrote:
> > > >
> > > > Since we don't allow changing the set of regions after creation, we can
> > > > make ext_set_placements() build up the region set directly in the
> > > > create_ext and assign it to the object later.  This is similar to what
> > > > we did for contexts with the proto-context only simpler because there's
> > > > no funny object shuffling.  This will be used in the next patch to allow
> > > > us to de-duplicate a bunch of code.  Also, since we know the maximum
> > > > number of regions up-front, we can use a fixed-size temporary array for
> > > > the regions.  This simplifies memory management a bit for this new
> > > > delayed approach.
> > > >
> > > > v2 (Matthew Auld):
> > > >  - Get rid of MAX_N_PLACEMENTS
> > > >  - Drop kfree(placements) from set_placements()
> > > >
> > > > Signed-off-by: Jason Ekstrand 
> > > > Cc: Matthew Auld 
> > > > ---
> > > >  drivers/gpu/drm/i915/gem/i915_gem_create.c | 81 --
> > > >  1 file changed, 45 insertions(+), 36 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
> > > > b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > index 51f92e4b1a69d..5766749a449c0 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > @@ -27,10 +27,13 @@ static u32 object_max_page_size(struct 
> > > > drm_i915_gem_object *obj)
> > > > return max_page_size;
> > > >  }
> > > >
> > > > -static void object_set_placements(struct drm_i915_gem_object *obj,
> > > > - struct intel_memory_region 
> > > > **placements,
> > > > - unsigned int n_placements)
> > > > +static int object_set_placements(struct drm_i915_gem_object *obj,
> > > > +struct intel_memory_region 
> > > > **placements,
> > > > +unsigned int n_placements)
> > > >  {
> > > > +   struct intel_memory_region **arr;
> > > > +   unsigned int i;
> > > > +
> > > > GEM_BUG_ON(!n_placements);
> > > >
> > > > /*
> > > > @@ -44,9 +47,20 @@ static void object_set_placements(struct 
> > > > drm_i915_gem_object *obj,
> > > > obj->mm.placements = >mm.regions[mr->id];
> > > > obj->mm.n_placements = 1;
> > > > } else {
> > > > -   obj->mm.placements = placements;
> > > > +   arr = kmalloc_array(n_placements,
> > > > +   sizeof(struct intel_memory_region 
> > > > *),
> > > > +   GFP_KERNEL);
> > > > +   if (!arr)
> > > > +   return -ENOMEM;
> > > > +
> > > > +   for (i = 0; i < n_placements; i++)
> > > > +   arr[i] = placements[i];
> > > > +
> > > > +   obj->mm.placements = arr;
> > > > obj->mm.n_placements = n_placements;
> > > > }
> > > > +
> > > > +   return 0;
> > > >  }
> > > >
> > > >  static int i915_gem_publish(struct drm_i915_gem_object *obj,
> > > > @@ -148,7 +162,9 @@ i915_gem_dumb_create(struct drm_file *file,
> > > > return -ENOMEM;
> > > >
> > > > mr = intel_memory_region_by_type(to_i915(dev), mem_type);
> > > > -   object_set_placements(obj, , 1);
> > > > +   ret = object_set_placements(obj, , 1);
> > > > +   if (ret)
> > > > +   goto object_free;
> > > >
> > > > ret = i915_gem_setup(obj, args->size);
> > > > if (ret)
> > > > @@ -184,7 +200,9 @@ i915_gem_create_ioctl(struct drm_device *dev, void 
> > > > *data,
> > > > return -ENOMEM;
> > > >
> > > > mr = intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM);
> > > > -   object_set_placements(obj, , 1);
> > > > +   ret = object_set_placements(obj, , 1);
> > > > +   if (ret)
> > > > +   goto object_free;
> > > >
> > > > ret = i915_gem_setup(obj, args->size);
> > > > if (ret)
> > > > @@ -199,7 +217,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void 
> > > > *data,
> > > >
> > > >  struct create_ext {
> > > > struct drm_i915_private *i915;
> > > > -   struct drm_i915_gem_object *vanilla_object;
> > > > +   struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
> > > > +   unsigned int n_placements;
> > > >  };
> > > >
> > > >  static void repr_placements(char *buf, size_t size,
> > > > @@ -230,8 +249,7 @@ static int set_placements(struct 
> > > > drm_i915_gem_create_ext_memory_regions *args,
> > > > struct drm_i915_private *i915 = ext_data->i915;
> > > > struct drm_i915_gem_memory_class_instance __user *uregions =
> > > > 

Re: [PATCH 14/14] drm/i915/guc/rc: Setup and enable GUCRC feature

2021-07-21 Thread Michal Wajdeczko



On 21.07.2021 18:11, Vinay Belgaumkar wrote:
> This feature hands over the control of HW RC6 to the GuC.
> GuC decides when to put HW into RC6 based on it's internal
> busyness algorithms.
> 
> GUCRC needs GuC submission to be enabled, and only
> supported on Gen12+ for now.
> 
> When GUCRC is enabled, do not set HW RC6. Use a H2G message
> to tell GuC to enable GUCRC. When disabling RC6, tell GuC to
> revert RC6 control back to KMD.
> 
> v2: Address comments (Michal W)
> 
> Signed-off-by: Vinay Belgaumkar 
> ---
>  drivers/gpu/drm/i915/Makefile |  1 +
>  drivers/gpu/drm/i915/gt/intel_rc6.c   | 22 +++--
>  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  6 ++
>  drivers/gpu/drm/i915/gt/uc/intel_guc.c|  1 +
>  drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
>  drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 81 +++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_rc.h | 31 +++
>  drivers/gpu/drm/i915/gt/uc/intel_uc.h |  2 +
>  8 files changed, 141 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_rc.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index d8eac4468df9..3fc17f20d88e 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -186,6 +186,7 @@ i915-y += gt/uc/intel_uc.o \
> gt/uc/intel_guc_fw.o \
> gt/uc/intel_guc_log.o \
> gt/uc/intel_guc_log_debugfs.o \
> +   gt/uc/intel_guc_rc.o \
> gt/uc/intel_guc_slpc.o \
> gt/uc/intel_guc_submission.o \
> gt/uc/intel_huc.o \
> diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c 
> b/drivers/gpu/drm/i915/gt/intel_rc6.c
> index 259d7eb4e165..299fcf10b04b 100644
> --- a/drivers/gpu/drm/i915/gt/intel_rc6.c
> +++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
> @@ -98,11 +98,19 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
>   set(uncore, GEN9_MEDIA_PG_IDLE_HYSTERESIS, 60);
>   set(uncore, GEN9_RENDER_PG_IDLE_HYSTERESIS, 60);
>  
> - /* 3a: Enable RC6 */
> - rc6->ctl_enable =
> - GEN6_RC_CTL_HW_ENABLE |
> - GEN6_RC_CTL_RC6_ENABLE |
> - GEN6_RC_CTL_EI_MODE(1);
> + /* 3a: Enable RC6
> +  *
> +  * With GUCRC, we do not enable bit 31 of RC_CTL,
> +  * thus allowing GuC to control RC6 entry/exit fully instead.
> +  * We will not set the HW ENABLE and EI bits
> +  */
> + if (!intel_guc_rc_enable(>uc.guc))
> + rc6->ctl_enable = GEN6_RC_CTL_RC6_ENABLE;
> + else
> + rc6->ctl_enable =
> + GEN6_RC_CTL_HW_ENABLE |
> + GEN6_RC_CTL_RC6_ENABLE |
> + GEN6_RC_CTL_EI_MODE(1);
>  
>   pg_enable =
>   GEN9_RENDER_PG_ENABLE |
> @@ -513,6 +521,10 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6)
>  {
>   struct drm_i915_private *i915 = rc6_to_i915(rc6);
>   struct intel_uncore *uncore = rc6_to_uncore(rc6);
> + struct intel_gt *gt = rc6_to_gt(rc6);
> +
> + /* Take control of RC6 back from GuC */
> + intel_guc_rc_disable(>uc.guc);
>  
>   intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
>   if (GRAPHICS_VER(i915) >= 9)
> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h 
> b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> index d832c8f11c11..5f1c82f35d97 100644
> --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> @@ -136,6 +136,7 @@ enum intel_guc_action {
>   INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION = 0x1008,
>   INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION = 0x1009,
>   INTEL_GUC_ACTION_SLPC_REQUEST = 0x3003,
> + INTEL_GUC_ACTION_SETUP_PC_GUCRC = 0x3004,
>   INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
>   INTEL_GUC_ACTION_REGISTER_CONTEXT = 0x4502,
>   INTEL_GUC_ACTION_DEREGISTER_CONTEXT = 0x4503,
> @@ -146,6 +147,11 @@ enum intel_guc_action {
>   INTEL_GUC_ACTION_LIMIT
>  };
>  
> +enum intel_guc_rc_options {
> + INTEL_GUCRC_HOST_CONTROL,
> + INTEL_GUCRC_FIRMWARE_CONTROL,
> +};
> +
>  enum intel_guc_preempt_options {
>   INTEL_GUC_PREEMPT_OPTION_DROP_WORK_Q = 0x4,
>   INTEL_GUC_PREEMPT_OPTION_DROP_SUBMIT_Q = 0x8,
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> index 686cb978662d..e474f554b17a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> @@ -159,6 +159,7 @@ void intel_guc_init_early(struct intel_guc *guc)
>   intel_guc_log_init_early(>log);
>   intel_guc_submission_init_early(guc);
>   intel_guc_slpc_init_early(>slpc);
> + intel_guc_rc_init_early(guc);
>  
>   mutex_init(>send_mutex);
>   spin_lock_init(>irq_lock);
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> index 

Re: [PATCH 12/14] drm/i915/guc/slpc: Sysfs hooks for SLPC

2021-07-21 Thread Michal Wajdeczko



On 21.07.2021 18:11, Vinay Belgaumkar wrote:
> Update the get/set min/max freq hooks to work for
> SLPC case as well. Consolidate helpers for requested/min/max
> frequency get/set to intel_rps where the proper action can
> be taken depending on whether slpc is enabled.

s/slpc/SLPC

> 
> v2: Add wrappers for getting rp0/1/n frequencies, update
> softlimits in set min/max slpc functions. Also check for
> boundary conditions before setting them.
> 
> v3: Address review comments (Michal W)
> 
> Signed-off-by: Vinay Belgaumkar 
> Signed-off-by: Tvrtko Ursulin 
> Signed-off-by: Sujaritha Sundaresan 
> ---
>  drivers/gpu/drm/i915/gt/intel_rps.c | 165 
>  drivers/gpu/drm/i915/gt/intel_rps.h |  11 ++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c |  14 ++
>  drivers/gpu/drm/i915/i915_pmu.c |   2 +-
>  drivers/gpu/drm/i915/i915_reg.h |   2 +
>  drivers/gpu/drm/i915/i915_sysfs.c   |  77 ++---
>  6 files changed, 207 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c 
> b/drivers/gpu/drm/i915/gt/intel_rps.c
> index e858eeb2c59d..48d4147165a9 100644
> --- a/drivers/gpu/drm/i915/gt/intel_rps.c
> +++ b/drivers/gpu/drm/i915/gt/intel_rps.c
> @@ -37,6 +37,13 @@ static struct intel_uncore *rps_to_uncore(struct intel_rps 
> *rps)
>   return rps_to_gt(rps)->uncore;
>  }
>  
> +static struct intel_guc_slpc *rps_to_slpc(struct intel_rps *rps)
> +{
> + struct intel_gt *gt = rps_to_gt(rps);
> +
> + return >uc.guc.slpc;
> +}
> +
>  static bool rps_uses_slpc(struct intel_rps *rps)
>  {
>   struct intel_gt *gt = rps_to_gt(rps);
> @@ -1960,6 +1967,164 @@ u32 intel_rps_read_actual_frequency(struct intel_rps 
> *rps)
>   return freq;
>  }
>  
> +u32 intel_rps_read_punit_req(struct intel_rps *rps)
> +{
> + struct intel_uncore *uncore = rps_to_uncore(rps);
> +
> + return intel_uncore_read(uncore, GEN6_RPNSWREQ);
> +}
> +
> +u32 intel_rps_get_req(struct intel_rps *rps, u32 pureq)
> +{
> + u32 req = pureq >> GEN9_SW_REQ_UNSLICE_RATIO_SHIFT;
> +
> + return req;
> +}
> +
> +u32 intel_rps_read_punit_req_frequency(struct intel_rps *rps)
> +{
> + u32 freq = intel_rps_get_req(rps, intel_rps_read_punit_req(rps));
> +
> + return intel_gpu_freq(rps, freq);
> +}
> +
> +u32 intel_rps_get_requested_frequency(struct intel_rps *rps)
> +{
> + if (rps_uses_slpc(rps))
> + return intel_rps_read_punit_req_frequency(rps);
> + else
> + return intel_gpu_freq(rps, rps->cur_freq);
> +}
> +
> +u32 intel_rps_get_max_frequency(struct intel_rps *rps)
> +{
> + struct intel_guc_slpc *slpc = rps_to_slpc(rps);
> +
> + if (rps_uses_slpc(rps))
> + return slpc->max_freq_softlimit;
> + else
> + return intel_gpu_freq(rps, rps->max_freq_softlimit);
> +}
> +
> +u32 intel_rps_get_rp0_frequency(struct intel_rps *rps)
> +{
> + struct intel_guc_slpc *slpc = rps_to_slpc(rps);
> +
> + if (rps_uses_slpc(rps))
> + return slpc->rp0_freq;
> + else
> + return intel_gpu_freq(rps, rps->rp0_freq);
> +}
> +
> +u32 intel_rps_get_rp1_frequency(struct intel_rps *rps)
> +{
> + struct intel_guc_slpc *slpc = rps_to_slpc(rps);
> +
> + if (rps_uses_slpc(rps))
> + return slpc->rp1_freq;
> + else
> + return intel_gpu_freq(rps, rps->rp1_freq);
> +}
> +
> +u32 intel_rps_get_rpn_frequency(struct intel_rps *rps)
> +{
> + struct intel_guc_slpc *slpc = rps_to_slpc(rps);
> +
> + if (rps_uses_slpc(rps))
> + return slpc->min_freq;
> + else
> + return intel_gpu_freq(rps, rps->min_freq);
> +}
> +
> +int intel_rps_set_max_frequency(struct intel_rps *rps, u32 val)
> +{
> + struct drm_i915_private *i915 = rps_to_i915(rps);
> + struct intel_guc_slpc *slpc = rps_to_slpc(rps);
> + int ret = 0;
> +
> + if (rps_uses_slpc(rps))
> + return intel_guc_slpc_set_max_freq(slpc, val);
> +
> + mutex_lock(>lock);
> +
> + val = intel_freq_opcode(rps, val);
> + if (val < rps->min_freq ||
> + val > rps->max_freq ||
> + val < rps->min_freq_softlimit) {
> + ret = -EINVAL;
> + goto unlock;
> + }
> +
> + if (val > rps->rp0_freq)
> + drm_dbg(>drm, "User requested overclocking to %d\n",
> +   intel_gpu_freq(rps, val));
> +
> + rps->max_freq_softlimit = val;
> +
> + val = clamp_t(int, rps->cur_freq,
> +   rps->min_freq_softlimit,
> +   rps->max_freq_softlimit);
> +
> + /*
> +  * We still need *_set_rps to process the new max_delay and
> +  * update the interrupt limits and PMINTRMSK even though
> +  * frequency request may be unchanged.
> +  */
> + intel_rps_set(rps, val);
> +
> +unlock:
> + mutex_unlock(>lock);
> +
> + return ret;
> +}
> +
> +u32 intel_rps_get_min_frequency(struct intel_rps *rps)
> +{
> + struct 

Re: [PATCH 11/14] drm/i915/guc/slpc: Cache platform frequency limits

2021-07-21 Thread Michal Wajdeczko



On 21.07.2021 18:11, Vinay Belgaumkar wrote:
> Cache rp0, rp1 and rpn platform limits into SLPC structure
> for range checking while setting min/max frequencies.
> 
> Also add "soft" limits which keep track of frequency changes
> made from userland. These are initially set to platform min
> and max.
> 
> v2: Address review comments (Michal W)
> 
> Signed-off-by: Vinay Belgaumkar 
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 98 +++
>  .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h |  9 ++
>  drivers/gpu/drm/i915/i915_reg.h   |  3 +
>  3 files changed, 110 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> index 8796a8929d89..134c57ca10b7 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> @@ -94,6 +94,9 @@ static int slpc_shared_data_init(struct intel_guc_slpc 
> *slpc)
>   return err;
>   }
>  
> + slpc->max_freq_softlimit = 0;
> + slpc->min_freq_softlimit = 0;
> +
>   return err;
>  }
>  
> @@ -121,6 +124,19 @@ static int guc_action_slpc_set_param(struct intel_guc 
> *guc, u8 id, u32 value)
>   return intel_guc_send(guc, request, ARRAY_SIZE(request));
>  }
>  
> +static int guc_action_slpc_unset_param(struct intel_guc *guc,
> + u8 id)
> +{
> + u32 request[] = {
> + INTEL_GUC_ACTION_SLPC_REQUEST,
> + SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 2),
> + id,
> + };
> +
> + return intel_guc_send(guc, request, ARRAY_SIZE(request));
> +}
> +
> +
>  static bool slpc_is_running(struct intel_guc_slpc *slpc)
>  {
>   return (slpc_get_state(slpc) == SLPC_GLOBAL_STATE_RUNNING);
> @@ -164,6 +180,16 @@ static int slpc_set_param(struct intel_guc_slpc *slpc, 
> u8 id, u32 value)
>   return guc_action_slpc_set_param(guc, id, value);
>  }
>  
> +static int slpc_unset_param(struct intel_guc_slpc *slpc,
> + u8 id)

likely can fit into one line

> +{
> + struct intel_guc *guc = slpc_to_guc(slpc);
> +
> + GEM_BUG_ON(id >= SLPC_MAX_PARAM);
> +
> + return guc_action_slpc_unset_param(guc, id);
> +}
> +
>  static const char *slpc_state_string(struct intel_guc_slpc *slpc)
>  {
>   const char *str = NULL;
> @@ -388,6 +414,55 @@ void intel_guc_pm_intrmsk_enable(struct intel_gt *gt)
>  GEN6_PMINTRMSK, pm_intrmsk_mbz, 0);
>  }
>  
> +static int intel_guc_slpc_set_softlimits(struct intel_guc_slpc *slpc)
> +{
> + int ret = 0;
> +
> + /* Softlimits are initially equivalent to platform limits
> +  * unless they have deviated from defaults, in which case,
> +  * we retain the values and set min/max accordingly.
> +  */
> + if (!slpc->max_freq_softlimit)
> + slpc->max_freq_softlimit = slpc->rp0_freq;
> + else if (slpc->max_freq_softlimit != slpc->rp0_freq)
> + ret = intel_guc_slpc_set_max_freq(slpc,
> + slpc->max_freq_softlimit);
> +
> + if (!slpc->min_freq_softlimit)
> + slpc->min_freq_softlimit = slpc->min_freq;
> + else if (slpc->min_freq_softlimit != slpc->min_freq)
> + ret = intel_guc_slpc_set_min_freq(slpc,
> + slpc->min_freq_softlimit);
> +
> + return ret;
> +}
> +
> +static void intel_guc_slpc_ignore_eff_freq(struct intel_guc_slpc *slpc, bool 
> ignore)
> +{
> + if (ignore) {
> + /* A failure here does not affect the algorithm in a fatal way 
> */
> + slpc_set_param(slpc,
> +SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
> +ignore);
> + slpc_set_param(slpc,
> +SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
> +slpc->min_freq);
> + } else {
> + slpc_unset_param(slpc,
> +SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY);
> + slpc_unset_param(slpc,
> +SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ);

hard to tell from mail client, but likely misalignment
did you run checkpatch.pl ?

> + }
> +}
> +
> +static void intel_guc_slpc_use_fused_rp0(struct intel_guc_slpc *slpc)
> +{
> + /* Force slpc to used platform rp0 */
> + slpc_set_param(slpc,
> +SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ,
> +slpc->rp0_freq);
> +}
> +
>  /*
>   * intel_guc_slpc_enable() - Start SLPC
>   * @slpc: pointer to intel_guc_slpc.
> @@ -405,6 +480,7 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
>  {
>   struct drm_i915_private *i915 = slpc_to_i915(slpc);
>   struct slpc_shared_data *data;
> + u32 rp_state_cap;
>   int ret;
>  
>   GEM_BUG_ON(!slpc->vma);
> @@ -442,6 +518,28 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
>   slpc_decode_min_freq(slpc),
>   slpc_decode_max_freq(slpc));
>  
> + rp_state_cap = 

Re: [PATCH 09/14] drm/i915/guc/slpc: Add debugfs for SLPC info

2021-07-21 Thread Michal Wajdeczko



On 21.07.2021 18:11, Vinay Belgaumkar wrote:
> This prints out relevant SLPC info from the SLPC shared structure.
> 
> We will send a h2g message which forces SLPC to update the
> shared data structure with latest information before reading it.
> 
> v2: Address review comments (Michal W)
> 
> Signed-off-by: Vinay Belgaumkar 
> Signed-off-by: Sundaresan Sujaritha 
> ---
>  .../gpu/drm/i915/gt/uc/intel_guc_debugfs.c| 23 +++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 40 +++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h   |  4 +-
>  3 files changed, 66 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
> index 72ddfff42f7d..46b22187927b 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
> @@ -12,6 +12,7 @@
>  #include "gt/uc/intel_guc_ct.h"
>  #include "gt/uc/intel_guc_ads.h"
>  #include "gt/uc/intel_guc_submission.h"
> +#include "gt/uc/intel_guc_slpc.h"
>  
>  static int guc_info_show(struct seq_file *m, void *data)
>  {
> @@ -50,11 +51,33 @@ static int guc_registered_contexts_show(struct seq_file 
> *m, void *data)
>  }
>  DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_registered_contexts);
>  
> +static int guc_slpc_info_show(struct seq_file *m, void *unused)
> +{
> + struct intel_guc *guc = m->private;
> + struct intel_guc_slpc *slpc = >slpc;
> + struct drm_printer p = drm_seq_file_printer(m);
> +
> + if (!intel_guc_slpc_is_used(guc))
> + return -ENODEV;
> +
> + return intel_guc_slpc_info(slpc, );
> +}
> +DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_slpc_info);
> +
> +bool intel_eval_slpc_support(void *data)
> +{
> + struct intel_guc *guc;
> +
> + guc = (struct intel_guc *)data;

struct intel_guc *guc = (struct intel_guc *)data;

> + return intel_guc_slpc_is_used(guc);
> +}
> +
>  void intel_guc_debugfs_register(struct intel_guc *guc, struct dentry *root)
>  {
>   static const struct debugfs_gt_file files[] = {
>   { "guc_info", _info_fops, NULL },
>   { "guc_registered_contexts", _registered_contexts_fops, 
> NULL },
> + { "guc_slpc_info", _slpc_info_fops, 
> _eval_slpc_support},
>   };
>  
>   if (!intel_guc_is_supported(guc))
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> index c1cf8d46e360..73379985c105 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> @@ -430,6 +430,46 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
>   return 0;
>  }
>  
> +int intel_guc_slpc_info(struct intel_guc_slpc *slpc, struct drm_printer *p)
> +{
> + struct drm_i915_private *i915 = guc_to_gt(slpc_to_guc(slpc))->i915;
> + struct slpc_shared_data *data;
> + struct slpc_task_state_data *slpc_tasks;
> + intel_wakeref_t wakeref;
> + int ret = 0;
> +
> + with_intel_runtime_pm(>runtime_pm, wakeref) {
> + if (slpc_query_task_state(slpc))
> + return -EIO;

not sure if you can return directly from "with_rpm"

> +
> + slpc_tasks = >task_state_data;
> +
> + drm_printf(p, "SLPC state: %s\n", slpc_state_string(slpc));
> + drm_printf(p, "\tgtperf task active: %s\n",
> + yesno(slpc_tasks->status & SLPC_GTPERF_TASK_ACTIVE));
> + drm_printf(p, "\tdcc task active: %s\n",
> + yesno(slpc_tasks->status & SLPC_DCC_TASK_ACTIVE));
> + drm_printf(p, "\tin dcc: %s\n",
> + yesno(slpc_tasks->status & SLPC_IN_DCC));
> + drm_printf(p, "\tfreq switch active: %s\n",
> + yesno(slpc_tasks->status & SLPC_FREQ_SWITCH_ACTIVE));
> + drm_printf(p, "\tibc enabled: %s\n",
> + yesno(slpc_tasks->status & SLPC_IBC_ENABLED));
> + drm_printf(p, "\tibc active: %s\n",
> + yesno(slpc_tasks->status & SLPC_IBC_ACTIVE));
> + drm_printf(p, "\tpg1 enabled: %s\n",
> + yesno(slpc_tasks->status & SLPC_PG1_ENABLED));
> + drm_printf(p, "\tpg1 active: %s\n",
> + yesno(slpc_tasks->status & SLPC_PG1_ACTIVE));
> + drm_printf(p, "\tmax freq: %dMHz\n",
> + slpc_decode_max_freq(slpc));
> + drm_printf(p, "\tmin freq: %dMHz\n",
> + slpc_decode_min_freq(slpc));

not sure what they are:

DCC ?
IBC ?
PG1 ?

and make sure to use %u for unsigned

Michal

> + }
> +
> + return ret;
> +}
> +
>  void intel_guc_slpc_fini(struct intel_guc_slpc *slpc)
>  {
>   if (!slpc->vma)
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
> index 627c71a95777..852c6316aa47 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
> +++ 

Re: [PATCH 08/14] drm/i915/guc/slpc: Add get max/min freq hooks

2021-07-21 Thread Michal Wajdeczko



On 21.07.2021 18:11, Vinay Belgaumkar wrote:
> Add helpers to read the min/max frequency being used
> by SLPC. This is done by send a H2G command which forces
> SLPC to update the shared data struct which can then be
> read.

add note that functions will be used later

> 
> v2: Address review comments (Michal W)
> 
> Signed-off-by: Vinay Belgaumkar 
> Signed-off-by: Sundaresan Sujaritha 
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 52 +
>  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h |  2 +
>  2 files changed, 54 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> index b40c39ba4049..c1cf8d46e360 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
> @@ -290,6 +290,32 @@ int intel_guc_slpc_set_max_freq(struct intel_guc_slpc 
> *slpc, u32 val)
>   return ret;
>  }
>  
> +/**
> + * intel_guc_slpc_get_max_freq() - Get max frequency limit for SLPC.
> + * @slpc: pointer to intel_guc_slpc.
> + * @val: pointer to val which will hold max frequency (MHz)
> + *
> + * This function will invoke GuC SLPC action to read the max frequency
> + * limit for unslice.
> + *
> + * Return: 0 on success, non-zero error code on failure.
> + */
> +int intel_guc_slpc_get_max_freq(struct intel_guc_slpc *slpc, u32 *val)
> +{
> + intel_wakeref_t wakeref;
> + struct drm_i915_private *i915 = guc_to_gt(slpc_to_guc(slpc))->i915;
> + int ret = 0;

struct drm_i915_private *i915 = slpc_to_i915(slpc);
intel_wakeref_t wakeref;
int ret = 0;

> +
> + with_intel_runtime_pm(>runtime_pm, wakeref) {
> + /* Force GuC to update task data */
> + slpc_query_task_state(slpc);

what if this call fails ?

> +
> + *val = slpc_decode_max_freq(slpc);
> + }
> +
> + return ret;
> +}
> +
>  /**
>   * intel_guc_slpc_set_min_freq() - Set min frequency limit for SLPC.
>   * @slpc: pointer to intel_guc_slpc.
> @@ -322,6 +348,32 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc 
> *slpc, u32 val)
>   return ret;
>  }
>  
> +/**
> + * intel_guc_slpc_get_min_freq() - Get min frequency limit for SLPC.
> + * @slpc: pointer to intel_guc_slpc.
> + * @val: pointer to val which will hold min frequency (MHz)
> + *
> + * This function will invoke GuC SLPC action to read the min frequency
> + * limit for unslice.
> + *
> + * Return: 0 on success, non-zero error code on failure.
> + */
> +int intel_guc_slpc_get_min_freq(struct intel_guc_slpc *slpc, u32 *val)
> +{
> + intel_wakeref_t wakeref;
> + struct drm_i915_private *i915 = guc_to_gt(slpc_to_guc(slpc))->i915;
> + int ret = 0;
> +
> + with_intel_runtime_pm(>runtime_pm, wakeref) {
> + /* Force GuC to update task data */
> + slpc_query_task_state(slpc);

same here

Michal

> +
> + *val = slpc_decode_min_freq(slpc);
> + }
> +
> + return ret;
> +}
> +
>  /*
>   * intel_guc_slpc_enable() - Start SLPC
>   * @slpc: pointer to intel_guc_slpc.
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
> index 3a1a7eaafc12..627c71a95777 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
> @@ -32,5 +32,7 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc);
>  void intel_guc_slpc_fini(struct intel_guc_slpc *slpc);
>  int intel_guc_slpc_set_max_freq(struct intel_guc_slpc *slpc, u32 val);
>  int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val);
> +int intel_guc_slpc_get_max_freq(struct intel_guc_slpc *slpc, u32 *val);
> +int intel_guc_slpc_get_min_freq(struct intel_guc_slpc *slpc, u32 *val);
>  
>  #endif
> 


[RESEND PATCH v6 14/14] drm/print: Add tracefs support to the drm logging helpers

2021-07-21 Thread Sean Paul
From: Sean Paul 

This patch adds a new module parameter called drm.trace which accepts
the same mask as drm.debug. When a debug category is enabled, log
messages will be put in a new tracefs instance called drm for
consumption.

Using the new tracefs instance will allow distros to enable drm logging
in production without impacting performance or spamming the system
logs.

Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Pekka Paalanen 
Cc: Rob Clark 
Cc: Steven Rostedt 
Cc: Thomas Zimmermann 
Cc: Ville Syrjälä 
Cc: Chris Wilson 
Cc: Steven Rostedt 
Reported-by: kernel test robot  # warning reported in v6
Acked-by: Pekka Paalanen 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20191010204823.195540-1-s...@poorly.run
 #v1
Link: 
https://lists.freedesktop.org/archives/dri-devel/2019-November/243230.html #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20191212203301.142437-1-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200114172155.215463-1-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-14-s...@poorly.run
 #v5
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200818210510.49730-15-s...@poorly.run
 #v6

Changes in v5:
-Re-write to use trace_array and the tracefs instance support
Changes in v6:
-Use the new trace_array_init_printk() to initialize global trace
 buffers
Changes in v6.5:
-Fix kernel test robot warning
-Add a trace printf in __drm_err
---
 Documentation/gpu/drm-uapi.rst |   6 +
 drivers/gpu/drm/drm_drv.c  |   3 +
 drivers/gpu/drm/drm_print.c| 223 -
 include/drm/drm_print.h|  63 --
 4 files changed, 255 insertions(+), 40 deletions(-)

diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index 7e51dd40bf6e..ce1ea39fb4b9 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -424,6 +424,12 @@ Debugfs Support
 .. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
:export:
 
+DRM Tracing
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_print.c
+   :doc: DRM Tracing
+
 Sysfs Support
 =
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8804ec7d3215..71dc0b161b51 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1034,12 +1034,15 @@ static void drm_core_exit(void)
drm_sysfs_destroy();
idr_destroy(_minors_idr);
drm_connector_ida_destroy();
+   drm_trace_cleanup();
 }
 
 static int __init drm_core_init(void)
 {
int ret;
 
+   drm_trace_init();
+
drm_connector_ida_init();
idr_init(_minors_idr);
drm_memcpy_init_early();
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 4d984a01b3a3..64d9a724c2df 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -43,17 +44,34 @@
 unsigned int __drm_debug_syslog;
 EXPORT_SYMBOL(__drm_debug_syslog);
 
-MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug 
category.\n"
-"\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n"
-"\t\tBit 1 (0x02)  will enable DRIVER messages (drm controller code)\n"
-"\t\tBit 2 (0x04)  will enable KMS messages (modesetting code)\n"
-"\t\tBit 3 (0x08)  will enable PRIME messages (prime code)\n"
-"\t\tBit 4 (0x10)  will enable ATOMIC messages (atomic code)\n"
-"\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n"
-"\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n"
-"\t\tBit 8 (0x100) will enable DP messages (displayport code)");
+/*
+ * __drm_debug_trace: Enable debug output in drm tracing instance.
+ * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
+ */
+unsigned int __drm_debug_trace;
+EXPORT_SYMBOL(__drm_debug_trace);
+
+#define DEBUG_PARM_DESC(dst) \
+"Enable debug output to " dst ", where each bit enables a debug category.\n" \
+"\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n" \
+"\t\tBit 1 (0x02)  will enable DRIVER messages (drm controller code)\n" \
+"\t\tBit 2 (0x04)  will enable KMS messages (modesetting code)\n" \
+"\t\tBit 3 (0x08)  will enable PRIME messages (prime code)\n" \
+"\t\tBit 4 (0x10)  will enable ATOMIC messages (atomic code)\n" \
+"\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n" \
+"\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n" \
+"\t\tBit 8 (0x100) will enable DP messages (displayport code)"
+
+MODULE_PARM_DESC(debug, DEBUG_PARM_DESC("syslog"));
 module_param_named(debug, __drm_debug_syslog, int, 0600);
 
+MODULE_PARM_DESC(trace, DEBUG_PARM_DESC("tracefs"));
+module_param_named(trace, __drm_debug_trace, int, 0600);
+
+#ifdef CONFIG_TRACING
+struct trace_array *trace_arr;
+#endif
+
 void __drm_puts_coredump(struct drm_printer *p, const char *str)
 {
struct drm_print_iterator *iterator = 

[RESEND PATCH v6 13/14] drm/atomic: Use debug category printer for atomic state printer

2021-07-21 Thread Sean Paul
From: Sean Paul 

The atomic state is printed if the DRM_UT_STATE is active, but it's
printed at INFO level. This patch converts it to use the debug
category printer so:

a- it's consistent with other DRM_UT_STATE logging
b- it's properly routed through drm_trace when introduced

Signed-off-by: Sean Paul 

Changes in v6:
-Added to the set
---
 drivers/gpu/drm/drm_atomic_uapi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 7e48d40600ff..7615ded60195 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1322,7 +1322,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
struct drm_out_fence_state *fence_state;
int ret = 0;
unsigned int i, j, num_fences;
-   struct drm_printer p = drm_info_printer(dev->dev);
+   struct drm_printer p = drm_debug_category_printer(DRM_UT_STATE, 
"commit_state");
 
/* disallow for drivers not supporting atomic: */
if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[RESEND PATCH v6 12/14] drm/i915: Use debug category printer for welcome message

2021-07-21 Thread Sean Paul
From: Sean Paul 

The welcome printer is meant to be gated on DRM_UT_DRIVER, so use the
debug category printer to avoid dumping the message in the wrong
place.

Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-13-s...@poorly.run
 #v5

Changes in v5:
-Added to the set
Changes in v6:
-None
---
 drivers/gpu/drm/i915/i915_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index c43b698bf0b9..93299af1e853 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -731,7 +731,8 @@ static void i915_driver_unregister(struct drm_i915_private 
*dev_priv)
 static void i915_welcome_messages(struct drm_i915_private *dev_priv)
 {
if (drm_debug_enabled(DRM_UT_DRIVER)) {
-   struct drm_printer p = drm_debug_printer("i915 device info:");
+   struct drm_printer p = drm_debug_category_printer(DRM_UT_DRIVER,
+   "i915 device info:");
 
drm_printf(, "pciid=0x%04x rev=0x%02x platform=%s 
(subplatform=0x%x) gen=%i\n",
   INTEL_DEVID(dev_priv),
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[RESEND PATCH v6 11/14] drm/mst: Convert debug printers to debug category printers

2021-07-21 Thread Sean Paul
From: Sean Paul 

The printers in dp_mst are meant to be gated on DRM_UT_DP, so use the
debug category printer to avoid dumping mst transactions to the wrong
place.

Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-12-s...@poorly.run
 #v5

Changes in v5:
-Added to the set
Changes in v6:
-None
Reviewed-by: Lyude Paul 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..b1dddecad4c6 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1356,7 +1356,8 @@ static int drm_dp_mst_wait_tx_reply(struct 
drm_dp_mst_branch *mstb,
}
 out:
if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) {
-   struct drm_printer p = drm_debug_printer(DBG_PREFIX);
+   struct drm_printer p = drm_debug_category_printer(DRM_UT_DP,
+ DBG_PREFIX);
 
drm_dp_mst_dump_sideband_msg_tx(, txmsg);
}
@@ -2873,7 +2874,8 @@ static int process_single_tx_qlock(struct 
drm_dp_mst_topology_mgr *mgr,
 
ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx);
if (unlikely(ret) && drm_debug_enabled(DRM_UT_DP)) {
-   struct drm_printer p = drm_debug_printer(DBG_PREFIX);
+   struct drm_printer p = drm_debug_category_printer(DRM_UT_DP,
+ DBG_PREFIX);
 
drm_printf(, "sideband msg failed to send\n");
drm_dp_mst_dump_sideband_msg_tx(, txmsg);
@@ -2917,7 +2919,8 @@ static void drm_dp_queue_down_tx(struct 
drm_dp_mst_topology_mgr *mgr,
list_add_tail(>next, >tx_msg_downq);
 
if (drm_debug_enabled(DRM_UT_DP)) {
-   struct drm_printer p = drm_debug_printer(DBG_PREFIX);
+   struct drm_printer p = drm_debug_category_printer(DRM_UT_DP,
+ DBG_PREFIX);
 
drm_dp_mst_dump_sideband_msg_tx(, txmsg);
}
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[RESEND PATCH v6 10/14] drm/print: Add drm_debug_category_printer

2021-07-21 Thread Sean Paul
From: Sean Paul 

This patch adds a new printer which will select the appropriate output
for a given debug category. Currently there is only one output target,
which is syslog. However in the future we'll have tracefs and it will be
useful to print to syslog, tracefs, or both. Drivers just need to create
the printer for the appropriate category and the printer will decide
where to send the output.

Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-11-s...@poorly.run
 #v5

Changes in v5:
-Added to the set
Changes in v6:
-None
---
 drivers/gpu/drm/drm_print.c |  5 +
 include/drm/drm_print.h | 28 
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 2ff7a6ecc632..4d984a01b3a3 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -172,6 +172,11 @@ void __drm_printfn_err(struct drm_printer *p, struct 
va_format *vaf)
 }
 EXPORT_SYMBOL(__drm_printfn_err);
 
+void __drm_printfn_noop(struct drm_printer *p, struct va_format *vaf)
+{
+}
+EXPORT_SYMBOL(__drm_printfn_noop);
+
 /**
  * drm_puts - print a const string to a _printer stream
  * @p: the  printer
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 2ea0ffd9c1ce..af31beeb82a1 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -87,6 +87,7 @@ void __drm_puts_seq_file(struct drm_printer *p, const char 
*str);
 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_debug_syslog(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf);
+void __drm_printfn_noop(struct drm_printer *p, struct va_format *vaf);
 
 __printf(2, 3)
 void drm_printf(struct drm_printer *p, const char *f, ...);
@@ -329,6 +330,33 @@ static inline bool drm_debug_enabled(enum 
drm_debug_category category)
return drm_debug_syslog_enabled(category);
 }
 
+/**
+ * drm_debug_category_printer - construct a _printer that outputs to
+ * pr_debug() if enabled for the given category.
+ * @category: the DRM_UT_* message category this message belongs to
+ * @prefix: trace output prefix
+ *
+ * RETURNS:
+ * The _printer object
+ */
+static inline struct drm_printer
+drm_debug_category_printer(enum drm_debug_category category,
+  const char *prefix)
+{
+   struct drm_printer p = {
+   .prefix = prefix
+   };
+
+   if (drm_debug_syslog_enabled(category)) {
+   p.printfn = __drm_printfn_debug_syslog;
+   } else {
+   WARN(1, "Debug category %d is inactive.", category);
+   p.printfn = __drm_printfn_noop;
+   }
+
+   return p;
+}
+
 /*
  * struct device based logging
  *
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[RESEND PATCH v6 09/14] drm/i915: Change infoframe debug checks to specify syslog

2021-07-21 Thread Sean Paul
From: Sean Paul 

Since the logs protected by these checks specifically target syslog,
use the new drm_debug_syslog_enabled() call to avoid triggering
these prints when only trace is enabled.

Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-10-s...@poorly.run
 #v5

Changes in v5:
-Added to the set
Changes in v6:
-None
---
 drivers/gpu/drm/i915/display/intel_display.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 65ddb6ca16e6..048d7335196b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7494,7 +7494,7 @@ static void
 intel_dump_infoframe(struct drm_i915_private *dev_priv,
 const union hdmi_infoframe *frame)
 {
-   if (!drm_debug_enabled(DRM_UT_KMS))
+   if (!drm_debug_syslog_enabled(DRM_UT_KMS))
return;
 
hdmi_infoframe_log(KERN_DEBUG, dev_priv->drm.dev, frame);
@@ -8215,7 +8215,7 @@ pipe_config_infoframe_mismatch(struct drm_i915_private 
*dev_priv,
   const union hdmi_infoframe *b)
 {
if (fastset) {
-   if (!drm_debug_enabled(DRM_UT_KMS))
+   if (!drm_debug_syslog_enabled(DRM_UT_KMS))
return;
 
drm_dbg_kms(_priv->drm,
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[RESEND PATCH v6 08/14] drm/nouveau: Change debug checks to specifically target syslog

2021-07-21 Thread Sean Paul
From: Sean Paul 

Since the logs protected by these checks specifically target syslog,
use the new drm_debug_syslog_enabled() call to avoid triggering
these prints when only trace is enabled.

Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-9-s...@poorly.run
 #v5

Changes in v5:
-Added to the set
Changes in v6:
-Rebased on drm-tip, changes in dispnv50/disp.h were rebased out
---
 drivers/gpu/drm/nouveau/nouveau_drv.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index ba65f136cf48..2caa5720f451 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -260,11 +260,11 @@ void nouveau_drm_device_remove(struct drm_device *dev);
 #define NV_INFO(drm,f,a...) NV_PRINTK(info, &(drm)->client, f, ##a)
 
 #define NV_DEBUG(drm,f,a...) do {  
\
-   if (drm_debug_enabled(DRM_UT_DRIVER))  \
+   if (drm_debug_syslog_enabled(DRM_UT_DRIVER))
  \
NV_PRINTK(info, &(drm)->client, f, ##a);   \
 } while(0)
 #define NV_ATOMIC(drm,f,a...) do { 
\
-   if (drm_debug_enabled(DRM_UT_ATOMIC))  \
+   if (drm_debug_syslog_enabled(DRM_UT_ATOMIC))
  \
NV_PRINTK(info, &(drm)->client, f, ##a);   \
 } while(0)
 
-- 
Sean Paul, Software Engineer, Google / Chromium OS



  1   2   3   >