On Thu, 2017-08-31 at 13:24 +0800, Zhi Wang wrote: > Also I should send a register diff at that time (RFC -> PATCH). Suppose > these two patches should keep the used PPAT registers unchanged like before. I knew you were going to ask this and logs :) I will check tomorrow carefully since right now I don't have access to the machine. Sorry about that. > > On 08/31/17 13:22, Wang, Zhi A wrote: > > Thanks for the test! Sorry I didn't have an CNL on my hand. > > > > This is only RFC now. after collecting all the comments, I will start full test. :) > > > > Thanks, > > Zhi. > > > > -----Original Message----- > > From: Rodrigo Vivi [mailto:rodrigo.vivi@xxxxxxxxx] > > Sent: Thursday, August 31, 2017 8:15 AM > > To: Wang, Zhi A <zhi.a.wang@xxxxxxxxx> > > Cc: Vivi, Rodrigo <rodrigo.vivi@xxxxxxxxx>; intel-gfx@xxxxxxxxxxxxxxxxxxxxx; Widawsky, Benjamin <benjamin.widawsky@xxxxxxxxx>; intel-gvt-dev@xxxxxxxxxxxxxxxxxxxxx > > Subject: Re: [RFCv6 2/2] drm/i915: Introduce private PAT management > > > > On Wed, Aug 30, 2017 at 9:49 PM, Zhi Wang <zhi.a.wang@xxxxxxxxx> wrote: > >> Hi Vivi: > >> Thanks for the reply! The register are written in ppat->update_hw() now. > > oh, I saw now... > > I hadden noticed that interation. > > > > But something seems really odd yet... > > My CNL with these 2 patches applied hangs on any execution... > > > >> > >> +static void cnl_private_pat_update_hw(struct drm_i915_private > >> +*dev_priv) { > >> + struct intel_ppat *ppat = &dev_priv->ppat; > >> + int i; > >> + > >> + for_each_set_bit(i, ppat->dirty, ppat->max_entries) { > >> + I915_WRITE(GEN10_PAT_INDEX(i), ppat->entries[i].value); > >> + clear_bit(i, ppat->dirty); > >> + } > >> +} > >> + > >> +static void bdw_private_pat_update_hw(struct drm_i915_private > >> +*dev_priv) { > >> + struct intel_ppat *ppat = &dev_priv->ppat; > >> + u64 pat = 0; > >> + int i; > >> + > >> + for (i = 0; i < ppat->max_entries; i++) > >> + pat |= GEN8_PPAT(i, ppat->entries[i].value); > >> + > >> + bitmap_clear(ppat->dirty, 0, ppat->max_entries); > >> + > >> + I915_WRITE(GEN8_PRIVATE_PAT_LO, lower_32_bits(pat)); > >> + I915_WRITE(GEN8_PRIVATE_PAT_HI, upper_32_bits(pat)); } > >> > >> On 08/31/17 06:00, Vivi, Rodrigo wrote: > >>> On Wed, 2017-08-30 at 02:14 +0800, Zhi Wang wrote: > >>>> The private PAT management is to support PPAT entry manipulation. > >>>> Two APIs are introduced for dynamically managing PPAT entries: > >>>> intel_ppat_get and intel_ppat_put. > >>>> > >>>> intel_ppat_get will search for an existing PPAT entry which > >>>> perfectly matches the required PPAT value. If not, it will try to > >>>> allocate or return a partially matched PPAT entry if there is any > >>>> available PPAT indexes or not. > >>>> > >>>> intel_ppat_put will put back the PPAT entry which comes from > >>>> intel_ppat_get. If it's dynamically allocated, the reference count > >>>> will be decreased. If the reference count turns into zero, the PPAT > >>>> index is freed again. > >>>> > >>>> Besides, another two callbacks are introduced to support the private > >>>> PAT management framework. One is ppat->update_hw(), which writes the > >>>> PPAT configurations in ppat->entries into HW. Another one is > >>>> ppat->match, which will return a score to show how two PPAT values > >>>> match with each other. > >>>> > >>>> v6: > >>>> > >>>> - Address all comments from Chris: > >>>> http://www.spinics.net/lists/intel-gfx/msg136850.html > >>>> > >>>> - Address all comments from Joonas: > >>>> http://www.spinics.net/lists/intel-gfx/msg136845.html > >>>> > >>>> v5: > >>>> > >>>> - Add check and warnnings for those platforms which don't have PPAT. > >>>> > >>>> v3: > >>>> > >>>> - Introduce dirty bitmap for PPAT registers. (Chris) > >>>> - Change the name of the pointer "dev_priv" to "i915". (Chris) > >>>> - intel_ppat_{get, put} returns/takes a const intel_ppat_entry *. > >>>> (Chris) > >>>> > >>>> v2: > >>>> > >>>> - API re-design. (Chris) > >>>> > >>>> Cc: Ben Widawsky <benjamin.widawsky@xxxxxxxxx> > >>>> Cc: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> > >>>> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > >>>> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> > >>>> Signed-off-by: Zhi Wang <zhi.a.wang@xxxxxxxxx> > >>>> --- > >>>> drivers/gpu/drm/i915/i915_drv.h | 2 + > >>>> drivers/gpu/drm/i915/i915_gem_gtt.c | 273 > >>>> +++++++++++++++++++++++++++++------- > >>>> drivers/gpu/drm/i915/i915_gem_gtt.h | 36 +++++ > >>>> 3 files changed, 262 insertions(+), 49 deletions(-) > >>>> > >>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h > >>>> b/drivers/gpu/drm/i915/i915_drv.h index 7587ef5..5ffde10 100644 > >>>> --- a/drivers/gpu/drm/i915/i915_drv.h > >>>> +++ b/drivers/gpu/drm/i915/i915_drv.h > >>>> @@ -2312,6 +2312,8 @@ struct drm_i915_private { > >>>> DECLARE_HASHTABLE(mm_structs, 7); > >>>> struct mutex mm_lock; > >>>> + struct intel_ppat ppat; > >>>> + > >>>> /* Kernel Modesetting */ > >>>> struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; > >>>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c > >>>> b/drivers/gpu/drm/i915/i915_gem_gtt.c > >>>> index b74fa9d..3106142 100644 > >>>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c > >>>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c > >>>> @@ -2816,41 +2816,200 @@ static int ggtt_probe_common(struct > >>>> i915_ggtt *ggtt, u64 size) > >>>> return 0; > >>>> } > >>>> -static void cnl_setup_private_ppat(struct drm_i915_private > >>>> *dev_priv) > >>>> +static struct intel_ppat_entry * > >>>> +__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 > >>>> value) > >>>> { > >>>> + struct intel_ppat_entry *entry = &ppat->entries[index]; > >>>> + > >>>> + GEM_BUG_ON(index >= ppat->max_entries); > >>>> + GEM_BUG_ON(test_bit(index, ppat->used)); > >>>> + > >>>> + entry->ppat = ppat; > >>>> + entry->value = value; > >>>> + kref_init(&entry->ref); > >>>> + set_bit(index, ppat->used); > >>>> + set_bit(index, ppat->dirty); > >>>> + > >>>> + return entry; > >>>> +} > >>>> + > >>>> +static void __free_ppat_entry(struct intel_ppat_entry *entry) { > >>>> + struct intel_ppat *ppat = entry->ppat; > >>>> + unsigned int index = entry - ppat->entries; > >>>> + > >>>> + GEM_BUG_ON(index >= ppat->max_entries); > >>>> + GEM_BUG_ON(!test_bit(index, ppat->used)); > >>>> + > >>>> + entry->value = ppat->clear_value; > >>>> + clear_bit(index, ppat->used); > >>>> + set_bit(index, ppat->dirty); } > >>>> + > >>>> +/** > >>>> + * intel_ppat_get - get a usable PPAT entry > >>>> + * @i915: i915 device instance > >>>> + * @value: the PPAT value required by the caller > >>>> + * > >>>> + * The function tries to search if there is an existing PPAT entry > >>>> +which > >>>> + * matches with the required value. If perfectly matched, the > >>>> +existing > >>>> PPAT > >>>> + * entry will be used. If only partially matched, it will try to > >>>> + check > >>>> if > >>>> + * there is any available PPAT index. If yes, it will allocate a > >>>> + new > >>>> PPAT > >>>> + * index for the required entry and update the HW. If not, the > >>>> +partially > >>>> + * matched entry will be used. > >>>> + */ > >>>> +const struct intel_ppat_entry * > >>>> +intel_ppat_get(struct drm_i915_private *i915, u8 value) { > >>>> + struct intel_ppat *ppat = &i915->ppat; > >>>> + struct intel_ppat_entry *entry; > >>>> + unsigned int scanned, best_score; > >>>> + int i; > >>>> + > >>>> + GEM_BUG_ON(!ppat->max_entries); > >>>> + > >>>> + scanned = best_score = 0; > >>>> + > >>>> + for_each_set_bit(i, ppat->used, ppat->max_entries) { > >>>> + unsigned int score; > >>>> + > >>>> + entry = &ppat->entries[i]; > >>>> + score = ppat->match(entry->value, value); > >>>> + if (score > best_score) { > >>>> + if (score == INTEL_PPAT_PERFECT_MATCH) { > >>>> + kref_get(&entry->ref); > >>>> + return entry; > >>>> + } > >>>> + best_score = score; > >>>> + } > >>>> + scanned++; > >>>> + } > >>>> + > >>>> + if (scanned == ppat->max_entries) { > >>>> + if (!best_score) > >>>> + return ERR_PTR(-ENOSPC); > >>>> + > >>>> + kref_get(&entry->ref); > >>>> + return entry; > >>>> + } > >>>> + > >>>> + i = find_first_zero_bit(ppat->used, ppat->max_entries); > >>>> + entry = __alloc_ppat_entry(ppat, i, value); > >>>> + ppat->update_hw(i915); > >>>> + return entry; > >>>> +} > >>>> + > >>>> +static void release_ppat(struct kref *kref) { > >>>> + struct intel_ppat_entry *entry = > >>>> + container_of(kref, struct intel_ppat_entry, ref); > >>>> + struct drm_i915_private *i915 = entry->ppat->i915; > >>>> + > >>>> + __free_ppat_entry(entry); > >>>> + entry->ppat->update_hw(i915); } > >>>> + > >>>> +/** > >>>> + * intel_ppat_put - put back the PPAT entry got from > >>>> +intel_ppat_get() > >>>> + * @entry: an intel PPAT entry > >>>> + * > >>>> + * Put back the PPAT entry got from intel_ppat_get(). If the PPAT > >>>> +index > >>>> of the > >>>> + * entry is dynamically allocated, its reference count will be > >>>> decreased. Once > >>>> + * the reference count becomes into zero, the PPAT index becomes > >>>> + free > >>>> again. > >>>> + */ > >>>> +void intel_ppat_put(const struct intel_ppat_entry *entry) { > >>>> + struct intel_ppat *ppat = entry->ppat; > >>>> + unsigned int index = entry - ppat->entries; > >>>> + > >>>> + GEM_BUG_ON(!ppat->max_entries); > >>>> + > >>>> + kref_put(&ppat->entries[index].ref, release_ppat); } > >>>> + > >>>> +static void cnl_private_pat_update_hw(struct drm_i915_private > >>>> +*dev_priv) { > >>>> + struct intel_ppat *ppat = &dev_priv->ppat; > >>>> + int i; > >>>> + > >>>> + for_each_set_bit(i, ppat->dirty, ppat->max_entries) { > >>>> + I915_WRITE(GEN10_PAT_INDEX(i), ppat->entries[i].value); > >>>> + clear_bit(i, ppat->dirty); > >>>> + } > >>>> +} > >>>> + > >>>> +static void bdw_private_pat_update_hw(struct drm_i915_private > >>>> +*dev_priv) { > >>>> + struct intel_ppat *ppat = &dev_priv->ppat; > >>>> + u64 pat = 0; > >>>> + int i; > >>>> + > >>>> + for (i = 0; i < ppat->max_entries; i++) > >>>> + pat |= GEN8_PPAT(i, ppat->entries[i].value); > >>>> + > >>>> + bitmap_clear(ppat->dirty, 0, ppat->max_entries); > >>>> + > >>>> + I915_WRITE(GEN8_PRIVATE_PAT_LO, lower_32_bits(pat)); > >>>> + I915_WRITE(GEN8_PRIVATE_PAT_HI, upper_32_bits(pat)); } > >>>> + > >>>> +static unsigned int bdw_private_pat_match(u8 src, u8 dst) { > >>>> + unsigned int score = 0; > >>>> + > >>>> + /* Cache attribute has to be matched. */ > >>>> + if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst)) > >>>> + return 0; > >>>> + > >>>> + if (GEN8_PPAT_GET_TC(src) == GEN8_PPAT_GET_TC(dst)) > >>>> + score += 2; > >>>> + > >>>> + if(GEN8_PPAT_GET_AGE(src) == GEN8_PPAT_GET_AGE(dst)) > >>>> + score += 1; > >>>> + > >>>> + if (score == 3) > >>>> + return INTEL_PPAT_PERFECT_MATCH; > >>>> + > >>>> + return score; > >>>> +} > >>>> + > >>>> +static unsigned int chv_private_pat_match(u8 src, u8 dst) { > >>>> + return (CHV_PPAT_GET_SNOOP(src) == CHV_PPAT_GET_SNOOP(dst)) ? > >>>> + INTEL_PPAT_PERFECT_MATCH : 0; } > >>>> + > >>>> +static void cnl_setup_private_ppat(struct intel_ppat *ppat) { > >>>> + ppat->max_entries = 8; > >>>> + ppat->update_hw = cnl_private_pat_update_hw; > >>>> + ppat->match = bdw_private_pat_match; > >>>> + ppat->clear_value = GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); > >>>> + > >>>> /* XXX: spec is unclear if this is still needed for CNL+ */ > >>>> - if (!USES_PPGTT(dev_priv)) { > >>>> - I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_UC); > >>>> + if (!USES_PPGTT(ppat->i915)) { > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_PDE_INDEX, > >>>> GEN8_PPAT_UC); > >>>> return; > >>>> } > >>>> - I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_WB | GEN8_PPAT_LLC); > >>>> - I915_WRITE(GEN10_PAT_INDEX(1), GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); > >>>> - I915_WRITE(GEN10_PAT_INDEX(2), GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); > >>>> - I915_WRITE(GEN10_PAT_INDEX(3), GEN8_PPAT_UC); > >>>> - I915_WRITE(GEN10_PAT_INDEX(4), GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(0)); > >>>> - I915_WRITE(GEN10_PAT_INDEX(5), GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(1)); > >>>> - I915_WRITE(GEN10_PAT_INDEX(6), GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(2)); > >>>> - I915_WRITE(GEN10_PAT_INDEX(7), GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(3)); > >>> > >>> Gen8 allocation style doesn't work on CNL. > >>> I don't see where all these registers would be getting properly written. > >>> > >>>> + /* See gen8_pte_encode() for the mapping from cache-level to > >>>> + PPAT > >>>> */ > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_PDE_INDEX, GEN8_PPAT_WB > >>>> + | > >>>> GEN8_PPAT_LLC); > >>>> + __alloc_ppat_entry(ppat, PPAT_DISPLAY_ELLC_INDEX, > >>>> + GEN8_PPAT_WT | > >>>> GEN8_PPAT_LLCELLC); > >>>> + __alloc_ppat_entry(ppat, PPAT_UNCACHED_INDEX, GEN8_PPAT_UC); > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_INDEX, > >>>> + GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(0)); > >>>> } > >>>> /* The GGTT and PPGTT need a private PPAT setup in order to > >>>> handle cacheability > >>>> * bits. When using advanced contexts each context stores its own > >>>> PAT, but > >>>> * writing this data shouldn't be harmful even in those cases. */ > >>>> -static void bdw_setup_private_ppat(struct drm_i915_private > >>>> *dev_priv) > >>>> +static void bdw_setup_private_ppat(struct intel_ppat *ppat) > >>>> { > >>>> - u64 pat; > >>>> + ppat->max_entries = 8; > >>>> + ppat->update_hw = bdw_private_pat_update_hw; > >>>> + ppat->match = bdw_private_pat_match; > >>>> + ppat->clear_value = GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(3); > >>>> - pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for > >>>> normal objects, no eLLC */ > >>>> - GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for > >>>> something pointing to ptes? */ > >>>> - GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for > >>>> scanout with eLLC */ > >>>> - GEN8_PPAT(3, GEN8_PPAT_UC) | /* > >>>> Uncached objects, mostly for scanout */ > >>>> - GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(0)) | > >>>> - GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(1)) | > >>>> - GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(2)) | > >>>> - GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | > >>>> GEN8_PPAT_AGE(3)); > >>>> - > >>>> - if (!USES_PPGTT(dev_priv)) > >>>> + if (!USES_PPGTT(ppat->i915)) { > >>>> /* Spec: "For GGTT, there is NO pat_sel[2:0] from > >>>> the entry, > >>>> * so RTL will always use the value corresponding to > >>>> * pat_sel = 000". > >>>> @@ -2864,17 +3023,26 @@ static void bdw_setup_private_ppat(struct > >>>> drm_i915_private *dev_priv) > >>>> * So we can still hold onto all our assumptions wrt cpu > >>>> * clflushing on LLC machines. > >>>> */ > >>>> - pat = GEN8_PPAT(0, GEN8_PPAT_UC); > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_PDE_INDEX, > >>>> GEN8_PPAT_UC); > >>>> + return; > >>>> + } > >>>> - /* XXX: spec defines this as 2 distinct registers. It's unclear > >>>> if a 64b > >>>> - * write would work. */ > >>>> - I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); > >>>> - I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); > >>>> + /* See gen8_pte_encode() for the mapping from cache-level to > >>>> + PPAT > >>>> */ > >>>> + /* for normal objects, no eLLC */ > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_PDE_INDEX, GEN8_PPAT_WB > >>>> + | > >>>> GEN8_PPAT_LLC); > >>>> + /* for scanout with eLLC */ > >>>> + __alloc_ppat_entry(ppat, PPAT_DISPLAY_ELLC_INDEX, > >>>> + GEN8_PPAT_WT | > >>>> GEN8_PPAT_LLCELLC); > >>>> + /* Uncached objects, mostly for scanout */ > >>>> + __alloc_ppat_entry(ppat, PPAT_UNCACHED_INDEX, GEN8_PPAT_UC); > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_INDEX, GEN8_PPAT_WB | > >>>> GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)); > >>>> } > >>>> -static void chv_setup_private_ppat(struct drm_i915_private > >>>> *dev_priv) > >>>> +static void chv_setup_private_ppat(struct intel_ppat *ppat) > >>>> { > >>>> - u64 pat; > >>>> + ppat->max_entries = 8; > >>>> + ppat->update_hw = bdw_private_pat_update_hw; > >>>> + ppat->match = chv_private_pat_match; > >>>> + ppat->clear_value = CHV_PPAT_SNOOP; > >>>> /* > >>>> * Map WB on BDW to snooped on CHV. > >>>> @@ -2894,17 +3062,12 @@ static void chv_setup_private_ppat(struct > >>>> drm_i915_private *dev_priv) > >>>> * Which means we must set the snoop bit in PAT entry 0 > >>>> * in order to keep the global status page working. > >>>> */ > >>>> - pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) | > >>>> - GEN8_PPAT(1, 0) | > >>>> - GEN8_PPAT(2, 0) | > >>>> - GEN8_PPAT(3, 0) | > >>>> - GEN8_PPAT(4, CHV_PPAT_SNOOP) | > >>>> - GEN8_PPAT(5, CHV_PPAT_SNOOP) | > >>>> - GEN8_PPAT(6, CHV_PPAT_SNOOP) | > >>>> - GEN8_PPAT(7, CHV_PPAT_SNOOP); > >>>> - I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); > >>>> - I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); > >>>> + /* See gen8_pte_encode() for the mapping from cache-level to > >>>> + PPAT > >>>> */ > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_PDE_INDEX, CHV_PPAT_SNOOP); > >>>> + __alloc_ppat_entry(ppat, PPAT_DISPLAY_ELLC_INDEX, 0); > >>>> + __alloc_ppat_entry(ppat, PPAT_UNCACHED_INDEX, 0); > >>>> + __alloc_ppat_entry(ppat, PPAT_CACHED_INDEX, CHV_PPAT_SNOOP); > >>>> } > >>>> static void gen6_gmch_remove(struct i915_address_space *vm) @@ > >>>> -2917,12 +3080,27 @@ static void gen6_gmch_remove(struct > >>>> i915_address_space *vm) > >>>> static void setup_private_pat(struct drm_i915_private *dev_priv) > >>>> { > >>>> + struct intel_ppat *ppat = &dev_priv->ppat; > >>>> + int i; > >>>> + > >>>> + ppat->i915 = dev_priv; > >>>> + > >>>> if (INTEL_GEN(dev_priv) >= 10) > >>>> - cnl_setup_private_ppat(dev_priv); > >>>> + cnl_setup_private_ppat(ppat); > >>>> else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) > >>>> - chv_setup_private_ppat(dev_priv); > >>>> + chv_setup_private_ppat(ppat); > >>>> else > >>>> - bdw_setup_private_ppat(dev_priv); > >>>> + bdw_setup_private_ppat(ppat); > >>>> + > >>>> + GEM_BUG_ON(ppat->max_entries > INTEL_MAX_PPAT_ENTRIES); > >>>> + > >>>> + for_each_clear_bit(i, ppat->used, ppat->max_entries) { > >>>> + ppat->entries[i].value = ppat->clear_value; > >>>> + ppat->entries[i].ppat = ppat; > >>>> + set_bit(i, ppat->dirty); > >>>> + } > >>>> + > >>>> + ppat->update_hw(dev_priv); > >>>> } > >>>> static int gen8_gmch_probe(struct i915_ggtt *ggtt) @@ -3236,13 > >>>> +3414,10 @@ void i915_gem_restore_gtt_mappings(struct > >>>> drm_i915_private *dev_priv) > >>>> ggtt->base.closed = false; > >>>> if (INTEL_GEN(dev_priv) >= 8) { > >>>> - if (INTEL_GEN(dev_priv) >= 10) > >>>> - cnl_setup_private_ppat(dev_priv); > >>>> - else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) > >>>> - chv_setup_private_ppat(dev_priv); > >>>> - else > >>>> - bdw_setup_private_ppat(dev_priv); > >>>> + struct intel_ppat *ppat = &dev_priv->ppat; > >>>> + bitmap_set(ppat->dirty, 0, ppat->max_entries); > >>>> + dev_priv->ppat.update_hw(dev_priv); > >>>> return; > >>>> } > >>>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h > >>>> b/drivers/gpu/drm/i915/i915_gem_gtt.h > >>>> index b4e3aa7..e10ca89 100644 > >>>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h > >>>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h > >>>> @@ -143,6 +143,11 @@ typedef u64 gen8_ppgtt_pml4e_t; > >>>> #define GEN8_PPAT_ELLC_OVERRIDE (0<<2) > >>>> #define GEN8_PPAT(i, x) ((u64)(x) << ((i) * 8)) > >>>> +#define GEN8_PPAT_GET_CA(x) ((x) & 3) > >>>> +#define GEN8_PPAT_GET_TC(x) ((x) & (3 << 2)) #define > >>>> +GEN8_PPAT_GET_AGE(x) ((x) & (3 << 4)) #define CHV_PPAT_GET_SNOOP(x) > >>>> +((x) & (1 << 6)) > >>>> + > >>>> struct sg_table; > >>>> struct intel_rotation_info { > >>>> @@ -536,6 +541,37 @@ i915_vm_to_ggtt(struct i915_address_space *vm) > >>>> return container_of(vm, struct i915_ggtt, base); > >>>> } > >>>> +#define INTEL_MAX_PPAT_ENTRIES 8 > >>>> +#define INTEL_PPAT_PERFECT_MATCH (~0U) > >>>> + > >>>> +struct intel_ppat; > >>>> + > >>>> +struct intel_ppat_entry { > >>>> + struct intel_ppat *ppat; > >>>> + struct kref ref; > >>>> + u8 value; > >>>> +}; > >>>> + > >>>> +struct intel_ppat { > >>>> + struct intel_ppat_entry entries[INTEL_MAX_PPAT_ENTRIES]; > >>>> + DECLARE_BITMAP(used, INTEL_MAX_PPAT_ENTRIES); > >>>> + DECLARE_BITMAP(dirty, INTEL_MAX_PPAT_ENTRIES); > >>>> + unsigned int max_entries; > >>>> + u8 clear_value; > >>>> + /* > >>>> + * Return a score to show how two PPAT values match, > >>>> + * a INTEL_PPAT_PERFECT_MATCH indicates a perfect match > >>>> + */ > >>>> + unsigned int (*match)(u8 src, u8 dst); > >>>> + void (*update_hw)(struct drm_i915_private *i915); > >>>> + > >>>> + struct drm_i915_private *i915; }; > >>>> + > >>>> +const struct intel_ppat_entry * > >>>> +intel_ppat_get(struct drm_i915_private *i915, u8 value); void > >>>> +intel_ppat_put(const struct intel_ppat_entry *entry); > >>>> + > >>>> int i915_gem_init_aliasing_ppgtt(struct drm_i915_private *i915); > >>>> void i915_gem_fini_aliasing_ppgtt(struct drm_i915_private *i915); > >>>> > >>> > >> _______________________________________________ > >> Intel-gfx mailing list > >> Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx > > > > > > -- > > Rodrigo Vivi > > Blog: http://blog.vivi.eng.br > _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx