Re: [PATCH 1/3] drm: Widen vblank count to 64 bits. Change vblank time precision to ns
On Wed, Jul 05, 2017 at 03:10:11PM -0700, Keith Packard wrote: > This modifies the datatypes used by the vblank code to provide both 64 > bits of vblank count and to increase the resolution of the vblank > timestamp from microseconds to nanoseconds. > > The driver interfaces have also been changed to return 64-bits of > vblank count; fortunately all of the code necessary to widen that value > was already included to handle devices returning fewer than 32-bits. Extending the reported/sw vblank counter to u64 makes sense imo, but do we have to extend the driver interfaces too? If there's no 64 bit hw vblank currently I think I'd be good to postpone that part, simply because I'm too lazy to audit all the drivers for correctly setting max_vblank_count after your change :-) Other thought on this, since you bother to change all the types: Afaik both timespec and timeval suffer from the 32bit issues. If we bother with changing everything I think it'd be neat to switch all internal interfaces over to ktime, and only convert to the userspace types once when we generate the event. I think that's how cool hackers are supposed to do it, but not fully sure. Otherwise looks all good, but haven't yet carefully hunted for fumbles in review before the above is clear. -Daniel > This will provide the necessary datatypes for the Vulkan API. > > Signed-off-by: Keith Packard > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- > drivers/gpu/drm/drm_vblank.c | 159 > ++- > drivers/gpu/drm/exynos/exynos_drm_crtc.c | 2 +- > drivers/gpu/drm/gma500/psb_drv.h | 2 +- > drivers/gpu/drm/gma500/psb_irq.c | 2 +- > drivers/gpu/drm/gma500/psb_irq.h | 2 +- > drivers/gpu/drm/i915/i915_irq.c | 4 +- > drivers/gpu/drm/mga/mga_drv.h| 2 +- > drivers/gpu/drm/mga/mga_irq.c| 2 +- > drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 2 +- > drivers/gpu/drm/r128/r128_drv.h | 2 +- > drivers/gpu/drm/r128/r128_irq.c | 2 +- > drivers/gpu/drm/radeon/radeon_drv.c | 2 +- > drivers/gpu/drm/radeon/radeon_kms.c | 2 +- > drivers/gpu/drm/tegra/dc.c | 2 +- > drivers/gpu/drm/via/via_drv.h| 2 +- > drivers/gpu/drm/via/via_irq.c| 5 +- > drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 +- > drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- > include/drm/drmP.h | 2 +- > include/drm/drm_crtc.h | 2 +- > include/drm/drm_drv.h| 4 +- > include/drm/drm_vblank.h | 18 ++-- > 24 files changed, 130 insertions(+), 98 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index e0adad590ecb..860f5e194864 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1979,7 +1979,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, > int amdgpu_suspend(struct amdgpu_device *adev); > int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon); > int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); > -u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > +u64 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); > int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); > void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); > long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > index 12497a40ef92..f8c814c9c91a 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > @@ -922,7 +922,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, > * Gets the frame count on the requested crtc (all asics). > * Returns frame count on success, -EINVAL on failure. > */ > -u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) > +u64 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) > { > struct amdgpu_device *adev = dev->dev_private; > int vpos, hpos, stat; > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > index 463e4d81fb0d..f55f997c0b8f 100644 > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -43,7 +43,7 @@ > > static bool > drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, > - struct timeval *tvblank, bool in_vblank_irq); > + struct timespec *tvblank, bool in_vblank_irq); > > static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ > > @@ -63,8 +63,8 @@ MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on > timestamps [usecs]"); > MODULE_PARM_
Re: [PATCH 2/3] drm: Reorganize drm_pending_event to support future event types
On Wed, Jul 05, 2017 at 03:10:12PM -0700, Keith Packard wrote: > Place drm_event_vblank in a new union that includes that and a bare > drm_event structure. This will allow new members of that union to be > added in the future without changing code related to the existing vbl > event type. > > Assignments to the crtc_id field are now done when the event is > allocated, rather than when delievered. This way, delivery doesn't > need to have the crtc ID available. > > Signed-off-by: Keith Packard A few nits below, but looks good otherwise. -Daniel > --- > drivers/gpu/drm/drm_atomic.c | 7 --- > drivers/gpu/drm/drm_plane.c | 2 +- > drivers/gpu/drm/drm_vblank.c | 27 --- > drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 ++-- > drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 4 ++-- > include/drm/drm_vblank.h | 8 +++- > 6 files changed, 32 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index c0f336d23f9c..f569d7f03f3c 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -1839,7 +1839,7 @@ int drm_atomic_debugfs_init(struct drm_minor *minor) > */ > > static struct drm_pending_vblank_event *create_vblank_event( > - struct drm_device *dev, uint64_t user_data) > + struct drm_device *dev, struct drm_crtc *crtc, uint64_t > user_data) Nit: Please also drop the dev argument, we have crtc->dev easily available. That fits better into my long-term goal of getting rid of the (dev, pipe) pairs everywhere in the vblank code and fully switching over to drm_crtc *. > { > struct drm_pending_vblank_event *e = NULL; > > @@ -1849,7 +1849,8 @@ static struct drm_pending_vblank_event > *create_vblank_event( > > e->event.base.type = DRM_EVENT_FLIP_COMPLETE; > e->event.base.length = sizeof(e->event); > - e->event.user_data = user_data; > + e->event.vbl.crtc_id = crtc->base.id; > + e->event.vbl.user_data = user_data; > > return e; > } > @@ -2052,7 +2053,7 @@ static int prepare_crtc_signaling(struct drm_device > *dev, > if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) { > struct drm_pending_vblank_event *e; > > - e = create_vblank_event(dev, arg->user_data); > + e = create_vblank_event(dev, crtc, arg->user_data); > if (!e) > return -ENOMEM; > > diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c > index 5dc8c4350602..fe9f31285bc2 100644 > --- a/drivers/gpu/drm/drm_plane.c > +++ b/drivers/gpu/drm/drm_plane.c > @@ -918,7 +918,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, > } > e->event.base.type = DRM_EVENT_FLIP_COMPLETE; > e->event.base.length = sizeof(e->event); > - e->event.user_data = page_flip->user_data; > + e->event.vbl.user_data = page_flip->user_data; > ret = drm_event_reserve_init(dev, file_priv, &e->base, > &e->event.base); > if (ret) { > kfree(e); > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > index f55f997c0b8f..9ae170857ef6 100644 > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -807,13 +807,18 @@ static void send_vblank_event(struct drm_device *dev, > struct drm_pending_vblank_event *e, > u64 seq, struct timespec *now) > { > - e->event.sequence = seq; > - e->event.tv_sec = now->tv_sec; > - e->event.tv_usec = now->tv_nsec / 1000; > - > - trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, > - e->event.sequence); > - > + switch (e->event.base.type) { > + case DRM_EVENT_VBLANK: > + case DRM_EVENT_FLIP_COMPLETE: > + if (seq) > + e->event.vbl.sequence = (u32) seq; > + if (now) { > + e->event.vbl.tv_sec = now->tv_sec; > + e->event.vbl.tv_usec = now->tv_nsec / 1000; > + } > + break; > + } Not sure why this change? Also prep for the new, presumably extended events? Seems at least slightly inconsistent with other paths, where we still unconditionally fill it in. > + trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq); > drm_send_event_locked(dev, &e->base); > } > > @@ -865,7 +870,6 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, > > e->pipe = pipe; > e->sequence = drm_vblank_count(dev, pipe); > - e->event.crtc_id = crtc->base.id; > list_add_tail(&e->base.link, &dev->vblank_event_list); > } > EXPORT_SYMBOL(drm_crtc_arm_vblank_event); > @@ -897,7 +901,6 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, > now = get_drm_timestamp(); > } > e->pipe = pipe;
Re: [PATCH 1/3] drm: Widen vblank count to 64 bits. Change vblank time precision to ns
On 06/07/17 07:10 AM, Keith Packard wrote: > This modifies the datatypes used by the vblank code to provide both 64 > bits of vblank count and to increase the resolution of the vblank > timestamp from microseconds to nanoseconds. > > The driver interfaces have also been changed to return 64-bits of > vblank count; fortunately all of the code necessary to widen that value > was already included to handle devices returning fewer than 32-bits. > > This will provide the necessary datatypes for the Vulkan API. > > Signed-off-by: Keith Packard [...] > @@ -1492,9 +1515,11 @@ int drm_wait_vblank(struct drm_device *dev, void *data, > > switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { > case _DRM_VBLANK_RELATIVE: > - vblwait->request.sequence += seq; > + req_seq = seq + vblwait->request.sequence; > vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; Subtle breakage here: vblwait->request.sequence must still get updated for _DRM_VBLANK_RELATIVE, in case we're interrupted by a signal. > @@ -317,6 +317,9 @@ int via_driver_irq_postinstall(struct drm_device *dev) > if (!dev_priv) > return -EINVAL; > > + if (dev->driver->get_vblank_counter) > + dev->max_vblank_count = 0x; What's the purpose of this? All drivers providing get_vblank_counter should already initialize max_vblank_count correctly. -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Mesa and X developer ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
On Wed, Jul 05, 2017 at 03:10:13PM -0700, Keith Packard wrote: > These provide crtc-id based functions instead of pipe-number, while > also offering higher resolution time (ns) and wider frame count (64) > as required by the Vulkan API. > > Signed-off-by: Keith Packard I very much like this since the old ioctl really is a rather bad horror show. And since it's tied in with ums drivers everything is complicated. \o/ for much cleaner ioctls. Bunch of comments below, but looks good overall. -Daniel > --- > drivers/gpu/drm/drm_internal.h | 6 ++ > drivers/gpu/drm/drm_ioctl.c| 2 + > drivers/gpu/drm/drm_vblank.c | 148 > + > include/drm/drm_vblank.h | 1 + > include/uapi/drm/drm.h | 32 + > 5 files changed, 189 insertions(+) > > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h > index 5cecc974d2f9..b68a193b7907 100644 > --- a/drivers/gpu/drm/drm_internal.h > +++ b/drivers/gpu/drm/drm_internal.h > @@ -65,6 +65,12 @@ int drm_legacy_irq_control(struct drm_device *dev, void > *data, > int drm_legacy_modeset_ctl(struct drm_device *dev, void *data, > struct drm_file *file_priv); > > +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, > + struct drm_file *filp); > + > +int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data, > + struct drm_file *filp); > + > /* drm_auth.c */ > int drm_getmagic(struct drm_device *dev, void *data, >struct drm_file *file_priv); > diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c > index f1e568176da9..63016cf3e224 100644 > --- a/drivers/gpu/drm/drm_ioctl.c > +++ b/drivers/gpu/drm/drm_ioctl.c > @@ -657,6 +657,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { > DRM_UNLOCKED|DRM_RENDER_ALLOW), > DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, > drm_syncobj_fd_to_handle_ioctl, > DRM_UNLOCKED|DRM_RENDER_ALLOW), > + DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, > DRM_UNLOCKED), > + DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, > drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), I started a discussion a while back whether these should be restricted to DRM_MASTER (i.e. the modeset resource owner) or available to everyone. Since it's read-only I guess we can keep it accessible to everyone, but it has a bit the problem that client app developers see this, think it does what it does and then use it to schedule frames without asking the compositor. Which sometimes even works, but isn't really proper design. The reasons seems to be that on X11 there's no EGL extension for accurate timing frame updates (DRI2/3 can do it ofc, and glx exposes it, but glx is uncool or something like that). > }; > > #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > index 9ae170857ef6..93004b1bf84c 100644 > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -817,6 +817,12 @@ static void send_vblank_event(struct drm_device *dev, > e->event.vbl.tv_usec = now->tv_nsec / 1000; > } > break; > + case DRM_EVENT_CRTC_SEQUENCE: > + if (seq) > + e->event.seq.sequence = seq; > + if (now) > + e->event.seq.time_ns = timespec_to_ns(now); > + break; > } > trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq); > drm_send_event_locked(dev, &e->base); > @@ -1516,6 +1522,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, > DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", > pipe, ret); > return ret; > } > + > seq = drm_vblank_count(dev, pipe); > > switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { > @@ -1676,3 +1683,144 @@ bool drm_crtc_handle_vblank(struct drm_crtc *crtc) > return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc)); > } > EXPORT_SYMBOL(drm_crtc_handle_vblank); > + > +/* > + * Get crtc VBLANK count. > + * > + * \param dev DRM device > + * \param data user arguement, pointing to a drm_crtc_get_sequence structure. > + * \param file_priv drm file private for the user's open file descriptor > + */ Since this stuff isn't parsed by kerneldoc I tend to just free-form ioctl comments completely. Someday maybe someone even gets around to doing proper uabi documentation :-) Just an aside. > + > +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, > + struct drm_file *file_priv) > +{ > + struct drm_crtc *crtc; > + int pipe; > + struct drm_crtc_get_sequence *get_seq = data; > + struct timespec now; > + You need a DRIVER_MODESET check here or the drm_crtc_find will oops. Same below. >
Re: [PATCH 12/14] drm/exynos: mic: clean up drm_bridge_add call
On 07/05/2017 04:42 PM, Emil Velikov wrote: On 5 July 2017 at 10:14, Archit Taneja wrote: On 07/05/2017 02:35 PM, Inki Dae wrote: 2017년 07월 05일 18:00에 Archit Taneja 이(가) 쓴 글: On 07/03/2017 02:12 PM, Inki Dae wrote: This patch removes unnecessary checking of return value. Ps. this patch depends on below one, http://www.spinics.net/lists/dri-devel/msg145687.html Will this one^ go via the exynos pull req or drm-misc? If there won't be any conflicts, we could get both the patches through drm-misc to keep things simple. exynos pull it would be better. I will pick this up. :) If patch # 1/14 goes through drm-misc, and the exynos patch goes through exynos pull, the drm-misc branch would break. That's the reason I preferred the exynos patches to go via misc. As mentioned in 1/14: If 1/14 is applied before the rest of the series all the drivers (addressed with 2-14) will fail to build. I think... Yeah, they would. We'd want to push 1/14 right at the end. Getting all the ones from 2-14 via drm-misc would make life simpler. Archit -Emil -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/3] drm: Widen vblank count to 64 bits. Change vblank time precision to ns
On 06/07/17 04:45 PM, Michel Dänzer wrote: > On 06/07/17 07:10 AM, Keith Packard wrote: >> This modifies the datatypes used by the vblank code to provide both 64 >> bits of vblank count and to increase the resolution of the vblank >> timestamp from microseconds to nanoseconds. >> >> The driver interfaces have also been changed to return 64-bits of >> vblank count; fortunately all of the code necessary to widen that value >> was already included to handle devices returning fewer than 32-bits. >> >> This will provide the necessary datatypes for the Vulkan API. >> >> Signed-off-by: Keith Packard > > [...] > >> @@ -1492,9 +1515,11 @@ int drm_wait_vblank(struct drm_device *dev, void >> *data, >> >> switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { >> case _DRM_VBLANK_RELATIVE: >> -vblwait->request.sequence += seq; >> +req_seq = seq + vblwait->request.sequence; >> vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; > > Subtle breakage here: vblwait->request.sequence must still get updated > for _DRM_VBLANK_RELATIVE, in case we're interrupted by a signal. BTW, this got me thinking that we should probably treat _DRM_VBLANK_NEXTONMISS the same way, i.e. clear the flag after updating vblwait->request.sequence. Otherwise there could theoretically (though unlikely) be an infinite loop: ioctl with _DRM_VBLANK_NEXTONMISS, target missed => wait for next vblank wait interrupted by signal lather, rinse, repeat I'd advise against adding a "next on miss" flag for the new ioctl until there is specific demand for that. -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Mesa and X developer ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 05/16] drm/fb-helper: do a generic fb_setcmap helper in terms of crtc .gamma_set
> >> @@ -1369,27 +1362,57 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, > >> struct fb_info *info) > >>memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g)); > >>memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b)); > >> > >> - for (j = 0; j < cmap->len; j++) { > >> - u16 hred, hgreen, hblue, htransp = 0x; > >> + ret = crtc->funcs->gamma_set(crtc, r, g, b, > >> + crtc->gamma_size, crtc_state); > > > > I guess my description of what I have in mind wasn't really clear. I think > > a proper atomic commit should never reuse one of the old hooks > > (->gamma_set) here, that's just confusing. Instead what I had in mind is > > to do the proper adjusting that gamma_set does here in this function, i.e. > > > > - create the new blob, fill it with the cmap data > > > > - assign that blob to the crtc state: > > > > drm_atomic_replace_property_blob(&crtc_state->gamma_lut, > > new_table, &temp); > > That function is static, and... Missed these comments here. I think we should just make them unstatic, that might also explain why gamma_set is going this indirect path. Means we need some kerneldoc, but that's not much work. Ping the original author if you have questions. Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 03/16] drm/fb-helper: remove drm_fb_helper_save_lut_atomic
On Tue, Jul 04, 2017 at 12:36:59PM +0200, Peter Rosin wrote: > drm_fb_helper_save_lut_atomic is redundant since the .gamma_store is > now always kept up to date by drm_fb_helper_setcmap. > > Signed-off-by: Peter Rosin Merged up to this patch to drm-misc-next, thanks. Pleas base your next round of patches on top of that tree (or drm-tip if you feel like). -Daniel > --- > drivers/gpu/drm/drm_fb_helper.c | 17 - > 1 file changed, 17 deletions(-) > > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index 41fd9e0..b75b1f2 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -253,22 +253,6 @@ int drm_fb_helper_remove_one_connector(struct > drm_fb_helper *fb_helper, > } > EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); > > -static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct > drm_fb_helper *helper) > -{ > - uint16_t *r_base, *g_base, *b_base; > - int i; > - > - if (helper->funcs->gamma_get == NULL) > - return; > - > - r_base = crtc->gamma_store; > - g_base = r_base + crtc->gamma_size; > - b_base = g_base + crtc->gamma_size; > - > - for (i = 0; i < crtc->gamma_size; i++) > - helper->funcs->gamma_get(crtc, &r_base[i], &g_base[i], > &b_base[i], i); > -} > - > static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc) > { > uint16_t *r_base, *g_base, *b_base; > @@ -309,7 +293,6 @@ int drm_fb_helper_debug_enter(struct fb_info *info) > if (drm_drv_uses_atomic_modeset(mode_set->crtc->dev)) > continue; > > - drm_fb_helper_save_lut_atomic(mode_set->crtc, helper); > funcs->mode_set_base_atomic(mode_set->crtc, > mode_set->fb, > mode_set->x, > -- > 2.1.4 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 00/14] clean up drm_bridge_add
On 07/03/2017 02:12 PM, Inki Dae wrote: This patch series changes return type of drm_bridge_add function to void one and also removes unnecessary checking of the return type from relevant drivers. Ps. I had just build test so each maintainer may need to check this. I pushed all the bridge driver patches (2/14 to 11/14) to drm-misc-next. We'll push the rest once we figure out which branch we want them to go through.. Archit Inki Dae (14): drm/bridge: change return type of drm_bridge_add function drm/bridge: adv7511: clean up drm_bridge_add call drm/bridge: analogix-anx78xx: clean up drm_bridge_add call drm/bridge: vga-dac: clean up drm_bridge_add call drm/bridge: nxp-ptn3460: clean up drm_bridge_add call drm/bridge: panel: clean up drm_bridge_add call drm/bridge: ps8622: clean up drm_bridge_add call drm/bridge: sii902x: clean up drm_bridge_add call drm/bridge: synopsys: dw-hdmi: clean up drm_bridge_add call drm/bridge: tc358767: clean up drm_bridge_add call drm/bridge: ti-tfp410: clean up drm_bridge_add call drm/exynos: mic: clean up drm_bridge_add call drm/mediatek: hdmi: clean up drm_bridge_add call drm/sti: sti_vdo: clean up drm_bridge_add call drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +- drivers/gpu/drm/bridge/analogix-anx78xx.c| 6 +- drivers/gpu/drm/bridge/dumb-vga-dac.c| 9 +++-- drivers/gpu/drm/bridge/nxp-ptn3460.c | 6 +- drivers/gpu/drm/bridge/panel.c | 5 + drivers/gpu/drm/bridge/parade-ps8622.c | 6 +- drivers/gpu/drm/bridge/sii902x.c | 6 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c| 7 +-- drivers/gpu/drm/bridge/tc358767.c| 6 +- drivers/gpu/drm/bridge/ti-tfp410.c | 6 +- drivers/gpu/drm/drm_bridge.c | 7 +-- drivers/gpu/drm/exynos/exynos_drm_mic.c | 6 +- drivers/gpu/drm/mediatek/mtk_hdmi.c | 6 +- drivers/gpu/drm/sti/sti_dvo.c| 6 +- include/drm/drm_bridge.h | 2 +- 15 files changed, 17 insertions(+), 73 deletions(-) -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH libdrm 2/2] radeon: use asic id table to get chipset name
On 5 July 2017 at 22:31, Li, Samuel wrote: >> - above all, as-is make check will fail > Right, I did not check that. > >> - keeping the radeon API symmetrical to the amdgpu one would a good idea > The issue is Radeon does not have a struct similar to amdgpu_device_handle. Attach it to analogous primitive? > I think the current radeon API is simpler. Maybe a follow up change can > change amdgpu's API similar to radeon. > Exposing 3 entry points instead of 1 is _not_simpler. Also you cannot change the existing API, since it also breaks the ABI. Leading to crash/cause memory corruption when using existing binaries. >> - is adding yet another header really justified? > radeon_asic_id.h? That is going to be used by ddx/mesa. > Where it's used is orthogonal. You don't need a separate _public_ header for nearly every entry point ;-) Thanks Emil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH][drm-next] drm/amdgpu: make arrays pctl0_data and pctl1_data static
From: Colin Ian King The arrays pctl0_data and pctl1_data do not need to be in global scope, so them both static. Cleans up sparse warnings: symbol 'pctl0_data' was not declared. Should it be static? symbol 'pctl1_data' was not declared. Should it be static? Signed-off-by: Colin Ian King --- drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 9804318f3488..4c079207d699 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -249,7 +249,7 @@ struct pctl_data { uint32_t data; }; -const struct pctl_data pctl0_data[] = { +static const struct pctl_data pctl0_data[] = { {0x0, 0x7a640}, {0x9, 0x2a64a}, {0xd, 0x2a680}, @@ -274,7 +274,7 @@ const struct pctl_data pctl0_data[] = { #define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640 #define PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa833 -const struct pctl_data pctl1_data[] = { +static const struct pctl_data pctl1_data[] = { {0x0, 0x39a000}, {0x3b, 0x44a040}, {0x81, 0x2a08d}, -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
On Thu, Jul 06, 2017 at 09:53:13AM +0200, Daniel Vetter wrote: > On Wed, Jul 05, 2017 at 03:10:13PM -0700, Keith Packard wrote: > > These provide crtc-id based functions instead of pipe-number, while > > also offering higher resolution time (ns) and wider frame count (64) > > as required by the Vulkan API. > > > > Signed-off-by: Keith Packard > > I very much like this since the old ioctl really is a rather bad horror > show. And since it's tied in with ums drivers everything is complicated. > > \o/ for much cleaner ioctls. > > Bunch of comments below, but looks good overall. > -Daniel > > > --- > > drivers/gpu/drm/drm_internal.h | 6 ++ > > drivers/gpu/drm/drm_ioctl.c| 2 + > > drivers/gpu/drm/drm_vblank.c | 148 > > + > > include/drm/drm_vblank.h | 1 + > > include/uapi/drm/drm.h | 32 + > > 5 files changed, 189 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h > > index 5cecc974d2f9..b68a193b7907 100644 > > --- a/drivers/gpu/drm/drm_internal.h > > +++ b/drivers/gpu/drm/drm_internal.h > > @@ -65,6 +65,12 @@ int drm_legacy_irq_control(struct drm_device *dev, void > > *data, > > int drm_legacy_modeset_ctl(struct drm_device *dev, void *data, > >struct drm_file *file_priv); > > > > +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, > > + struct drm_file *filp); > > + > > +int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data, > > + struct drm_file *filp); > > + > > /* drm_auth.c */ > > int drm_getmagic(struct drm_device *dev, void *data, > > struct drm_file *file_priv); > > diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c > > index f1e568176da9..63016cf3e224 100644 > > --- a/drivers/gpu/drm/drm_ioctl.c > > +++ b/drivers/gpu/drm/drm_ioctl.c > > @@ -657,6 +657,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { > > DRM_UNLOCKED|DRM_RENDER_ALLOW), > > DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, > > drm_syncobj_fd_to_handle_ioctl, > > DRM_UNLOCKED|DRM_RENDER_ALLOW), > > + DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, > > DRM_UNLOCKED), > > + DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, > > drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), > > I started a discussion a while back whether these should be restricted to > DRM_MASTER (i.e. the modeset resource owner) or available to everyone. > Since it's read-only I guess we can keep it accessible to everyone, but it > has a bit the problem that client app developers see this, think it does > what it does and then use it to schedule frames without asking the > compositor. Which sometimes even works, but isn't really proper design. > The reasons seems to be that on X11 there's no EGL extension for accurate > timing frame updates (DRI2/3 can do it ofc, and glx exposes it, but glx is > uncool or something like that). > > > }; > > > > #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) > > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > > index 9ae170857ef6..93004b1bf84c 100644 > > --- a/drivers/gpu/drm/drm_vblank.c > > +++ b/drivers/gpu/drm/drm_vblank.c > > @@ -817,6 +817,12 @@ static void send_vblank_event(struct drm_device *dev, > > e->event.vbl.tv_usec = now->tv_nsec / 1000; > > } > > break; > > + case DRM_EVENT_CRTC_SEQUENCE: > > + if (seq) > > + e->event.seq.sequence = seq; > > + if (now) > > + e->event.seq.time_ns = timespec_to_ns(now); > > + break; > > } > > trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq); > > drm_send_event_locked(dev, &e->base); > > @@ -1516,6 +1522,7 @@ int drm_wait_vblank(struct drm_device *dev, void > > *data, > > DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", > > pipe, ret); > > return ret; > > } > > + > > seq = drm_vblank_count(dev, pipe); > > > > switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { > > @@ -1676,3 +1683,144 @@ bool drm_crtc_handle_vblank(struct drm_crtc *crtc) > > return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc)); > > } > > EXPORT_SYMBOL(drm_crtc_handle_vblank); > > + > > +/* > > + * Get crtc VBLANK count. > > + * > > + * \param dev DRM device > > + * \param data user arguement, pointing to a drm_crtc_get_sequence > > structure. > > + * \param file_priv drm file private for the user's open file descriptor > > + */ > > Since this stuff isn't parsed by kerneldoc I tend to just free-form ioctl > comments completely. Someday maybe someone even gets around to doing > proper uabi documentation :-) Just an aside. > > + > > +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, > > + st
[PATCH] drm/bridge: dw_hdmi: add cec notifier support
From: Russell King Add CEC notifier support to the HDMI bridge driver, so that the CEC part of the IP can receive its physical address. Tested-by: Neil Armstrong Acked-by: Neil Armstrong Acked-by: Hans Verkuil Signed-off-by: Russell King Signed-off-by: Neil Armstrong --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++ 1 file changed, 18 insertions(+) Hi Archit, Hans, This is repost of Russell's patch from his dw-hdmi CEC patchset. Since his CEC implementation will be integrated in the bridge driver, this notifier patch won't be re-posted. But the Amlogic Platform needs a notifier since it uses a standalone CEC controller. Thanks, Neil diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index ead1124..9c03846 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -33,6 +33,8 @@ #include #include +#include + #include "dw-hdmi.h" #include "dw-hdmi-audio.h" @@ -175,6 +177,8 @@ struct dw_hdmi { struct regmap *regm; void (*enable_audio)(struct dw_hdmi *hdmi); void (*disable_audio)(struct dw_hdmi *hdmi); + + struct cec_notifier *cec_notifier; }; #define HDMI_IH_PHY_STAT0_RX_SENSE \ @@ -1896,6 +1900,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); hdmi->sink_has_audio = drm_detect_monitor_audio(edid); drm_mode_connector_update_edid_property(connector, edid); + cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); ret = drm_add_edid_modes(connector, edid); /* Store the ELD */ drm_edid_to_eld(connector, edid); @@ -2077,6 +2082,10 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) dw_hdmi_update_phy_mask(hdmi); } mutex_unlock(&hdmi->mutex); + + if (!rx_sense && !hpd) + cec_notifier_set_phys_addr(hdmi->cec_notifier, + CEC_PHYS_ADDR_INVALID); } void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) @@ -2376,6 +2385,12 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) if (ret) goto err_iahb; + hdmi->cec_notifier = cec_notifier_get(dev); + if (!hdmi->cec_notifier) { + ret = -ENOMEM; + goto err_iahb; + } + /* * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator * N and cts values before enabling phy @@ -2452,6 +2467,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) hdmi->ddc = NULL; } + if (hdmi->cec_notifier) + cec_notifier_put(hdmi->cec_notifier); + clk_disable_unprepare(hdmi->iahb_clk); err_isfr: clk_disable_unprepare(hdmi->isfr_clk); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
On Thu, Jul 6, 2017 at 12:16 PM, Ville Syrjälä wrote: >> > + if (!dev->irq_enabled) >> > + return -EINVAL; >> > + >> > + crtc = drm_crtc_find(dev, get_seq->crtc_id); >> > + if (!crtc) >> > + return -ENOENT; >> > + >> > + pipe = drm_crtc_index(crtc); >> > + >> > + get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); >> >> This can give you and old vblank if the vblank is off (i.e. sw state >> hasn't be regularly updated). I think we want a new >> drm_crtc_accurate_vblank_count_and_time variant. > > Or better yet just do what Chris did for the old ioctl in commit > b33b02707ba3 ("drm: Peek at the current counter/timestamp for vblank queries") Yeah the READ_ONCE(vblank->enabled) is a nice fastpath. But we still need the accurate one as slowpath in case the vblank irq is off. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH] drm/crc: Handle opening and closing crc better
Looks good to me: Reviewed-by: Tomeu Vizoso I guess you have tested this with IGT? In any case, I think it would be good to mention how a patch has been tested in the changelog. That can be very useful to others if things go wrong at some point. Thanks, Tomeu On 21 June 2017 at 13:00, Maarten Lankhorst wrote: > When I was doing a grep . -r /sys/kernel/debug/dri/0 I noticed a WARN > appearing when I aborted the grep with ^C. > > After investigating I've also noticed that the error handling was > lacking and there are race conditions involving multiple calls to > open/close simultaneously. > > Fix this by setting the opened flag first and using crc->entries to > decide when crc can be collected. > > Also call unset crc source before cleaning up, this way there is > no race with a future open(). > > Signed-off-by: Maarten Lankhorst > --- > drivers/gpu/drm/drm_debugfs_crc.c | 46 > ++- > 1 file changed, 31 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/drm_debugfs_crc.c > b/drivers/gpu/drm/drm_debugfs_crc.c > index 1722d8f21449..d0ea4627a093 100644 > --- a/drivers/gpu/drm/drm_debugfs_crc.c > +++ b/drivers/gpu/drm/drm_debugfs_crc.c > @@ -136,21 +136,38 @@ static int crtc_crc_data_count(struct drm_crtc_crc *crc) > return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR); > } > > +static void crtc_crc_cleanup(struct drm_crtc_crc *crc) > +{ > + kfree(crc->entries); > + crc->entries = NULL; > + crc->head = 0; > + crc->tail = 0; > + crc->values_cnt = 0; > + crc->opened = false; > +} > + > static int crtc_crc_open(struct inode *inode, struct file *filep) > { > struct drm_crtc *crtc = inode->i_private; > struct drm_crtc_crc *crc = &crtc->crc; > struct drm_crtc_crc_entry *entries = NULL; > size_t values_cnt; > - int ret; > + int ret = 0; > > - if (crc->opened) > - return -EBUSY; > + spin_lock_irq(&crc->lock); > + if (!crc->opened) > + crc->opened = true; > + else > + ret = -EBUSY; > + spin_unlock_irq(&crc->lock); > > - ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt); > if (ret) > return ret; > > + ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt); > + if (ret) > + goto err; > + > if (WARN_ON(values_cnt > DRM_MAX_CRC_NR)) { > ret = -EINVAL; > goto err_disable; > @@ -170,7 +187,6 @@ static int crtc_crc_open(struct inode *inode, struct file > *filep) > spin_lock_irq(&crc->lock); > crc->entries = entries; > crc->values_cnt = values_cnt; > - crc->opened = true; > > /* > * Only return once we got a first frame, so userspace doesn't have to > @@ -182,12 +198,17 @@ static int crtc_crc_open(struct inode *inode, struct > file *filep) > crc->lock); > spin_unlock_irq(&crc->lock); > > - WARN_ON(ret); > + if (ret) > + goto err_disable; > > return 0; > > err_disable: > crtc->funcs->set_crc_source(crtc, NULL, &values_cnt); > +err: > + spin_lock_irq(&crc->lock); > + crtc_crc_cleanup(crc); > + spin_unlock_irq(&crc->lock); > return ret; > } > > @@ -197,17 +218,12 @@ static int crtc_crc_release(struct inode *inode, struct > file *filep) > struct drm_crtc_crc *crc = &crtc->crc; > size_t values_cnt; > > + crtc->funcs->set_crc_source(crtc, NULL, &values_cnt); > + > spin_lock_irq(&crc->lock); > - kfree(crc->entries); > - crc->entries = NULL; > - crc->head = 0; > - crc->tail = 0; > - crc->values_cnt = 0; > - crc->opened = false; > + crtc_crc_cleanup(crc); > spin_unlock_irq(&crc->lock); > > - crtc->funcs->set_crc_source(crtc, NULL, &values_cnt); > - > return 0; > } > > @@ -334,7 +350,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool > has_frame, > spin_lock(&crc->lock); > > /* Caller may not have noticed yet that userspace has stopped reading > */ > - if (!crc->opened) { > + if (!crc->entries) { > spin_unlock(&crc->lock); > return -EINVAL; > } > -- > 2.11.0 > > ___ > Intel-gfx mailing list > intel-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support
On 07/06/2017 12:43 PM, Jose Abreu wrote: > Hi Neil, > > > On 06-07-2017 11:33, Neil Armstrong wrote: >> From: Russell King >> >> Add CEC notifier support to the HDMI bridge driver, so that the CEC >> part of the IP can receive its physical address. >> >> Tested-by: Neil Armstrong >> Acked-by: Neil Armstrong >> Acked-by: Hans Verkuil >> Signed-off-by: Russell King >> Signed-off-by: Neil Armstrong >> --- >> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++ >> 1 file changed, 18 insertions(+) >> >> Hi Archit, Hans, >> >> This is repost of Russell's patch from his dw-hdmi CEC patchset. >> >> Since his CEC implementation will be integrated in the bridge driver, >> this notifier patch won't be re-posted. >> >> But the Amlogic Platform needs a notifier since it uses a standalone CEC >> controller. >> >> Thanks, >> Neil >> >> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >> index ead1124..9c03846 100644 >> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >> @@ -33,6 +33,8 @@ >> #include >> #include >> >> +#include > > Don't you also have to "select CEC_NOTIFIER" in Kconfig? Or is it > not needed anymore with the recent Kconfig changes of CEC? Hi Jose, Seems no, since the cec functions are protected with : #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) and replaced with dummy inline functions. Neil > > Best regards, > Jose Miguel Abreu > >> + >> #include "dw-hdmi.h" >> #include "dw-hdmi-audio.h" >> >> @@ -175,6 +177,8 @@ struct dw_hdmi { >> struct regmap *regm; >> void (*enable_audio)(struct dw_hdmi *hdmi); >> void (*disable_audio)(struct dw_hdmi *hdmi); >> + >> +struct cec_notifier *cec_notifier; >> }; >> >> #define HDMI_IH_PHY_STAT0_RX_SENSE \ >> @@ -1896,6 +1900,7 @@ static int dw_hdmi_connector_get_modes(struct >> drm_connector *connector) >> hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); >> hdmi->sink_has_audio = drm_detect_monitor_audio(edid); >> drm_mode_connector_update_edid_property(connector, edid); >> +cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); >> ret = drm_add_edid_modes(connector, edid); >> /* Store the ELD */ >> drm_edid_to_eld(connector, edid); >> @@ -2077,6 +2082,10 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, >> bool hpd, bool rx_sense) >> dw_hdmi_update_phy_mask(hdmi); >> } >> mutex_unlock(&hdmi->mutex); >> + >> +if (!rx_sense && !hpd) >> +cec_notifier_set_phys_addr(hdmi->cec_notifier, >> + CEC_PHYS_ADDR_INVALID); >> } >> >> void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) >> @@ -2376,6 +2385,12 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) >> if (ret) >> goto err_iahb; >> >> +hdmi->cec_notifier = cec_notifier_get(dev); >> +if (!hdmi->cec_notifier) { >> +ret = -ENOMEM; >> +goto err_iahb; >> +} >> + >> /* >> * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator >> * N and cts values before enabling phy >> @@ -2452,6 +2467,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) >> hdmi->ddc = NULL; >> } >> >> +if (hdmi->cec_notifier) >> +cec_notifier_put(hdmi->cec_notifier); >> + >> clk_disable_unprepare(hdmi->iahb_clk); >> err_isfr: >> clk_disable_unprepare(hdmi->isfr_clk); > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support
On 07/06/2017 01:05 PM, Russell King - ARM Linux wrote: > On Thu, Jul 06, 2017 at 12:33:06PM +0200, Neil Armstrong wrote: >> From: Russell King >> >> Add CEC notifier support to the HDMI bridge driver, so that the CEC >> part of the IP can receive its physical address. >> >> Tested-by: Neil Armstrong >> Acked-by: Neil Armstrong >> Acked-by: Hans Verkuil >> Signed-off-by: Russell King >> Signed-off-by: Neil Armstrong >> --- >> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++ >> 1 file changed, 18 insertions(+) >> >> Hi Archit, Hans, >> >> This is repost of Russell's patch from his dw-hdmi CEC patchset. >> >> Since his CEC implementation will be integrated in the bridge driver, >> this notifier patch won't be re-posted. >> >> But the Amlogic Platform needs a notifier since it uses a standalone CEC >> controller. > > Without this, the dw-hdmi CEC support will be totally useless anyway, > and it's pointless to merge it without this patch. > Hi Russell, While following discussion on your last patchset, it seems you agreed with Hans to no more rely on the cec-notifier but directly call the dw-hdmi-cec functions. Anyway, if this patch is merged separately and you still depend on it, you could still rebase on it when it appears on drm-misc-next... Neil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support
On 07/06/2017 01:45 PM, Russell King - ARM Linux wrote: > On Thu, Jul 06, 2017 at 01:29:54PM +0200, Neil Armstrong wrote: >> On 07/06/2017 01:05 PM, Russell King - ARM Linux wrote: >>> On Thu, Jul 06, 2017 at 12:33:06PM +0200, Neil Armstrong wrote: >>>> From: Russell King >>>> >>>> Add CEC notifier support to the HDMI bridge driver, so that the CEC >>>> part of the IP can receive its physical address. >>>> >>>> Tested-by: Neil Armstrong >>>> Acked-by: Neil Armstrong >>>> Acked-by: Hans Verkuil >>>> Signed-off-by: Russell King >>>> Signed-off-by: Neil Armstrong >>>> --- >>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++ >>>> 1 file changed, 18 insertions(+) >>>> >>>> Hi Archit, Hans, >>>> >>>> This is repost of Russell's patch from his dw-hdmi CEC patchset. >>>> >>>> Since his CEC implementation will be integrated in the bridge driver, >>>> this notifier patch won't be re-posted. >>>> >>>> But the Amlogic Platform needs a notifier since it uses a standalone CEC >>>> controller. >>> >>> Without this, the dw-hdmi CEC support will be totally useless anyway, >>> and it's pointless to merge it without this patch. >>> >> >> Hi Russell, >> >> While following discussion on your last patchset, it seems you agreed with >> Hans >> to no more rely on the cec-notifier but directly call the dw-hdmi-cec >> functions. > > Incorrect. I think you're looking at the discussion in "thread mode" > and assuming that messages are stored in date order... > > There was a discussion about removing the cec-notifier which happened > on June 1st/2nd, based off the covering email. > > However, there was a later discussion on June 9th (sparked by your > requirement) which changed the resolution from "lets remove the > notifier" to "we need to keep the notifier". This was based on > patch 2/4. > > I never posted an updated patch set, because of the dependencies, but > Hans decided on June 12th to do I-don't-know-what with the patches I > sent, resulting in what we have queued up today. This brought the > sub-thread containing the cec-notifier removal discussion to be _after_ > the June 9th discussion, which is probably what's causing some > confusion here. > > However, I can assure you that the resolution of the discussion with > the cec-notifier was that it should remain in place - this is from > the last few messages in the discussion: > > Hans wrote on 9th June: > | You wrote on 9th June: > | > It won't since the Meson platform needs it... > | > | Ah, I wasn't aware of that when I wrote my original comments. In that case > | we do need the notifier. Which is fine, as long as the reason for that is > | documented. > > From what you're saying, it sounds like the CEC dw-hdmi-cec.c still > relies on the notifier, but the patch which adds the CEC notifier > to dw-hdmi.c was omited from what Hans did, which will result in the > whole thing being a total waste of time. > >> Anyway, if this patch is merged separately and you still depend on it, >> you could still rebase on it when it appears on drm-misc-next... > > Well, from what I can see in 4.12, the cec-notifier stuff is rather > broken (tda998x has stopped working as its stuck with a physical > address of f.f.f.f) so I think the whole thing is rather moot right > now. I don't yet know what's going on with that, other than the > notifier stuff seems to not be working, despite being enabled in > the .config. > Indeed, I missed some parts of the thread, sorry for the confusion. Anyway, is it a showstopper to have this patch merged separately ? If you prefer re-posting a serie with this patch inside, no problem, but the Amlogic platform still needs this patch to have CEC working. Maybe it's because of fixes introduced in 4.13, but using next-20170706 and this patch, make things works perfectly. Neil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/4] Make fbcon a built-time depency for fbdev, take 2
Hi all, So the original simple hack failed and we need to do a bit more. This time tested including depmod for all combos. And since I had the pleasure to read more fbdev code, 3 simple patches on top to clean up some more. Cheers, Daniel Daniel Vetter (4): fbcon: Make fbcon a built-time depency for fbdev fbdev: Nuke FBINFO_MODULE drm/qxl: Drop fbdev hwaccel flags drm/: Drop fbdev info flags drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 1 - drivers/gpu/drm/armada/armada_fbdev.c| 1 - drivers/gpu/drm/ast/ast_fb.c | 1 - drivers/gpu/drm/bochs/bochs_fbdev.c | 1 - drivers/gpu/drm/cirrus/cirrus_fbdev.c| 1 - drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c| 1 - drivers/gpu/drm/i915/intel_fbdev.c | 1 - drivers/gpu/drm/mgag200/mgag200_fb.c | 1 - drivers/gpu/drm/msm/msm_fbdev.c | 1 - drivers/gpu/drm/omapdrm/omap_fbdev.c | 1 - drivers/gpu/drm/qxl/qxl_fb.c | 1 - drivers/gpu/drm/radeon/radeon_fb.c | 1 - drivers/gpu/drm/udl/udl_fb.c | 1 - drivers/gpu/drm/virtio/virtgpu_fb.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 1 - drivers/video/console/Kconfig| 2 +- drivers/video/console/Makefile | 8 drivers/video/fbdev/core/Makefile| 11 +++ drivers/video/{console => fbdev/core}/bitblit.c | 4 drivers/video/{console => fbdev/core}/fbcon.c| 15 --- drivers/video/{console => fbdev/core}/fbcon.h| 0 drivers/video/{console => fbdev/core}/fbcon_ccw.c| 4 drivers/video/{console => fbdev/core}/fbcon_cw.c | 4 drivers/video/{console => fbdev/core}/fbcon_rotate.c | 4 drivers/video/{console => fbdev/core}/fbcon_rotate.h | 0 drivers/video/{console => fbdev/core}/fbcon_ud.c | 4 drivers/video/fbdev/core/fbmem.c | 10 -- drivers/video/{console => fbdev/core}/softcursor.c | 4 drivers/video/{console => fbdev/core}/tileblit.c | 5 - include/linux/fb.h | 7 +-- include/linux/fbcon.h| 12 31 files changed, 37 insertions(+), 72 deletions(-) rename drivers/video/{console => fbdev/core}/bitblit.c (98%) rename drivers/video/{console => fbdev/core}/fbcon.c (99%) rename drivers/video/{console => fbdev/core}/fbcon.h (100%) rename drivers/video/{console => fbdev/core}/fbcon_ccw.c (98%) rename drivers/video/{console => fbdev/core}/fbcon_cw.c (98%) rename drivers/video/{console => fbdev/core}/fbcon_rotate.c (95%) rename drivers/video/{console => fbdev/core}/fbcon_rotate.h (100%) rename drivers/video/{console => fbdev/core}/fbcon_ud.c (98%) rename drivers/video/{console => fbdev/core}/softcursor.c (93%) rename drivers/video/{console => fbdev/core}/tileblit.c (96%) create mode 100644 include/linux/fbcon.h -- 2.13.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/4] fbcon: Make fbcon a built-time depency for fbdev
There's a bunch of folks who're trying to make printk less contended and faster, but there's a problem: printk uses the console_lock, and the console lock has become the BKL for all things fbdev/fbcon, which in turn pulled in half the drm subsystem under that lock. That's awkward. There reasons for that is probably just a historical accident: - fbcon is a runtime option of fbdev, i.e. at runtime you can pick whether your fbdev driver instances are used as kernel consoles. Unfortunately this wasn't implemented with some module option, but through some module loading magic: As long as you don't load fbcon.ko, there's no fbdev console support, but loading it (in any order wrt fbdev drivers) will create console instances for all fbdev drivers. - This was implemented through a notifier chain. fbcon.ko enumerates all fbdev instances at load time and also registers itself as listener in the fbdev notifier. The fbdev core tries to register new fbdev instances with fbcon using the notifier. - On top of that the modifier chain is also used at runtime by the fbdev subsystem to e.g. control backlights for panels. - The problem is that the notifier puts a mutex locking context between fbdev and fbcon, which mixes up the locking contexts for both the runtime usage and the register time usage to notify fbcon. And at runtime fbcon (through the fbdev core) might call into the notifier from a printk critical section while console_lock is held. - This means console_lock must be an outer lock for the entire fbdev subsystem, which also means it must be acquired when registering a new framebuffer driver as the outermost lock since we might call into fbcon (through the notifier) which would result in a locking inversion if fbcon would acquire the console_lock from its notifier callback (which it needs to register the console). - console_lock can be held anywhere, since printk can be called anywhere, and through the above story, plus drm/kms being an fbdev driver, we pull in a shocking amount of locking hiercharchy underneath the console_lock. Which makes cleaning up printk really hard (not even splitting console_lock into an rwsem is all that useful due to this). There's various ways to address this, but the cleanest would be to make fbcon a compile-time option, where fbdev directly calls the fbcon register functions from register_framebuffer, or dummy static inline versions if fbcon is disabled. Maybe augmented with a runtime knob to disable fbcon, if that's needed (for debugging perhaps). But this could break some users who rely on the magic "loading fbcon.ko enables/disables fbdev framebuffers at runtime" thing, even if that's unlikely. Hence we must be careful: 1. Create a compile-time dependency between fbcon and fbdev in the least minimal way. This is what this patch does. 2. Wait at least 1 year to give possible users time to scream about how we broke their setup. Unlikely, since all distros make fbcon compile-in, and embedded platforms only compile stuff they know they need anyway. But still. 3. Convert the notifier to direct functions calls, with dummy static inlines if fbcon is disabled. We'll still need the fb notifier for the other uses (like backlights), but we can probably move it into the fb core (atm it must be built-into vmlinux). 4. Push console_lock down the call-chain, until it is down in console_register again. 5. Finally start to clean up and rework the printk/console locking. For context of this saga see commit 50e244cc793d511b86adea24972f3a7264cae114 Author: Alan Cox Date: Fri Jan 25 10:28:15 2013 +1000 fb: rework locking to fix lock ordering on takeover plus the pile of commits on top that tried to make this all work without terminally upsetting lockdep. We've uncovered all this when console_lock lockdep annotations where added in commit daee779718a319ff9f83e1ba3339334ac650bb22 Author: Daniel Vetter Date: Sat Sep 22 19:52:11 2012 +0200 console: implement lockdep support for console_lock On the patch itself: - Switch CONFIG_FRAMEBUFFER_CONSOLE to be a boolean, using the overall CONFIG_FB tristate to decided whether it should be a module or built-in. - At first I thought I could force the build depency with just a dummy symbol that fbcon.ko exports and fb.ko uses. But that leads to a module depency cycle (it works fine when built-in). Since this tight binding is the entire goal the simplest solution is to move all the fbcon modules (and there's a bunch of optinal source-files which are each modules of their own, for no good reason) into the overall fb.ko core module. That's a bit more than what I would have liked to do in this patch, but oh well. Cc: Alan Cox Cc: Sergey Senozhatsky Cc: Linux Fbdev development list Cc: Steven Rostedt Cc: Bartlomiej Zolnierkiewicz Cc: dri-devel@lists.freedesktop.org Signed-off-by: Daniel Vetter --- v2: Switch to building fbcon code into fb.ko right away because the c
[PATCH 4/4] drm/: Drop fbdev info flags
- FBINFO_CAN_FORCE_OUTPUT has been a lie ever since we nerfed&removed the entire panic handling code in our fbdev emulation. We might restore kms panic output, but not through the bazillion of legacy code layers called fbdev/fbcon, there's just no way to make that work safely. - With the module check change FBINFO_DEFAULT is always 0, so can be removed too. That removes another change to cargo-cult stuff in kms drivers, yay! Signed-off-by: Daniel Vetter --- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c| 1 - drivers/gpu/drm/armada/armada_fbdev.c | 1 - drivers/gpu/drm/ast/ast_fb.c | 1 - drivers/gpu/drm/bochs/bochs_fbdev.c | 1 - drivers/gpu/drm/cirrus/cirrus_fbdev.c | 1 - drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c | 1 - drivers/gpu/drm/i915/intel_fbdev.c| 1 - drivers/gpu/drm/mgag200/mgag200_fb.c | 1 - drivers/gpu/drm/msm/msm_fbdev.c | 1 - drivers/gpu/drm/omapdrm/omap_fbdev.c | 1 - drivers/gpu/drm/qxl/qxl_fb.c | 1 - drivers/gpu/drm/radeon/radeon_fb.c| 1 - drivers/gpu/drm/udl/udl_fb.c | 1 - drivers/gpu/drm/virtio/virtgpu_fb.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_fb.c| 1 - 15 files changed, 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index c0d8c6ff6380..1c57fefc364c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -245,7 +245,6 @@ static int amdgpufb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &amdgpufb_ops; tmp = amdgpu_bo_gpu_offset(abo) - adev->mc.vram_start; diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index 602dfead8eef..5b479b0ed06c 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -81,7 +81,6 @@ static int armada_fb_create(struct drm_fb_helper *fbh, strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id)); info->par = fbh; - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &armada_fb_ops; info->fix.smem_start = obj->phys_addr; info->fix.smem_len = obj->obj.size; diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index 4ad4acd0ccab..53ca6d099234 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -231,7 +231,6 @@ static int astfb_create(struct drm_fb_helper *helper, strcpy(info->fix.id, "astdrmfb"); - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &astfb_ops; info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0); diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index 49d5a2b7d630..14eb8d0d5a00 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -118,7 +118,6 @@ static int bochsfb_create(struct drm_fb_helper *helper, strcpy(info->fix.id, "bochsdrmfb"); - info->flags = FBINFO_DEFAULT; info->fbops = &bochsfb_ops; drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index 7fa58eeadc9d..c69586163d92 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c @@ -215,7 +215,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper, strcpy(info->fix.id, "cirrusdrmfb"); - info->flags = FBINFO_DEFAULT; info->fbops = &cirrusfb_ops; drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c index f5ac80daeef2..9740eed9231a 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c @@ -131,7 +131,6 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper, strcpy(info->fix.id, "hibmcdrmfb"); - info->flags = FBINFO_DEFAULT; info->fbops = &hibmc_drm_fb_ops; drm_fb_helper_fill_fix(info, hi_fbdev->fb->fb.pitches[0], diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 5536591d3da0..b953365a3eec 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -232,7 +232,6 @@ static int intelfb_create(struct drm_fb_helper *helper, strcpy(info->fix.id, "inteldrmfb"); - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &intelfb_ops; /* setup aperture base/size for vesafb takeover */ diff --gi
[PATCH 3/4] drm/qxl: Drop fbdev hwaccel flags
It's not accelarated, just system memory. Note we don't even need to set the default flag since that's now always 0. Cc: Dave Airlie Cc: Gerd Hoffmann Cc: virtualizat...@lists.linux-foundation.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/qxl/qxl_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 573e7e9a5f98..69e7359b562a 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -275,7 +275,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; + info->flags = FBINFO_DEFAULT; info->fbops = &qxlfb_ops; /* -- 2.13.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/4] fbdev: Nuke FBINFO_MODULE
Instead check info->ops->owner, which amounts to the same. Spotted because I want to remove the pile of broken and cargo-culted fb_info->flags assignments in drm drivers. Cc: Bartlomiej Zolnierkiewicz Cc: linux-fb...@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/video/fbdev/core/fbcon.c | 2 +- drivers/video/fbdev/core/fbmem.c | 4 ++-- include/linux/fb.h | 7 +-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 86b3bcbd01a8..431a1533a2fe 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -564,7 +564,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, unsigned short *save = NULL, *r, *q; int logo_height; - if (info->flags & FBINFO_MODULE) { + if (info->fbops->owner) { logo_shown = FBCON_LOGO_DONTSHOW; return; } diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 283d57cf8526..2636f192e8c9 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -463,7 +463,7 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, /* Return if the frame buffer is not mapped or suspended */ if (logo == NULL || info->state != FBINFO_STATE_RUNNING || - info->flags & FBINFO_MODULE) + info->fbops->owner) return 0; image.depth = 8; @@ -601,7 +601,7 @@ int fb_prepare_logo(struct fb_info *info, int rotate) memset(&fb_logo, 0, sizeof(struct logo_data)); if (info->flags & FBINFO_MISC_TILEBLITTING || - info->flags & FBINFO_MODULE) + info->fbops->owner) return 0; if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { diff --git a/include/linux/fb.h b/include/linux/fb.h index a964d076b4dc..40b767fa622f 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -400,7 +400,7 @@ struct fb_tile_ops { #endif /* CONFIG_FB_TILEBLITTING */ /* FBINFO_* = fb_info.flags bit flags */ -#define FBINFO_MODULE 0x0001 /* Low-level driver is a module */ +#define FBINFO_DEFAULT 0 #define FBINFO_HWACCEL_DISABLED0x0002 /* When FBINFO_HWACCEL_DISABLED is set: * Hardware acceleration is turned off. Software implementations @@ -533,11 +533,6 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { return a; } -#ifdef MODULE -#define FBINFO_DEFAULT FBINFO_MODULE -#else -#define FBINFO_DEFAULT 0 -#endif // This will go away #define FBINFO_FLAG_MODULE FBINFO_MODULE -- 2.13.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/5] drm/i915: Protect against deferred fbdev setup
We could probably hit this already with our current async fbdev init, but it's much easier to hit this with the new deferred fbdev setup that I'm working on polishing. Cc: Maarten Lankhorst Reported-by: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 643f56b8b87c..9f7e7730bb82 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1931,7 +1931,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) return ret; #ifdef CONFIG_DRM_FBDEV_EMULATION - if (dev_priv->fbdev) { + if (dev_priv->fbdev && dev_priv->fbdev->helper.fb) { fbdev_fb = to_intel_framebuffer(dev_priv->fbdev->helper.fb); seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", -- 2.13.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/5] drm/i915/fbdev: Always forward hotplug events
With deferred fbdev setup we always need to forward hotplug events, even if fbdev isn't fully set up yet. Otherwise the deferred setup will neer happen. Originally this check was added in commit c45eb4fed12d278d3619f1904885bd0d7bcbf036 (tag: drm-intel-next-fixes-2016-08-05) Author: Chris Wilson Date: Wed Jul 13 18:34:45 2016 +0100 drm/i915/fbdev: Check for the framebuffer before use But the specific case of the hotplug function blowing up was fixed in commit 50c3dc970a09b3b60422a58934cc27a413288bab Author: Daniel Vetter Date: Fri Jun 27 17:19:22 2014 +0200 drm/fb-helper: Fix hpd vs. initial config races Cc: Maarten Lankhorst Cc: Mika Kuoppala Cc: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_fbdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index f11ee039ff45..5536591d3da0 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -821,7 +821,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev) { struct intel_fbdev *ifbdev = to_i915(dev)->fbdev; - if (ifbdev && ifbdev->vma) + if (ifbdev) drm_fb_helper_hotplug_event(&ifbdev->helper); } -- 2.13.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/5] drm/fb-helper: Support deferred setup
FB helper code falls back to a 1024x768 mode if no outputs are connected or don't report back any modes upon initialization. This can be annoying because outputs that are added to FB helper later on can't be used with FB helper if they don't support a matching mode. The fallback is in place because VGA connectors can happen to report an unknown connection status even when they are in fact connected. Some drivers have custom solutions in place to defer FB helper setup until at least one output is connected. But the logic behind these solutions is always the same and there is nothing driver-specific about it, so a better alterative is to fix the FB helper core and add support for all drivers automatically. This patch adds support for deferred FB helper setup. It checks all the connectors for their connection status, and if all of them report to be disconnected marks the FB helper as needing deferred setup. Whet setup is deferred, the FB helper core will automatically retry setup after a hotplug event, and it will keep trying until it succeeds. v2: Rebase onto my entirely reworked fbdev helper locking. One big difference is that this version again drops&reacquires the fbdev lock (which is now fb_helper->lock, but before this patch series it was mode_config->mutex), because register_framebuffer must be able to recurse back into fbdev helper code for the initial screen setup. v3: __drm_fb_helper_initial_config must hold fb_helper->lock upon return, I've fumbled that in the deferred setup case (Liviu). v4: I was blind, redo this all. __drm_fb_helper_initial_config shouldn't need to reacquire fb_helper->lock, that just confuses callers. I myself got confused by kernel_fb_helper_lock and somehow thought it's the same as fb_helper->lock. Tsk. Also simplify the logic a bit (we don't need two functions to probe connectors), we can stick much closer to the existing code. And update some comments I've spotted that are outdated. v5: Don't pass -EAGAIN to drivers, it's just an internal error code (Liviu). v6: Add _and_unlock suffix to clarify locking (Maarten) Cc: Liviu Dudau Cc: John Stultz Cc: Thierry Reding Cc: Maarten Lankhorst Tested-by: John Stultz Signed-off-by: Thierry Reding (v1) Reviewed-by: Maarten Lankhorst Reviewed-by: Liviu Dudau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c | 102 ++-- include/drm/drm_fb_helper.h | 23 + 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 721511da4de6..0c3aaabe7819 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -501,6 +501,9 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) if (!drm_fbdev_emulation) return -ENODEV; + if (READ_ONCE(fb_helper->deferred_setup)) + return 0; + mutex_lock(&fb_helper->lock); ret = restore_fbdev_mode(fb_helper); @@ -1618,8 +1621,7 @@ EXPORT_SYMBOL(drm_fb_helper_pan_display); /* * Allocates the backing storage and sets up the fbdev info structure through - * the ->fb_probe callback and then registers the fbdev and sets up the panic - * notifier. + * the ->fb_probe callback. */ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, int preferred_bpp) @@ -1717,13 +1719,8 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, } if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { - /* -* hmm everyone went away - assume VGA cable just fell out -* and will come back later. -*/ - DRM_INFO("Cannot find any crtc or sizes - going 1024x768\n"); - sizes.fb_width = sizes.surface_width = 1024; - sizes.fb_height = sizes.surface_height = 768; + DRM_INFO("Cannot find any crtc or sizes\n"); + return -EAGAIN; } /* Handle our overallocation */ @@ -2352,6 +2349,59 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, kfree(enabled); } +/* Note: Drops fb_helper->lock before returning. */ +static int +__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, + int bpp_sel) +{ + struct drm_device *dev = fb_helper->dev; + struct fb_info *info; + unsigned int width, height; + int ret; + + width = dev->mode_config.max_width; + height = dev->mode_config.max_height; + + drm_setup_crtcs(fb_helper, width, height); + ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); + if (ret < 0) { + if (ret == -EAGAIN) { + fb_helper->preferred_bpp = bpp_sel; + fb_helper->deferred_setup = true; + ret =
[PATCH 5/5] drm/hisilicon: Remove custom FB helper deferred setup
From: Thierry Reding The FB helper core now supports deferred setup, so the driver's custom implementation can be removed. v2: Dont' resurrect drm_vblank_cleanup. Cc: Xinliang Liu Cc: Rongrong Zou Cc: Xinwei Kong Cc: Chen Feng Signed-off-by: Thierry Reding (v1) Signed-off-by: Daniel Vetter --- drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 8065d6cb1d7f..1178341c3858 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -54,14 +54,7 @@ static void kirin_fbdev_output_poll_changed(struct drm_device *dev) { struct kirin_drm_private *priv = dev->dev_private; - if (priv->fbdev) { - drm_fbdev_cma_hotplug_event(priv->fbdev); - } else { - priv->fbdev = drm_fbdev_cma_init(dev, 32, - dev->mode_config.num_connector); - if (IS_ERR(priv->fbdev)) - priv->fbdev = NULL; - } + drm_fbdev_cma_hotplug_event(priv->fbdev); } #endif @@ -128,11 +121,18 @@ static int kirin_drm_kms_init(struct drm_device *dev) /* init kms poll for handling hpd */ drm_kms_helper_poll_init(dev); - /* force detection after connectors init */ - (void)drm_helper_hpd_irq_event(dev); + priv->fbdev = drm_fbdev_cma_init(dev, 32, +dev->mode_config.num_connector); + if (IS_ERR(priv->fbdev)) { + DRM_ERROR("failed to initialize fbdev.\n"); + ret = PTR_ERR(priv->fbdev); + goto err_cleanup_poll; + } return 0; +err_cleanup_poll: + drm_kms_helper_poll_fini(dev); err_unbind_all: component_unbind_all(dev->dev, dev); err_dc_cleanup: -- 2.13.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/5] drm/exynos: Remove custom FB helper deferred setup
From: Thierry Reding The FB helper core now supports deferred setup, so the driver's custom implementation can be removed. v2: Drop NULL check, drm_fb_helper_hotplug_event handles that already. Cc: Inki Dae Cc: Joonyoung Shim Cc: Seung-Woo Kim Cc: Kyungmin Park Signed-off-by: Thierry Reding (v1) Reviewed-by: Inki Dae Tested-by: Inki Dae Signed-off-by: Daniel Vetter --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 6 -- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 26 +- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 35a8dfc93836..cab9e12d7846 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -395,8 +395,9 @@ static int exynos_drm_bind(struct device *dev) /* init kms poll for handling hpd */ drm_kms_helper_poll_init(drm); - /* force connectors detection */ - drm_helper_hpd_irq_event(drm); + ret = exynos_drm_fbdev_init(drm); + if (ret) + goto err_cleanup_poll; /* register the DRM device */ ret = drm_dev_register(drm, 0); @@ -407,6 +408,7 @@ static int exynos_drm_bind(struct device *dev) err_cleanup_fbdev: exynos_drm_fbdev_fini(drm); +err_cleanup_poll: drm_kms_helper_poll_fini(drm); exynos_drm_device_subdrv_remove(drm); err_unbind_all: diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 641531243e04..c3a068409b48 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -183,24 +183,6 @@ static const struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = { .fb_probe = exynos_drm_fbdev_create, }; -static bool exynos_drm_fbdev_is_anything_connected(struct drm_device *dev) -{ - struct drm_connector *connector; - bool ret = false; - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->status != connector_status_connected) - continue; - - ret = true; - break; - } - mutex_unlock(&dev->mode_config.mutex); - - return ret; -} - int exynos_drm_fbdev_init(struct drm_device *dev) { struct exynos_drm_fbdev *fbdev; @@ -211,9 +193,6 @@ int exynos_drm_fbdev_init(struct drm_device *dev) if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector) return 0; - if (!exynos_drm_fbdev_is_anything_connected(dev)) - return 0; - fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); if (!fbdev) return -ENOMEM; @@ -304,8 +283,5 @@ void exynos_drm_output_poll_changed(struct drm_device *dev) struct exynos_drm_private *private = dev->dev_private; struct drm_fb_helper *fb_helper = private->fb_helper; - if (fb_helper) - drm_fb_helper_hotplug_event(fb_helper); - else - exynos_drm_fbdev_init(dev); + drm_fb_helper_hotplug_event(fb_helper); } -- 2.13.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/crc: Only open CRC on atomic drivers when the CRTC is active.
Op 06-07-17 om 13:09 schreef Tomeu Vizoso: > Looks good to me: > > Reviewed-by: Tomeu Vizoso > > I guess you have tested this with IGT? In any case, I think it would > be good to mention how a patch has been tested in the changelog. That > can be very useful to others if things go wrong at some point. Testcase: debugfs_test.read_all_entries But I hit it by doing a recursive grep, which I guess is the same thing here. :) One further improvement I wanted to do was reject opening the CRC with -EIO when the crtc is not active, that way the above test will not hang. Does the below patch also look good to you? 8<- Commit e8fa5671183c ("drm: crc: Wait for a frame before returning from open()") adds a wait for CRC frame, but with the CRTC off this will never be generated. For atomic drivers we know if a CRTC is active through crtc_state->active, so when inactive reject the open with -EIO. Signed-off-by: Maarten Lankhorst Fixes: e8fa5671183c ("drm: crc: Wait for a frame before returning from open()") Testcase: debugfs_test.read_all_entries --- diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index d0ea4627a093..f9e26dda56d6 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -154,6 +154,19 @@ static int crtc_crc_open(struct inode *inode, struct file *filep) size_t values_cnt; int ret = 0; + if (drm_drv_uses_atomic_modeset(crtc->dev)) { + ret = drm_modeset_lock_interruptible(&crtc->mutex, NULL); + if (ret) + return ret; + + if (!crtc->state->active) + ret = -EIO; + drm_modeset_unlock(&crtc->mutex); + + if (ret) + return ret; + } + spin_lock_irq(&crc->lock); if (!crc->opened) crc->opened = true; ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/5] drm/i915/fbdev: Always forward hotplug events
Op 06-07-17 om 15:00 schreef Daniel Vetter: > With deferred fbdev setup we always need to forward hotplug events, > even if fbdev isn't fully set up yet. Otherwise the deferred setup > will neer happen. > > Originally this check was added in > > commit c45eb4fed12d278d3619f1904885bd0d7bcbf036 (tag: > drm-intel-next-fixes-2016-08-05) > Author: Chris Wilson > Date: Wed Jul 13 18:34:45 2016 +0100 > > drm/i915/fbdev: Check for the framebuffer before use > > But the specific case of the hotplug function blowing up was fixed in > > commit 50c3dc970a09b3b60422a58934cc27a413288bab > Author: Daniel Vetter > Date: Fri Jun 27 17:19:22 2014 +0200 > > drm/fb-helper: Fix hpd vs. initial config races > > Cc: Maarten Lankhorst > Cc: Mika Kuoppala > Cc: Chris Wilson > Signed-off-by: Daniel Vetter > --- > drivers/gpu/drm/i915/intel_fbdev.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_fbdev.c > b/drivers/gpu/drm/i915/intel_fbdev.c > index f11ee039ff45..5536591d3da0 100644 > --- a/drivers/gpu/drm/i915/intel_fbdev.c > +++ b/drivers/gpu/drm/i915/intel_fbdev.c > @@ -821,7 +821,7 @@ void intel_fbdev_output_poll_changed(struct drm_device > *dev) > { > struct intel_fbdev *ifbdev = to_i915(dev)->fbdev; > > - if (ifbdev && ifbdev->vma) > + if (ifbdev) > drm_fb_helper_hotplug_event(&ifbdev->helper); > } > Reviewed-by: Maarten Lankhorst Could you also change the @intel.com to @linux.intel.com in second patch? :-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
RE: [PATCH libdrm 2/2] radeon: use asic id table to get chipset name
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Emil Velikov > Sent: Thursday, July 06, 2017 5:21 AM > To: Li, Samuel > Cc: ML dri-devel; amd-gfx mailing list > Subject: Re: [PATCH libdrm 2/2] radeon: use asic id table to get chipset name > > On 5 July 2017 at 22:31, Li, Samuel wrote: > >> - above all, as-is make check will fail > > Right, I did not check that. > > > >> - keeping the radeon API symmetrical to the amdgpu one would a good > idea > > The issue is Radeon does not have a struct similar to > amdgpu_device_handle. > Attach it to analogous primitive? Radeon libdrm is much different than amdgpu. There is no analog. > > > I think the current radeon API is simpler. Maybe a follow up change can > change amdgpu's API similar to radeon. > > > Exposing 3 entry points instead of 1 is _not_simpler. Also you cannot > change the existing API, since it also breaks the ABI. > Leading to crash/cause memory corruption when using existing binaries. > > >> - is adding yet another header really justified? > > radeon_asic_id.h? That is going to be used by ddx/mesa. > > > Where it's used is orthogonal. You don't need a separate _public_ > header for nearly every entry point ;-) Actually having a separate header makes sense for radeon. We currently expose a separate header for each set of functionality (one for buffer management, one for command submission, one for surface management). Adding the asic names to any of the existing ones doesn’t really make sense from a functional standpoint. Alex > > Thanks > Emil > ___ > amd-gfx mailing list > amd-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
On Thu, Jul 06, 2017 at 01:04:18PM +0200, Daniel Vetter wrote: > On Thu, Jul 6, 2017 at 12:16 PM, Ville Syrjälä > wrote: > >> > + if (!dev->irq_enabled) > >> > + return -EINVAL; > >> > + > >> > + crtc = drm_crtc_find(dev, get_seq->crtc_id); > >> > + if (!crtc) > >> > + return -ENOENT; > >> > + > >> > + pipe = drm_crtc_index(crtc); > >> > + > >> > + get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); > >> > >> This can give you and old vblank if the vblank is off (i.e. sw state > >> hasn't be regularly updated). I think we want a new > >> drm_crtc_accurate_vblank_count_and_time variant. > > > > Or better yet just do what Chris did for the old ioctl in commit > > b33b02707ba3 ("drm: Peek at the current counter/timestamp for vblank > > queries") > > Yeah the READ_ONCE(vblank->enabled) is a nice fastpath. But we still > need the accurate one as slowpath in case the vblank irq is off. Maybe, or maybe we want to turn the interrupt on in that case? That's what the old ioctl does. -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH][drm-next] drm/amdgpu: make arrays pctl0_data and pctl1_data static
On Thu, Jul 6, 2017 at 5:58 AM, Colin King wrote: > From: Colin Ian King > > The arrays pctl0_data and pctl1_data do not need to be in global scope, > so them both static. > > Cleans up sparse warnings: > symbol 'pctl0_data' was not declared. Should it be static? > symbol 'pctl1_data' was not declared. Should it be static? > > Signed-off-by: Colin Ian King Applied. thanks! Alex > --- > drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c > b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c > index 9804318f3488..4c079207d699 100644 > --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c > @@ -249,7 +249,7 @@ struct pctl_data { > uint32_t data; > }; > > -const struct pctl_data pctl0_data[] = { > +static const struct pctl_data pctl0_data[] = { > {0x0, 0x7a640}, > {0x9, 0x2a64a}, > {0xd, 0x2a680}, > @@ -274,7 +274,7 @@ const struct pctl_data pctl0_data[] = { > #define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640 > #define PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa833 > > -const struct pctl_data pctl1_data[] = { > +static const struct pctl_data pctl1_data[] = { > {0x0, 0x39a000}, > {0x3b, 0x44a040}, > {0x81, 0x2a08d}, > -- > 2.11.0 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RESEND GIT PULL] mediatek drm next for 4.13
Hi, Dave: This include new color format support and some fixups. Please kindly let me know if there is any problem. Regards, CK The following changes since commit 6d61e70ccc21606ffb8a0a03bd3aba24f659502b: Backmerge tag 'v4.12-rc7' into drm-next (2017-06-27 08:28:30 +1000) are available in the git repository at: https://github.com/ckhu-mediatek/linux.git-tags.git mediatek-drm-next-4.13 for you to fetch changes up to 5ac5895a84d92bd2b3db490f8ee242ccb4d77e96: drm/mediatek: separate color module to fixup error memory reallocation (2017-06-27 17:34:53 +0800) Bibby Hsieh (1): drm/mediatek: Support UYVY and YUYV format for overlay Christophe Jaillet (1): drm/mediatek: check for memory allocation failure Colin Ian King (1): drm/mediatek: re-phrase DRM_INFO error message Philipp Zabel (1): drm/mediatek: use platform_register_drivers yt.s...@mediatek.com (1): drm/mediatek: separate color module to fixup error memory reallocation drivers/gpu/drm/mediatek/Makefile | 3 +- drivers/gpu/drm/mediatek/mtk_disp_color.c | 176 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 7 ++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 2 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 80 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 33 ++ drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 + drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 + drivers/gpu/drm/mediatek/mtk_dsi.c | 2 +- drivers/gpu/drm/mediatek/mtk_hdmi.c | 27 + 10 files changed, 205 insertions(+), 128 deletions(-) create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_color.c ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 2/3] dt-bindings: display: panel: Add support for Orise Tech otm8009a dsi panel
On 07/04/2017 06:30 PM, Philippe CORNU wrote: > The Orise Tech OTM8009A is a 3.97" 480x800 TFT LCD panel connected using > a MIPI-DSI video interface. Its backlight is managed through the DSI link. > > Signed-off-by: Philippe CORNU > --- > .../bindings/display/panel/orisetech,otm8009a.txt| 20 > > 1 file changed, 20 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt > > diff --git > a/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt > b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt > new file mode 100644 > index 000..0bb8237 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt > @@ -0,0 +1,20 @@ > +Orise Tech OTM8009A 3.97" 480x800 TFT LCD panel (MIPI-DSI video mode) > + > +The Orise Tech OTM8009A is a 3.97" 480x800 TFT LCD panel connected using > +a MIPI-DSI video interface. Its backlight is managed through the DSI link. > + > +Required properties: > + - compatible: "orisetech,otm8009a" > + - reg: the virtual channel number of a DSI peripheral > + - reset-gpios: a GPIO spec for the reset pin (active low). (Optional) > + > +Example: > +&dsi { > + ... > + > + panel@0 { > + compatible = "orisetech,otm8009a"; > + reg = <0>; > + reset-gpios = <&gpioh 7 0>; Hi All, I should have written instead: + reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>; reset-gpios is active low and the define GPIO_ACTIVE_LOW = 1 so the example was not good. I will send soon the v2 with the correction. Many thanks Philippe > + }; > +}; > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
xilinx_drm vblank from VDMA callback
> On Jul 5, 2017, at 18:56, Hyun Kwon wrote: > > For VDMA, I think you can use the DMA engine complete callback to generate > the vblank. > > But, please note that it's not a global solution, and it doesn't work for > some other pipelines. For example, the ZU+ DPDMA operation is synchronized > with vblank, not with the done event. Thus if the page flip request comes in > between done event and vblank, it'll end up flipping pages while the > application would expect the flip to take place after vblank. Thanks for that warning. I will make sure I get the timing right for my pipeline. I will probably not submit this work upstream... yet. > > For the xilinx drm clean up, what you described in the previous email, to use > drm_of_component_probe(), makes sense. I'm doing the clean in that direction > too. In the end I did not use drm_of_component_probe() as it make assumptions that the CRTC is a component and treats it specially, failing that, the function aborts. Since I didn't want to refactor xilinx_drm_crtc to a component at this stage, especially knowing the refactoring that is upcoming, I went for a similar but manual way. Here it is, just for fun... /* component master bind callback */ static int xilinx_drm_bind(struct device *dev) { struct drm_device *drm; struct xilinx_drm_private *private; struct drm_encoder *encoder; struct drm_connector *connector; struct device_node *encoder_node; unsigned int bpp, align, i = 0; int ret; private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL); if (!private) return -ENOMEM; dev_set_drvdata(dev, private); drm = drm_dev_alloc(&xilinx_drm_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); drm->dev_private = private; private->drm = drm; platform_set_drvdata(to_platform_device(dev), private); drm_mode_config_init(drm); /* create a xilinx crtc */ private->crtc = xilinx_drm_crtc_create(drm); if (IS_ERR(private->crtc)) { DRM_DEBUG_DRIVER("failed to create xilinx crtc\n"); ret = PTR_ERR(private->crtc); goto err_free; } xilinx_drm_mode_config_init(drm); while ((encoder_node = of_parse_phandle(drm->dev->of_node, "xlnx,encoder-slave", i))) { encoder = xilinx_drm_encoder_create(drm, encoder_node); of_node_put(encoder_node); if (IS_ERR(encoder)) { DRM_DEBUG_DRIVER("failed to create xilinx encoder\n"); ret = PTR_ERR(encoder); goto err_free; } connector = xilinx_drm_connector_create(drm, encoder, i); if (IS_ERR(connector)) { DRM_DEBUG_DRIVER("failed to create xilinx connector\n"); ret = PTR_ERR(connector); goto err_free; } i++; } ret = drm_dev_register(drm, 0); if (ret) { DRM_ERROR("failed to register drm_dev: %d\n", ret); goto err_free; } ret = component_bind_all(dev, drm); if (ret) { DRM_ERROR("Failed to bind all components\n"); goto err_unregister; } ret = drm_vblank_init(drm, 1); if (ret) { dev_err(dev, "failed to initialize vblank\n"); goto err_unbind_all; } /* enable irq to enable vblank feature */ drm->irq_enabled = true; /* initialize xilinx framebuffer */ bpp = xilinx_drm_format_bpp(xilinx_drm_crtc_get_format(private->crtc)); align = xilinx_drm_crtc_get_align(private->crtc); private->fb = xilinx_drm_fb_init(drm, bpp, 1, 1, align, xilinx_drm_fbdev_vres); if (IS_ERR(private->fb)) { DRM_ERROR("failed to initialize drm cma fb\n"); ret = PTR_ERR(private->fb); goto err_vblank_cleanup; } drm_helper_disable_unused_functions(drm); drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); return 0; err_vblank_cleanup: drm_vblank_cleanup(drm); err_unbind_all: component_unbind_all(dev, drm); err_unregister: drm_dev_unregister(drm); err_free: drm_mode_config_cleanup(drm); dev_set_drvdata(dev, NULL); drm_dev_unref(drm); return ret; } static void xilinx_drm_unbind(struct device *dev) { struct xilinx_drm_private *private = dev_get_drvdata(dev); struct drm_device *drm = private->drm; drm_kms_helper_poll_fini(drm); xilinx_drm_fb_fini(private->fb); component_unbind_all(dev, drm); drm_vblank_cleanup(drm); drm_mode_con
Re: [PATCH v1 3/3] drm/panel: Add support for otm8009a panel driver
On 07/05/2017 11:28 AM, Andrzej Hajda wrote: > On 04.07.2017 18:30, Philippe CORNU wrote: >> This patch adds Orise Tech otm8009a 3.97" 480x800 TFT LCD >> panel driver (MIPI-DSI video mode). The panel backlight is >> managed through the DSI link. This panel driver is used in >> several STM32 boards. >> >> Signed-off-by: Philippe CORNU >> --- >> drivers/gpu/drm/panel/Kconfig| 9 + >> drivers/gpu/drm/panel/Makefile | 1 + >> drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 517 >> +++ >> 3 files changed, 527 insertions(+) >> create mode 100755 drivers/gpu/drm/panel/panel-orisetech-otm8009a.c >> >> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig >> index d84a031..c1c9291 100644 >> --- a/drivers/gpu/drm/panel/Kconfig >> +++ b/drivers/gpu/drm/panel/Kconfig >> @@ -117,4 +117,13 @@ config DRM_PANEL_SITRONIX_ST7789V >>Say Y here if you want to enable support for the Sitronix >>ST7789V controller for 240x320 LCD panels >> >> +config DRM_PANEL_ORISETECH_OTM8009A >> +tristate "Orise Tech otm8009a 480p dsi 2dl video mode panel" >> +depends on OF >> +depends on DRM_MIPI_DSI >> +depends on BACKLIGHT_CLASS_DEVICE >> +help >> + Say Y here if you want to enable support for Orise Tech OTM8009A >> + 480x800 DSI panel >> + >> endmenu >> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile >> index 9f6610d..ac798f3 100644 >> --- a/drivers/gpu/drm/panel/Makefile >> +++ b/drivers/gpu/drm/panel/Makefile >> @@ -10,3 +10,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += >> panel-samsung-s6e8aa0.o >> obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o >> obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o >> obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o >> +obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o >> \ No newline at end of file >> diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c >> b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c >> new file mode 100755 >> index 000..7aefc09 >> --- /dev/null >> +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c >> @@ -0,0 +1,517 @@ >> +/* >> + * Copyright (C) STMicroelectronics SA 2017 >> + * >> + * Authors: Philippe Cornu >> + * Yannick Fertre >> + * >> + * License terms: GNU General Public License (GPL), version 2 >> + */ >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define DRV_NAME "orisetech_otm8009a" >> + >> +#define OTM8009A_BACKLIGHT_DEFAULT 240 >> +#define OTM8009A_BACKLIGHT_MAX 255 >> + >> +struct otm8009a { >> +struct device *dev; >> +struct drm_panel panel; >> +struct backlight_device *bl_dev; >> +struct gpio_desc *reset_gpio; >> +bool prepared; >> +bool enabled; >> +}; >> + >> +static const struct drm_display_mode default_mode = { >> +.clock = 32729, >> +.hdisplay = 480, >> +.hsync_start = 480 + 120, >> +.hsync_end = 480 + 120 + 63, >> +.htotal = 480 + 120 + 63 + 120, >> +.vdisplay = 800, >> +.vsync_start = 800 + 12, >> +.vsync_end = 800 + 12 + 12, >> +.vtotal = 800 + 12 + 12 + 12, >> +.vrefresh = 50, >> +.flags = 0, >> +.width_mm = 52, >> +.height_mm = 86, >> +}; >> + >> +static inline struct otm8009a *panel_to_otm8009a(struct drm_panel *panel) >> +{ >> +return container_of(panel, struct otm8009a, panel); >> +} >> + >> +static void otm8009a_dcs_write_buf(struct otm8009a *ctx, const void *data, >> + size_t len) >> +{ >> +struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); >> + >> +if (mipi_dsi_dcs_write_buffer(dsi, data, len) < 0) >> +DRM_WARN("mipi dsi dcs write buffer failed"); > > New line at the end of string. > > I see another way of fighting with error handling, its drawback is that > failure does not prevent further execution. > Since I am lost what error handling pattern is currently accepted in > panels subsystem, I cannot advice if this should be changed. > Hi Andrzef, First of all, a big *THANK YOU* for this nice code review. Your comments are very relevant :-) Regarding the error management, there are actually several solutions to deal with errors but I confess that for the moment none really convinced me... that is why I proposed here the *minimal solution of the trace*... >> +} >> + >> +#define dcs_write_seq(seq...) \ >> +do {\ >> +static const u8 d[] = { seq }; \ >> +otm8009a_dcs_write_buf(ctx, d, ARRAY_SIZE(d)); \ >> +} while (0) > > It is up to your preferences, but I think "do {} while(0)" construct is > kind of workaround and is obsoleted in favor of ({ ... }) statement > expressions[1]. > More serious issue is that you
Re: [PATCH 1/3] drm: Widen vblank count to 64 bits. Change vblank time precision to ns
Daniel Vetter writes: > Extending the reported/sw vblank counter to u64 makes sense imo, but do we > have to extend the driver interfaces too? If there's no 64 bit hw vblank > currently I think I'd be good to postpone that part, simply because I'm > too lazy to audit all the drivers for correctly setting max_vblank_count > after your change :-) As I said, it's easy enough to do that; I figured I'd do the obvious part and let you decide if you wanted that or not. We could also set max_vblank_count to 0x if it wasn't set by the driver, and/or add a WARN_ON_ONCE if it wasn't set. Given that it takes over two years to wrap this counter at 60Hz, we're never likely to hit a bug in testing. Let me know what you think; I'm not invested in any particular solution at this point. > Other thought on this, since you bother to change all the types: Afaik > both timespec and timeval suffer from the 32bit issues. I'm not sure what 32bit issues you're concerned about here? We don't compare these values, just report them up to user space. > If we bother with changing everything I think it'd be neat to switch > all internal interfaces over to ktime, and only convert to the > userspace types once when we generate the event. I think that's how > cool hackers are supposed to do it, but not fully sure. Yeah, I can definitely get behind that plan. A simple 64-bit value instead of a struct with two semi-related values which are hard to do arithmetic on. > Otherwise looks all good, but haven't yet carefully hunted for fumbles in > review before the above is clear. Thanks. I'll switch over to ktime and wait to hear what your thoughts are on the vblank count interface changes. -- -keith signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/3] drm: Widen vblank count to 64 bits. Change vblank time precision to ns
Michel Dänzer writes: > Subtle breakage here: vblwait->request.sequence must still get updated > for _DRM_VBLANK_RELATIVE, in case we're interrupted by a signal. Thanks for finding this. I think it might be better to just not modify the request.type field instead, so that on re-entry it gets recomputed? That would mean that a signal might cause the value to be different if the application takes a long time processing the signal, but I'm not sure that's wrong? >> @@ -317,6 +317,9 @@ int via_driver_irq_postinstall(struct drm_device *dev) >> if (!dev_priv) >> return -EINVAL; >> >> +if (dev->driver->get_vblank_counter) >> +dev->max_vblank_count = 0x; > > What's the purpose of this? All drivers providing get_vblank_counter > should already initialize max_vblank_count correctly. Yeah, I couldn't prove that this driver did that, and as Daniel says, we haven't ever audited the drivers to make sure they do. We have a check to see that they don't set max_vblank_count if they don't provide a get function, but I can't find the matching check for drivers that do provide a function and aren't setting max_vblank_count. Do you have any thoughts on the wisdom of changing this API before we have a driver that needs it? And, of course, thanks for your review! -- -keith signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/3] drm: Widen vblank count to 64 bits. Change vblank time precision to ns
Michel Dänzer writes: > BTW, this got me thinking that we should probably treat > _DRM_VBLANK_NEXTONMISS the same way, i.e. clear the flag after updating > vblwait->request.sequence. Otherwise there could theoretically (though > unlikely) be an infinite loop: I was thinking that we should just re-compute the target sequence from scratch and not modify the request at all. But, now I see your point -- if the wait is interrupted long after it starts, then we don't want to change the target number. I wonder if anyone actually waits for vblank anymore, or if everyone just uses the event interface... > ioctl with _DRM_VBLANK_NEXTONMISS, target missed => wait for next vblank > wait interrupted by signal > lather, rinse, repeat Yeah, sounds like a latent bug. Ok, to retract my last email, I'll go ahead and fix things up so that the request sequence gets set to the correct absolute value and that any flags which modify it get cleared. > I'd advise against adding a "next on miss" flag for the new ioctl until > there is specific demand for that. Thanks for your advice :-) -- -keith signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 99801] Rx480 doesn't output properly onto z27q at 5120x2880
https://bugs.freedesktop.org/show_bug.cgi?id=99801 --- Comment #13 from Matthew Treinish --- I was wondering if there was any update on this? I'm still seeing the same issue on a 4.11.7 kernel. I'm willing to test out any patches or provide any additional debug info that is needed. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 194761] amdgpu driver breaks on Oland (SI)
https://bugzilla.kernel.org/show_bug.cgi?id=194761 Alexander Tsoy (alexan...@tsoy.me) changed: What|Removed |Added CC||alexan...@tsoy.me --- Comment #70 from Alexander Tsoy (alexan...@tsoy.me) --- For me P4_8x16 config fixed this issue. $ sudo dmesg | egrep 'RAM width|OLAND' [1.670667] [drm] initializing kernel modesetting (OLAND 0x1002:0x6613 0x174B:0xE266 0x00). [2.754782] [drm] RAM width 128bits GDDR5 -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/3] drm: Reorganize drm_pending_event to support future event types
Daniel Vetter writes: > A few nits below, but looks good otherwise. Thanks. >> static struct drm_pending_vblank_event *create_vblank_event( >> -struct drm_device *dev, uint64_t user_data) >> +struct drm_device *dev, struct drm_crtc *crtc, uint64_t >> user_data) > > Nit: Please also drop the dev argument, we have crtc->dev easily > available. That fits better into my long-term goal of getting rid of the > (dev, pipe) pairs everywhere in the vblank code and fully switching over > to drm_crtc *. As 'dev' isn't used anyways, this seems like a fine plan. >> +switch (e->event.base.type) { >> +case DRM_EVENT_VBLANK: >> +case DRM_EVENT_FLIP_COMPLETE: >> +if (seq) >> +e->event.vbl.sequence = (u32) seq; >> +if (now) { >> +e->event.vbl.tv_sec = now->tv_sec; >> +e->event.vbl.tv_usec = now->tv_nsec / 1000; >> +} >> +break; >> +} > > Not sure why this change? Also prep for the new, presumably extended > events? Seems at least slightly inconsistent with other paths, where we > still unconditionally fill it in. Yes, this prepares for the new events to make that patch smaller. The places where the data are still unconditionally assigned should know that the event in the struct is either a VBLANK or FLIP_COMPLETE. >> +struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); > > This'll oops on ums drivers since kms isn't set up. How about this fix? diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 857b7cf011e1..e39b2bd074e4 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1355,7 +1355,6 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, union drm_wait_vblank *vblwait, struct drm_file *file_priv) { - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; struct drm_pending_vblank_event *e; struct timespec now; @@ -1373,7 +1372,12 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, e->event.base.type = DRM_EVENT_VBLANK; e->event.base.length = sizeof(e->event.vbl); e->event.vbl.user_data = vblwait->request.signal; - e->event.vbl.crtc_id = crtc ? crtc->base.id : 0; + e->event.vbl.crtc_id = 0; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); + if (crtc) + e->event.vbl.crtc_id = crtc->base.id; + } spin_lock_irqsave(&dev->event_lock, flags); > Or maybe I shouldn't have told you this and seized this opportunity to > break all the old drivers :-) You now know my evil plan :-) -- -keith signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 194761] amdgpu driver breaks on Oland (SI)
https://bugzilla.kernel.org/show_bug.cgi?id=194761 --- Comment #71 from Alexander Tsoy (alexan...@tsoy.me) --- (In reply to Alexander Tsoy from comment #70) > For me P4_8x16 config fixed this issue. > > $ sudo dmesg | egrep 'RAM width|OLAND' > [1.670667] [drm] initializing kernel modesetting (OLAND 0x1002:0x6613 > 0x174B:0xE266 0x00). > [2.754782] [drm] RAM width 128bits GDDR5 To clarify a bit. I've applied the following two patches on top of 4.11.9: https://bugzilla.kernel.org/attachment.cgi?id=256727 https://bugzilla.kernel.org/attachment.cgi?id=256845 So I guess the following patch should also work for me: https://bugzilla.kernel.org/attachment.cgi?id=256949 -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
Daniel Vetter writes: > I very much like this since the old ioctl really is a rather bad horror > show. And since it's tied in with ums drivers everything is > complicated. Thanks for your kind words. > I started a discussion a while back whether these should be restricted to > DRM_MASTER (i.e. the modeset resource owner) or available to everyone. > Since it's read-only I guess we can keep it accessible to everyone, but it > has a bit the problem that client app developers see this, think it does > what it does and then use it to schedule frames without asking the > compositor. Which sometimes even works, but isn't really proper design. > The reasons seems to be that on X11 there's no EGL extension for accurate > timing frame updates (DRI2/3 can do it ofc, and glx exposes it, but glx is > uncool or something like that). In the absence of a suitable EGL api, I'm not sure what to suggest, other than fixing EGL instead of blaming the kernel... However, for the leasing stuff, this doesn't really matter as I've got a master FD to play with, so if you wanted to restrict it to master, that'd be fine by me. >> + >> +/* >> + * Get crtc VBLANK count. >> + * >> + * \param dev DRM device >> + * \param data user arguement, pointing to a drm_crtc_get_sequence >> structure. >> + * \param file_priv drm file private for the user's open file descriptor >> + */ > > Since this stuff isn't parsed by kerneldoc I tend to just free-form ioctl > comments completely. Someday maybe someone even gets around to doing > proper uabi documentation :-) Just an aside. I'm just trying to follow along with the local "conventions" in the file. Let me know if you have a future plan to make this better and I'll just reformat to suit. >> + >> +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, >> +struct drm_file *file_priv) >> +{ >> +struct drm_crtc *crtc; >> +int pipe; >> +struct drm_crtc_get_sequence *get_seq = data; >> +struct timespec now; >> + > > You need a DRIVER_MODESET check here or the drm_crtc_find will oops. Same > below. Like this? diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index e39b2bd074e4..3738ff484f36 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1712,6 +1712,9 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, struct drm_crtc_get_sequence *get_seq = data; struct timespec now; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + if (!dev->irq_enabled) return -EINVAL; @@ -1749,6 +1752,9 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data, int ret; unsigned long spin_flags; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + if (!dev->irq_enabled) return -EINVAL; >> +get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); > > This can give you and old vblank if the vblank is off (i.e. sw state > hasn't be regularly updated). I think we want a new > drm_crtc_accurate_vblank_count_and_time variant. Right, I saw that code in the wait_vblank case and forgot to carry it over. Here's a duplicate of what that function does; we'll need this code in any case for drivers which don't provide the necessary support for accurate vblank counts: --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1711,6 +1711,8 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, int pipe; struct drm_crtc_get_sequence *get_seq = data; struct timespec now; + bool vblank_enabled; + int ret; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; @@ -1724,8 +1726,19 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, pipe = drm_crtc_index(crtc); + vblank_enabled = dev->vblank_disable_immediately && READ_ONCE(vblank->enabled); + + if (!vblank_enabled) { + ret = drm_vblank_get(dev, pipe); + if (ret) { + DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); + return ret; + } + } get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); get_seq->sequence_ns = timespec_to_ns(&now); + if (!vblank_enabled) + drm_vblank_put(dev, pipe); return 0; } > Another thing that is very ill-defined in the old vblank ioctl and that we > could fix here: Asking for vblanks when the CRTC is off is a bit silly. > Asking for the sequence when it's off makes some sense, but might still be > good to give userspace some indication in the new struct? This also from > the pov of the unpriviledge vblank waiter use-case that I wondered about > earlier. Hrm. It's certainly easy to do, however an application using this withou
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
Ville Syrjälä writes: > Maybe, or maybe we want to turn the interrupt on in that case? That's > what the old ioctl does. That's what I suggested in my reply to Daniel's review. Even if we add the accurate function, we'll still need the interrupt-enable case as a fallback for drivers which don't support the accurate path, right? -- -keith signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 99292] GPU hang in High Fidelity
https://bugs.freedesktop.org/show_bug.cgi?id=99292 --- Comment #5 from Christoph Haag --- I don't know if it's still the same problem but now it always happens *very* quickly after starting the app. Here's a fresh api trace: https://haagch.frickel.club/files/interface-2.trace.xz -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
On Thu, Jul 06, 2017 at 09:28:40AM -0700, Keith Packard wrote: > Ville Syrjälä writes: > > > Maybe, or maybe we want to turn the interrupt on in that case? That's > > what the old ioctl does. > > That's what I suggested in my reply to Daniel's review. Even if we add > the accurate function, we'll still need the interrupt-enable case as a > fallback for drivers which don't support the accurate path, right? TBH I didn't even consider that case, but yeah makes sense. Otherwise the counter won't start to tick and the result of the query is pretty much useless. I was mostly thinking of the 'seq = query(); wait(seq + n);' pattern where we can avoid doing the full update more than once if we enable the interrupt already during the query. -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
Ville Syrjälä writes: > I was mostly thinking of the 'seq = query(); wait(seq + n);' pattern > where we can avoid doing the full update more than once if we enable > the interrupt already during the query. Don't we still wait 5 seconds before disabling vblank? In that case, the chances of hitting an idle vblank are pretty slim if the application is actually busy. -- -keith signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 99859] Glamor Crashes on big endian Hardware
https://bugs.freedesktop.org/show_bug.cgi?id=99859 --- Comment #22 from intermedi...@hotmail.com --- last mesa xorg log just to report. different error. with last mesa dev OpenGL core profile version string: 3.3 (Core Profile) Mesa 17.2.0-devel (git-f78aa2c986) [ 5057.542] (II) glamor: OpenGL accelerated X.org driver based. [ 5057.583] (EE) [ 5057.583] (EE) Backtrace: [ 5057.584] (EE) 0: /usr/libexec/Xorg (OsLookupColor+0x23c) [0x1021908c] [ 5057.585] (EE) 1: linux-vdso64.so.1 (?+0x23c) [0x3fff88570710] [ 5057.585] (EE) unw_get_proc_info failed: no unwind info found [-10] [ 5057.585] (EE) [ 5057.585] (EE) Segmentation fault at address 0x2b56ebec [ 5057.585] (EE) Fatal server error: [ 5057.585] (EE) Caught signal 11 (Segmentation fault). Server aborting -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 196273] Loss of video output and system freezes *ERROR* Couldn't read SADs: 0
https://bugzilla.kernel.org/show_bug.cgi?id=196273 --- Comment #8 from Olaf H B (o...@seldiame.net) --- (In reply to Michel Dänzer from comment #6) > Is this a regression from older kernel versions? If yes, can you bisect? I don't think this is a regression because I had similar issues with kernel 4.11 I got other freeze some minutes ago. This appears in the kernel.log: (complete file in attachment) Jul 6 13:18:35 hiperion kernel: [47523.933893] general protection fault: [#1] SMP Jul 6 13:18:35 hiperion kernel: [47523.934043] Modules linked in: kvm_amd kvm irqbypass aesni_intel aes_x86_64 amdgpu crypto_simd cryptd glue_helper input_leds fam15h_power k10temp mfd_core backlight ttm acpi_cpufreq Jul 6 13:18:35 hiperion kernel: [47523.934565] CPU: 2 PID: 12681 Comm: Timer Not tainted 4.12.0 #3 Jul 6 13:18:35 hiperion kernel: [47523.934746] Hardware name: To be filled by O.E.M. To be filled by O.E.M./M5A97 R2.0, BIOS 2603 06/26/2015 Jul 6 13:18:35 hiperion kernel: [47523.935031] task: 88031ba00d00 task.stack: c900015b8000 Jul 6 13:18:35 hiperion kernel: [47523.935146] RIP: 0010:0x8106674e Jul 6 13:18:35 hiperion kernel: [47523.935178] RSP: 0018:c900015bbcd8 EFLAGS: 00010002 Jul 6 13:18:35 hiperion kernel: [47523.935221] RAX: 81808320 RBX: 8804294aa700 RCX: 0001 Jul 6 13:18:35 hiperion kernel: [47523.935276] RDX: 0010 RSI: RDI: 8804294aa700 Jul 6 13:18:35 hiperion kernel: [47523.935332] RBP: c900015bbd20 R08: 0041 R09: 0001 Jul 6 13:18:35 hiperion kernel: [47523.935387] R10: ea000c6fed00 R11: R12: 0001 Jul 6 13:18:35 hiperion kernel: [47523.935443] R13: 8804294aadbc R14: 0046 R15: 00018740 Jul 6 13:18:35 hiperion kernel: [47523.935499] FS: 7f2b6bb57700() GS:88043ec8() knlGS: Jul 6 13:18:35 hiperion kernel: [47523.935561] CS: 0010 DS: ES: CR0: 80050033 Jul 6 13:18:35 hiperion kernel: [47523.935607] CR2: 7f53897ea000 CR3: 0003c397f000 CR4: 000406e0 Jul 6 13:18:35 hiperion kernel: [47523.935662] Call Trace: Jul 6 13:18:35 hiperion kernel: [47523.935685] 0x81066aad Jul 6 13:18:35 hiperion kernel: [47523.935712] 0x8114a7c1 Jul 6 13:18:35 hiperion kernel: [47523.935738] ? 0x81066aa0 Jul 6 13:18:35 hiperion kernel: [47523.935766] 0x8107a1cd Jul 6 13:18:35 hiperion kernel: [47523.935792] 0x8107a70f Jul 6 13:18:35 hiperion kernel: [47523.935818] 0x8113e761 Jul 6 13:18:35 hiperion kernel: [47523.935845] 0x81134dff Jul 6 13:18:35 hiperion kernel: [47523.935872] 0x8113569e Jul 6 13:18:35 hiperion kernel: [47523.935898] ? 0x810adcf8 Jul 6 13:18:35 hiperion kernel: [47523.935925] 0x81136b8a Jul 6 13:18:35 hiperion kernel: [47523.935952] 0x816b96a0 Jul 6 13:18:35 hiperion kernel: [47523.935978] RIP: 0033:0x7f2b8be0fe5d Jul 6 13:18:35 hiperion kernel: [47523.936010] RSP: 002b:7f2b6bb56790 EFLAGS: 0293 ORIG_RAX: 0001 Jul 6 13:18:35 hiperion kernel: [47523.936070] RAX: ffda RBX: 7f2b8bd3edb0 RCX: 7f2b8be0fe5d Jul 6 13:18:35 hiperion kernel: [47523.936125] RDX: 0001 RSI: 7f2b6bb567a7 RDI: 001b Jul 6 13:18:35 hiperion kernel: [47523.936180] RBP: 00fa R08: 7f2b76687908 R09: Jul 6 13:18:35 hiperion kernel: [47523.936234] R10: 002b R11: 0293 R12: 0005 Jul 6 13:18:35 hiperion kernel: [47523.936289] R13: R14: 7f2b6bb56a28 R15: 2b38d797ff91 Jul 6 13:18:35 hiperion kernel: [47523.936368] Code: 88 83 04 04 00 00 0f 85 66 01 00 00 83 bb 1c 03 00 00 01 0f 8e b8 01 00 00 48 8b 43 68 ba 10 00 00 00 8b 73 50 44 89 e1 48 89 df 50 40 48 8d 93 20 03 00 00 41 89 c0 44 89 c0 48 0f a3 02 0f Jul 6 13:18:35 hiperion kernel: [47523.936551] RIP: 0x8106674e RSP: c900015bbcd8 Jul 6 13:18:35 hiperion kernel: [47523.956831] ---[ end trace de9deca7f7bcb1e8 ]--- -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 196273] Loss of video output and system freezes *ERROR* Couldn't read SADs: 0
https://bugzilla.kernel.org/show_bug.cgi?id=196273 --- Comment #9 from Olaf H B (o...@seldiame.net) --- Created attachment 257391 --> https://bugzilla.kernel.org/attachment.cgi?id=257391&action=edit kern.log -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
On Thu, Jul 06, 2017 at 11:22:43AM -0700, Keith Packard wrote: > Ville Syrjälä writes: > > > I was mostly thinking of the 'seq = query(); wait(seq + n);' pattern > > where we can avoid doing the full update more than once if we enable > > the interrupt already during the query. > > Don't we still wait 5 seconds before disabling vblank? In that case, the > chances of hitting an idle vblank are pretty slim if the application is > actually busy. With the disable_immediate thing we only wait until the next vblank before disabling the irq again. -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 196273] Loss of video output and system freezes *ERROR* Couldn't read SADs: 0
https://bugzilla.kernel.org/show_bug.cgi?id=196273 --- Comment #10 from Alex Deucher (alexdeuc...@gmail.com) --- Can you get a log with symbols? -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 4/4] drm/i915: Acquire PUNIT->PMIC bus for intel_uncore_forcewake_reset()
intel_uncore_forcewake_reset() does forcewake puts and gets as such we need to make sure that no-one tries to access the PUNIT->PMIC bus (on systems where this bus is shared) while it runs, otherwise bad things happen. Normally this is taken care of by the i915_pmic_bus_access_notifier() which does an intel_uncore_forcewake_get(FORCEWAKE_ALL) when some other driver tries to access the PMIC bus, so that later forcewake gets are no-ops (for the duration of the bus access). But intel_uncore_forcewake_reset gets called in 3 cases: 1) Before registering the pmic_bus_access_notifier 2) After unregistering the pmic_bus_access_notifier 3) To reset forcewake state on a GPU reset In all 3 cases the i915_pmic_bus_access_notifier() protection is insufficient. This commit fixes the pmic bus access race this causes by making intel_uncore_forcewake_reset() call iosf_mbi_punit_acquire() (and iosf_mbi_punit_release() when done). Note that iosf_mbi_punit_acquire() locks a mutex and thus intel_uncore_forcewake_reset() may sleep after this commit. I've checked all callers and they all already take other mutexes, so this is not a problem. Signed-off-by: Hans de Goede --- Changes in v2: -Rebase on current (July 6th 2017) drm-next --- drivers/gpu/drm/i915/intel_uncore.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 4a547cdfafa9..f9441c9ae226 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -237,6 +237,9 @@ static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv, int retry_count = 100; enum forcewake_domains fw, active_domains; + /* Acquire the PUNIT->PMIC bus before modifying forcewake settings */ + iosf_mbi_punit_acquire(); + /* Hold uncore.lock across reset to prevent any register access * with forcewake not set correctly. Wait until all pending * timers are run before holding. @@ -294,6 +297,7 @@ static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv, assert_forcewakes_inactive(dev_priv); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); + iosf_mbi_punit_release(); } static u64 gen9_edram_size(struct drm_i915_private *dev_priv) -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 1/4] drm/i915: Fix false-positive assert_rpm_wakelock_held in i915_pmic_bus_access_notifier
assert_rpm_wakelock_held is triggered from i915_pmic_bus_access_notifier even though it gets unregistered on (runtime) suspend, this is caused by a race happening under the following circumstances: intel_runtime_pm_put does: atomic_dec(&dev_priv->pm.wakeref_count); pm_runtime_mark_last_busy(kdev); pm_runtime_put_autosuspend(kdev); And pm_runtime_put_autosuspend calls intel_runtime_suspend from a workqueue, so there is ample of time between the atomic_dec() and intel_runtime_suspend() unregistering the notifier. If the notifier gets called in this windowd assert_rpm_wakelock_held falsely triggers (at this point we're not runtime-suspended yet). This commit adds disable_rpm_wakeref_asserts and enable_rpm_wakeref_asserts calls around the intel_uncore_forcewake_get(FORCEWAKE_ALL) call in i915_pmic_bus_access_notifier fixing the false-positive WARN_ON. Reported-by: FKr Signed-off-by: Hans de Goede --- Changes in v2: -Rebase on current (July 6th 2017) drm-next --- drivers/gpu/drm/i915/intel_uncore.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 9882724bc2b6..168b28a87f76 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1171,8 +1171,15 @@ static int i915_pmic_bus_access_notifier(struct notifier_block *nb, * bus, which will be busy after this notification, leading to: * "render: timed out waiting for forcewake ack request." * errors. +* +* This notifier may get called between intel_runtime_pm_put() +* doing atomic_dec(wakeref_count) and intel_runtime_resume() +* unregistering this notifier, which leads to false-positive +* assert_rpm_wakelock_held() triggering. */ + disable_rpm_wakeref_asserts(dev_priv); intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + enable_rpm_wakeref_asserts(dev_priv); break; case MBI_PMIC_BUS_ACCESS_END: intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/4] drm/i915: Re-register PMIC bus access notifier on runtime resume
intel_uncore_suspend() unregisters the uncore code's PMIC bus access notifier and gets called on both normal and runtime suspend. intel_uncore_resume_early() re-registers the notifier, but only on normal resume. Add a new intel_uncore_runtime_resume() function which only re-registers the notifier and call that on runtime resume. Reported-by: Imre Deak Signed-off-by: Hans de Goede --- Changes in v2: -Rebase on current (July 6th 2017) drm-next --- drivers/gpu/drm/i915/i915_drv.c | 2 ++ drivers/gpu/drm/i915/intel_uncore.c | 6 ++ drivers/gpu/drm/i915/intel_uncore.h | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ee2325b180e7..ce31d9ed23dc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2510,6 +2510,8 @@ static int intel_runtime_resume(struct device *kdev) ret = vlv_resume_prepare(dev_priv, true); } + intel_uncore_runtime_resume(dev_priv); + /* * No point of rolling back things in case of an error, as the best * we can do is to hope that things will still work (and disable RPM). diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 168b28a87f76..4a547cdfafa9 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -434,6 +434,12 @@ void intel_uncore_resume_early(struct drm_i915_private *dev_priv) i915_check_and_clear_faults(dev_priv); } +void intel_uncore_runtime_resume(struct drm_i915_private *dev_priv) +{ + iosf_mbi_register_pmic_bus_access_notifier( + &dev_priv->uncore.pmic_bus_access_nb); +} + void intel_uncore_sanitize(struct drm_i915_private *dev_priv) { i915.enable_rc6 = sanitize_rc6_option(dev_priv, i915.enable_rc6); diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 5f90278da461..0bdc3fcc0e64 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -121,6 +121,7 @@ bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv void intel_uncore_fini(struct drm_i915_private *dev_priv); void intel_uncore_suspend(struct drm_i915_private *dev_priv); void intel_uncore_resume_early(struct drm_i915_private *dev_priv); +void intel_uncore_runtime_resume(struct drm_i915_private *dev_priv); u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv); void assert_forcewakes_inactive(struct drm_i915_private *dev_priv); -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 3/4] drm/i915: Call uncore_suspend before platform suspend handlers
Quoting Ville: "the forcewake timer might still be active until the uncore suspend, and having active forcewakes while we've already told the GT wake stuff to stop acting normally doesn't seem quite right to me." Reported-by: Ville Syrjälä Suggested-by: Imre Deak Signed-off-by: Hans de Goede --- Changes in v2: -Rebase on current (July 6th 2017) drm-next --- drivers/gpu/drm/i915/i915_drv.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ce31d9ed23dc..4a6cd3176e0a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2415,6 +2415,8 @@ static int intel_runtime_suspend(struct device *kdev) intel_runtime_pm_disable_interrupts(dev_priv); + intel_uncore_suspend(dev_priv); + ret = 0; if (IS_GEN9_LP(dev_priv)) { bxt_display_core_uninit(dev_priv); @@ -2427,6 +2429,8 @@ static int intel_runtime_suspend(struct device *kdev) if (ret) { DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret); + intel_uncore_runtime_resume(dev_priv); + intel_runtime_pm_enable_interrupts(dev_priv); enable_rpm_wakeref_asserts(dev_priv); @@ -2434,8 +2438,6 @@ static int intel_runtime_suspend(struct device *kdev) return ret; } - intel_uncore_suspend(dev_priv); - enable_rpm_wakeref_asserts(dev_priv); WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count)); -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
Ville Syrjälä writes: > With the disable_immediate thing we only wait until the next vblank > before disabling the irq again. Ok, still sounds like we'll be doing fine if the application does a get immediately followed by a queue event. At least most of the time. -- -keith signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 01/22] drm/i915: Pass the new crtc state to color management code
From: Ville Syrjälä In an effort to eliminate the obj->state usage let's pass on the new crtc state pointer (which we already have!) to the color management code. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0648fd74be87..90fba8a44630 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13546,8 +13546,8 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, if (!modeset && (intel_cstate->base.color_mgmt_changed || intel_cstate->update_pipe)) { - intel_color_set_csc(crtc->state); - intel_color_load_luts(crtc->state); + intel_color_set_csc(&intel_cstate->base); + intel_color_load_luts(&intel_cstate->base); } /* Perform vblank evasion around commit operation */ -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 03/22] drm/i915: Eliminate obj->state usage in g4x/vlv/chv wm computation
From: Ville Syrjälä Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.h | 9 + drivers/gpu/drm/i915/intel_drv.h | 8 drivers/gpu/drm/i915/intel_pm.c | 30 +++--- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 81cd21ecfa7d..baec61b078f5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -563,6 +563,15 @@ struct i915_hotplug { (__i)++) \ for_each_if (plane_state) +#define for_each_oldnew_intel_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \ + for ((__i) = 0; \ +(__i) < (__state)->base.dev->mode_config.num_total_plane && \ +((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \ + (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), \ + (new_plane_state) = to_intel_plane_state((__state)->base.planes[__i].new_state), 1); \ +(__i)++) \ + for_each_if (plane) + struct drm_i915_private; struct i915_mm_struct; struct i915_mmu_object; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d22ca42f35da..e9d61a03c46e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1208,6 +1208,14 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) } static inline struct intel_crtc_state * +intel_atomic_get_old_crtc_state(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + return to_intel_crtc_state(drm_atomic_get_old_crtc_state(&state->base, +&crtc->base)); +} + +static inline struct intel_crtc_state * intel_atomic_get_new_crtc_state(struct intel_atomic_state *state, struct intel_crtc *crtc) { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c3fcadfa0ae7..62320d70dc6f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1302,21 +1302,21 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state) int num_active_planes = hweight32(crtc_state->active_planes & ~BIT(PLANE_CURSOR)); const struct g4x_pipe_wm *raw; - struct intel_plane_state *plane_state; + const struct intel_plane_state *old_plane_state; + const struct intel_plane_state *new_plane_state; struct intel_plane *plane; enum plane_id plane_id; int i, level; unsigned int dirty = 0; - for_each_intel_plane_in_state(state, plane, plane_state, i) { - const struct intel_plane_state *old_plane_state = - to_intel_plane_state(plane->base.state); - - if (plane_state->base.crtc != &crtc->base && + for_each_oldnew_intel_plane_in_state(state, plane, +old_plane_state, +new_plane_state, i) { + if (new_plane_state->base.crtc != &crtc->base && old_plane_state->base.crtc != &crtc->base) continue; - if (g4x_raw_plane_wm_compute(crtc_state, plane_state)) + if (g4x_raw_plane_wm_compute(crtc_state, new_plane_state)) dirty |= BIT(plane->id); } @@ -1811,21 +1811,21 @@ static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state) int num_active_planes = hweight32(crtc_state->active_planes & ~BIT(PLANE_CURSOR)); bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->base); - struct intel_plane_state *plane_state; + const struct intel_plane_state *old_plane_state; + const struct intel_plane_state *new_plane_state; struct intel_plane *plane; enum plane_id plane_id; int level, ret, i; unsigned int dirty = 0; - for_each_intel_plane_in_state(state, plane, plane_state, i) { - const struct intel_plane_state *old_plane_state = - to_intel_plane_state(plane->base.state); - - if (plane_state->base.crtc != &crtc->base && + for_each_oldnew_intel_plane_in_state(state, plane, +old_plane_state, +new_plane_state, i) { + if (new_plane_state->base.crtc != &crtc->base && old_plane_state->base.crtc != &crtc->base) continue; - if (vlv_raw_plane_wm_compute(crtc_state, plane_state)) + if (vlv_raw_plane_wm_compute(crtc_state, new_plane_state)) dirty |= BIT(plane->id); } @@ -1844,7 +1844
[PATCH 02/22] drm/i915: Pass the crtc state explicitly to intel_pipe_update_start/end()
From: Ville Syrjälä Pass the appropriate new crtc state explicitly to intel_pipe_update_start/end() instead of of mucking around with crtc->state. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 18 +++--- drivers/gpu/drm/i915/intel_drv.h | 13 +++-- drivers/gpu/drm/i915/intel_sprite.c | 28 ++-- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 90fba8a44630..cdfa95be4b8e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10645,7 +10645,7 @@ static void intel_mmio_flip_work_func(struct work_struct *w) WARN_ON(i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT, NULL) < 0); - intel_pipe_update_start(crtc); + intel_pipe_update_start(crtc->config); if (INTEL_GEN(dev_priv) >= 9) skl_do_mmio_flip(crtc, work->rotation, work); @@ -10653,7 +10653,7 @@ static void intel_mmio_flip_work_func(struct work_struct *w) /* use_mmio_flip() retricts MMIO flips to ilk+ */ ilk_do_mmio_flip(crtc, work); - intel_pipe_update_end(crtc, work); + intel_pipe_update_end(crtc->config, work); } static int intel_default_queue_flip(struct drm_device *dev, @@ -13535,13 +13535,13 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *intel_cstate = - to_intel_crtc_state(crtc->state); struct intel_crtc_state *old_intel_cstate = to_intel_crtc_state(old_crtc_state); struct intel_atomic_state *old_intel_state = to_intel_atomic_state(old_crtc_state->state); - bool modeset = needs_modeset(crtc->state); + struct intel_crtc_state *intel_cstate = + intel_atomic_get_new_crtc_state(old_intel_state, intel_crtc); + bool modeset = needs_modeset(&intel_cstate->base); if (!modeset && (intel_cstate->base.color_mgmt_changed || @@ -13551,7 +13551,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, } /* Perform vblank evasion around commit operation */ - intel_pipe_update_start(intel_crtc); + intel_pipe_update_start(intel_cstate); if (modeset) goto out; @@ -13571,8 +13571,12 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_atomic_state *old_intel_state = + to_intel_atomic_state(old_crtc_state->state); + struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(old_intel_state, intel_crtc); - intel_pipe_update_end(intel_crtc, NULL); + intel_pipe_update_end(new_crtc_state, NULL); } /** diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d17a32437f07..d22ca42f35da 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1207,6 +1207,14 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) return container_of(intel_hdmi, struct intel_digital_port, hdmi); } +static inline struct intel_crtc_state * +intel_atomic_get_new_crtc_state(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + return to_intel_crtc_state(drm_atomic_get_new_crtc_state(&state->base, +&crtc->base)); +} + /* intel_fifo_underrun.c */ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable); @@ -1900,8 +1908,9 @@ struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe, int plane); int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); -void intel_pipe_update_start(struct intel_crtc *crtc); -void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work); +void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state); +void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state, + struct intel_flip_work *work); /* intel_tv.c */ void intel_tv_init(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 0c650c2cbca8..697b95016c7a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -69,8 +69,7 @@ int intel_usecs_to_scanlines(const struct drm_display_mo
[PATCH 05/22] drm/i915: Eliminate obj->state usage from pre/post plane update
From: Ville Syrjälä Dig up the appropriate new crtc and plane states from the top level atomic state in intel_pre_plane_update() and intel_post_plane_update(). Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6440479d6fe2..182881c4d6d3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4994,7 +4994,8 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); struct drm_atomic_state *old_state = old_crtc_state->base.state; struct intel_crtc_state *pipe_config = - to_intel_crtc_state(crtc->base.state); + intel_atomic_get_new_crtc_state(to_intel_atomic_state(old_state), + crtc); struct drm_plane *primary = crtc->base.primary; struct drm_plane_state *old_pri_state = drm_atomic_get_existing_plane_state(old_state, primary); @@ -5006,7 +5007,8 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) if (old_pri_state) { struct intel_plane_state *primary_state = - to_intel_plane_state(primary->state); + intel_atomic_get_new_plane_state(to_intel_atomic_state(old_state), + to_intel_plane(primary)); struct intel_plane_state *old_primary_state = to_intel_plane_state(old_pri_state); @@ -5035,7 +5037,8 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state, if (old_pri_state) { struct intel_plane_state *primary_state = - to_intel_plane_state(primary->state); + intel_atomic_get_new_plane_state(old_intel_state, + to_intel_plane(primary)); struct intel_plane_state *old_primary_state = to_intel_plane_state(old_pri_state); -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 00/22] drm/i915: Fix pre-g4x GPU reset, again (v2)
From: Ville Syrjälä OK, so here's the full version of my rw_semaphore GPU vs. display reset fix. The only issue I'm aware of is that SKL watermark code still uses obj->state and thus I have no clue what would happen if one tries to run this on SKL. Untangling that would likely mean making the SKL wm code more in line with the g4x/vlv/chv code (ie. track things in the crtc state). I decided not to embark on that quest at this time. Entire series available here: git://github.com/vsyrjala/linux.git reset_commit_rwsem_4 Ville Syrjälä (22): drm/i915: Pass the new crtc state to color management code drm/i915: Pass the crtc state explicitly to intel_pipe_update_start/end() drm/i915: Eliminate obj->state usage in g4x/vlv/chv wm computation drm/i915: Pass proper old/new states to intel_plane_atomic_check_with_state() drm/i915: Eliminate obj->state usage from pre/post plane update drm/i915: Eliminate crtc->state usage from intel_update_pipe_config() drm/i915: Eliminate crtc->state usage from intel_atomic_commit_tail and .crtc_update() drm: Add drm_dynarray drm/atomic: Convert state->connectors to drm_dynarray drm/atomic: Remove pointless private object NULL state check drm/atomic: Convert private_objs to drm_dynarray drm/atomic: Make private objs proper objects drm/atomic: Pass old state to __drm_atomic_helper_crtc_duplicate_state() & co. explicitly drm/arm: s/old_state/old_mali_state/ drm/mediatek: s/old_state/old_mtk_state/ drm/atomic: Pass old state explicitly to .atomic_duplicate_state() drm/atomic: Fix up the kernel docs for the state duplication functions drm: Return the connector from drm_connector_get() drm/i915% Store vma gtt offset in plane state drm/i915: Refactor __intel_atomic_commit_tail() drm/atomic: Introduce drm_atomic_helper_duplicate_commited_state() drm/i915: Solve the GPU reset vs. modeset deadlocks with an rw_semaphore Documentation/gpu/drm-utils.rst | 15 ++ Documentation/gpu/index.rst | 1 + drivers/gpu/drm/Makefile| 2 +- drivers/gpu/drm/arm/malidp_crtc.c | 18 +- drivers/gpu/drm/arm/malidp_planes.c | 10 +- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 10 +- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 5 +- drivers/gpu/drm/drm_atomic.c| 174 +++- drivers/gpu/drm/drm_atomic_helper.c | 318 -- drivers/gpu/drm/drm_crtc_helper.c | 12 +- drivers/gpu/drm/drm_dp_mst_topology.c | 65 +++-- drivers/gpu/drm/drm_dynarray.c | 97 +++ drivers/gpu/drm/drm_fb_helper.c | 7 +- drivers/gpu/drm/drm_plane_helper.c | 12 +- drivers/gpu/drm/exynos/exynos_drm_plane.c | 8 +- drivers/gpu/drm/i915/i915_drv.h | 11 + drivers/gpu/drm/i915/intel_atomic.c | 16 +- drivers/gpu/drm/i915/intel_atomic_plane.c | 47 ++-- drivers/gpu/drm/i915/intel_display.c| 342 drivers/gpu/drm/i915/intel_drv.h| 52 +++- drivers/gpu/drm/i915/intel_pm.c | 30 +-- drivers/gpu/drm/i915/intel_sdvo.c | 9 +- drivers/gpu/drm/i915/intel_sprite.c | 37 +-- drivers/gpu/drm/imx/ipuv3-crtc.c| 6 +- drivers/gpu/drm/imx/ipuv3-plane.c | 8 +- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 6 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 10 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c| 10 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 14 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 8 +- drivers/gpu/drm/nouveau/nouveau_connector.h | 3 +- drivers/gpu/drm/nouveau/nv50_display.c | 16 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 10 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 10 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 +- drivers/gpu/drm/tegra/dc.c | 16 +- drivers/gpu/drm/tegra/dsi.c | 8 +- drivers/gpu/drm/tegra/sor.c | 8 +- drivers/gpu/drm/vc4/vc4_crtc.c | 6 +- drivers/gpu/drm/vc4/vc4_plane.c | 10 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 26 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 9 +- include/drm/drm_atomic.h| 179 - include/drm/drm_atomic_helper.h | 31 ++- include/drm/drm_connector.h | 23 +- include/drm/drm_crtc.h | 16 +- include/drm/drm_dp_mst_helper.h | 10 + include/drm/drm_dynarray.h | 54 include/drm/drm_plane.h | 16 +- 49 files changed, 1324 insertions(+), 493 deletions(-) create mode 100644 Documentation/gpu/drm-utils.rst create mode 100644 drivers/gpu/drm/drm
[PATCH 04/22] drm/i915: Pass proper old/new states to intel_plane_atomic_check_with_state()
From: Ville Syrjälä Eliminate plane->state and crtc->state usage from intel_plane_atomic_check_with_state() and its callers. Instead pass the proper states in or dig them up from the top level atomic state. Note that intel_plane_atomic_check_with_state() itself isn't allowed to use the top level atomic state as there is none when it gets called from the legacy cursor short circuit path. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_atomic_plane.c | 40 +++ drivers/gpu/drm/i915/intel_display.c | 12 ++ drivers/gpu/drm/i915/intel_drv.h | 16 +++-- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index ee76fab7bb6f..7cdbe9ae2c96 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -107,7 +107,9 @@ intel_plane_destroy_state(struct drm_plane *plane, drm_atomic_helper_plane_destroy_state(plane, state); } -int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state, +int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *crtc_state, + const struct intel_plane_state *old_plane_state, struct intel_plane_state *intel_state) { struct drm_plane *plane = intel_state->base.plane; @@ -124,7 +126,7 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state, * anything driver-specific we need to test in that case, so * just return success. */ - if (!intel_state->base.crtc && !plane->state->crtc) + if (!intel_state->base.crtc && !old_plane_state->base.crtc) return 0; /* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */ @@ -194,17 +196,21 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state, else crtc_state->active_planes &= ~BIT(intel_plane->id); - return intel_plane_atomic_calc_changes(&crtc_state->base, state); + return intel_plane_atomic_calc_changes(old_crtc_state, + &crtc_state->base, + old_plane_state, + state); } static int intel_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { - struct drm_crtc *crtc = state->crtc; + const struct drm_plane_state *old_plane_state = + drm_atomic_get_old_plane_state(state->state, plane); + struct drm_crtc *crtc = state->crtc ?: old_plane_state->crtc; + const struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *drm_crtc_state; - crtc = crtc ? crtc : plane->state->crtc; - /* * Both crtc and plane->crtc could be NULL if we're updating a * property while the plane is disabled. We don't actually have @@ -214,29 +220,33 @@ static int intel_plane_atomic_check(struct drm_plane *plane, if (!crtc) return 0; - drm_crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); - if (WARN_ON(!drm_crtc_state)) - return -EINVAL; + old_crtc_state = drm_atomic_get_old_crtc_state(state->state, crtc); + drm_crtc_state = drm_atomic_get_new_crtc_state(state->state, crtc); - return intel_plane_atomic_check_with_state(to_intel_crtc_state(drm_crtc_state), + return intel_plane_atomic_check_with_state(to_intel_crtc_state(old_crtc_state), + to_intel_crtc_state(drm_crtc_state), + to_intel_plane_state(old_plane_state), to_intel_plane_state(state)); } static void intel_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { + struct intel_atomic_state *state = to_intel_atomic_state(old_state->state); struct intel_plane *intel_plane = to_intel_plane(plane); - struct intel_plane_state *intel_state = - to_intel_plane_state(plane->state); - struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc; + const struct intel_plane_state *intel_state = + intel_atomic_get_new_plane_state(state, intel_plane); + struct drm_crtc *crtc = intel_state->base.crtc ?: old_state->crtc; if (intel_state->base.visible) { + const struct intel_crtc_state *intel_crtc_state = + intel_atomic_get_new_crtc_state(state, to_intel_crtc(crtc)); + trace_intel_update_plane(plane, to_intel_crtc(c
[PATCH 07/22] drm/i915: Eliminate crtc->state usage from intel_atomic_commit_tail and .crtc_update()
From: Ville Syrjälä We already have the correct new crtc state so just use that instead of crtc->state. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0c18e3e7c6a5..791204c8621c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12970,7 +12970,7 @@ static void skl_update_crtcs(struct drm_atomic_state *state, unsigned int cmask = drm_crtc_mask(crtc); intel_crtc = to_intel_crtc(crtc); - cstate = to_intel_crtc_state(crtc->state); + cstate = to_intel_crtc_state(new_crtc_state); pipe = intel_crtc->pipe; if (updated & cmask || !cstate->base.active) @@ -13073,7 +13073,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) intel_check_cpu_fifo_underruns(dev_priv); intel_check_pch_fifo_underruns(dev_priv); - if (!crtc->state->active) { + if (!new_crtc_state->active) { /* * Make sure we don't call initial_watermarks * for ILK-style watermark updates. @@ -13082,7 +13082,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) */ if (INTEL_GEN(dev_priv) >= 9) dev_priv->display.initial_watermarks(intel_state, - to_intel_crtc_state(crtc->state)); + to_intel_crtc_state(new_crtc_state)); } } } -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 06/22] drm/i915: Eliminate crtc->state usage from intel_update_pipe_config()
From: Ville Syrjälä Pass the correct new crtc state to intel_update_pipe_config() instead of using crtc->state. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 182881c4d6d3..0c18e3e7c6a5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3633,15 +3633,14 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) return pending; } -static void intel_update_pipe_config(struct intel_crtc *crtc, -struct intel_crtc_state *old_crtc_state) +static void intel_update_pipe_config(const struct intel_crtc_state *old_crtc_state, +const struct intel_crtc_state *new_crtc_state) { + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_crtc_state *pipe_config = - to_intel_crtc_state(crtc->base.state); /* drm_atomic_helper_update_legacy_modeset_state might not be called. */ - crtc->base.mode = crtc->base.state->mode; + crtc->base.mode = new_crtc_state->base.mode; /* * Update pipe size and adjust fitter if needed: the reason for this is @@ -3653,17 +3652,17 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, */ I915_WRITE(PIPESRC(crtc->pipe), - ((pipe_config->pipe_src_w - 1) << 16) | - (pipe_config->pipe_src_h - 1)); + ((new_crtc_state->pipe_src_w - 1) << 16) | + (new_crtc_state->pipe_src_h - 1)); /* on skylake this is done by detaching scalers */ if (INTEL_GEN(dev_priv) >= 9) { skl_detach_scalers(crtc); - if (pipe_config->pch_pfit.enabled) + if (new_crtc_state->pch_pfit.enabled) skylake_pfit_enable(crtc); } else if (HAS_PCH_SPLIT(dev_priv)) { - if (pipe_config->pch_pfit.enabled) + if (new_crtc_state->pch_pfit.enabled) ironlake_pfit_enable(crtc); else if (old_crtc_state->pch_pfit.enabled) ironlake_pfit_disable(crtc, true); @@ -13560,7 +13559,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, goto out; if (intel_cstate->update_pipe) - intel_update_pipe_config(intel_crtc, old_intel_cstate); + intel_update_pipe_config(old_intel_cstate, intel_cstate); else if (INTEL_GEN(dev_priv) >= 9) skl_detach_scalers(intel_crtc); -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 08/22] drm: Add drm_dynarray
From: Ville Syrjälä Add a small helper that gives us dynamically growing arrays. We have a couple hand rolled implementations of this in the atomic code, which we can unify to use a common implementation. Signed-off-by: Ville Syrjälä --- Documentation/gpu/drm-utils.rst | 15 +++ Documentation/gpu/index.rst | 1 + drivers/gpu/drm/Makefile| 2 +- drivers/gpu/drm/drm_dynarray.c | 97 + include/drm/drm_dynarray.h | 54 +++ 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 Documentation/gpu/drm-utils.rst create mode 100644 drivers/gpu/drm/drm_dynarray.c create mode 100644 include/drm/drm_dynarray.h diff --git a/Documentation/gpu/drm-utils.rst b/Documentation/gpu/drm-utils.rst new file mode 100644 index ..bff8c899d7cd --- /dev/null +++ b/Documentation/gpu/drm-utils.rst @@ -0,0 +1,15 @@ += +DRM Utilities += + +Dynamic arrays +-- + +.. kernel-doc:: drivers/gpu/drm/drm_dynarray.c + :doc: Dynamic arrays + +.. kernel-doc:: drivers/gpu/drm/drm_dynarray.c + :export: + +.. kernel-doc:: include/drm/drm_dynarray.h + :internal: diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index 35d673bf9b56..b7d196e5c70d 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -10,6 +10,7 @@ Linux GPU Driver Developer's Guide drm-kms drm-kms-helpers drm-uapi + drm-utils i915 meson pl111 diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 24a066e1841c..b637a34df388 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. drm-y := drm_auth.o drm_bufs.o drm_cache.o \ - drm_context.o drm_dma.o \ + drm_context.o drm_dma.o drm_dynarray.o \ drm_file.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_drv.o \ drm_scatter.o drm_pci.o \ diff --git a/drivers/gpu/drm/drm_dynarray.c b/drivers/gpu/drm/drm_dynarray.c new file mode 100644 index ..69a8819ecb62 --- /dev/null +++ b/drivers/gpu/drm/drm_dynarray.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +/** + * DOC: Dynamic arrays + * + * Helper that provides dynamically growing arrays. The array + * must be initilaized to specify the size of each element, and + * space can be reserved in the array by specifying the element + * index to be used. + */ + +/** + * drm_dynarray_init - Initialize the dynamic array + * @dynarr: the dynamic array + * @elem_size: size of each element in bytes + * + * Initialize the dynamic array and specify the size of + * each element of the array. + */ +void drm_dynarray_init(struct drm_dynarray *dynarr, + unsigned int elem_size) +{ + memset(dynarr, 0, sizeof(*dynarr)); + dynarr->elem_size = elem_size; +} +EXPORT_SYMBOL(drm_dynarray_init); + +/** + * drm_dynarray_fini - Finalize the dynamic array + * @dynarr: the dynamic array + * + * Finalize the dynamic array, ie. free the memory + * used by the array. + */ +void drm_dynarray_fini(struct drm_dynarray *dynarr) +{ + kfree(dynarr->elems); + memset(dynarr, 0, sizeof(*dynarr)); +} +EXPORT_SYMBOL(drm_dynarray_fini); + +/** + * drm_dynarray_reserve - Reserve space in the dynamic array + * @dynarr: the dynamic array + * @index: the index of the element to reserve + * + * Grow the array sufficiently to make sure @index points + * to a valid memory location within the array. + */ +int drm_dynarray_reserve(struct drm_dynarray *dynarr, +unsigned int index) +{ + unsigned int num_elems = index + 1; + unsigned int old_num_elems = dynarr->num_elems; + void *elems; + +
[PATCH 10/22] drm/atomic: Remove pointless private object NULL state check
From: Ville Syrjälä We will never add private objects with a NULL state into the atomic state, hence checking for that is pointless. Cc: Dhinakaran Pandiyan Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_atomic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 1663ec3626a1..a61e396b11a8 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1019,8 +1019,7 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj, struct __drm_private_objs_state *arr; for (i = 0; i < state->num_private_objs; i++) - if (obj == state->private_objs[i].obj && - state->private_objs[i].obj_state) + if (obj == state->private_objs[i].obj) return state->private_objs[i].obj_state; num_objs = state->num_private_objs + 1; -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 13/22] drm/atomic: Pass old state to __drm_atomic_helper_crtc_duplicate_state() & co. explicitly
From: Ville Syrjälä We'll be wanting to duplicate other states besides the one pointed to by crtc->state & co., so pass the duplicated state in explicitly. @r@ identifier F =~ "^__drm_atomic_helper_.*_duplicate_state$"; identifier O, S; type T, TS; @@ F(T O, TS *S + ,const TS *old_state ) { <... - O->state + old_state ...> } @@ identifier r.F; expression E; @@ F(E, ... + ,E->state ) Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/arm/malidp_crtc.c | 3 ++- drivers/gpu/drm/arm/malidp_planes.c| 3 ++- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 3 ++- drivers/gpu/drm/drm_atomic_helper.c| 30 -- drivers/gpu/drm/drm_dp_mst_topology.c | 3 ++- drivers/gpu/drm/exynos/exynos_drm_plane.c | 3 ++- drivers/gpu/drm/i915/intel_atomic.c| 6 -- drivers/gpu/drm/i915/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/intel_sdvo.c | 4 +++- drivers/gpu/drm/imx/ipuv3-crtc.c | 3 ++- drivers/gpu/drm/imx/ipuv3-plane.c | 3 ++- drivers/gpu/drm/mediatek/mtk_drm_crtc.c| 3 ++- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 3 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 3 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_connector.c| 3 ++- drivers/gpu/drm/nouveau/nv50_display.c | 6 -- drivers/gpu/drm/rcar-du/rcar_du_plane.c| 3 ++- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 3 ++- drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 3 ++- drivers/gpu/drm/tegra/dc.c | 6 -- drivers/gpu/drm/tegra/dsi.c| 3 ++- drivers/gpu/drm/tegra/sor.c| 3 ++- drivers/gpu/drm/vc4/vc4_crtc.c | 3 ++- drivers/gpu/drm/vc4/vc4_plane.c| 3 ++- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c| 7 +++--- include/drm/drm_atomic_helper.h| 12 +++ 27 files changed, 85 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 3615d18a7ddf..037514f42a83 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -427,7 +427,8 @@ static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc) if (!state) return NULL; - __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); + __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base, +crtc->state); memcpy(state->gamma_coeffs, old_state->gamma_coeffs, sizeof(state->gamma_coeffs)); memcpy(state->coloradj_coeffs, old_state->coloradj_coeffs, diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 600fa7bd7f52..fe744396bc99 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -98,7 +98,8 @@ drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane) return NULL; m_state = to_malidp_plane_state(plane->state); - __drm_atomic_helper_plane_duplicate_state(plane, &state->base); + __drm_atomic_helper_plane_duplicate_state(plane, &state->base, + plane->state); state->rotmem_size = m_state->rotmem_size; state->format = m_state->format; state->n_planes = m_state->n_planes; diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index 441769c5bcd4..bb7c5eb9526a 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -385,7 +385,8 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) state = kmalloc(sizeof(*state), GFP_KERNEL); if (!state) return NULL; - __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); + __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base, +crtc->state); cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); state->output_mode = cur->output_mode; diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index bc7d3a5a50f7..0745a08a6cc2 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3374,9 +3374,10 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); * This is useful for drivers that subclass the CRTC state. */ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, - struct drm_crtc_state *state) + struct drm_crtc_state *state, + const struct drm_crtc_state *old_state) { - memcpy(state, crtc->state, sizeof(*state)); +
[PATCH 09/22] drm/atomic: Convert state->connectors to drm_dynarray
From: Ville Syrjälä state->connectors[] can grows dynamically, so we can switch over to using the new drm_dynarray. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_atomic.c| 49 +++-- drivers/gpu/drm/drm_atomic_helper.c | 4 +-- include/drm/drm_atomic.h| 42 ++- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 09ca662fcd35..1663ec3626a1 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -53,7 +54,7 @@ EXPORT_SYMBOL(__drm_crtc_commit_free); */ void drm_atomic_state_default_release(struct drm_atomic_state *state) { - kfree(state->connectors); + drm_dynarray_fini(&state->connectors); kfree(state->crtcs); kfree(state->planes); kfree(state->private_objs); @@ -87,6 +88,9 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) if (!state->planes) goto fail; + drm_dynarray_init(&state->connectors, + sizeof(struct __drm_connectors_state)); + state->dev = dev; DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state); @@ -142,15 +146,17 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state); for (i = 0; i < state->num_connector; i++) { - struct drm_connector *connector = state->connectors[i].ptr; + struct __drm_connectors_state *c = + __drm_atomic_state_connector(state, i); + struct drm_connector *connector = c->ptr; if (!connector) continue; connector->funcs->atomic_destroy_state(connector, - state->connectors[i].state); - state->connectors[i].ptr = NULL; - state->connectors[i].state = NULL; + c->state); + c->ptr = NULL; + c->state = NULL; drm_connector_put(connector); } @@ -1064,6 +1070,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, int ret, index; struct drm_mode_config *config = &connector->dev->mode_config; struct drm_connector_state *connector_state; + struct __drm_connectors_state *c; WARN_ON(!state->acquire_ctx); @@ -1073,35 +1080,29 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, index = drm_connector_index(connector); - if (index >= state->num_connector) { - struct __drm_connnectors_state *c; - int alloc = max(index + 1, config->num_connector); - - c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL); - if (!c) - return ERR_PTR(-ENOMEM); - - state->connectors = c; - memset(&state->connectors[state->num_connector], 0, - sizeof(*state->connectors) * (alloc - state->num_connector)); + ret = drm_dynarray_reserve(&state->connectors, + max(index, config->num_connector - 1)); + if (ret) + return ERR_PTR(ret); - state->num_connector = alloc; - } + c = __drm_atomic_state_connector(state, index); - if (state->connectors[index].state) - return state->connectors[index].state; + if (c->state) + return c->state; connector_state = connector->funcs->atomic_duplicate_state(connector); if (!connector_state) return ERR_PTR(-ENOMEM); drm_connector_get(connector); - state->connectors[index].state = connector_state; - state->connectors[index].old_state = connector->state; - state->connectors[index].new_state = connector_state; - state->connectors[index].ptr = connector; + c->state = connector_state; + c->old_state = connector->state; + c->new_state = connector_state; + c->ptr = connector; connector_state->state = state; + state->num_connector = state->connectors.num_elems; + DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n", connector->base.id, connector->name, connector_state, state); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 667ec97d4efb..2d747ac35ecf 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2297,7 +2297,7 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state, old_conn_state->state = state; new_conn_state->state =
[PATCH 15/22] drm/mediatek: s/old_state/old_mtk_state/
From: Ville Syrjälä Rename the local 'old_state' variable to 'old_mtk_state' to get it out of the way of some cocci refactoring. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index 9ecc23f67cc7..67c7bd17e350 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -52,7 +52,7 @@ static void mtk_plane_reset(struct drm_plane *plane) static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane) { - struct mtk_plane_state *old_state = to_mtk_plane_state(plane->state); + struct mtk_plane_state *old_mtk_state = to_mtk_plane_state(plane->state); struct mtk_plane_state *state; state = kzalloc(sizeof(*state), GFP_KERNEL); @@ -64,7 +64,7 @@ static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane WARN_ON(state->base.plane != plane); - state->pending = old_state->pending; + state->pending = old_mtk_state->pending; return &state->base; } -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/6] drm: Add helper to check exporting driver of a DMA-buf
Am 06.07.2017 um 22:16 schrieb Felix Kuehling: This allows drivers to check if a DMA-buf contains a GEM object and whether it comes from the same driver. It may be from the same or a different device. Signed-off-by: Felix Kuehling I think Daniel/Dave hadmore a function which returns the casted GEM object or NULL in mind, but that should o it as well. Patch is Reviewed-by: Christian König Regards, Christian. --- drivers/gpu/drm/drm_prime.c | 24 include/drm/drmP.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 25aa455..a50baec 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -594,6 +594,30 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); /** + * drm_gem_prime_dmabuf_is_from_driver - check exporting driver of a dma-buf + * @dma_buf: dma-buf object to check + * @driver: driver that is the expected exporter of the dma-buf + * + * Returns true if @driver exported @dma_buf. Returns false if + * @dma_buf was exported by a different driver. + */ +bool drm_gem_prime_dmabuf_is_from_driver(const struct dma_buf *dma_buf, +const struct drm_driver *driver) +{ + struct drm_gem_object *obj; + + if (dma_buf->ops != &drm_gem_prime_dmabuf_ops) + return false; + + obj = dma_buf->priv; + if (obj->dev->driver != driver) + return false; + + return true; +} +EXPORT_SYMBOL(drm_gem_prime_dmabuf_is_from_driver); + +/** * drm_gem_prime_import - helper library implementation of the import callback * @dev: drm_device to import into * @dma_buf: dma-buf object to import diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 6105c05..052f747 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -767,6 +767,8 @@ extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd); +extern bool drm_gem_prime_dmabuf_is_from_driver(const struct dma_buf *dma_buf, + const struct drm_driver *driver); extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 11/22] drm/atomic: Convert private_objs to drm_dynarray
From: Ville Syrjälä state->private_objs grows dynamically, so switch it over to use the new drm_dynarray helper. Cc: Dhinakaran Pandiyan Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_atomic.c| 64 - drivers/gpu/drm/drm_atomic_helper.c | 2 +- include/drm/drm_atomic.h| 15 ++--- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a61e396b11a8..5eb14c73c0fb 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -57,7 +57,7 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state) drm_dynarray_fini(&state->connectors); kfree(state->crtcs); kfree(state->planes); - kfree(state->private_objs); + drm_dynarray_fini(&state->private_objs); } EXPORT_SYMBOL(drm_atomic_state_default_release); @@ -90,6 +90,8 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) drm_dynarray_init(&state->connectors, sizeof(struct __drm_connectors_state)); + drm_dynarray_init(&state->private_objs, + sizeof(struct __drm_private_objs_state)); state->dev = dev; @@ -193,12 +195,14 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) } for (i = 0; i < state->num_private_objs; i++) { - void *obj_state = state->private_objs[i].obj_state; - - state->private_objs[i].funcs->destroy_state(obj_state); - state->private_objs[i].obj = NULL; - state->private_objs[i].obj_state = NULL; - state->private_objs[i].funcs = NULL; + struct __drm_private_objs_state *p = + __drm_atomic_state_private_obj(state, i); + void *obj_state = p->obj_state; + + p->funcs->destroy_state(obj_state); + p->obj = NULL; + p->obj_state = NULL; + p->funcs = NULL; } state->num_private_objs = 0; @@ -1014,36 +1018,36 @@ void * drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj, const struct drm_private_state_funcs *funcs) { - int index, num_objs, i; - size_t size; - struct __drm_private_objs_state *arr; - - for (i = 0; i < state->num_private_objs; i++) - if (obj == state->private_objs[i].obj) - return state->private_objs[i].obj_state; - - num_objs = state->num_private_objs + 1; - size = sizeof(*state->private_objs) * num_objs; - arr = krealloc(state->private_objs, size, GFP_KERNEL); - if (!arr) - return ERR_PTR(-ENOMEM); + struct __drm_private_objs_state *p; + int index = state->num_private_objs; + int ret, i; + + for (i = 0; i < state->num_private_objs; i++) { + p = __drm_atomic_state_private_obj(state, i); + + if (obj == p->obj) + return p->obj_state; + } - state->private_objs = arr; - index = state->num_private_objs; - memset(&state->private_objs[index], 0, sizeof(*state->private_objs)); + ret = drm_dynarray_reserve(&state->private_objs, index); + if (ret) + return ERR_PTR(ret); - state->private_objs[index].obj_state = funcs->duplicate_state(state, obj); - if (!state->private_objs[index].obj_state) + p = __drm_atomic_state_private_obj(state, index); + + p->obj_state = funcs->duplicate_state(state, obj); + if (!p->obj_state) return ERR_PTR(-ENOMEM); - state->private_objs[index].obj = obj; - state->private_objs[index].funcs = funcs; - state->num_private_objs = num_objs; + p->obj = obj; + p->funcs = funcs; + + state->num_private_objs = index + 1; DRM_DEBUG_ATOMIC("Added new private object state %p to %p\n", -state->private_objs[index].obj_state, state); +p->obj_state, state); - return state->private_objs[index].obj_state; + return p->obj_state; } EXPORT_SYMBOL(drm_atomic_get_private_obj_state); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 2d747ac35ecf..77b57cdf0460 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2331,7 +2331,7 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state, } __for_each_private_obj(state, obj, obj_state, i, funcs) - funcs->swap_state(obj, &state->private_objs[i].obj_state); + funcs->swap_state(obj, &__drm_atomic_state_private_obj(state, i)->obj_state); } EXPORT_SYMBOL(drm_atomic_helper_swap_state); diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 44316ce45fbb..809e8b4c3719 100644 --- a/in
[PATCH 17/22] drm/atomic: Fix up the kernel docs for the state duplication functions
From: Ville Syrjälä Coccinelle doesn't fix up the docs for us, so let's do it manually. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_atomic_helper.c | 12 +--- include/drm/drm_connector.h | 2 +- include/drm/drm_crtc.h | 2 +- include/drm/drm_plane.h | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index c60fb6289276..f0887f231fb8 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3368,7 +3368,8 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); /** * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state * @crtc: CRTC object - * @state: atomic CRTC state + * @state: new CRTC state + * @old_state: old CRTC state * * Copies atomic state from a CRTC's current state and resets inferred values. * This is useful for drivers that subclass the CRTC state. @@ -3401,6 +3402,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); /** * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook * @crtc: drm CRTC + * @old_state: old CRTC state * * Default CRTC state duplicate hook for drivers which don't have their own * subclassed CRTC state structure. @@ -3481,7 +3483,8 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_reset); /** * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state * @plane: plane object - * @state: atomic plane state + * @state: new plane state + * @old_state: old plane state * * Copies atomic state from a plane's current state. This is useful for * drivers that subclass the plane state. @@ -3502,6 +3505,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); /** * drm_atomic_helper_plane_duplicate_state - default state duplicate hook * @plane: drm plane + * @old_state: old plane state * * Default plane state duplicate hook for drivers which don't have their own * subclassed plane state structure. @@ -3605,7 +3609,8 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_reset); /** * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state * @connector: connector object - * @state: atomic connector state + * @state: new connector state + * @old_state: old connector state * * Copies atomic state from a connector's current state. This is useful for * drivers that subclass the connector state. @@ -3624,6 +3629,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state); /** * drm_atomic_helper_connector_duplicate_state - default state duplicate hook * @connector: drm connector + * @old_state: old connector state * * Default connector state duplicate hook for drivers which don't have their own * subclassed connector state structure. diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index ee9a15a87db5..a0d862d23082 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -514,7 +514,7 @@ struct drm_connector_funcs { /** * @atomic_duplicate_state: * -* Duplicate the current atomic state for this connector and return it. +* Duplicate the passed in atomic state for this connector and return it. * The core and helpers guarantee that any atomic state duplicated with * this hook and still owned by the caller (i.e. not transferred to the * driver by calling &drm_mode_config_funcs.atomic_commit) will be diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 1d187331fe5d..8bfbc54660ab 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -497,7 +497,7 @@ struct drm_crtc_funcs { /** * @atomic_duplicate_state: * -* Duplicate the current atomic state for this CRTC and return it. +* Duplicate the passed in atomic state for this CRTC and return it. * The core and helpers guarantee that any atomic state duplicated with * this hook and still owned by the caller (i.e. not transferred to the * driver by calling &drm_mode_config_funcs.atomic_commit) will be diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index f01023ed1c7b..08ad4b58adbe 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -249,7 +249,7 @@ struct drm_plane_funcs { /** * @atomic_duplicate_state: * -* Duplicate the current atomic state for this plane and return it. +* Duplicate the passed in atomic state for this plane and return it. * The core and helpers guarantee that any atomic state duplicated with * this hook and still owned by the caller (i.e. not transferred to the * driver by calling &drm_mode_config_funcs.atomic_commit) will be -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 16/22] drm/atomic: Pass old state explicitly to .atomic_duplicate_state()
From: Ville Syrjälä We'll be wanting to duplicate other states besides the one pointed to by crtc->state & co., so pass the duplicated state in explicitly. I wanted to make the old_state const, but that would have results in tons of new warnings because some drivers have their to_foo_state()s as static inlines. So I decided to leave old_state as non-const in the end. @r@ identifier F =~ "^[^_].*duplicate_.*state$"; identifier I; type TO, TS; @@ TS F(TO I + ,TS old_state ) { <... - I->state + old_state ...> } @@ identifier r.F; expression E; @@ F(E + ,E->state ) @@ type r.TO; type r.TS; type TF; identifier I; @@ TF { ... TS (*atomic_duplicate_state)(TO I +,TS old_state ); ... }; @@ expression X, E; @@ X->atomic_duplicate_state(E + ,E->state ) Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/arm/malidp_crtc.c | 9 + drivers/gpu/drm/arm/malidp_planes.c | 9 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 9 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 5 +++-- drivers/gpu/drm/drm_atomic.c| 10 ++ drivers/gpu/drm/drm_atomic_helper.c | 21 - drivers/gpu/drm/drm_crtc_helper.c | 12 drivers/gpu/drm/drm_dp_mst_topology.c | 7 --- drivers/gpu/drm/drm_plane_helper.c | 12 drivers/gpu/drm/exynos/exynos_drm_plane.c | 7 --- drivers/gpu/drm/i915/intel_atomic.c | 14 -- drivers/gpu/drm/i915/intel_atomic_plane.c | 7 --- drivers/gpu/drm/i915/intel_display.c| 2 +- drivers/gpu/drm/i915/intel_drv.h| 9 ++--- drivers/gpu/drm/i915/intel_sdvo.c | 7 --- drivers/gpu/drm/imx/ipuv3-crtc.c| 5 +++-- drivers/gpu/drm/imx/ipuv3-plane.c | 7 --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 5 +++-- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 7 --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c| 9 + drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 13 +++-- drivers/gpu/drm/nouveau/nouveau_connector.c | 7 --- drivers/gpu/drm/nouveau/nouveau_connector.h | 3 ++- drivers/gpu/drm/nouveau/nv50_display.c | 14 -- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 9 + drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 9 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 5 +++-- drivers/gpu/drm/tegra/dc.c | 14 -- drivers/gpu/drm/tegra/dsi.c | 7 --- drivers/gpu/drm/tegra/sor.c | 7 --- drivers/gpu/drm/vc4/vc4_crtc.c | 5 +++-- drivers/gpu/drm/vc4/vc4_plane.c | 9 + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 25 ++--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 9 ++--- include/drm/drm_atomic.h| 3 ++- include/drm/drm_atomic_helper.h | 9 ++--- include/drm/drm_connector.h | 3 ++- include/drm/drm_crtc.h | 3 ++- include/drm/drm_plane.h | 3 ++- 39 files changed, 194 insertions(+), 136 deletions(-) diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 2a92cb066bea..8c78cb13b23b 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -415,20 +415,21 @@ static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = { .atomic_disable = malidp_crtc_atomic_disable, }; -static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc) +static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) { struct malidp_crtc_state *state, *old_mali_state; - if (WARN_ON(!crtc->state)) + if (WARN_ON(!old_state)) return NULL; - old_mali_state = to_malidp_crtc_state(crtc->state); + old_mali_state = to_malidp_crtc_state(old_state); state = kmalloc(sizeof(*state), GFP_KERNEL); if (!state) return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base, -crtc->state); +old_state); memcpy(state->gamma_coeffs, old_mali_state->gamma_coeffs, sizeof(state->gamma_coeffs)); memcpy(state->coloradj_coeffs, old_mali_state->coloradj_coeffs, diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index fe744396bc99..33b0c07ad3a3 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/driver
[PATCH 12/22] drm/atomic: Make private objs proper objects
From: Ville Syrjälä Make the atomic private object stuff less special by introducing proper base classes for the object and its state. Drivers can embed these in their own appropriate objects, after which these things will work exactly like the plane/crtc/connector states during atomic operations. Cc: Dhinakaran Pandiyan Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_atomic.c | 78 +++-- drivers/gpu/drm/drm_atomic_helper.c | 30 +++-- drivers/gpu/drm/drm_dp_mst_topology.c | 63 + include/drm/drm_atomic.h | 123 +- include/drm/drm_atomic_helper.h | 4 ++ include/drm/drm_dp_mst_helper.h | 10 +++ 6 files changed, 206 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 5eb14c73c0fb..da7752230e4c 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -197,12 +197,14 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) for (i = 0; i < state->num_private_objs; i++) { struct __drm_private_objs_state *p = __drm_atomic_state_private_obj(state, i); - void *obj_state = p->obj_state; + struct drm_private_obj *obj = p->ptr; - p->funcs->destroy_state(obj_state); - p->obj = NULL; - p->obj_state = NULL; - p->funcs = NULL; + if (WARN_ON(!obj)) + continue; + + obj->funcs->atomic_destroy_state(obj, p->state); + p->ptr = NULL; + p->state = NULL; } state->num_private_objs = 0; @@ -1000,11 +1002,44 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, } /** + * drm_atomic_private_obj_init - initialize private object + * @obj: private object + * @state: initial private object state + * @funcs: pointer to the struct of function pointers that identify the object + * type + * + * Initialize the private object, which can be embedded into any + * driver private object that needs its own atomic state. + */ +void +drm_atomic_private_obj_init(struct drm_private_obj *obj, + struct drm_private_state *state, + const struct drm_private_state_funcs *funcs) +{ + memset(obj, 0, sizeof(*obj)); + + obj->state = state; + obj->funcs = funcs; +} +EXPORT_SYMBOL(drm_atomic_private_obj_init); + +/** + * drm_atomic_private_obj_fini - finalize private object + * @obj: private object + * + * Finalize the private object. + */ +void +drm_atomic_private_obj_fini(struct drm_private_obj *obj) +{ + obj->funcs->atomic_destroy_state(obj, obj->state); +} +EXPORT_SYMBOL(drm_atomic_private_obj_fini); + +/** * drm_atomic_get_private_obj_state - get private object state * @state: global atomic state * @obj: private object to get the state for - * @funcs: pointer to the struct of function pointers that identify the object - * type * * This function returns the private object state for the given private object, * allocating the state if needed. It does not grab any locks as the caller is @@ -1014,19 +1049,21 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, * * Either the allocated state or the error code encoded into a pointer. */ -void * -drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj, - const struct drm_private_state_funcs *funcs) +struct drm_private_state * +drm_atomic_get_private_obj_state(struct drm_atomic_state *state, +struct drm_private_obj *obj) { + const struct drm_private_state_funcs *funcs = obj->funcs; struct __drm_private_objs_state *p; + struct drm_private_state *obj_state; int index = state->num_private_objs; int ret, i; for (i = 0; i < state->num_private_objs; i++) { p = __drm_atomic_state_private_obj(state, i); - if (obj == p->obj) - return p->obj_state; + if (obj == p->ptr) + return p->state; } ret = drm_dynarray_reserve(&state->private_objs, index); @@ -1035,19 +1072,22 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj, p = __drm_atomic_state_private_obj(state, index); - p->obj_state = funcs->duplicate_state(state, obj); - if (!p->obj_state) + obj_state = funcs->atomic_duplicate_state(obj); + if (!obj_state) return ERR_PTR(-ENOMEM); - p->obj = obj; - p->funcs = funcs; + p->state = obj_state; + p->old_state = obj->state; + p->new_state = obj_state; + p->ptr = obj; + obj_state->state = state; state->num_private_objs = index + 1; - DRM_DEBUG_ATOMIC("Added new private obj
[PATCH 20/22] drm/i915: Refactor __intel_atomic_commit_tail()
From: Ville Syrjälä Split intel_atomic_commit_tail() into a lower level function that does the actual commit, and a higher level one that waits for the dependencies and signals the commit as done. We'll reuse the lower level function to perform commits during GPU resets. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0ff3f254ee58..e9c85d7cbb3e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13021,7 +13021,7 @@ static void intel_atomic_helper_free_state_worker(struct work_struct *work) intel_atomic_helper_free_state(dev_priv); } -static void intel_atomic_commit_tail(struct drm_atomic_state *state) +static void __intel_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; struct intel_atomic_state *intel_state = to_intel_atomic_state(state); @@ -13034,8 +13034,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) unsigned crtc_vblank_mask = 0; int i; - drm_atomic_helper_wait_for_dependencies(state); - if (intel_state->modeset) intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); @@ -13160,8 +13158,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) if (intel_state->modeset && intel_can_enable_sagv(state)) intel_enable_sagv(dev_priv); - drm_atomic_helper_commit_hw_done(state); - if (intel_state->modeset) { /* As one of the primary mmio accessors, KMS has a high * likelihood of triggering bugs in unclaimed access. After we @@ -13172,6 +13168,18 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) intel_uncore_arm_unclaimed_mmio_detection(dev_priv); intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); } +} + +static void intel_atomic_commit_tail(struct drm_atomic_state *state) +{ + struct drm_device *dev = state->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + + drm_atomic_helper_wait_for_dependencies(state); + + __intel_atomic_commit_tail(state); + + drm_atomic_helper_commit_hw_done(state); mutex_lock(&dev->struct_mutex); drm_atomic_helper_cleanup_planes(dev, state); -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 19/22] drm/i915% Store vma gtt offset in plane state
From: Ville Syrjälä To avoid having to deference plane_state->vma during the commit phase of plane updates, let's store the vma gtt offset (or the bus address when we need it) in the plane state. This is crucial for doing the modeset operations during GPU reset as as plane_state->vma gets cleared when we duplicate the state and we won't be calling .prepare_fb() during GPU reset plane commits. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 38 +--- drivers/gpu/drm/i915/intel_drv.h | 6 +- drivers/gpu/drm/i915/intel_sprite.c | 8 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1016afebef27..0ff3f254ee58 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2744,7 +2744,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, if (!state->vma) continue; - if (intel_plane_ggtt_offset(state) == plane_config->base) { + if (state->gtt_offset == plane_config->base) { fb = c->primary->fb; drm_framebuffer_reference(fb); goto valid_fb; @@ -2771,6 +2771,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, mutex_lock(&dev->struct_mutex); intel_state->vma = intel_pin_and_fence_fb_obj(fb, primary->state->rotation); + intel_state->gtt_offset = i915_ggtt_offset(intel_state->vma); + mutex_unlock(&dev->struct_mutex); if (IS_ERR(intel_state->vma)) { DRM_ERROR("failed to pin boot fb on pipe %d: %li\n", @@ -3122,19 +3124,16 @@ static void i9xx_update_primary_plane(struct intel_plane *primary, I915_WRITE_FW(DSPSTRIDE(plane), fb->pitches[0]); if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { I915_WRITE_FW(DSPSURF(plane), - intel_plane_ggtt_offset(plane_state) + - crtc->dspaddr_offset); + plane_state->gtt_offset + crtc->dspaddr_offset); I915_WRITE_FW(DSPOFFSET(plane), (y << 16) | x); } else if (INTEL_GEN(dev_priv) >= 4) { I915_WRITE_FW(DSPSURF(plane), - intel_plane_ggtt_offset(plane_state) + - crtc->dspaddr_offset); + plane_state->gtt_offset + crtc->dspaddr_offset); I915_WRITE_FW(DSPTILEOFF(plane), (y << 16) | x); I915_WRITE_FW(DSPLINOFF(plane), linear_offset); } else { I915_WRITE_FW(DSPADDR(plane), - intel_plane_ggtt_offset(plane_state) + - crtc->dspaddr_offset); + plane_state->gtt_offset + crtc->dspaddr_offset); } POSTING_READ_FW(reg); @@ -3395,7 +3394,7 @@ static void skylake_update_primary_plane(struct intel_plane *plane, } I915_WRITE_FW(PLANE_SURF(pipe, plane_id), - intel_plane_ggtt_offset(plane_state) + surf_addr); + plane_state->gtt_offset + surf_addr); POSTING_READ_FW(PLANE_SURF(pipe, plane_id)); @@ -9202,15 +9201,9 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state) struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev); const struct drm_framebuffer *fb = plane_state->base.fb; - const struct drm_i915_gem_object *obj = intel_fb_obj(fb); u32 base; - if (INTEL_INFO(dev_priv)->cursor_needs_physical) - base = obj->phys_handle->busaddr; - else - base = intel_plane_ggtt_offset(plane_state); - - base += plane_state->main.offset; + base = plane_state->gtt_offset + plane_state->main.offset; /* ILK+ do this automagically */ if (HAS_GMCH_DISPLAY(dev_priv) && @@ -10863,8 +10856,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->old_vma = to_intel_plane_state(primary->state)->vma; to_intel_plane_state(primary->state)->vma = vma; + to_intel_plane_state(primary->state)->gtt_offset = + i915_ggtt_offset(vma); - work->gtt_offset = i915_ggtt_offset(vma) + intel_crtc->dspaddr_offset; + work->gtt_offset = to_intel_plane_state(primary->state)->gtt_offset + + intel_crtc->dspaddr_offset; work->rotation = crtc->primary->state->rotation; /* @@ -10920,6 +10916,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, i915_add_request(request); cleanup_unpin: to_intel_plane_state(primary->state)->vma = work->old_vma; + to_intel_plane_state(primary->state)->gtt_offset = + i915_ggtt_offset(work->old_vma); intel_unpin_fb_vma(vma); cle
[PATCH v3 21/22] drm/atomic: Introduce drm_atomic_helper_duplicate_commited_state()
From: Ville Syrjälä For i915 GPU reset handling we'll want to be able to duplicate the state that was last commited to the hardware. For that purpose let's start to track the commited state for each object and provide a way to duplicate the commmited state into a new drm_atomic_state. The locking for .commited_state must to be provided by the driver. drm_atomic_helper_duplicate_commited_state() duplicates the state to both old_state and new_state. For the purposes of i915 GPU reset we would only need one of them, but we actually need two top level states; one for disabling everything (which would need the duplicated state to be old_state), and another to reenable everything (which would need the duplicated state to be new_state). So to make it less comples I figured I'd just always duplicate both. Might want to rethink this if for no other reason that reducing the chances of memory allocation failure. Due to the double state duplication we need drm_atomic_helper_clean_commited_state() to clean up the duplicated old_state since that's not handled by the normal drm_atomic_state cleanup code. TODO: do we want this in the helper, or maybe it should be just in i915? v2: s/commited/committed/ everywhere (checkpatch) Handle state duplication errors better v3: Even more care in dealing with memory allocation errors Handle private objs too Deal with the potential ordering issues between swap_state() and hw_done() by keeping track of which state was swapped in last Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_atomic.c| 1 + drivers/gpu/drm/drm_atomic_helper.c | 231 include/drm/drm_atomic.h| 4 + include/drm/drm_atomic_helper.h | 8 ++ include/drm/drm_connector.h | 11 ++ include/drm/drm_crtc.h | 11 ++ include/drm/drm_plane.h | 11 ++ 7 files changed, 277 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 56925b93f598..e1578d50d66f 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1020,6 +1020,7 @@ drm_atomic_private_obj_init(struct drm_private_obj *obj, memset(obj, 0, sizeof(*obj)); obj->state = state; + obj->committed_state = state; obj->funcs = funcs; } EXPORT_SYMBOL(drm_atomic_private_obj_init); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index f0887f231fb8..c3d02f12cd5d 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1815,6 +1815,11 @@ void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state) } EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); +static bool state_seqno_after(unsigned int a, unsigned int b) +{ + return (int)(b - a) < 0; +} + /** * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit * @old_state: atomic state object with old state structures @@ -1833,11 +1838,39 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state) { struct drm_crtc *crtc; + struct drm_plane *plane; + struct drm_connector *connector; + struct drm_private_obj *obj; struct drm_crtc_state *new_crtc_state; + struct drm_plane_state *new_plane_state; + struct drm_connector_state *new_connector_state; + struct drm_private_state *new_obj_state; struct drm_crtc_commit *commit; int i; + static DEFINE_SPINLOCK(committed_state_lock); + + spin_lock(&committed_state_lock); + + for_each_new_plane_in_state(old_state, plane, new_plane_state, i) { + if (plane->committed_state && + state_seqno_after(new_plane_state->seqno, + plane->committed_state->seqno)) + plane->committed_state = new_plane_state; + } + + for_each_new_connector_in_state(old_state, connector, new_connector_state, i) { + if (connector->committed_state && + state_seqno_after(new_connector_state->seqno, + connector->committed_state->seqno)) + connector->committed_state = new_connector_state; + } for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { + if (crtc->committed_state && + state_seqno_after(new_crtc_state->seqno, + crtc->committed_state->seqno)) + crtc->committed_state = new_crtc_state; + commit = old_state->crtcs[i].commit; if (!commit) continue; @@ -1846,6 +1879,15 @@ void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state) WARN_ON(new_crtc_state->event); complete_all(&commit->hw_done); } + + for
[PATCH 18/22] drm: Return the connector from drm_connector_get()
From: Ville Syrjälä Make drm_connector_get() return the connector. This allows the nice pattern of 'foo->connector = drm_connector_get(connector)' Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_atomic.c| 3 +-- drivers/gpu/drm/drm_fb_helper.c | 7 +++ include/drm/drm_connector.h | 7 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index b1983e7b65d2..56925b93f598 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1139,11 +1139,10 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, if (!connector_state) return ERR_PTR(-ENOMEM); - drm_connector_get(connector); c->state = connector_state; c->old_state = connector->state; c->new_state = connector_state; - c->ptr = connector; + c->ptr = drm_connector_get(connector); connector_state->state = state; state->num_connector = state->connectors.num_elems; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 721511da4de6..f520c235a6fb 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -138,8 +138,7 @@ static int __drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, if (!fb_conn) return -ENOMEM; - drm_connector_get(connector); - fb_conn->connector = connector; + fb_conn->connector = drm_connector_get(connector); fb_helper->connector_info[fb_helper->connector_count++] = fb_conn; return 0; @@ -2338,8 +2337,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, fb_crtc->y = offset->y; modeset->mode = drm_mode_duplicate(dev, fb_crtc->desired_mode); - drm_connector_get(connector); - modeset->connectors[modeset->num_connectors++] = connector; + modeset->connectors[modeset->num_connectors++] = + drm_connector_get(connector); modeset->fb = fb_helper->fb; modeset->x = offset->x; modeset->y = offset->y; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index a0d862d23082..8f26166f78b4 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -916,10 +916,15 @@ static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev, * @connector: DRM connector * * This function increments the connector's refcount. + + * Returns: + * + * The connector. */ -static inline void drm_connector_get(struct drm_connector *connector) +static inline struct drm_connector *drm_connector_get(struct drm_connector *connector) { drm_mode_object_get(&connector->base); + return connector; } /** -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 14/22] drm/arm: s/old_state/old_mali_state/
From: Ville Syrjälä Rename the local 'old_state' variable to 'old_mali_state' to get it out of the way of some cocci refactoring. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/arm/malidp_crtc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 037514f42a83..2a92cb066bea 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -417,23 +417,23 @@ static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = { static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc) { - struct malidp_crtc_state *state, *old_state; + struct malidp_crtc_state *state, *old_mali_state; if (WARN_ON(!crtc->state)) return NULL; - old_state = to_malidp_crtc_state(crtc->state); + old_mali_state = to_malidp_crtc_state(crtc->state); state = kmalloc(sizeof(*state), GFP_KERNEL); if (!state) return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base, crtc->state); - memcpy(state->gamma_coeffs, old_state->gamma_coeffs, + memcpy(state->gamma_coeffs, old_mali_state->gamma_coeffs, sizeof(state->gamma_coeffs)); - memcpy(state->coloradj_coeffs, old_state->coloradj_coeffs, + memcpy(state->coloradj_coeffs, old_mali_state->coloradj_coeffs, sizeof(state->coloradj_coeffs)); - memcpy(&state->scaler_config, &old_state->scaler_config, + memcpy(&state->scaler_config, &old_mali_state->scaler_config, sizeof(state->scaler_config)); state->scaled_planes_mask = 0; -- 2.13.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 22/22] drm/i915: Solve the GPU reset vs. modeset deadlocks with an rw_semaphore
From: Ville Syrjälä Introduce an rw_semaphore to protect the display commits. All normal commits use down_read() and hence can proceed in parallel, but GPU reset will use down_write() making sure no other commits are in progress when we have to pull the plug on the display engine on pre-g4x platforms. There are no modeset/gem locks taken inside __intel_atomic_commit_tail() itself, and we wait for all dependencies before the down_read(), and thus there is no chance of deadlocks with this scheme. During reset we will recommit the state that was commited last. Hence we require tracking which state that was, and we need a way to duplicate that state. That is now handled by the atomic core and helpers. We also have to be sure that none of the commit codepaths look up plane->state, crtc->state, etc. as that would lead us to pontetially commit some future state prematurely. crtc->config is actually fine since that gets update during the commit as well (although eventually we do want to rid ourselves of crtc->config). I left out the state readout from the post-reset display reinitialization as that still likes to clobber crtc->state etc. If we make it use a free standing atomic state and mke sure it doesn't need any locks we could reintroduce it. For now I just mark the post-reset display state as dirty as possible to make sure we reinitialize everything. One potential issue remains in the form of display detection. Either we need to protect that with the same rw_semaphore as well, or perhaps it would be enough to force gmbus into bitbanging mode while the reset is happening and we don't have interrupts, and just across the actual hardware GPU reset we could hold the gmbus mutex. v2: Keep intel_prepare/finish_reset() outside struct_mutex (Chris) v3: Drop all the committed_state refactoring to make this less obnoxious to backport (Daniel) v4: Preserve the wedge timeout mechanism (Chris) v5: Go back to the full committed state tracking since it actually is needed Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_display.c | 220 --- drivers/gpu/drm/i915/intel_sprite.c | 1 + 3 files changed, 157 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index baec61b078f5..432b356017ba 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2247,6 +2247,8 @@ struct drm_i915_private { struct drm_atomic_state *modeset_restore_state; struct drm_modeset_acquire_ctx reset_ctx; + struct rw_semaphore commit_sem; + struct list_head vm_list; /* Global list of all address spaces */ struct i915_ggtt ggtt; /* VM representing the global address space */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e9c85d7cbb3e..e8ff5095ede3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -123,6 +123,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc); static void intel_modeset_setup_hw_state(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc); +static void __intel_atomic_commit_tail(struct drm_atomic_state *state, bool is_reset); struct intel_limit { struct { @@ -3432,15 +3433,15 @@ static void intel_update_primary_planes(struct drm_device *dev) for_each_crtc(dev, crtc) { struct intel_plane *plane = to_intel_plane(crtc->primary); - struct intel_plane_state *plane_state = - to_intel_plane_state(plane->base.state); + const struct intel_plane_state *plane_state = + to_intel_plane_state(plane->base.committed_state); if (plane_state->base.visible) { trace_intel_update_plane(&plane->base, to_intel_crtc(crtc)); plane->update_plane(plane, - to_intel_crtc_state(crtc->state), + to_intel_crtc_state(crtc->committed_state), plane_state); } } @@ -3491,27 +3492,97 @@ static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv) INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv); } -void intel_prepare_reset(struct drm_i915_private *dev_priv) +static void init_intel_state(struct intel_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + int i; + + state->modeset = true; + + for_each_oldnew_crtc_in_state(&state->base, crtc, old_crtc_state, new_crtc_state, i) { + if (new_crtc_state->active) +
[PATCH 1/6] drm: Add helper to check exporting driver of a DMA-buf
This allows drivers to check if a DMA-buf contains a GEM object and whether it comes from the same driver. It may be from the same or a different device. Signed-off-by: Felix Kuehling --- drivers/gpu/drm/drm_prime.c | 24 include/drm/drmP.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 25aa455..a50baec 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -594,6 +594,30 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); /** + * drm_gem_prime_dmabuf_is_from_driver - check exporting driver of a dma-buf + * @dma_buf: dma-buf object to check + * @driver: driver that is the expected exporter of the dma-buf + * + * Returns true if @driver exported @dma_buf. Returns false if + * @dma_buf was exported by a different driver. + */ +bool drm_gem_prime_dmabuf_is_from_driver(const struct dma_buf *dma_buf, +const struct drm_driver *driver) +{ + struct drm_gem_object *obj; + + if (dma_buf->ops != &drm_gem_prime_dmabuf_ops) + return false; + + obj = dma_buf->priv; + if (obj->dev->driver != driver) + return false; + + return true; +} +EXPORT_SYMBOL(drm_gem_prime_dmabuf_is_from_driver); + +/** * drm_gem_prime_import - helper library implementation of the import callback * @dev: drm_device to import into * @dma_buf: dma-buf object to import diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 6105c05..052f747 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -767,6 +767,8 @@ extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd); +extern bool drm_gem_prime_dmabuf_is_from_driver(const struct dma_buf *dma_buf, + const struct drm_driver *driver); extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls
On Thu, Jul 6, 2017 at 6:27 PM, Keith Packard wrote: > Daniel Vetter writes: > >> I very much like this since the old ioctl really is a rather bad horror >> show. And since it's tied in with ums drivers everything is >> complicated. > > Thanks for your kind words. > >> I started a discussion a while back whether these should be restricted to >> DRM_MASTER (i.e. the modeset resource owner) or available to everyone. >> Since it's read-only I guess we can keep it accessible to everyone, but it >> has a bit the problem that client app developers see this, think it does >> what it does and then use it to schedule frames without asking the >> compositor. Which sometimes even works, but isn't really proper design. >> The reasons seems to be that on X11 there's no EGL extension for accurate >> timing frame updates (DRI2/3 can do it ofc, and glx exposes it, but glx is >> uncool or something like that). > > In the absence of a suitable EGL api, I'm not sure what to suggest, > other than fixing EGL instead of blaming the kernel... > > However, for the leasing stuff, this doesn't really matter as I've got a > master FD to play with, so if you wanted to restrict it to master, > that'd be fine by me. Was just a thought, I don't mind either way really I think. >>> + >>> +/* >>> + * Get crtc VBLANK count. >>> + * >>> + * \param dev DRM device >>> + * \param data user arguement, pointing to a drm_crtc_get_sequence >>> structure. >>> + * \param file_priv drm file private for the user's open file descriptor >>> + */ >> >> Since this stuff isn't parsed by kerneldoc I tend to just free-form ioctl >> comments completely. Someday maybe someone even gets around to doing >> proper uabi documentation :-) Just an aside. > > I'm just trying to follow along with the local "conventions" in the > file. Let me know if you have a future plan to make this better and I'll > just reformat to suit. Yeah that \param stuff is all back from really old libdrm. Just shows how old this code is :-) >>> + >>> +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, >>> +struct drm_file *file_priv) >>> +{ >>> +struct drm_crtc *crtc; >>> +int pipe; >>> +struct drm_crtc_get_sequence *get_seq = data; >>> +struct timespec now; >>> + >> >> You need a DRIVER_MODESET check here or the drm_crtc_find will oops. Same >> below. > > Like this? Yup. > > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > index e39b2bd074e4..3738ff484f36 100644 > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -1712,6 +1712,9 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, > void *data, > struct drm_crtc_get_sequence *get_seq = data; > struct timespec now; > > + if (!drm_core_check_feature(dev, DRIVER_MODESET)) > + return -EINVAL; > + > if (!dev->irq_enabled) > return -EINVAL; > > @@ -1749,6 +1752,9 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device > *dev, void *data, > int ret; > unsigned long spin_flags; > > + if (!drm_core_check_feature(dev, DRIVER_MODESET)) > + return -EINVAL; > + > if (!dev->irq_enabled) > return -EINVAL; > > >>> +get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); >> >> This can give you and old vblank if the vblank is off (i.e. sw state >> hasn't be regularly updated). I think we want a new >> drm_crtc_accurate_vblank_count_and_time variant. > > Right, I saw that code in the wait_vblank case and forgot to carry it > over. Here's a duplicate of what that function does; we'll need this > code in any case for drivers which don't provide the necessary support > for accurate vblank counts: > > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -1711,6 +1711,8 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, > void *data, > int pipe; > struct drm_crtc_get_sequence *get_seq = data; > struct timespec now; > + bool vblank_enabled; > + int ret; > > if (!drm_core_check_feature(dev, DRIVER_MODESET)) > return -EINVAL; > @@ -1724,8 +1726,19 @@ int drm_crtc_get_sequence_ioctl(struct drm_device > *dev, void *data, > > pipe = drm_crtc_index(crtc); > > + vblank_enabled = dev->vblank_disable_immediately && > READ_ONCE(vblank->enabled); > + > + if (!vblank_enabled) { > + ret = drm_vblank_get(dev, pipe); > + if (ret) { > + DRM_DEBUG("crtc %d failed to acquire vblank counter, > %d\n", pipe, ret); > + return ret; > + } > + } > get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); > get_seq->sequence_ns = timespec_to_ns(&now); > + if (!vblank_enabled) > + drm_vblank_put(dev, pipe); > return 0; > } Yeah looks good. >> Another thing that is very ill-def
Re: [PATCH libdrm] libdrm_amdgpu: add kernel semaphore support
Chrstian, you are probably the best person to ack this, I'd like to get the radv code landed and allow the GL code to get going. Dave. > This adds kernel semaphore support to the command submission > interface in what should be a backwards compatible manner, > it adds a new command submission API. > > Signed-off-by: Dave Airlie > --- > amdgpu/amdgpu.h| 29 - > amdgpu/amdgpu_cs.c | 118 > + > 2 files changed, 138 insertions(+), 9 deletions(-) > > diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h > index 1901fa8..649b66e 100644 > --- a/amdgpu/amdgpu.h > +++ b/amdgpu/amdgpu.h > @@ -369,6 +369,16 @@ struct amdgpu_cs_request { > struct amdgpu_cs_fence_info fence_info; > }; > > +struct amdgpu_cs_request_syncobj { > + /* > +* > +*/ > + uint32_t number_in_syncobj; > + uint32_t number_out_syncobj; > + uint32_t *in_syncobj; > + uint32_t *out_syncobj; > +}; > + > /** > * Structure which provide information about GPU VM MC Address space > * alignments requirements > @@ -886,6 +896,12 @@ int amdgpu_cs_submit(amdgpu_context_handle context, > struct amdgpu_cs_request *ibs_request, > uint32_t number_of_requests); > > +int amdgpu_cs_submit_syncobj(amdgpu_context_handle context, > +uint64_t flags, > +struct amdgpu_cs_request *ibs_request, > +struct amdgpu_cs_request_syncobj *ibs_syncobj, > +uint32_t number_of_requests); > + > /** > * Query status of Command Buffer Submission > * > @@ -1328,8 +1344,19 @@ int > amdgpu_cs_destroy_semaphore(amdgpu_semaphore_handle sem); > */ > const char *amdgpu_get_marketing_name(amdgpu_device_handle dev); > > + > +int amdgpu_cs_create_syncobj(amdgpu_device_handle dev, > +uint32_t *syncobj); > +int amdgpu_cs_export_syncobj(amdgpu_device_handle dev, > +uint32_t syncobj, > +int *shared_fd); > +int amdgpu_cs_import_syncobj(amdgpu_device_handle dev, > +int shared_fd, > +uint32_t *syncobj); > +int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev, > + uint32_t syncobj); > + > #ifdef __cplusplus > } > #endif > - > #endif /* #ifdef _AMDGPU_H_ */ > diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c > index 868eb7b..339c5f9 100644 > --- a/amdgpu/amdgpu_cs.c > +++ b/amdgpu/amdgpu_cs.c > @@ -168,7 +168,8 @@ int amdgpu_cs_query_reset_state(amdgpu_context_handle > context, > * \sa amdgpu_cs_submit() > */ > static int amdgpu_cs_submit_one(amdgpu_context_handle context, > - struct amdgpu_cs_request *ibs_request) > + struct amdgpu_cs_request *ibs_request, > + struct amdgpu_cs_request_syncobj > *syncobj_request) > { > union drm_amdgpu_cs cs; > uint64_t *chunk_array; > @@ -176,10 +177,13 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle > context, > struct drm_amdgpu_cs_chunk_data *chunk_data; > struct drm_amdgpu_cs_chunk_dep *dependencies = NULL; > struct drm_amdgpu_cs_chunk_dep *sem_dependencies = NULL; > + struct drm_amdgpu_cs_chunk_sem *in_syncobj_dependencies = NULL; > + struct drm_amdgpu_cs_chunk_sem *out_syncobj_dependencies = NULL; > struct list_head *sem_list; > amdgpu_semaphore_handle sem, tmp; > - uint32_t i, size, sem_count = 0; > + uint32_t i, j, size, sem_count = 0; > bool user_fence; > + uint32_t sem_size = 0; > int r = 0; > > if (ibs_request->ip_type >= AMDGPU_HW_IP_NUM) > @@ -194,7 +198,11 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle > context, > } > user_fence = (ibs_request->fence_info.handle != NULL); > > - size = ibs_request->number_of_ibs + (user_fence ? 2 : 1) + 1; > + if (syncobj_request) { > + sem_size += syncobj_request->number_in_syncobj ? 1 : 0; > + sem_size += syncobj_request->number_out_syncobj ? 1 : 0; > + } > + size = ibs_request->number_of_ibs + (user_fence ? 2 : 1) + 1 + > sem_size; > > chunk_array = alloca(sizeof(uint64_t) * size); > chunks = alloca(sizeof(struct drm_amdgpu_cs_chunk) * size); > @@ -306,6 +314,45 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle > context, > chunks[i].chunk_data = (uint64_t)(uintptr_t)sem_dependencies; > } > > + if (syncobj_request) { > + if (syncobj_request->number_in_syncobj) { > + in_syncobj_dependencies = malloc(sizeof(struct > drm_amdgpu_cs_chunk_sem) * syncobj_request->number_in_syncobj); > + if (!in_syncobj_dependencies) { > + r = -ENOMEM; > +
[Bug 101712] CPU lockup after ring 0 stalled
https://bugs.freedesktop.org/show_bug.cgi?id=101712 guiscara...@gmail.com changed: What|Removed |Added Assignee|mesa-dev@lists.freedesktop. |dri-devel@lists.freedesktop |org |.org QA Contact|mesa-dev@lists.freedesktop. |dri-devel@lists.freedesktop |org |.org Component|Drivers/X11 |Drivers/Gallium/radeonsi -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 08/14] drm: gma500: remove dead code and pointless local lut storage
The redundant fb helpers .gamma_set and .gamma_get are no longer used. Remove the dead code and hook up the crtc .gamma_set to use the crtc gamma_store directly instead of duplicating that info locally. Signed-off-by: Peter Rosin --- drivers/gpu/drm/gma500/framebuffer.c | 22 drivers/gpu/drm/gma500/gma_display.c | 32 ++ drivers/gpu/drm/gma500/psb_intel_display.c | 7 +-- drivers/gpu/drm/gma500/psb_intel_drv.h | 1 - 4 files changed, 12 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 7da70b6..2570c7f 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -479,26 +479,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create return psb_framebuffer_create(dev, cmd, r); } -static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct gma_crtc *gma_crtc = to_gma_crtc(crtc); - - gma_crtc->lut_r[regno] = red >> 8; - gma_crtc->lut_g[regno] = green >> 8; - gma_crtc->lut_b[regno] = blue >> 8; -} - -static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, int regno) -{ - struct gma_crtc *gma_crtc = to_gma_crtc(crtc); - - *red = gma_crtc->lut_r[regno] << 8; - *green = gma_crtc->lut_g[regno] << 8; - *blue = gma_crtc->lut_b[regno] << 8; -} - static int psbfb_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { @@ -525,8 +505,6 @@ static int psbfb_probe(struct drm_fb_helper *helper, } static const struct drm_fb_helper_funcs psb_fb_helper_funcs = { - .gamma_set = psbfb_gamma_set, - .gamma_get = psbfb_gamma_get, .fb_probe = psbfb_probe, }; diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index e7fd356..f3c48a2 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -144,33 +144,32 @@ void gma_crtc_load_lut(struct drm_crtc *crtc) struct gma_crtc *gma_crtc = to_gma_crtc(crtc); const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe]; int palreg = map->palette; + u16 *r, *g, *b; int i; /* The clocks have to be on to load the palette. */ if (!crtc->enabled) return; + r = crtc->gamma_store; + g = r + crtc->gamma_size; + b = g + crtc->gamma_size; + if (gma_power_begin(dev, false)) { for (i = 0; i < 256; i++) { REG_WRITE(palreg + 4 * i, - ((gma_crtc->lut_r[i] + - gma_crtc->lut_adj[i]) << 16) | - ((gma_crtc->lut_g[i] + - gma_crtc->lut_adj[i]) << 8) | - (gma_crtc->lut_b[i] + - gma_crtc->lut_adj[i])); + (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) | + (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) | + ((*b++ >> 8) + gma_crtc->lut_adj[i])); } gma_power_end(dev); } else { for (i = 0; i < 256; i++) { /* FIXME: Why pipe[0] and not pipe[..._crtc->pipe]? */ dev_priv->regs.pipe[0].palette[i] = - ((gma_crtc->lut_r[i] + - gma_crtc->lut_adj[i]) << 16) | - ((gma_crtc->lut_g[i] + - gma_crtc->lut_adj[i]) << 8) | - (gma_crtc->lut_b[i] + - gma_crtc->lut_adj[i]); + (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) | + (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) | + ((*b++ >> 8) + gma_crtc->lut_adj[i]); } } @@ -180,15 +179,6 @@ int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, u32 size, struct drm_modeset_acquire_ctx *ctx) { - struct gma_crtc *gma_crtc = to_gma_crtc(crtc); - int i; - - for (i = 0; i < size; i++) { - gma_crtc->lut_r[i] = red[i] >> 8; - gma_crtc->lut_g[i] = green[i] >> 8; - gma_crtc->lut_b[i] = blue[i] >> 8; - } - gma_crtc_load_lut(crtc); return 0; diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 7b6c849..8762efa 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_displ
[PATCH v4 11/14] drm: nouveau: remove dead code and pointless local lut storage
The redundant fb helpers .load_lut, .gamma_set and .gamma_get are no longer used. Remove the dead code and hook up the crtc .gamma_set to use the crtc gamma_store directly instead of duplicating that info locally. Signed-off-by: Peter Rosin --- drivers/gpu/drm/nouveau/dispnv04/crtc.c | 26 - drivers/gpu/drm/nouveau/nouveau_crtc.h | 3 --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 22 -- drivers/gpu/drm/nouveau/nv50_display.c | 40 +++-- 4 files changed, 22 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 4b4b0b4..8f689f1 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -764,13 +764,18 @@ nv_crtc_gamma_load(struct drm_crtc *crtc) struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct drm_device *dev = nv_crtc->base.dev; struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs; + u16 *r, *g, *b; int i; rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC; + r = crtc->gamma_store; + g = r + crtc->gamma_size; + b = g + crtc->gamma_size; + for (i = 0; i < 256; i++) { - rgbs[i].r = nv_crtc->lut.r[i] >> 8; - rgbs[i].g = nv_crtc->lut.g[i] >> 8; - rgbs[i].b = nv_crtc->lut.b[i] >> 8; + rgbs[i].r = *r++ >> 8; + rgbs[i].g = *g++ >> 8; + rgbs[i].b = *b++ >> 8; } nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg); @@ -792,13 +797,6 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, struct drm_modeset_acquire_ctx *ctx) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - int i; - - for (i = 0; i < size; i++) { - nv_crtc->lut.r[i] = r[i]; - nv_crtc->lut.g[i] = g[i]; - nv_crtc->lut.b[i] = b[i]; - } /* We need to know the depth before we upload, but it's possible to * get called before a framebuffer is bound. If this is the case, @@ -1095,7 +1093,6 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { .mode_set = nv_crtc_mode_set, .mode_set_base = nv04_crtc_mode_set_base, .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic, - .load_lut = nv_crtc_gamma_load, .disable = nv_crtc_disable, }; @@ -1103,17 +1100,12 @@ int nv04_crtc_create(struct drm_device *dev, int crtc_num) { struct nouveau_crtc *nv_crtc; - int ret, i; + int ret; nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); if (!nv_crtc) return -ENOMEM; - for (i = 0; i < 256; i++) { - nv_crtc->lut.r[i] = i << 8; - nv_crtc->lut.g[i] = i << 8; - nv_crtc->lut.b[i] = i << 8; - } nv_crtc->lut.depth = 0; nv_crtc->index = crtc_num; diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h index 050fcf3..b7a18fb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h @@ -61,9 +61,6 @@ struct nouveau_crtc { struct { struct nouveau_bo *nvbo; - uint16_t r[256]; - uint16_t g[256]; - uint16_t b[256]; int depth; } lut; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 2665a07..f770784 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -278,26 +278,6 @@ nouveau_fbcon_accel_init(struct drm_device *dev) info->fbops = &nouveau_fbcon_ops; } -static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - nv_crtc->lut.r[regno] = red; - nv_crtc->lut.g[regno] = green; - nv_crtc->lut.b[regno] = blue; -} - -static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - *red = nv_crtc->lut.r[regno]; - *green = nv_crtc->lut.g[regno]; - *blue = nv_crtc->lut.b[regno]; -} - static void nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon) { @@ -467,8 +447,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info) } static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = { - .gamma_set = nouveau_fbcon_gamma_set, - .gamma_get = nouveau_fbcon_gamma_get, .fb_probe = nouveau_fbcon_create, }; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 42a85c1
[PATCH v4 12/14] drm: radeon: remove dead code and pointless local lut storage
The redundant fb helpers .load_lut, .gamma_set and .gamma_get are no longer used. Remove the dead code and hook up the crtc .gamma_set to use the crtc gamma_store directly instead of duplicating that info locally. Signed-off-by: Peter Rosin --- drivers/gpu/drm/radeon/atombios_crtc.c | 1 - drivers/gpu/drm/radeon/radeon_connectors.c | 7 ++- drivers/gpu/drm/radeon/radeon_display.c | 71 - drivers/gpu/drm/radeon/radeon_fb.c | 2 - drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 1 - drivers/gpu/drm/radeon/radeon_mode.h| 4 -- 6 files changed, 33 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 3c492a0..02baaaf 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -2217,7 +2217,6 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { .mode_set_base_atomic = atombios_crtc_set_base_atomic, .prepare = atombios_crtc_prepare, .commit = atombios_crtc_commit, - .load_lut = radeon_crtc_load_lut, .disable = atombios_crtc_disable, }; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 27affbd..2f642cb 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -773,12 +773,15 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct if (connector->encoder->crtc) { struct drm_crtc *crtc = connector->encoder->crtc; - const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); radeon_crtc->output_csc = radeon_encoder->output_csc; - (*crtc_funcs->load_lut)(crtc); + /* +* Our .gamma_set assumes the .gamma_store has been +* prefilled and don't care about its arguments. +*/ + crtc->funcs->gamma_set(crtc, NULL, NULL, NULL, 0, NULL); } } diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 17d3daf..8b7d7a0 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -42,6 +42,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; + u16 *r, *g, *b; int i; DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); @@ -60,11 +61,14 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x003f); WREG8(AVIVO_DC_LUT_RW_INDEX, 0); + r = crtc->gamma_store; + g = r + crtc->gamma_size; + b = g + crtc->gamma_size; for (i = 0; i < 256; i++) { WREG32(AVIVO_DC_LUT_30_COLOR, -(radeon_crtc->lut_r[i] << 20) | -(radeon_crtc->lut_g[i] << 10) | -(radeon_crtc->lut_b[i] << 0)); + ((*r++ & 0xffc0) << 14) | + ((*g++ & 0xffc0) << 4) | + (*b++ >> 6)); } /* Only change bit 0 of LUT_SEL, other bits are set elsewhere */ @@ -76,6 +80,7 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc) struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; + u16 *r, *g, *b; int i; DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); @@ -93,11 +98,14 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc) WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x0007); WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); + r = crtc->gamma_store; + g = r + crtc->gamma_size; + b = g + crtc->gamma_size; for (i = 0; i < 256; i++) { WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, - (radeon_crtc->lut_r[i] << 20) | - (radeon_crtc->lut_g[i] << 10) | - (radeon_crtc->lut_b[i] << 0)); + ((*r++ & 0xffc0) << 14) | + ((*g++ & 0xffc0) << 4) | + (*b++ >> 6)); } } @@ -106,6 +114,7 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc) struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; + u16 *r, *g, *b; int i; DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); @@
Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support
On Thu, Jul 06, 2017 at 12:33:06PM +0200, Neil Armstrong wrote: > From: Russell King > > Add CEC notifier support to the HDMI bridge driver, so that the CEC > part of the IP can receive its physical address. > > Tested-by: Neil Armstrong > Acked-by: Neil Armstrong > Acked-by: Hans Verkuil > Signed-off-by: Russell King > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++ > 1 file changed, 18 insertions(+) > > Hi Archit, Hans, > > This is repost of Russell's patch from his dw-hdmi CEC patchset. > > Since his CEC implementation will be integrated in the bridge driver, > this notifier patch won't be re-posted. > > But the Amlogic Platform needs a notifier since it uses a standalone CEC > controller. Without this, the dw-hdmi CEC support will be totally useless anyway, and it's pointless to merge it without this patch. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 05/16] drm/fb-helper: do a generic fb_setcmap helper in terms of crtc .gamma_set
On 2017-07-06 07:55, Daniel Vetter wrote: > On Wed, Jul 5, 2017 at 7:50 PM, Peter Rosin wrote: +retry: +ret = drm_modeset_lock_all_ctx(dev, &ctx); >>> >>> With atomic you don't need to grab locks, this is done behind the scenes >>> (as long as you handle the retry/backoff correctly). See the kerneldoc for >>> the various drm_atomic_get_*_state functions. >> >> It doesn't work if I remove it. What is the disconnect? > > Good question, Duh, for symmetry I also removed the dropping of the locks. So the next call of course had no chance of getting access. How silly of me... >didn't spot this at first, but your backoff/retry logic > is proken. When typing drm_modeset_lock locking code please make sure > you've enabled both CONFIG_PROVE_LOCKING and > CONFIG_DEBUG_WW_MUTEX_SLOWPATH. Without these two it's really easy to > get this wrong. Please also read > https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#kms-locking > carefully plus all the kernel-doc of the various hooks. This stuff is > a really tricky locking scheme, it takes a while to understand it and > implement it correctly. Which is why all the locking magic is in > shared code and for normal drivers no need think about it. For the > fundamental algorithm, you can also check out the docs for w/w mutexes > at https://www.kernel.org/doc/Documentation/locking/ww-mutex-design.txt > > Might also help to read a bunch of the other locking paths again, with > my patches there's a few just in drm_fbdev_helper.c. I'll leave you > with these snippets here since I think this is fun to learn, but when > you're stuck I'm happy to help learn. I'll take a long look at this before I send a cleaned up v4. Thanks for the pointers... Cheers, peda ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 02/14] drm/atomic-helper: update lut props directly in ..._legacy_gamma_set
Do not waste cycles looking up the property id when we have the actual property already. Signed-off-by: Peter Rosin --- drivers/gpu/drm/drm_atomic_helper.c | 23 --- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 667ec97..5a4a344 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3769,11 +3769,11 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, struct drm_modeset_acquire_ctx *ctx) { struct drm_device *dev = crtc->dev; - struct drm_mode_config *config = &dev->mode_config; struct drm_atomic_state *state; struct drm_crtc_state *crtc_state; struct drm_property_blob *blob = NULL; struct drm_color_lut *blob_data; + bool replaced = false; int i, ret = 0; state = drm_atomic_state_alloc(crtc->dev); @@ -3805,20 +3805,13 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, } /* Reset DEGAMMA_LUT and CTM properties. */ - ret = drm_atomic_crtc_set_property(crtc, crtc_state, - config->degamma_lut_property, 0); - if (ret) - goto fail; - - ret = drm_atomic_crtc_set_property(crtc, crtc_state, - config->ctm_property, 0); - if (ret) - goto fail; - - ret = drm_atomic_crtc_set_property(crtc, crtc_state, - config->gamma_lut_property, blob->base.id); - if (ret) - goto fail; + drm_atomic_replace_property_blob(&crtc_state->degamma_lut, +NULL, &replaced); + drm_atomic_replace_property_blob(&crtc_state->ctm, +NULL, &replaced); + drm_atomic_replace_property_blob(&crtc_state->gamma_lut, +blob, &replaced); + crtc_state->color_mgmt_changed |= replaced; ret = drm_atomic_commit(state); -- 2.1.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 06/14] drm: ast: remove dead code and pointless local lut storage
The redundant fb helpers .load_lut, .gamma_set and .gamma_get are no longer used. Remove the dead code and hook up the crtc .gamma_set to use the crtc gamma_store directly instead of duplicating that info locally. Signed-off-by: Peter Rosin --- drivers/gpu/drm/ast/ast_drv.h | 1 - drivers/gpu/drm/ast/ast_fb.c | 20 drivers/gpu/drm/ast/ast_mode.c | 26 ++ 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 8880f0b..569a148 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -245,7 +245,6 @@ struct ast_connector { struct ast_crtc { struct drm_crtc base; - u8 lut_r[256], lut_g[256], lut_b[256]; struct drm_gem_object *cursor_bo; uint64_t cursor_addr; int cursor_width, cursor_height; diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index 4ad4acd..dbabcac 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -255,27 +255,7 @@ static int astfb_create(struct drm_fb_helper *helper, return ret; } -static void ast_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct ast_crtc *ast_crtc = to_ast_crtc(crtc); - ast_crtc->lut_r[regno] = red >> 8; - ast_crtc->lut_g[regno] = green >> 8; - ast_crtc->lut_b[regno] = blue >> 8; -} - -static void ast_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - struct ast_crtc *ast_crtc = to_ast_crtc(crtc); - *red = ast_crtc->lut_r[regno] << 8; - *green = ast_crtc->lut_g[regno] << 8; - *blue = ast_crtc->lut_b[regno] << 8; -} - static const struct drm_fb_helper_funcs ast_fb_helper_funcs = { - .gamma_set = ast_fb_gamma_set, - .gamma_get = ast_fb_gamma_get, .fb_probe = astfb_create, }; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index aaef0a6..724c16b 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -63,15 +63,18 @@ static inline void ast_load_palette_index(struct ast_private *ast, static void ast_crtc_load_lut(struct drm_crtc *crtc) { struct ast_private *ast = crtc->dev->dev_private; - struct ast_crtc *ast_crtc = to_ast_crtc(crtc); + u16 *r, *g, *b; int i; if (!crtc->enabled) return; + r = crtc->gamma_store; + g = r + crtc->gamma_size; + b = g + crtc->gamma_size; + for (i = 0; i < 256; i++) - ast_load_palette_index(ast, i, ast_crtc->lut_r[i], - ast_crtc->lut_g[i], ast_crtc->lut_b[i]); + ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8); } static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode, @@ -633,7 +636,6 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { .mode_set = ast_crtc_mode_set, .mode_set_base = ast_crtc_mode_set_base, .disable = ast_crtc_disable, - .load_lut = ast_crtc_load_lut, .prepare = ast_crtc_prepare, .commit = ast_crtc_commit, @@ -648,15 +650,6 @@ static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, uint32_t size, struct drm_modeset_acquire_ctx *ctx) { - struct ast_crtc *ast_crtc = to_ast_crtc(crtc); - int i; - - /* userspace palettes are always correct as is */ - for (i = 0; i < size; i++) { - ast_crtc->lut_r[i] = red[i] >> 8; - ast_crtc->lut_g[i] = green[i] >> 8; - ast_crtc->lut_b[i] = blue[i] >> 8; - } ast_crtc_load_lut(crtc); return 0; @@ -681,7 +674,6 @@ static const struct drm_crtc_funcs ast_crtc_funcs = { static int ast_crtc_init(struct drm_device *dev) { struct ast_crtc *crtc; - int i; crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL); if (!crtc) @@ -690,12 +682,6 @@ static int ast_crtc_init(struct drm_device *dev) drm_crtc_init(dev, &crtc->base, &ast_crtc_funcs); drm_mode_crtc_set_gamma_size(&crtc->base, 256); drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs); - - for (i = 0; i < 256; i++) { - crtc->lut_r[i] = i; - crtc->lut_g[i] = i; - crtc->lut_b[i] = i; - } return 0; } -- 2.1.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support
On Thu, Jul 06, 2017 at 02:38:41PM +0100, Russell King - ARM Linux wrote: > On Thu, Jul 06, 2017 at 12:56:43PM +0100, Russell King - ARM Linux wrote: > > On Thu, Jul 06, 2017 at 12:45:55PM +0100, Russell King - ARM Linux wrote: > > > Well, from what I can see in 4.12, the cec-notifier stuff is rather > > > broken (tda998x has stopped working as its stuck with a physical > > > address of f.f.f.f) so I think the whole thing is rather moot right > > > now. I don't yet know what's going on with that, other than the > > > notifier stuff seems to not be working, despite being enabled in > > > the .config. > > > > The problem there appears to be the changes that were made with the > > way the config works - which IMHO are totally broken. > > > > Let's take this scenario: > > > > - You have a HDMI bridge, and you build that into the kernel, because you > > want the display to come up early. > > - You have a CEC driver, which you build as a module. > > > > If the HDMI bridge driver selects CEC_NOTIFIER and the CEC driver selects > > both CEC_NOTIFIER and CEC_CORE, you end up with CEC_NOTIFIER=y and > > CEC_CORE=m. > > > > We now come to this: > > > > #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) > > > > The definition of IS_REACHABLE() is that it is false if the config symbol > > is selected as a module. So, in this case, we end up compiling out all > > the CEC notifier functions from the HDMI bridge, and building them into > > the CEC driver. > > > > The CEC notifier also gets built as a module, meaning that there's no way > > for the built-in HDMI bridge could ever call the notifier. > > > > The overall result of this is that such a configuration completely breaks > > such a setup - a setup that worked fine before the CEC Kconfig changes. > > > > This isn't limited to tda998x - I'd expect the same to be true of dw-hdmi. > > Fixing this so cec-notifier is built-in isn't sufficient, because we > also need the cec-edid parsing code as well, which is currently part > of cec-core, and that function gets stubbed out if cec-core is not > built-in... > > The patch below works for me. I missed the include/media changes... drivers/media/Makefile | 2 +- drivers/media/cec/Makefile | 6 ++--- drivers/media/cec/cec-core.c | 2 +- include/media/cec-notifier.h | 2 +- include/media/cec.h | 54 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 044503aa8801..0c02fbe4b9c7 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_DVB_CORE) += dvb-core/ # There are both core and drivers at RC subtree - merge before drivers obj-y += rc/ -obj-$(CONFIG_CEC_CORE) += cec/ +obj-y += cec/ # # Finally, merge the drivers that require the core diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile index eaf408e64669..58394b77a328 100644 --- a/drivers/media/cec/Makefile +++ b/drivers/media/cec/Makefile @@ -1,7 +1,7 @@ cec-objs := cec-core.o cec-adap.o cec-api.o cec-edid.o -ifeq ($(CONFIG_CEC_NOTIFIER),y) - cec-objs += cec-notifier.o -endif +obj-$(CONFIG_CEC_NOTIFIER) += cec-notifier.o cec-edid.o + +cec-objs := $(filter-out $(obj-y) $(obj-m), $(cec-objs)) obj-$(CONFIG_CEC_CORE) += cec.o diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index 2f87748ba4fc..bce26b94c348 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -187,7 +187,7 @@ static void cec_devnode_unregister(struct cec_devnode *devnode) put_device(&devnode->dev); } -#ifdef CONFIG_CEC_NOTIFIER +#if IS_ENABLED(CONFIG_CEC_NOTIFIER) static void cec_cec_notify(struct cec_adapter *adap, u16 pa) { cec_s_phys_addr(adap, pa, false); diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h index 298f996969df..83bdc221d0a0 100644 --- a/include/media/cec-notifier.h +++ b/include/media/cec-notifier.h @@ -29,7 +29,7 @@ struct edid; struct cec_adapter; struct cec_notifier; -#if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) +#if IS_ENABLED(CONFIG_CEC_NOTIFIER) /** * cec_notifier_get - find or create a new cec_notifier for the given device. diff --git a/include/media/cec.h b/include/media/cec.h index 201f060978da..039aad98462d 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -225,6 +225,36 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); +#if IS_ENABLED(CONFIG_CEC_NOTIFIER) +void cec_register_cec_notifier(struct cec_adapter *adap, + struct cec_notifier *notifier); +#endif + +#else + +static inline int cec_register_adapter(struct cec_adapter *adap, + struct device *parent) +{ + return 0; +}
Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support
Hi Neil, On 06-07-2017 11:33, Neil Armstrong wrote: > From: Russell King > > Add CEC notifier support to the HDMI bridge driver, so that the CEC > part of the IP can receive its physical address. > > Tested-by: Neil Armstrong > Acked-by: Neil Armstrong > Acked-by: Hans Verkuil > Signed-off-by: Russell King > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++ > 1 file changed, 18 insertions(+) > > Hi Archit, Hans, > > This is repost of Russell's patch from his dw-hdmi CEC patchset. > > Since his CEC implementation will be integrated in the bridge driver, > this notifier patch won't be re-posted. > > But the Amlogic Platform needs a notifier since it uses a standalone CEC > controller. > > Thanks, > Neil > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index ead1124..9c03846 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -33,6 +33,8 @@ > #include > #include > > +#include Don't you also have to "select CEC_NOTIFIER" in Kconfig? Or is it not needed anymore with the recent Kconfig changes of CEC? Best regards, Jose Miguel Abreu > + > #include "dw-hdmi.h" > #include "dw-hdmi-audio.h" > > @@ -175,6 +177,8 @@ struct dw_hdmi { > struct regmap *regm; > void (*enable_audio)(struct dw_hdmi *hdmi); > void (*disable_audio)(struct dw_hdmi *hdmi); > + > + struct cec_notifier *cec_notifier; > }; > > #define HDMI_IH_PHY_STAT0_RX_SENSE \ > @@ -1896,6 +1900,7 @@ static int dw_hdmi_connector_get_modes(struct > drm_connector *connector) > hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); > hdmi->sink_has_audio = drm_detect_monitor_audio(edid); > drm_mode_connector_update_edid_property(connector, edid); > + cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); > ret = drm_add_edid_modes(connector, edid); > /* Store the ELD */ > drm_edid_to_eld(connector, edid); > @@ -2077,6 +2082,10 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, > bool hpd, bool rx_sense) > dw_hdmi_update_phy_mask(hdmi); > } > mutex_unlock(&hdmi->mutex); > + > + if (!rx_sense && !hpd) > + cec_notifier_set_phys_addr(hdmi->cec_notifier, > +CEC_PHYS_ADDR_INVALID); > } > > void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) > @@ -2376,6 +2385,12 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > if (ret) > goto err_iahb; > > + hdmi->cec_notifier = cec_notifier_get(dev); > + if (!hdmi->cec_notifier) { > + ret = -ENOMEM; > + goto err_iahb; > + } > + > /* >* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator >* N and cts values before enabling phy > @@ -2452,6 +2467,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > hdmi->ddc = NULL; > } > > + if (hdmi->cec_notifier) > + cec_notifier_put(hdmi->cec_notifier); > + > clk_disable_unprepare(hdmi->iahb_clk); > err_isfr: > clk_disable_unprepare(hdmi->isfr_clk); ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support
On Thu, Jul 06, 2017 at 01:55:58PM +0200, Neil Armstrong wrote: > On 07/06/2017 01:45 PM, Russell King - ARM Linux wrote: > > Well, from what I can see in 4.12, the cec-notifier stuff is rather > > broken (tda998x has stopped working as its stuck with a physical > > address of f.f.f.f) so I think the whole thing is rather moot right > > now. I don't yet know what's going on with that, other than the > > notifier stuff seems to not be working, despite being enabled in > > the .config. > > > > Indeed, I missed some parts of the thread, sorry for the confusion. > > Anyway, is it a showstopper to have this patch merged separately ? It shouldn't be provided it makes _this_ merge window or the -rc following, but it doesn't really comprise a "fix" in that the feature never worked in the previous kernel (and we are supposed to have the rule that features are merged prior to the merge window.) It's up to the maintainers to decide what to do at this point. > If you prefer re-posting a serie with this patch inside, no problem, > but the Amlogic platform still needs this patch to have CEC working. I suspect (because I've not seen what has been queued to be merged yet) that even the dw-hdmi "native" side will be similarly broken - unless Hans merged some other changes to make it work. So, I suggest we all sit tight and wait until what was merged appears in Linus' tree. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 03/14] drm/fb-helper: separate the fb_setcmap helper into atomic and legacy paths
The legacy path implements setcmap in terms of crtc .gamma_set. The atomic path implements setcmap by directly updating the crtc gamma_lut property. This has a couple of benefits: - it makes the redundant fb helpers .load_lut, .gamma_set and .gamma_get completely obsolete. They are now unused and subject for removal. - atomic drivers that support clut modes get fbdev support for those from the drm core. This includes atmel-hlcdc, but perhaps others as well? Signed-off-by: Peter Rosin --- drivers/gpu/drm/drm_fb_helper.c | 232 1 file changed, 161 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 721511d..32d6ea1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1195,27 +1195,6 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, } EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked); -static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, -u16 blue, u16 regno, struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_framebuffer *fb = fb_helper->fb; - - /* -* The driver really shouldn't advertise pseudo/directcolor -* visuals if it can't deal with the palette. -*/ - if (WARN_ON(!fb_helper->funcs->gamma_set || - !fb_helper->funcs->gamma_get)) - return -EINVAL; - - WARN_ON(fb->format->cpp[0] != 1); - - fb_helper->funcs->gamma_set(crtc, red, green, blue, regno); - - return 0; -} - static int setcmap_pseudo_palette(struct fb_cmap *cmap, struct fb_info *info) { u32 *palette = (u32 *)info->pseudo_palette; @@ -1248,57 +1227,140 @@ static int setcmap_pseudo_palette(struct fb_cmap *cmap, struct fb_info *info) return 0; } -/** - * drm_fb_helper_setcmap - implementation for &fb_ops.fb_setcmap - * @cmap: cmap to set - * @info: fbdev registered by the helper - */ -int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) +static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info) { struct drm_fb_helper *fb_helper = info->par; - struct drm_device *dev = fb_helper->dev; - const struct drm_crtc_helper_funcs *crtc_funcs; - u16 *red, *green, *blue, *transp; struct drm_crtc *crtc; u16 *r, *g, *b; - int i, j, rc = 0; - int start; + int i, ret = 0; - if (oops_in_progress) - return -EBUSY; + drm_modeset_lock_all(fb_helper->dev); + for (i = 0; i < fb_helper->crtc_count; i++) { + crtc = fb_helper->crtc_info[i].mode_set.crtc; + if (!crtc->funcs->gamma_set || !crtc->gamma_size) + return -EINVAL; - mutex_lock(&fb_helper->lock); - if (!drm_fb_helper_is_bound(fb_helper)) { - mutex_unlock(&fb_helper->lock); - return -EBUSY; + if (cmap->start + cmap->len > crtc->gamma_size) + return -EINVAL; + + r = crtc->gamma_store; + g = r + crtc->gamma_size; + b = g + crtc->gamma_size; + + memcpy(r + cmap->start, cmap->red, cmap->len * sizeof(*r)); + memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g)); + memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b)); + + ret = crtc->funcs->gamma_set(crtc, r, g, b, +crtc->gamma_size, NULL); + if (ret) + return ret; } + drm_modeset_unlock_all(fb_helper->dev); - drm_modeset_lock_all(dev); - if (info->fix.visual == FB_VISUAL_TRUECOLOR) { - rc = setcmap_pseudo_palette(cmap, info); - goto out; + return ret; +} + +static struct drm_property_blob *setcmap_new_gamma_lut(struct drm_crtc *crtc, + struct fb_cmap *cmap) +{ + struct drm_device *dev = crtc->dev; + struct drm_property_blob *gamma_lut; + struct drm_color_lut *lut; + int size = crtc->gamma_size; + int i; + + if (!size || cmap->start + cmap->len > size) + return ERR_PTR(-EINVAL); + + gamma_lut = drm_property_create_blob(dev, sizeof(*lut) * size, NULL); + if (IS_ERR(gamma_lut)) + return gamma_lut; + + lut = (struct drm_color_lut *)gamma_lut->data; + if (cmap->start || cmap->len != size) { + u16 *r = crtc->gamma_store; + u16 *g = r + crtc->gamma_size; + u16 *b = g + crtc->gamma_size; + + for (i = 0; i < cmap->start; i++) { + lut[i].red = r[i]; + lut[i].green = g[i]; + lut[i].blue = b[i]; + } + for (i = cmap->start + cmap->len; i < size; i
printk: Should console related code avoid __GFP_DIRECT_RECLAIM memory allocations?
Hello. I noticed that printing to consoles can stop forever because console drivers can wait for memory allocation when memory allocation cannot make progress. I was testing almost OOM situation and reproduced a situation where allocation requests fall into infinite too_many_isolated() trap in shrink_inactive_list(). Since nothing will be printed to consoles when we hit that situation, I tried to confirm that I actually reproduced that situation using SysRq-t. However, SysRq-t printed nothing for some reason. Therefore, I used SysRq-c at uptime = 910. Complete log is at http://I-love.SAKURA.ne.jp/tmp/serial-20170706.txt.xz : [ 779.494100] Mem-Info: [ 779.495493] active_anon:846948 inactive_anon:5416 isolated_anon:0 [ 779.495493] active_file:33 inactive_file:13 isolated_file:47 [ 779.495493] unevictable:0 dirty:11 writeback:0 unstable:0 [ 779.495493] slab_reclaimable:0 slab_unreclaimable:11 [ 779.495493] mapped:3580 shmem:5581 pagetables:7491 bounce:0 [ 779.495493] free:21354 free_pcp:87 free_cma:0 [ 779.510664] Node 0 active_anon:3387792kB inactive_anon:21664kB active_file:132kB inactive_file:52kB unevictable:0kB isolated(anon):0kB isolated(file):188kB mapped:14320kB dirty:44kB writeback:0kB shmem:22324kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 3067904kB writeback_tmp:0kB unstable:0kB all_unreclaimable? no [ 779.522778] Node 0 DMA free:14836kB min:284kB low:352kB high:420kB active_anon:1024kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:15988kB managed:15904kB mlocked:0kB kernel_stack:0kB pagetables:8kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB [ 779.533972] lowmem_reserve[]: 0 2700 3642 3642 [ 779.536321] Node 0 DMA32 free:53656kB min:49888kB low:62360kB high:74832kB active_anon:2710360kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:3129216kB managed:2765492kB mlocked:0kB kernel_stack:0kB pagetables:12kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB [ 779.548127] lowmem_reserve[]: 0 0 942 942 [ 779.550326] Node 0 Normal free:16924kB min:17404kB low:21752kB high:26100kB active_anon:676260kB inactive_anon:21664kB active_file:340kB inactive_file:244kB unevictable:0kB writepending:44kB present:1048576kB managed:964816kB mlocked:0kB kernel_stack:13600kB pagetables:29944kB bounce:0kB free_pcp:348kB local_pcp:0kB free_cma:0kB [ 779.563405] lowmem_reserve[]: 0 0 0 0 [ 779.565537] Node 0 DMA: 1*4kB (U) 0*8kB 1*16kB (U) 1*32kB (U) 1*64kB (U) 1*128kB (U) 1*256kB (U) 0*512kB 2*1024kB (UM) 0*2048kB 3*4096kB (M) = 14836kB [ 779.571291] Node 0 DMA32: 6*4kB (UM) 8*8kB (UM) 8*16kB (UM) 20*32kB (U) 29*64kB (UM) 32*128kB (UM) 13*256kB (UM) 9*512kB (UM) 10*1024kB (UM) 0*2048kB 7*4096kB (UME) = 53656kB [ 779.578672] Node 0 Normal: 734*4kB (UE) 478*8kB (UME) 266*16kB (UE) 163*32kB (UE) 7*64kB (U) 3*128kB (UM) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 17064kB [ 779.585618] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=1048576kB [ 779.589721] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB [ 779.593765] 5660 total pagecache pages [ 779.596059] 0 pages in swap cache [ 779.598144] Swap cache stats: add 0, delete 0, find 0/0 [ 779.600947] Free swap = 0kB [ 779.602837] Total swap = 0kB [ 779.604716] 1048445 pages RAM [ 779.606691] 0 pages HighMem/MovableOnly [ 779.608974] 111892 pages reserved [ 779.611075] 0 pages cma reserved [ 779.613118] 0 pages hwpoisoned [ 779.615117] Out of memory: Kill process 3655 (c.out) score 999 or sacrifice child [ 779.618790] Killed process 3655 (c.out) total-vm:4168kB, anon-rss:88kB, file-rss:0kB, shmem-rss:0kB [ 779.625401] oom_reaper: reaped process 3655 (c.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB ** 1838 printk messages dropped ** [ 912.886103] __do_fault+0x19/0xf0 [ 912.886108] __handle_mm_fault+0xb0b/0x1030 [ 912.886114] handle_mm_fault+0xf4/0x220 [ 912.886117] __do_page_fault+0x25b/0x4a0 [ 912.886120] do_page_fault+0x30/0x80 [ 912.886124] ? do_syscall_64+0xfd/0x140 [ 912.886127] page_fault+0x28/0x30 (...snipped...) [ 912.892027] kworker/3:3 D12120 3217 2 0x0080 [ 912.892041] Workqueue: events console_callback [ 912.892042] Call Trace: [ 912.892047] __schedule+0x23f/0x5d0 [ 912.892051] schedule+0x31/0x80 [ 912.892056] schedule_preempt_disabled+0x9/0x10 [ 912.892061] __mutex_lock.isra.2+0x2ac/0x4d0 [ 912.892068] __mutex_lock_slowpath+0xe/0x10 [ 912.892072] ? __mutex_lock_slowpath+0xe/0x10 [ 912.892077] mutex_lock+0x2a/0x30 [ 912.892105] vmw_fb_pan_display+0x35/0x90 [vmwgfx] [ 912.892114] fb_pan_display+0xca/0x160 [ 912.892118] bit_update_start+0x1b/0x40 [ 912.892123] fbcon_switch+0x4a6/0x630 [ 912.892128] redraw_screen+0x15a/0x240 [ 912.892132] ? update_attr.isra.3+0x90/0x90 [ 912.892139] complete_change_console+0x3d/0xd0
[PATCH v4 09/14] drm: i915: remove dead code and pointless local lut storage
The driver stores lut values from the fbdev interface, and is able to give them back, but does not appear to do anything with these lut values. The generic fb helpers have replaced this function, and may even have made the driver work for the C8 mode from the fbdev interface. But that is untested. Since the fb helpers .gamma_set and .gamma_get are obsolete, remove the dead code. Signed-off-by: Peter Rosin --- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_fbdev.c | 31 --- 2 files changed, 32 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d93efb4..bc7bfa0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -786,7 +786,6 @@ struct intel_crtc { struct drm_crtc base; enum pipe pipe; enum plane plane; - u8 lut_r[256], lut_g[256], lut_b[256]; /* * Whether the crtc and the connected output pipeline is active. Implies * that crtc->enabled is set, i.e. the current mode configuration has diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 460ca0b..19d650b 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -281,27 +281,6 @@ static int intelfb_create(struct drm_fb_helper *helper, return ret; } -/** Sets the color ramps on behalf of RandR */ -static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - intel_crtc->lut_r[regno] = red >> 8; - intel_crtc->lut_g[regno] = green >> 8; - intel_crtc->lut_b[regno] = blue >> 8; -} - -static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - *red = intel_crtc->lut_r[regno] << 8; - *green = intel_crtc->lut_g[regno] << 8; - *blue = intel_crtc->lut_b[regno] << 8; -} - static struct drm_fb_helper_crtc * intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc) { @@ -376,7 +355,6 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, struct drm_connector *connector; struct drm_encoder *encoder; struct drm_fb_helper_crtc *new_crtc; - struct intel_crtc *intel_crtc; fb_conn = fb_helper->connector_info[i]; connector = fb_conn->connector; @@ -418,13 +396,6 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, num_connectors_enabled++; - intel_crtc = to_intel_crtc(connector->state->crtc); - for (j = 0; j < 256; j++) { - intel_crtc->lut_r[j] = j; - intel_crtc->lut_g[j] = j; - intel_crtc->lut_b[j] = j; - } - new_crtc = intel_fb_helper_crtc(fb_helper, connector->state->crtc); @@ -527,8 +498,6 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { .initial_config = intel_fb_initial_config, - .gamma_set = intel_crtc_fb_gamma_set, - .gamma_get = intel_crtc_fb_gamma_get, .fb_probe = intelfb_create, }; -- 2.1.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel