On 2017.08.16 05:31:10 +0800, Zhi Wang wrote: > This patch introduces private PAT operations for GEN8. > > The "get_pat_value" operation offers an API to get a PPAT entry from the > virtual or physical PPAT MMIO registers. Similar with the "get_pat_value", > the "set_pat_value" operation offers the API to write a PPAT entry back to > PPAT MMIO registers. The caller doesn't need to care about the PPAT MMIO > layout, since the layout is different between different GENs. > > The "match_pat_value" will try to compare two PAT entries and give a score > to indicate how perfect they match with each other. The most important > attribute is "cache attribute", which affects the correctness and has to > be matched. Other attributes gain different scores by the their > importance in a partial match. > > Signed-off-by: Zhi Wang <zhi.a.wang@xxxxxxxxx> > --- > drivers/gpu/drm/i915/gvt/gtt.c | 81 ++++++++++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/i915/gvt/gtt.h | 9 +++++ > 2 files changed, 90 insertions(+) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index e6dfc33..16bfca9 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -402,6 +402,80 @@ DEFINE_PPGTT_GMA_TO_INDEX(gen8, l3_pdp, (gma >> 30 & 0x3)); > DEFINE_PPGTT_GMA_TO_INDEX(gen8, l4_pdp, (gma >> 30 & 0x1ff)); > DEFINE_PPGTT_GMA_TO_INDEX(gen8, pml4, (gma >> 39 & 0x1ff)); > > +static unsigned int gen8_pat_get_value(u32 *mem, unsigned int index, > + struct intel_gvt *gvt) > +{ > + struct drm_i915_private *dev_priv = gvt->dev_priv; > + int reg_index = index / 4; > + u32 buf[2]; > + > + if (WARN_ON(reg_index >= 2)) > + return 0; > + > + if (!mem) { > + mem = buf; > + mem[reg_index] = reg_index ? I915_READ(GEN8_PRIVATE_PAT_HI) : > + I915_READ(GEN8_PRIVATE_PAT_LO); > + } > + > + index -= reg_index * 4; > + return (mem[reg_index] >> (index * 8)) & 0x3f; > +} > + > +static void gen8_pat_set_value(u32 *mem, unsigned int index, unsigned int value, > + struct intel_gvt *gvt) > +{ > + struct drm_i915_private *dev_priv = gvt->dev_priv; > + int reg_index = index / 4; > + u32 buf[2]; > + bool writeback = false; > + > + if (WARN_ON(reg_index >= 2)) > + return; > + > + if (!mem) { > + mem = buf; > + writeback = true; > + mem[reg_index] = reg_index ? I915_READ(GEN8_PRIVATE_PAT_HI) : > + I915_READ(GEN8_PRIVATE_PAT_LO); > + } > + > + index -= reg_index * 4; > + > + mem[reg_index] &= ~(0xff << (index * 8)); > + mem[reg_index] |= ((value & 0x3f) << (index * 8)); > + > + if (writeback) { > + if (reg_index) > + I915_WRITE(GEN8_PRIVATE_PAT_LO, mem[1]); > + else > + I915_WRITE(GEN8_PRIVATE_PAT_LO, mem[0]); > + } > +} Make sure you get runtime pm for mmio. > + > +#define gen8_pat_ca(v) ((v) & 0x3) > +#define gen8_pat_tc(v) ((v) >> 2 & 0x3) > +#define gen8_pat_age(v) ((v) >> 4 & 0x3) > + > +static unsigned int gen8_pat_match_value(unsigned int src, unsigned int dst) > +{ > + unsigned int score = 0; > + > + if (gen8_pat_ca(src) != gen8_pat_ca(dst)) > + return 0; > + > + if (gen8_pat_age(src) == gen8_pat_age(dst)) > + score += 1; > + > + if (gen8_pat_tc(src) == gen8_pat_tc(dst)) > + score += 2; Can define more bits on age/target score to count for more precision. > + > + if (score == 3) > + return ~0; > + > + return score; > +} > + > static struct intel_gvt_gtt_pte_ops gen8_gtt_pte_ops = { > .get_entry = gtt_get_entry64, > .set_entry = gtt_set_entry64, > @@ -421,6 +495,12 @@ static struct intel_gvt_gtt_gma_ops gen8_gtt_gma_ops = { > .gma_to_pml4_index = gen8_gma_to_pml4_index, > }; > > +static struct intel_gvt_gtt_pat_ops gen8_pat_ops = { > + .get_pat_value = gen8_pat_get_value, > + .set_pat_value = gen8_pat_set_value, > + .match_pat_value = gen8_pat_match_value, > +}; > + > static int gtt_entry_p2m(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *p, > struct intel_gvt_gtt_entry *m) > { > @@ -2267,6 +2347,7 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) > || IS_KABYLAKE(gvt->dev_priv)) { > gvt->gtt.pte_ops = &gen8_gtt_pte_ops; > gvt->gtt.gma_ops = &gen8_gtt_gma_ops; > + gvt->gtt.pat_ops = &gen8_pat_ops; > gvt->gtt.mm_alloc_page_table = gen8_mm_alloc_page_table; > gvt->gtt.mm_free_page_table = gen8_mm_free_page_table; > } else { > diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h > index 30a4c8d..7a9eb05 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.h > +++ b/drivers/gpu/drm/i915/gvt/gtt.h > @@ -77,9 +77,18 @@ struct intel_gvt_gtt_gma_ops { > unsigned long (*gma_to_pml4_index)(unsigned long gma); > }; > > +struct intel_gvt_gtt_pat_ops { > + unsigned int (*get_pat_value)(u32 *mem, unsigned int index, > + struct intel_gvt *gvt); > + void (*set_pat_value)(u32 *mem, unsigned int index, unsigned int value, > + struct intel_gvt *gvt); > + unsigned int (*match_pat_value)(unsigned int src, unsigned int dst); > +}; > + > struct intel_gvt_gtt { > struct intel_gvt_gtt_pte_ops *pte_ops; > struct intel_gvt_gtt_gma_ops *gma_ops; > + struct intel_gvt_gtt_pat_ops *pat_ops; > int (*mm_alloc_page_table)(struct intel_vgpu_mm *mm); > void (*mm_free_page_table)(struct intel_vgpu_mm *mm); > struct list_head oos_page_use_list_head; > -- > 2.7.4 > > _______________________________________________ > intel-gvt-dev mailing list > intel-gvt-dev@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev -- Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx