On Tue, Nov 05, 2013 at 07:00:14AM +0000, Ramakutty, SandeepX wrote: > Hi Ville, > > Thanks for the information. Here MI_LOAD_REGISTER_IMM is used and not > MI_LOAD_REGISTER_MEM. Is SRM needed after MI_LOAD_REGISTER_IMM? BSpec for > MI_LOAD_REGISTER_IMM does not mention any thing about using SRM, but it is > there for MI_LOAD_REGISTER_MEM.
Just checked BSpec and it's still there: "Limited LRI cycles to the Display Engine 0x40000-0xBFFFF) are allowed, but must be spaced to allow only one pending at a time. This can be done by issuing an SRM to the same address immediately after each LRI." > > Regards, > Sandeep > > -----Original Message----- > From: Ville Syrjälä [mailto:ville.syrj...@linux.intel.com] > Sent: Thursday, October 31, 2013 5:54 PM > To: Ramakutty, SandeepX > Cc: intel-gfx@lists.freedesktop.org > Subject: Re: [Intel-gfx] [PATCH] drm/i915: Add support to change pixel > format, tiling mode, tiling offset. > > On Thu, Oct 31, 2013 at 12:15:17PM +0000, Ramakutty, SandeepX wrote: > > Hi Ville , > > > > Thanks for the feedback. > > > > We verified without updating watermarks and found that the video playback, > > 3DMark and GLBenchmark plays fine. There was no underrun error too. > > Cases tried out- > > Pixel format changed to 32BPP when water mark calculated based on > > 16BPP Pixel format changed to 16BPP when water mark calculated based on > > 32BPP. > > > > In both cases, we verified with video playback, 3DMark and GLBenchmark and > > did not see any underrun error. Is there any specific situations in which > > not setting WM can throw up an issue? > > > > With MMIO there may be a possibility of flickering. The pixel format may be > > updated well before a page flip. With MMIO, the format will be written to > > register before a page flip and this can cause unwanted effects. Hence we > > used MI commands as this will get updated much nearer to a page flip. > > > > What is SRM? > > "store register mem". It reads the register and stores the result to memory. > > BSpec tells us that there can only be one outstanding LRI targeted at the > display registers at any given. So you need to do LRI+SRM for every display > register you want to write w/ LRI. > > > > > Regards, > > Sandeep > > > > -----Original Message----- > > From: Ville Syrjälä [mailto:ville.syrj...@linux.intel.com] > > Sent: Friday, September 13, 2013 7:56 PM > > To: Ramakutty, SandeepX > > Cc: intel-gfx@lists.freedesktop.org > > Subject: Re: [Intel-gfx] [PATCH] drm/i915: Add support to change pixel > > format, tiling mode, tiling offset. > > > > On Fri, Sep 13, 2013 at 07:05:31PM +0530, Sandeep Ramankutty wrote: > > > Change: Add support to change the pixel format, base surface > > > address, tiling mode, tiling offset on the flow during the primary plane > > > flip. > > > > > > Issue: This support is needed by hardware composer to meet the > > > performance optimization requirement for 3D benchmark. This patch > > > enables change in pixel format and tiling params without adding and > > > removing the framebuffer. > > > Adding and removing the framebuffer impacts performance. > > > > We can't do it quite like this unfortunately. Watermarksm may need to be > > updated carefully if the bpp changes. Also updating multiple plane > > registers isn't always atomic, so we anyway need the vblank evade tricks to > > make it look pretty. I suppose it might be possible to make all that work > > via the ring, but my plan is to go for MMIO, and later investigate if we > > can optimize it by using the ring. > > > > As far as the lowlevel details go, you supposedly need a SRM after each LRI > > aimed at the display registers. Otherwise I guess you could even blast all > > the registers with a single LRI. > > > > > Change Details- > > > drm: Defined function pointer set_pixelformat in drm_crtc_funcs. > > > drm_crtc.c is modified to execute the function to update pixel format. > > > drm/i915: intel_crtc_set_pixel_format() implemented in i915 driver > > > code (intel_display.c) and set to drm_crtc_funcs->set_pixelformat. > > > haswell_set_pixelformat() implemented to update pixel format. This > > > is specific to Haswell > > > haswell_update_plane() implemented to update changes in tiling > > > offset, surface base address and stride-fb->pitches[0]. Sends MI > > > command to update the params in primary plane control registers. > > > > > > Change-Id: I4b0af83f641b2b79ee4f5c3401790d7d90ccd9ef > > > Signed-off-by: Pallavi G <pallav...@intel.com> > > > Signed-off-by: Sandeep Ramakutty <sandeepx.ramaku...@intel.com> > > > --- > > > drivers/gpu/drm/drm_crtc.c | 15 +++- > > > drivers/gpu/drm/i915/intel_display.c | 156 > > > ++++++++++++++++++++++++++++++++++ > > > include/drm/drm_crtc.h | 8 ++ > > > 3 files changed, 176 insertions(+), 3 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > > > index c9f9f3d..4739b6c 100644 > > > --- a/drivers/gpu/drm/drm_crtc.c > > > +++ b/drivers/gpu/drm/drm_crtc.c > > > @@ -3518,9 +3518,18 @@ int drm_mode_page_flip_ioctl(struct drm_device > > > *dev, > > > } > > > > > > if (crtc->fb->pixel_format != fb->pixel_format) { > > > - DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer > > > format.\n"); > > > - ret = -EINVAL; > > > - goto out; > > > + if (crtc->funcs->set_pixelformat == NULL) { > > > + DRM_DEBUG_KMS("Pixel format change not allowed"); > > > + ret = -EINVAL; > > > + goto out; > > > + } > > > + /* supports dynamic change in pixel format */ > > > + ret = crtc->funcs->set_pixelformat(crtc, fb->pixel_format); > > > + if (ret) { > > > + DRM_DEBUG_KMS("Pixel format change failed %d", > > > + fb->pixel_format); > > > + goto out; > > > + } > > > } > > > > > > if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { diff --git > > > a/drivers/gpu/drm/i915/intel_display.c > > > b/drivers/gpu/drm/i915/intel_display.c > > > index 955df91..7bfe088 100644 > > > --- a/drivers/gpu/drm/i915/intel_display.c > > > +++ b/drivers/gpu/drm/i915/intel_display.c > > > @@ -45,6 +45,7 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, > > > int type); static void intel_increase_pllclock(struct drm_crtc > > > *crtc); static void intel_crtc_update_cursor(struct drm_crtc *crtc, > > > bool on); > > > > > > + > > > typedef struct { > > > int min, max; > > > } intel_range_t; > > > @@ -1959,6 +1960,128 @@ static int i9xx_update_plane(struct drm_crtc > > > *crtc, struct drm_framebuffer *fb, > > > return 0; > > > } > > > > > > +/* Set Pixel format for Haswell using MI commands */ static int > > > +haswell_set_pixelformat(struct drm_crtc *crtc, u32 pixel_format) { > > > + u32 dspcntr, reg; > > > + struct drm_device *dev = crtc->dev; > > > + struct drm_i915_private *dev_priv = dev->dev_private; > > > + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); > > > + struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; > > > + int ret = 0; > > > + > > > + reg = DSPCNTR(intel_crtc->pipe); > > > + dspcntr = I915_READ(reg); > > > + DRM_DEBUG_DRIVER("pixel format = %d\n", pixel_format); > > > + /* Mask out pixel format bits in case we change it */ > > > + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; > > > + switch (pixel_format) { > > > + case DRM_FORMAT_C8: > > > + dspcntr |= DISPPLANE_8BPP; > > > + break; > > > + case DRM_FORMAT_XRGB1555: > > > + case DRM_FORMAT_ARGB1555: > > > + dspcntr |= DISPPLANE_BGRX555; > > > + break; > > > + case DRM_FORMAT_RGB565: > > > + dspcntr |= DISPPLANE_BGRX565; > > > + break; > > > + case DRM_FORMAT_XRGB8888: > > > + case DRM_FORMAT_ARGB8888: > > > + dspcntr |= DISPPLANE_BGRX888; > > > + break; > > > + case DRM_FORMAT_XBGR8888: > > > + case DRM_FORMAT_ABGR8888: > > > + dspcntr |= DISPPLANE_RGBX888; > > > + break; > > > + case DRM_FORMAT_XRGB2101010: > > > + case DRM_FORMAT_ARGB2101010: > > > + dspcntr |= DISPPLANE_BGRX101010; > > > + break; > > > + case DRM_FORMAT_XBGR2101010: > > > + case DRM_FORMAT_ABGR2101010: > > > + dspcntr |= DISPPLANE_RGBX101010; > > > + break; > > > + default: > > > + DRM_ERROR("Unsupported pixel format 0x%08x\n", pixel_format); > > > + return -EINVAL; > > > + } > > > + > > > + /* Write pixel format update command to ring */ > > > + ret = intel_ring_begin(ring, 4); > > > + if (ret) { > > > + DRM_ERROR("MI Command emit failed.\n"); > > > + return ret; > > > + } > > > + intel_ring_emit(ring, MI_NOOP); > > > + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); > > > + intel_ring_emit(ring, reg); > > > + intel_ring_emit(ring, dspcntr); > > > + intel_ring_advance(ring); > > > + return 0; > > > +} > > > + > > > +/* Update the primary plane registers. Uses MI commands */ static > > > +int haswell_update_plane(struct drm_crtc *crtc, > > > + struct drm_framebuffer *fb, int x, int y) { > > > + int ret; > > > + struct drm_device *dev = crtc->dev; > > > + struct drm_i915_private *dev_priv = dev->dev_private; > > > + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); > > > + struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; > > > + struct drm_i915_gem_object *obj; > > > + int plane = intel_crtc->plane; > > > + > > > + switch (plane) { > > > + case 0: > > > + case 1: > > > + case 2: > > > + break; > > > + default: > > > + DRM_ERROR("Can't update plane %c\n", plane_name(plane)); > > > + return -EINVAL; > > > + } > > > + obj = to_intel_framebuffer(fb)->obj; > > > + > > > + /* Set pixel format */ > > > + haswell_set_pixelformat(crtc, fb->pixel_format); > > > + > > > + /* Set tiling offsets. Tiling mode is not set here as * > > > + * it is set from intel_gen7_queue_flip. Send MI Command * > > > + * to change - * > > > + * 1. Tiling offset * > > > + * 2. stride - fb->pitches[0] * > > > + * 2. surface base address * > > > + * Linear offset and tile offset is same for Haswell */ > > > + intel_crtc->dspaddr_offset = > > > + intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, > > > + fb->bits_per_pixel / 8, > > > + fb->pitches[0]); > > > + > > > + DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n", > > > + obj->gtt_offset, intel_crtc->dspaddr_offset, > > > + x, y, fb->pitches[0]); > > > + > > > + /* Emit MI commands here */ > > > + ret = intel_ring_begin(ring, 10); > > > + if (ret) > > > + return ret; > > > + intel_ring_emit(ring, MI_NOOP); > > > + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); > > > + intel_ring_emit(ring, DSPOFFSET(plane)); > > > + intel_ring_emit(ring, (y << 16) | x); > > > + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); > > > + intel_ring_emit(ring, DSPSTRIDE(plane)); > > > + intel_ring_emit(ring, fb->pitches[0]); > > > + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); > > > + intel_ring_emit(ring, DSPSURF(plane)); > > > + intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); > > > + intel_ring_advance(ring); > > > + > > > + return 0; > > > +} > > > + > > > static int ironlake_update_plane(struct drm_crtc *crtc, > > > struct drm_framebuffer *fb, int x, int y) { > > > @@ -7494,9 > > > +7617,26 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, > > > struct drm_framebuffer *old_fb = crtc->fb; > > > struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; > > > struct intel_crtc *intel_crtc = to_intel_crtc(crtc); > > > + struct intel_framebuffer *intel_fb; > > > struct intel_unpin_work *work; > > > unsigned long flags; > > > int ret; > > > + /* > > > + * TILEOFF registers can't be changed via MI display flips. > > > + * Changes in pitches[0] and offsets[0] updates the primary plane > > > + * control registers. > > > + */ > > > + intel_fb = to_intel_framebuffer(crtc->fb); > > > + if ((IS_HASWELL(dev)) && > > > + ((obj->tiling_mode != intel_fb->obj->tiling_mode) || > > > + (fb->offsets[0] != crtc->fb->offsets[0]) || > > > + (fb->pitches[0] != crtc->fb->pitches[0]))) { > > > + DRM_DEBUG_DRIVER(" crtc fb: pitch = %d offset = %d\n", > > > + crtc->fb->pitches[0], crtc->fb->offsets[0]); > > > + DRM_DEBUG_DRIVER(" input fb: pitch = %d offset = %d\n", > > > + fb->pitches[0], fb->offsets[0]); > > > + haswell_update_plane(crtc, fb, 0, 0); > > > + } > > > > > > work = kzalloc(sizeof *work, GFP_KERNEL); > > > if (work == NULL) > > > @@ -8766,6 +8906,20 @@ out_config: > > > return ret; > > > } > > > > > > +/* Callback function - Called if change in pixel format is detected. > > > +* Sends MI command to update change in pixel format. > > > +*/ > > > +static int intel_crtc_set_pixel_format(struct drm_crtc *crtc, u32 > > > +pixel_format) { > > > + struct drm_device *dev = crtc->dev; > > > + if (IS_HASWELL(dev)) { > > > + return haswell_set_pixelformat(crtc, pixel_format); > > > + } else { > > > + DRM_ERROR("Pixel format change not allowed.\n"); > > > + return -EINVAL; > > > + } > > > +} > > > + > > > static const struct drm_crtc_funcs intel_crtc_funcs = { > > > .cursor_set = intel_crtc_cursor_set, > > > .cursor_move = intel_crtc_cursor_move, @@ -8773,6 +8927,7 @@ > > > static const struct drm_crtc_funcs intel_crtc_funcs = { > > > .set_config = intel_crtc_set_config, > > > .destroy = intel_crtc_destroy, > > > .page_flip = intel_crtc_page_flip, > > > + .set_pixelformat = intel_crtc_set_pixel_format, > > > }; > > > > > > static void intel_cpu_pll_init(struct drm_device *dev) @@ -10180,3 > > > +10335,4 @@ intel_display_print_error_state(struct > > > +drm_i915_error_state_buf *m, > > > } > > > } > > > #endif > > > + > > > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index > > > e215bcc..9a0ea92 100644 > > > --- a/include/drm/drm_crtc.h > > > +++ b/include/drm/drm_crtc.h > > > @@ -323,6 +323,7 @@ struct drm_plane; > > > * @set_property: called when a property is changed > > > * @set_config: apply a new CRTC configuration > > > * @page_flip: initiate a page flip > > > + * @set_pixelformat: apply new pixel format to primary plane > > > + control register > > > * > > > * The drm_crtc_funcs structure is the central CRTC management structure > > > * in the DRM. Each CRTC controls one or more connectors (note > > > that the name @@ -369,6 +370,13 @@ struct drm_crtc_funcs { > > > > > > int (*set_property)(struct drm_crtc *crtc, > > > struct drm_property *property, uint64_t val); > > > + /* > > > + * Update the primary plane pixel format register during page flip. > > > + * To support dynamic change in pixel format define the callback > > > + * function for set_pixelformat. > > > + */ > > > + int (*set_pixelformat)(struct drm_crtc *crtc, > > > + uint32_t pixel_format); > > > }; > > > > > > /** > > > -- > > > 1.7.9.5 > > > > > > _______________________________________________ > > > Intel-gfx mailing list > > > Intel-gfx@lists.freedesktop.org > > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx > > > > -- > > Ville Syrjälä > > Intel OTC > > -- > Ville Syrjälä > Intel OTC -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx