Re: [PATCH v11 04/25] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On 12/18/19 10:52 PM, Dan Williams wrote: On Wed, Dec 18, 2019 at 9:51 PM John Hubbard wrote: On 12/18/19 9:27 PM, Dan Williams wrote: ... @@ -461,5 +449,5 @@ void __put_devmap_managed_page(struct page *page) page->mapping = NULL; page->pgmap->ops->page_free(page); } -EXPORT_SYMBOL(__put_devmap_managed_page); +EXPORT_SYMBOL(free_devmap_managed_page); This patch does not have a module consumer for free_devmap_managed_page(), so the export should move to the patch that needs the new export. Hi Dan, OK, I know that's a policy--although it seems quite pointless here given that this is definitely going to need an EXPORT. At the moment, the series doesn't use it in any module at all, so I'll just delete the EXPORT for now. Also the only reason that put_devmap_managed_page() is EXPORT_SYMBOL instead of EXPORT_SYMBOL_GPL is that there was no practical way to hide the devmap details from evey module in the kernel that did put_page(). I would expect free_devmap_managed_page() to EXPORT_SYMBOL_GPL if it is not inlined into an existing exported static inline api. Sure, I'll change it to EXPORT_SYMBOL_GPL when the time comes. We do have to be careful that we don't shut out normal put_page() types of callers, but...glancing through the current callers, that doesn't look to be a problem. Good. So it should be OK to do EXPORT_SYMBOL_GPL here. Are you *sure* you don't want to just pre-emptively EXPORT now, and save looking at it again? I'm positive. There is enough history for "trust me the consumer is coming" turning out not to be true to justify the hassle in my mind. I do trust you, but things happen. OK, it's deleted locally. Thanks for looking at the patch. I'll post a v12 series that includes the change, once it looks like reviews are slowing down. thanks, -- John Hubbard NVIDIA ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v11 04/25] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On Wed, Dec 18, 2019 at 9:51 PM John Hubbard wrote: > > On 12/18/19 9:27 PM, Dan Williams wrote: > ... > >> @@ -461,5 +449,5 @@ void __put_devmap_managed_page(struct page *page) > >> page->mapping = NULL; > >> page->pgmap->ops->page_free(page); > >> } > >> -EXPORT_SYMBOL(__put_devmap_managed_page); > >> +EXPORT_SYMBOL(free_devmap_managed_page); > > > > This patch does not have a module consumer for > > free_devmap_managed_page(), so the export should move to the patch > > that needs the new export. > > Hi Dan, > > OK, I know that's a policy--although it seems quite pointless here given > that this is definitely going to need an EXPORT. > > At the moment, the series doesn't use it in any module at all, so I'll just > delete the EXPORT for now. > > > > > Also the only reason that put_devmap_managed_page() is EXPORT_SYMBOL > > instead of EXPORT_SYMBOL_GPL is that there was no practical way to > > hide the devmap details from evey module in the kernel that did > > put_page(). I would expect free_devmap_managed_page() to > > EXPORT_SYMBOL_GPL if it is not inlined into an existing exported > > static inline api. > > > > Sure, I'll change it to EXPORT_SYMBOL_GPL when the time comes. We do have > to be careful that we don't shut out normal put_page() types of callers, > but...glancing through the current callers, that doesn't look to be a problem. > Good. So it should be OK to do EXPORT_SYMBOL_GPL here. > > Are you *sure* you don't want to just pre-emptively EXPORT now, and save > looking at it again? I'm positive. There is enough history for "trust me the consumer is coming" turning out not to be true to justify the hassle in my mind. I do trust you, but things happen. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v11 04/25] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On 12/18/19 9:27 PM, Dan Williams wrote: ... @@ -461,5 +449,5 @@ void __put_devmap_managed_page(struct page *page) page->mapping = NULL; page->pgmap->ops->page_free(page); } -EXPORT_SYMBOL(__put_devmap_managed_page); +EXPORT_SYMBOL(free_devmap_managed_page); This patch does not have a module consumer for free_devmap_managed_page(), so the export should move to the patch that needs the new export. Hi Dan, OK, I know that's a policy--although it seems quite pointless here given that this is definitely going to need an EXPORT. At the moment, the series doesn't use it in any module at all, so I'll just delete the EXPORT for now. Also the only reason that put_devmap_managed_page() is EXPORT_SYMBOL instead of EXPORT_SYMBOL_GPL is that there was no practical way to hide the devmap details from evey module in the kernel that did put_page(). I would expect free_devmap_managed_page() to EXPORT_SYMBOL_GPL if it is not inlined into an existing exported static inline api. Sure, I'll change it to EXPORT_SYMBOL_GPL when the time comes. We do have to be careful that we don't shut out normal put_page() types of callers, but...glancing through the current callers, that doesn't look to be a problem. Good. So it should be OK to do EXPORT_SYMBOL_GPL here. Are you *sure* you don't want to just pre-emptively EXPORT now, and save looking at it again? thanks, -- John Hubbard NVIDIA ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v11 04/25] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On Mon, Dec 16, 2019 at 2:26 PM John Hubbard wrote: > > An upcoming patch changes and complicates the refcounting and > especially the "put page" aspects of it. In order to keep > everything clean, refactor the devmap page release routines: > > * Rename put_devmap_managed_page() to page_is_devmap_managed(), > and limit the functionality to "read only": return a bool, > with no side effects. > > * Add a new routine, put_devmap_managed_page(), to handle checking > what kind of page it is, and what kind of refcount handling it > requires. > > * Rename __put_devmap_managed_page() to free_devmap_managed_page(), > and limit the functionality to unconditionally freeing a devmap > page. > > This is originally based on a separate patch by Ira Weiny, which > applied to an early version of the put_user_page() experiments. > Since then, Jérôme Glisse suggested the refactoring described above. > > Cc: Christoph Hellwig > Suggested-by: Jérôme Glisse > Reviewed-by: Dan Williams > Reviewed-by: Jan Kara > Signed-off-by: Ira Weiny > Signed-off-by: John Hubbard > --- > include/linux/mm.h | 17 + > mm/memremap.c | 16 ++-- > mm/swap.c | 24 > 3 files changed, 39 insertions(+), 18 deletions(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index c97ea3b694e6..77a4df06c8a7 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -952,9 +952,10 @@ static inline bool is_zone_device_page(const struct page > *page) > #endif > > #ifdef CONFIG_DEV_PAGEMAP_OPS > -void __put_devmap_managed_page(struct page *page); > +void free_devmap_managed_page(struct page *page); > DECLARE_STATIC_KEY_FALSE(devmap_managed_key); > -static inline bool put_devmap_managed_page(struct page *page) > + > +static inline bool page_is_devmap_managed(struct page *page) > { > if (!static_branch_unlikely(_managed_key)) > return false; > @@ -963,7 +964,6 @@ static inline bool put_devmap_managed_page(struct page > *page) > switch (page->pgmap->type) { > case MEMORY_DEVICE_PRIVATE: > case MEMORY_DEVICE_FS_DAX: > - __put_devmap_managed_page(page); > return true; > default: > break; > @@ -971,7 +971,14 @@ static inline bool put_devmap_managed_page(struct page > *page) > return false; > } > > +bool put_devmap_managed_page(struct page *page); > + > #else /* CONFIG_DEV_PAGEMAP_OPS */ > +static inline bool page_is_devmap_managed(struct page *page) > +{ > + return false; > +} > + > static inline bool put_devmap_managed_page(struct page *page) > { > return false; > @@ -1028,8 +1035,10 @@ static inline void put_page(struct page *page) > * need to inform the device driver through callback. See > * include/linux/memremap.h and HMM for details. > */ > - if (put_devmap_managed_page(page)) > + if (page_is_devmap_managed(page)) { > + put_devmap_managed_page(page); > return; > + } > > if (put_page_testzero(page)) > __put_page(page); > diff --git a/mm/memremap.c b/mm/memremap.c > index e899fa876a62..2ba773859031 100644 > --- a/mm/memremap.c > +++ b/mm/memremap.c > @@ -411,20 +411,8 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn, > EXPORT_SYMBOL_GPL(get_dev_pagemap); > > #ifdef CONFIG_DEV_PAGEMAP_OPS > -void __put_devmap_managed_page(struct page *page) > +void free_devmap_managed_page(struct page *page) > { > - int count = page_ref_dec_return(page); > - > - /* still busy */ > - if (count > 1) > - return; > - > - /* only triggered by the dev_pagemap shutdown path */ > - if (count == 0) { > - __put_page(page); > - return; > - } > - > /* notify page idle for dax */ > if (!is_device_private_page(page)) { > wake_up_var(>_refcount); > @@ -461,5 +449,5 @@ void __put_devmap_managed_page(struct page *page) > page->mapping = NULL; > page->pgmap->ops->page_free(page); > } > -EXPORT_SYMBOL(__put_devmap_managed_page); > +EXPORT_SYMBOL(free_devmap_managed_page); This patch does not have a module consumer for free_devmap_managed_page(), so the export should move to the patch that needs the new export. Also the only reason that put_devmap_managed_page() is EXPORT_SYMBOL instead of EXPORT_SYMBOL_GPL is that there was no practical way to hide the devmap details from evey module in the kernel that did put_page(). I would expect free_devmap_managed_page() to EXPORT_SYMBOL_GPL if it is not inlined into an existing exported static inline api. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/2] drm/amdgpu/display: use msleep rather than udelay for HDCP
On Wed, Dec 18, 2019 at 6:07 PM Dave Airlie wrote: > > Hey, > > I've pulled in these two patches to drm-next directly because my arm > test build was broken. Sounds good. Alex > > Dave. > > On Wed, 18 Dec 2019 at 06:47, Alex Deucher wrote: > > > > ARM has a 2000us limit for udelay. Switch to msleep. This code > > executes in a worker thread so shouldn't be an atomic context. > > > > Signed-off-by: Alex Deucher > > --- > > drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > > b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > > index bcbc0b8a9aa0..f730b94ac3c0 100644 > > --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > > +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > > @@ -153,7 +153,7 @@ static enum mod_hdcp_status > > poll_l_prime_available(struct mod_hdcp *hdcp) > > { > > enum mod_hdcp_status status; > > uint8_t size; > > - uint16_t max_wait = 2; // units of us > > + uint16_t max_wait = 20; // units of ms > > uint16_t num_polls = 5; > > uint16_t wait_time = max_wait / num_polls; > > > > @@ -161,7 +161,7 @@ static enum mod_hdcp_status > > poll_l_prime_available(struct mod_hdcp *hdcp) > > status = MOD_HDCP_STATUS_INVALID_OPERATION; > > else > > for (; num_polls; num_polls--) { > > - udelay(wait_time); > > + msleep(wait_time); > > > > status = mod_hdcp_read_rxstatus(hdcp); > > if (status != MOD_HDCP_STATUS_SUCCESS) > > @@ -474,7 +474,7 @@ static enum mod_hdcp_status locality_check(struct > > mod_hdcp *hdcp, > > hdcp, "lc_init_write")) > > goto out; > > if (is_dp_hdcp(hdcp)) > > - udelay(16000); > > + msleep(16); > > else > > if (!mod_hdcp_execute_and_set(poll_l_prime_available, > > >l_prime_available_poll, , > > -- > > 2.23.0 > > > > ___ > > 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
[PATCH 4/6] drm/virtio: simplify getting fake offset
This is a little simpler. Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_drv.h | 8 +--- drivers/gpu/drm/virtio/virtgpu_gem.c | 4 +--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 3e0580a8d818..578d5e42946e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -365,18 +365,12 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_params *params, struct virtio_gpu_object **bo_ptr, struct virtio_gpu_fence *fence); - /* virtgpu_prime.c */ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); -static inline u64 virtio_gpu_object_mmap_offset(struct virtio_gpu_object *bo) -{ - return drm_vma_node_offset_addr(>base.base.vma_node); -} - -/* virgl debufs */ +/* virgl debugfs */ int virtio_gpu_debugfs_init(struct drm_minor *minor); #endif diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index 4c1f579edfb3..0a2b62279647 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -96,14 +96,12 @@ int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, uint32_t handle, uint64_t *offset_p) { struct drm_gem_object *gobj; - struct virtio_gpu_object *obj; BUG_ON(!offset_p); gobj = drm_gem_object_lookup(file_priv, handle); if (gobj == NULL) return -ENOENT; - obj = gem_to_virtio_gpu_obj(gobj); - *offset_p = virtio_gpu_object_mmap_offset(obj); + *offset_p = drm_vma_node_offset_addr(>vma_node); drm_gem_object_put_unlocked(gobj); return 0; } -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 6/6] drm/virtio: move drm_connector_to_virtio_gpu_output to virtgpu_display
That's the only file that uses it. Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_display.c | 3 +++ drivers/gpu/drm/virtio/virtgpu_drv.h | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index c76d69fecfeb..0966208ec30d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -43,6 +43,9 @@ #define XRES_MAX 8192 #define YRES_MAX 8192 +#define drm_connector_to_virtio_gpu_output(x) \ + container_of(x, struct virtio_gpu_output, conn) + static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy= drm_crtc_cleanup, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index b16e04bd67b7..7e69c06e168e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -133,8 +133,6 @@ struct virtio_gpu_output { }; #define drm_crtc_to_virtio_gpu_output(x) \ container_of(x, struct virtio_gpu_output, crtc) -#define drm_connector_to_virtio_gpu_output(x) \ - container_of(x, struct virtio_gpu_output, conn) struct virtio_gpu_framebuffer { struct drm_framebuffer base; -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/6] drm/virtio: static-ify virtio_gpu_framebuffer_init
Not used anywhere else. Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_display.c | 2 +- drivers/gpu/drm/virtio/virtgpu_drv.h | 4 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index e622485ae826..c76d69fecfeb 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -59,7 +59,7 @@ static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { .dirty = drm_atomic_helper_dirtyfb, }; -int +static int virtio_gpu_framebuffer_init(struct drm_device *dev, struct virtio_gpu_framebuffer *vgfb, const struct drm_mode_fb_cmd2 *mode_cmd, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 349c1dea61c7..cf09e4af2fc5 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -342,10 +342,6 @@ void virtio_gpu_disable_notify(struct virtio_gpu_device *vgdev); void virtio_gpu_enable_notify(struct virtio_gpu_device *vgdev); /* virtio_gpu_display.c */ -int virtio_gpu_framebuffer_init(struct drm_device *dev, - struct virtio_gpu_framebuffer *vgfb, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/6] drm/virtio: get rid of drm_encoder_to_virtio_gpu_output
Not used anywhere. Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index cf09e4af2fc5..3e0580a8d818 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -137,8 +137,6 @@ struct virtio_gpu_output { container_of(x, struct virtio_gpu_output, crtc) #define drm_connector_to_virtio_gpu_output(x) \ container_of(x, struct virtio_gpu_output, conn) -#define drm_encoder_to_virtio_gpu_output(x) \ - container_of(x, struct virtio_gpu_output, enc) struct virtio_gpu_framebuffer { struct drm_framebuffer base; -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/6] drm/virtio: move to_virtio_fence inside virtgpu_fence
That's the only file that uses it. Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 -- drivers/gpu/drm/virtio/virtgpu_fence.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 578d5e42946e..b16e04bd67b7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -103,8 +103,6 @@ struct virtio_gpu_fence { struct virtio_gpu_fence_driver *drv; struct list_head node; }; -#define to_virtio_fence(x) \ - container_of(x, struct virtio_gpu_fence, f) struct virtio_gpu_vbuffer { char *buf; diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 5466aab7d39a..5b2a4146c5bd 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -27,6 +27,9 @@ #include "virtgpu_drv.h" +#define to_virtio_fence(x) \ + container_of(x, struct virtio_gpu_fence, f) + static const char *virtio_get_driver_name(struct dma_fence *f) { return "virtio_gpu"; -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/6] drm/virtio: static-ify virtio_fence_signaled
Not used anywhere else. Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_fence.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 29cf005ed6b9..349c1dea61c7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -356,7 +356,6 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, int index); /* virtio_gpu_fence.c */ -bool virtio_fence_signaled(struct dma_fence *f); struct virtio_gpu_fence *virtio_gpu_fence_alloc( struct virtio_gpu_device *vgdev); void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index a4b9881ca1d3..5466aab7d39a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -37,7 +37,7 @@ static const char *virtio_get_timeline_name(struct dma_fence *f) return "controlq"; } -bool virtio_fence_signaled(struct dma_fence *f) +static bool virtio_fence_signaled(struct dma_fence *f) { struct virtio_gpu_fence *fence = to_virtio_fence(f); -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v12] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
An upcoming patch changes and complicates the refcounting and especially the "put page" aspects of it. In order to keep everything clean, refactor the devmap page release routines: * Rename put_devmap_managed_page() to page_is_devmap_managed(), and limit the functionality to "read only": return a bool, with no side effects. * Add a new routine, put_devmap_managed_page(), to handle decrementing the refcount for ZONE_DEVICE pages. * Change callers (just release_pages() and put_page()) to check page_is_devmap_managed() before calling the new put_devmap_managed_page() routine. This is a performance point: put_page() is a hot path, so we need to avoid non- inline function calls where possible. * Rename __put_devmap_managed_page() to free_devmap_managed_page(), and limit the functionality to unconditionally freeing a devmap page. This is originally based on a separate patch by Ira Weiny, which applied to an early version of the put_user_page() experiments. Since then, Jérôme Glisse suggested the refactoring described above. Cc: Christoph Hellwig Suggested-by: Jérôme Glisse Reviewed-by: Dan Williams Reviewed-by: Jan Kara Signed-off-by: Ira Weiny Signed-off-by: John Hubbard --- include/linux/mm.h | 18 +- mm/memremap.c | 16 ++-- mm/swap.c | 27 ++- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index c97ea3b694e6..87b54126e46d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -952,9 +952,10 @@ static inline bool is_zone_device_page(const struct page *page) #endif #ifdef CONFIG_DEV_PAGEMAP_OPS -void __put_devmap_managed_page(struct page *page); +void free_devmap_managed_page(struct page *page); DECLARE_STATIC_KEY_FALSE(devmap_managed_key); -static inline bool put_devmap_managed_page(struct page *page) + +static inline bool page_is_devmap_managed(struct page *page) { if (!static_branch_unlikely(_managed_key)) return false; @@ -963,7 +964,6 @@ static inline bool put_devmap_managed_page(struct page *page) switch (page->pgmap->type) { case MEMORY_DEVICE_PRIVATE: case MEMORY_DEVICE_FS_DAX: - __put_devmap_managed_page(page); return true; default: break; @@ -971,11 +971,17 @@ static inline bool put_devmap_managed_page(struct page *page) return false; } +void put_devmap_managed_page(struct page *page); + #else /* CONFIG_DEV_PAGEMAP_OPS */ -static inline bool put_devmap_managed_page(struct page *page) +static inline bool page_is_devmap_managed(struct page *page) { return false; } + +static inline void put_devmap_managed_page(struct page *page) +{ +} #endif /* CONFIG_DEV_PAGEMAP_OPS */ static inline bool is_device_private_page(const struct page *page) @@ -1028,8 +1034,10 @@ static inline void put_page(struct page *page) * need to inform the device driver through callback. See * include/linux/memremap.h and HMM for details. */ - if (put_devmap_managed_page(page)) + if (page_is_devmap_managed(page)) { + put_devmap_managed_page(page); return; + } if (put_page_testzero(page)) __put_page(page); diff --git a/mm/memremap.c b/mm/memremap.c index e899fa876a62..2ba773859031 100644 --- a/mm/memremap.c +++ b/mm/memremap.c @@ -411,20 +411,8 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn, EXPORT_SYMBOL_GPL(get_dev_pagemap); #ifdef CONFIG_DEV_PAGEMAP_OPS -void __put_devmap_managed_page(struct page *page) +void free_devmap_managed_page(struct page *page) { - int count = page_ref_dec_return(page); - - /* still busy */ - if (count > 1) - return; - - /* only triggered by the dev_pagemap shutdown path */ - if (count == 0) { - __put_page(page); - return; - } - /* notify page idle for dax */ if (!is_device_private_page(page)) { wake_up_var(>_refcount); @@ -461,5 +449,5 @@ void __put_devmap_managed_page(struct page *page) page->mapping = NULL; page->pgmap->ops->page_free(page); } -EXPORT_SYMBOL(__put_devmap_managed_page); +EXPORT_SYMBOL(free_devmap_managed_page); #endif /* CONFIG_DEV_PAGEMAP_OPS */ diff --git a/mm/swap.c b/mm/swap.c index 5341ae93861f..cf39d24ada2a 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -813,8 +813,10 @@ void release_pages(struct page **pages, int nr) * processing, and instead, expect a call to * put_page_testzero(). */ - if (put_devmap_managed_page(page)) + if (page_is_devmap_managed(page)) { + put_devmap_managed_page(page); continue; + } } page =
Re: [PATCH v11 04/25] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On 12/18/19 8:04 AM, Kirill A. Shutemov wrote: On Mon, Dec 16, 2019 at 02:25:16PM -0800, John Hubbard wrote: An upcoming patch changes and complicates the refcounting and especially the "put page" aspects of it. In order to keep everything clean, refactor the devmap page release routines: * Rename put_devmap_managed_page() to page_is_devmap_managed(), and limit the functionality to "read only": return a bool, with no side effects. * Add a new routine, put_devmap_managed_page(), to handle checking what kind of page it is, and what kind of refcount handling it requires. * Rename __put_devmap_managed_page() to free_devmap_managed_page(), and limit the functionality to unconditionally freeing a devmap page. What the reason to separate put_devmap_managed_page() from free_devmap_managed_page() if free_devmap_managed_page() has exacly one caller? Is it preparation for the next patches? Yes. A later patch, #23, adds another caller: __unpin_devmap_managed_user_page(). ... @@ -971,7 +971,14 @@ static inline bool put_devmap_managed_page(struct page *page) return false; } +bool put_devmap_managed_page(struct page *page); + #else /* CONFIG_DEV_PAGEMAP_OPS */ +static inline bool page_is_devmap_managed(struct page *page) +{ + return false; +} + static inline bool put_devmap_managed_page(struct page *page) { return false; @@ -1028,8 +1035,10 @@ static inline void put_page(struct page *page) * need to inform the device driver through callback. See * include/linux/memremap.h and HMM for details. */ - if (put_devmap_managed_page(page)) + if (page_is_devmap_managed(page)) { + put_devmap_managed_page(page); put_devmap_managed_page() has yet another page_is_devmap_managed() check inside. It looks strange. Good point, it's an extra unnecessary check. So to clean it up, I'll note that the "if" check is required here in put_page(), in order to stay out of non-inlined function calls in the hot path (put_page()). So I'll do the following: * Leave the above code as it is here * Simplify put_devmap_managed_page(), it was trying to do two separate things, and those two things have different requirements. So change it to a void function, with a WARN_ON_ONCE to assert that page_is_devmap_managed() is true, * And change the other caller (release_pages()) to do that check. ... @@ -1102,3 +1102,27 @@ void __init swap_setup(void) * _really_ don't want to cluster much more */ } + +#ifdef CONFIG_DEV_PAGEMAP_OPS +bool put_devmap_managed_page(struct page *page) +{ + bool is_devmap = page_is_devmap_managed(page); + + if (is_devmap) { Reversing the condition would save you an indentation level. Yes. Done. I'll also git-reply with an updated patch so you can see what it looks like. thanks, -- John Hubbard NVIDIA ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[GIT PULL] exynos-drm-fixes
Hi Dave, Just one bug fixup which makes sure to unregister a component for Exynos gscaler driver. Please kindly let me know if there is any problem. Thanks, Inki Dae The following changes since commit d1eef1c619749b2a57e514a3fa67d9a516ffa919: Linux 5.5-rc2 (2019-12-15 15:16:08 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos tags/exynos-drm-fixes-for-v5.5-rc3 for you to fetch changes up to 84c92365b20a44c363b95390ea00dfbdd786f031: drm/exynos: gsc: add missed component_del (2019-12-19 08:52:42 +0900) Just one bug fixup . Make sure to unregister a component for Exynos gscaler driver when the driver is removed. Chuhong Yuan (1): drm/exynos: gsc: add missed component_del drivers/gpu/drm/exynos/exynos_drm_gsc.c | 1 + 1 file changed, 1 insertion(+) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 2/9] drm/amd/display: Fix compilation issue.
On Wed, Dec 18, 2019 at 09:43:49PM +0530, Manna, Animesh wrote: > > On 18-12-2019 21:12, Harry Wentland wrote: > >On 2019-12-18 10:13 a.m., Animesh Manna wrote: > >>[Why]: > >>Aligh with DP spec wanted to follow same naming convention. > >> > >>[How]: > >>Changed the macro name of the dpcd address used for getting requested > >>test-pattern. > >> > >Please roll this into your patch that renames the definition. All > >patches should compile on their own. > > > Thanks Harry for review, wanted to follow similar commit-description format > followed in amd-driver compare to i915 and created a separate patch. Maybe > is it good idea to change the patch sequence and make it as first patch. > > Regards, > Animesh Like Harry said, all these changes should happen in the same patch that renames the DP_TEST_PHY_PATTERN which is patch 1/9 because like you see the build still fails now since patch 1 doesnt compile. So the idea would be in patch 1 - rename, make changes in AMD and existing place where it gets used Patch 2 - get/set PHY test paarams that use this renamed value Manasi > > > > >Thanks, > >Harry > > > >>Cc: Harry Wentland > >>Cc: Alex Deucher > >>Signed-off-by: Animesh Manna > >>--- > >> drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- > >> 1 file changed, 1 insertion(+), 1 deletion(-) > >> > >>diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > >>b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > >>index 42aa889fd0f5..1a6109be2fce 100644 > >>--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > >>+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > >>@@ -2491,7 +2491,7 @@ static void dp_test_send_phy_test_pattern(struct > >>dc_link *link) > >>/* get phy test pattern and pattern parameters from DP receiver */ > >>core_link_read_dpcd( > >>link, > >>- DP_TEST_PHY_PATTERN, > >>+ DP_PHY_TEST_PATTERN, > >>_test_pattern.raw, > >>sizeof(dpcd_test_pattern)); > >>core_link_read_dpcd( > >> ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC v2 02/12] drm/i915/svm: Runtime (RT) allocator support
On Tue, Dec 17, 2019 at 08:18:21PM +, Jason Gunthorpe wrote: On Fri, Dec 13, 2019 at 01:56:04PM -0800, Niranjana Vishwanathapura wrote: + ctx = i915_gem_context_lookup(file->driver_priv, args->rsvd1); + if (!ctx || !rcu_access_pointer(ctx->vm)) + return -ENOENT; + + rcu_read_lock(); + vm = i915_vm_get(ctx->vm); + rcu_read_unlock(); This looks like wrong use of RCU to me. Getting a rcu lock and not calling rcu_dereference under it is basically guarenteed to be wrong.. Oops, yah, I should be just calling i915_gem_context_get_vm_rcu(). Thanks, Niranjana Jason ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [RFC v2 02/12] drm/i915/svm: Runtime (RT) allocator support
On Tue, Dec 17, 2019 at 12:01:26PM -0600, Jason Ekstrand wrote: On Sun, Dec 15, 2019 at 10:24 PM Niranjan Vishwanathapura wrote: On Sat, Dec 14, 2019 at 10:31:37AM +, Chris Wilson wrote: >Quoting Jason Ekstrand (2019-12-14 00:36:19) >> On Fri, Dec 13, 2019 at 5:24 PM Niranjan Vishwanathapura < >> niranjana.vishwanathap...@intel.com> wrote: >> >> On Fri, Dec 13, 2019 at 04:58:42PM -0600, Jason Ekstrand wrote: >> > >> > +/** >> > + * struct drm_i915_gem_vm_bind >> > + * >> > + * Bind an object in a vm's page table. >> > >> > First off, this is something I've wanted for a while for Vulkan, it's >> just >> > never made its way high enough up the priority list. However, it's >> going >> > to have to come one way or another soon. I'm glad to see kernel API >> for >> > this being proposed. >> > I do, however, have a few high-level comments/questions about the API: >> >1. In order to be useful for sparse memory support, the API has to go >> the >> > other way around so that it binds a VA range to a range within the BO. >> It >> > also needs to be able to handle overlapping where two different VA >> ranges >> > may map to the same underlying bytes in the BO. This likely means that >> > unbind needs to also take a VA range and only unbind that range. >> >2. If this is going to be useful for managing GL's address space where >> we >> > have lots of BOs, we probably want it to take a list of ranges so we >> > aren't making one ioctl for each thing we want to bind. >> >> Hi Jason, >> >> Yah, some of these requirements came up. >> >> >> Yes, I have raised them every single time an API like this has come across my >> e-mail inbox for years and they continue to get ignored. Why are we landing an >> API that we know isn't the API we want especially when it's pretty obvious >> roughly what the API we want is? It may be less time in the short term, but >> long-term it means two ioctls and two implementations in i915, IGT tests for >> both code paths, and code in all UMDs to call one or the other depending on >> what kernel you're running on, and we have to maintain all that code going >> forward forever. Sure, that's a price we pay today for a variety of things but >> that's because they all seemed like the right thing at the time. Landing the >> wrong API when we know it's the wrong API seems foolish. > >Exactly. This is not even close to the uAPI we need. Reposting an RFC >without taking in the concerns last time (or the time before that, or >the time before that...) suggests that you aren't really requesting for >comments at all. Thanks Jason for detailed exlanation. Chris, all comments and guidance are much appreciated :) I haven't looked in detail, but my concern is that implementing partial object binding (offset, lenght) from vma down to [un]binding in ppgtt might be a lot of work to include in this SVM patch series. I believe we need the partial object binding in non-SVM scenario as well? Yes, the Vulkan APIs require both partial binding and aliasing. It may be worth pointing out that we're already doing some of this stuff today, although in a rather backwards way. Our non-softpin model for Vulkan uses a memfd which we then map in userspace and turn into a BO via userptr. Due to the way we handle threading in the driver, we end up with multiple BOs pointing to the same overlapping range in the memfd and hence the same pages. That doesn't mean that everything in the path is already set up for what you need but the VA -> page mappings should be. Also, avoiding these kinds of shinanigans is exactly why we want a "real" kernel API for this. :-) Ok thanks Jason for the explantion. Will look into supporting this here. Ok, let me change the interface as below. struct drm_i915_gem_vm_bind_va { /** VA start to bind **/ __u64 start; /** Offset in Object to bind for I915_GEM_VM_BIND_SVM_OBJ type **/ __u64 offset; /** VA length to [un]bind **/ __u64 length; /** Type of memory to [un]bind **/ __u32 type; #define I915_GEM_VM_BIND_SVM_OBJ 0 #define I915_GEM_VM_BIND_SVM_BUFFER 1 /** Object handle to [un]bind for I915_GEM_VM_BIND_SVM_OBJ type **/ __u32 handle; /** Flags **/ __u32 flags; #define I915_GEM_VM_BIND_UNBIND (1 << 0) #define I915_GEM_VM_BIND_READONLY(1 << 1) } struct
linux-next: build warning after merge of the amdgpu tree
Hi all, After merging the amdgpu tree, today's linux-next build (x86_64 allmodconfig) produced this warning: drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c: In function 'vcn_v2_5_hw_init': drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c:288:5: warning: 'r' may be used uninitialized in this function [-Wmaybe-uninitialized] 288 | if (!r) | ^ Introduced by commit 99bcbf833e6a ("drm/amdgpu: enable VCN0 and VCN1 sriov instances support for Arcturus") -- Cheers, Stephen Rothwell pgpKAcDAqTBfJ.pgp Description: OpenPGP digital signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/2] drm/amdgpu/display: use msleep rather than udelay for HDCP
Hey, I've pulled in these two patches to drm-next directly because my arm test build was broken. Dave. On Wed, 18 Dec 2019 at 06:47, Alex Deucher wrote: > > ARM has a 2000us limit for udelay. Switch to msleep. This code > executes in a worker thread so shouldn't be an atomic context. > > Signed-off-by: Alex Deucher > --- > drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > index bcbc0b8a9aa0..f730b94ac3c0 100644 > --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c > @@ -153,7 +153,7 @@ static enum mod_hdcp_status poll_l_prime_available(struct > mod_hdcp *hdcp) > { > enum mod_hdcp_status status; > uint8_t size; > - uint16_t max_wait = 2; // units of us > + uint16_t max_wait = 20; // units of ms > uint16_t num_polls = 5; > uint16_t wait_time = max_wait / num_polls; > > @@ -161,7 +161,7 @@ static enum mod_hdcp_status poll_l_prime_available(struct > mod_hdcp *hdcp) > status = MOD_HDCP_STATUS_INVALID_OPERATION; > else > for (; num_polls; num_polls--) { > - udelay(wait_time); > + msleep(wait_time); > > status = mod_hdcp_read_rxstatus(hdcp); > if (status != MOD_HDCP_STATUS_SUCCESS) > @@ -474,7 +474,7 @@ static enum mod_hdcp_status locality_check(struct > mod_hdcp *hdcp, > hdcp, "lc_init_write")) > goto out; > if (is_dp_hdcp(hdcp)) > - udelay(16000); > + msleep(16); > else > if (!mod_hdcp_execute_and_set(poll_l_prime_available, > >l_prime_available_poll, , > -- > 2.23.0 > > ___ > 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: [Intel-gfx] [RFC v2 02/12] drm/i915/svm: Runtime (RT) allocator support
On Sun, Dec 15, 2019 at 08:15:24PM -0800, Niranjan Vishwanathapura wrote: On Sat, Dec 14, 2019 at 10:56:54AM +, Chris Wilson wrote: Quoting Niranjana Vishwanathapura (2019-12-13 21:56:04) Shared Virtual Memory (SVM) runtime allocator support allows binding a shared virtual address to a buffer object (BO) in the device page table through an ioctl call. Cc: Joonas Lahtinen Cc: Jon Bloomfield Cc: Daniel Vetter Cc: Sudeep Dutt Signed-off-by: Niranjana Vishwanathapura --- drivers/gpu/drm/i915/Kconfig | 11 drivers/gpu/drm/i915/Makefile | 3 + .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 58 ++ drivers/gpu/drm/i915/gem/i915_gem_svm.c | 60 +++ drivers/gpu/drm/i915/gem/i915_gem_svm.h | 22 +++ drivers/gpu/drm/i915/i915_drv.c | 21 +++ drivers/gpu/drm/i915/i915_drv.h | 22 +++ drivers/gpu/drm/i915/i915_gem_gtt.c | 1 + drivers/gpu/drm/i915/i915_gem_gtt.h | 13 include/uapi/drm/i915_drm.h | 27 + 10 files changed, 227 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_svm.c create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_svm.h diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index ba9595960bbe..c2e48710eec8 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -137,6 +137,16 @@ config DRM_I915_GVT_KVMGT Choose this option if you want to enable KVMGT support for Intel GVT-g. +config DRM_I915_SVM + bool "Enable Shared Virtual Memory support in i915" + depends on STAGING + depends on DRM_I915 + default n + help + Choose this option if you want Shared Virtual Memory (SVM) + support in i915. With SVM support, one can share the virtual + address space between a process and the GPU. + menu "drm/i915 Debugging" depends on DRM_I915 depends on EXPERT diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index e0fd10c0cfb8..75fe45633779 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -153,6 +153,9 @@ i915-y += \ intel_region_lmem.o \ intel_wopcm.o +# SVM code +i915-$(CONFIG_DRM_I915_SVM) += gem/i915_gem_svm.o + # general-purpose microcontroller (GuC) support obj-y += gt/uc/ i915-y += gt/uc/intel_uc.o \ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 5003e616a1ad..af360238a392 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2836,10 +2836,14 @@ int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { + struct drm_i915_gem_exec_object2 *exec2_list, *exec2_list_user; struct drm_i915_gem_execbuffer2 *args = data; - struct drm_i915_gem_exec_object2 *exec2_list; - struct drm_syncobj **fences = NULL; const size_t count = args->buffer_count; + struct drm_syncobj **fences = NULL; + unsigned int i = 0, svm_count = 0; + struct i915_address_space *vm; + struct i915_gem_context *ctx; + struct i915_svm_obj *svm_obj; int err; if (!check_buffer_count(count)) { @@ -2851,15 +2855,46 @@ i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, if (err) return err; + ctx = i915_gem_context_lookup(file->driver_priv, args->rsvd1); + if (!ctx || !rcu_access_pointer(ctx->vm)) + return -ENOENT; This is just hopelessly wrong. For persistence, the _ce_->vm will have a list of must-be-present vma, with a flag for whether they need prefaulting (!svm everything must be prefaulted obviously). Then during reservation we ensure that all those persistent vma are in place (so we probably use an eviction list to keep track of those we need to instantiate on this execbuf). We don't even want to individually track activity on those vma, preferring to assume they are used by every request and so on change they need serialising [for explicit uAPI unbind, where possible we strive to do it async for endless, or at least sync against iova semaphore] against the last request in the vm (so we need a vm->active). However, we do need an EXT_EXTENSION to mark writes for implicit fencing (e.g. exported dmabuf) to replace the information lost from execobject[] I did not understand some points above. I am no expert here, and appreciate the feedback. My understanding is that [excluding endless batch buffer scenario which is not supported in this patch series,] VM_BIND is no different than the soft-pinning of objects we have today in the execbuf path. Hence the idea here is to add those VM_BIND objects to the execobject[] and let the execbuffer path to take care of the rest. Persistence of bindings across multiple requests is something
Re: [RFC v2 05/12] drm/i915/svm: Page table mirroring support
On Tue, Dec 17, 2019 at 08:31:07PM +, Jason Gunthorpe wrote: On Fri, Dec 13, 2019 at 01:56:07PM -0800, Niranjana Vishwanathapura wrote: +static struct i915_svm *vm_get_svm(struct i915_address_space *vm) +{ + struct i915_svm *svm = vm->svm; + + mutex_lock(>svm_mutex); + if (svm && !kref_get_unless_zero(>ref)) + svm = NULL; Quite strange to see a get_unless_zero under a lock.. Thanks. Yah I agree (construct taken from a differnt place). It should go away once I swith to mmu_notifier_get/put. +static void release_svm(struct kref *ref) +{ + struct i915_svm *svm = container_of(ref, typeof(*svm), ref); + struct i915_address_space *vm = svm->vm; + + mmu_notifier_unregister(>notifier, svm->notifier.mm); This would be a lot better to use mmu_notifier_put to manage the reference and deallocation. Yah, have that in mind, will use that. +static u32 i915_svm_build_sg(struct i915_address_space *vm, +struct hmm_range *range, +struct sg_table *st) +{ + struct scatterlist *sg; + u32 sg_page_sizes = 0; + u64 i, npages; + + sg = NULL; + st->nents = 0; + npages = (range->end - range->start) / PAGE_SIZE; + + /* +* No need to dma map the host pages and later unmap it, as +* GPU is not allowed to access it with SVM. +* XXX: Need to dma map host pages for integrated graphics while +* extending SVM support there. +*/ + for (i = 0; i < npages; i++) { + u64 addr = range->pfns[i] & ~((1UL << range->pfn_shift) - 1); + + if (sg && (addr == (sg_dma_address(sg) + sg->length))) { + sg->length += PAGE_SIZE; + sg_dma_len(sg) += PAGE_SIZE; + continue; + } + + if (sg) + sg_page_sizes |= sg->length; + + sg = sg ? __sg_next(sg) : st->sgl; + sg_dma_address(sg) = addr; + sg_dma_len(sg) = PAGE_SIZE; This still can't be like this - assigning pfn to 'dma_address' is fundamentally wrong. Whatever explanation you had, this needs to be fixed up first before we get to this patch. The pfn is converted into a device address which goes into sg_dma_address. Ok, let me think about what else we can do here. As device addresses are not dma mapped, may be we can look at it as direct mapped (__phys_to_dma())? Or perhaps define our own sgl. Not sure, will look into it. +static int i915_range_fault(struct svm_notifier *sn, + struct drm_i915_gem_vm_bind *args, + struct sg_table *st, u64 *pfns) +{ + unsigned long timeout = + jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + /* Have HMM fault pages within the fault window to the GPU. */ + struct hmm_range range = { + .notifier = >notifier, + .start = sn->notifier.interval_tree.start, + .end = sn->notifier.interval_tree.last + 1, + .pfns = pfns, + .pfn_shift = PAGE_SHIFT, + .flags = i915_range_flags, + .values = i915_range_values, + .default_flags = (range.flags[HMM_PFN_VALID] | + ((args->flags & I915_GEM_VM_BIND_READONLY) ? + 0 : range.flags[HMM_PFN_WRITE])), + .pfn_flags_mask = 0, + + }; + struct i915_svm *svm = sn->svm; + struct mm_struct *mm = sn->notifier.mm; + struct i915_address_space *vm = svm->vm; + u32 sg_page_sizes; + u64 flags; + long ret; + + while (true) { + if (time_after(jiffies, timeout)) + return -EBUSY; + + range.notifier_seq = mmu_interval_read_begin(range.notifier); + down_read(>mmap_sem); + ret = hmm_range_fault(, 0); + up_read(>mmap_sem); + if (ret <= 0) { + if (ret == 0 || ret == -EBUSY) + continue; + return ret; + } + + sg_page_sizes = i915_svm_build_sg(vm, , st); + mutex_lock(>mutex); + if (mmu_interval_read_retry(range.notifier, + range.notifier_seq)) { + mutex_unlock(>mutex); + continue; + } + break; + } + + flags = (args->flags & I915_GEM_VM_BIND_READONLY) ? + I915_GTT_SVM_READONLY : 0; + ret = svm_bind_addr_commit(vm, args->start, args->length, + flags, st, sg_page_sizes); + mutex_unlock(>mutex); This looks better.. +int i915_gem_vm_bind_svm_buffer(struct i915_address_space *vm, + struct drm_i915_gem_vm_bind *args)
Re: [PATCH v11 01/25] mm/gup: factor out duplicate code from four routines
On Wed, Dec 18, 2019 at 02:15:53PM -0800, John Hubbard wrote: > On 12/18/19 7:52 AM, Kirill A. Shutemov wrote: > > On Mon, Dec 16, 2019 at 02:25:13PM -0800, John Hubbard wrote: > > > +static void put_compound_head(struct page *page, int refs) > > > +{ > > > + /* Do a get_page() first, in case refs == page->_refcount */ > > > + get_page(page); > > > + page_ref_sub(page, refs); > > > + put_page(page); > > > +} > > > > It's not terribly efficient. Maybe something like: > > > > VM_BUG_ON_PAGE(page_ref_count(page) < ref, page); > > if (refs > 2) > > page_ref_sub(page, refs - 1); > > put_page(page); > > > > ? > > OK, but how about this instead? I don't see the need for a "2", as that > is a magic number that requires explanation. Whereas "1" is not a magic > number--here it means: either there are "many" (>1) refs, or not. Yeah, it's my thinko. Sure, it has to be '1' (or >= 2, which is less readable). > And the routine won't be called with refs less than about 32 (2MB huge > page, 64KB base page == 32 subpages) anyway. It's hard to make predictions about future :P > VM_BUG_ON_PAGE(page_ref_count(page) < refs, page); > /* >* Calling put_page() for each ref is unnecessarily slow. Only the last >* ref needs a put_page(). >*/ > if (refs > 1) > page_ref_sub(page, refs - 1); > put_page(page); Looks good to me. -- Kirill A. Shutemov ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 9/9] drm/bridge: ti-sn65dsi86: Avoid invalid rates
Hi, On Tue, Dec 17, 2019 at 8:03 PM Rob Clark wrote: > > > > + for (i = 0; i < ARRAY_SIZE(sink_rates); i++) { > > > + rate_times_200khz = le16_to_cpu(sink_rates[i]); > > > + > > > + if (!rate_times_200khz) > > > + break; > > > + > > > + switch (rate_times_200khz) { > > > + case 27000: > > > > maybe a bit bike-sheddy, but I kinda prefer to use traditional normal > > units, ie. just multiply the returned value by 200 and adjust the > > switch case values. At least then they match the values in the lut > > (other than khz vs mhz), which makes this whole logic a bit more > > obvious... and at that point, maybe just loop over the lut table? > > (hit SEND too soon) > > and other than that, lgtm but haven't had a chance to test it yet > (although I guess none of us have an eDP 1.4+ screen so maybe that is > moot :-)) I think v3 should look much better to you. I also added a note to the commit log indicating that the DP 1.4 patch was only tested via hackery... https://lore.kernel.org/r/20191218143416.v3.9.Ib59207b66db377380d13748752d6fce5596462c5@changeid -Doug ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 1/9] drm/bridge: ti-sn65dsi86: Split the setting of the dp and dsi rates
These two things were in one function. Split into two. This looks like it's duplicating some code, but don't worry. This is is just in preparation for future changes. This is intended to have zero functional change and will just make future patches easier to understand. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/ti-sn65dsi86.c | 33 +++ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 43abf01ebd4c..2fb9370a76e6 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -417,6 +417,24 @@ static void ti_sn_bridge_set_refclk_freq(struct ti_sn_bridge *pdata) REFCLK_FREQ(i)); } +static void ti_sn_bridge_set_dsi_rate(struct ti_sn_bridge *pdata) +{ + unsigned int bit_rate_mhz, clk_freq_mhz; + unsigned int val; + struct drm_display_mode *mode = + >bridge.encoder->crtc->state->adjusted_mode; + + /* set DSIA clk frequency */ + bit_rate_mhz = (mode->clock / 1000) * + mipi_dsi_pixel_format_to_bpp(pdata->dsi->format); + clk_freq_mhz = bit_rate_mhz / (pdata->dsi->lanes * 2); + + /* for each increment in val, frequency increases by 5MHz */ + val = (MIN_DSI_CLK_FREQ_MHZ / 5) + + (((clk_freq_mhz - MIN_DSI_CLK_FREQ_MHZ) / 5) & 0xFF); + regmap_write(pdata->regmap, SN_DSIA_CLK_FREQ_REG, val); +} + /** * LUT index corresponds to register value and * LUT values corresponds to dp data rate supported @@ -426,22 +444,16 @@ static const unsigned int ti_sn_bridge_dp_rate_lut[] = { 0, 1620, 2160, 2430, 2700, 3240, 4320, 5400 }; -static void ti_sn_bridge_set_dsi_dp_rate(struct ti_sn_bridge *pdata) +static void ti_sn_bridge_set_dp_rate(struct ti_sn_bridge *pdata) { - unsigned int bit_rate_mhz, clk_freq_mhz, dp_rate_mhz; - unsigned int val, i; + unsigned int bit_rate_mhz, dp_rate_mhz; + unsigned int i; struct drm_display_mode *mode = >bridge.encoder->crtc->state->adjusted_mode; /* set DSIA clk frequency */ bit_rate_mhz = (mode->clock / 1000) * mipi_dsi_pixel_format_to_bpp(pdata->dsi->format); - clk_freq_mhz = bit_rate_mhz / (pdata->dsi->lanes * 2); - - /* for each increment in val, frequency increases by 5MHz */ - val = (MIN_DSI_CLK_FREQ_MHZ / 5) + - (((clk_freq_mhz - MIN_DSI_CLK_FREQ_MHZ) / 5) & 0xFF); - regmap_write(pdata->regmap, SN_DSIA_CLK_FREQ_REG, val); /* set DP data rate */ dp_rate_mhz = ((bit_rate_mhz / pdata->dsi->lanes) * DP_CLK_FUDGE_NUM) / @@ -510,7 +522,8 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge) val); /* set dsi/dp clk frequency value */ - ti_sn_bridge_set_dsi_dp_rate(pdata); + ti_sn_bridge_set_dsi_rate(pdata); + ti_sn_bridge_set_dp_rate(pdata); /* enable DP PLL */ regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 1); -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 0/9] drm/bridge: ti-sn65dsi86: Improve support for AUO B116XAK01 + other DP
This series contains a pile of patches that was created to support hooking up the AUO B116XAK01 panel to the eDP side of the bridge. In general it should be useful for hooking up a wider variety of DP panels to the bridge, especially those with lower resolution and lower bits per pixel. The overall result of this series: * Allows panels with fewer than 4 DP lanes hooked up to work. * Optimizes the link rate for panels with 6 bpp. * Supports trying more than one link rate when training if the main link rate didn't work. * Avoids invalid link rates. It's not expected that this series will break any existing users but testing is always good. To support the AUO B116XAK01, we could actually stop at the ("Use 18-bit DP if we can") patch since that causes the panel to run at a link rate of 1.62 which works. The patches to try more than one link rate were all developed prior to realizing that I could just use 18-bit mode and were validated with that patch reverted. These patches were tested on sdm845-cheza atop mainline as of 2019-12-13 and also on another board (the one with AUO B116XAK01) atop a downstream kernel tree. This patch series doesn't do anything to optimize the MIPI link and only focuses on the DP link. For instance, it's left as an exercise to the reader to see if we can use the 666-packed mode on the MIPI link and save some power (because we could lower the clock rate). I am nowhere near a display expert and my knowledge of DP and MIPI is pretty much zero. If something about this patch series smells wrong, it probably is. Please let know and I'll try to fix it. Changes in v3: - Init rate_valid table, don't rely on stack being 0 (oops). - Rename rate_times_200khz to rate_per_200khz. - Loop over the ti_sn_bridge_dp_rate_lut table, making code smaller. - Use 'true' instead of 1 for bools. - Added note to commit message noting DP 1.4+ isn't well tested. Changes in v2: - Squash in maybe-uninitialized fix from Rob Clark. - Patch ("Avoid invalid rates") replaces ("Skip non-standard DP rates") Douglas Anderson (9): drm/bridge: ti-sn65dsi86: Split the setting of the dp and dsi rates drm/bridge: ti-sn65dsi86: zero is never greater than an unsigned int drm/bridge: ti-sn65dsi86: Don't use MIPI variables for DP link drm/bridge: ti-sn65dsi86: Config number of DP lanes Mo' Betta drm/bridge: ti-sn65dsi86: Read num lanes from the DP sink drm/bridge: ti-sn65dsi86: Use 18-bit DP if we can drm/bridge: ti-sn65dsi86: Group DP link training bits in a function drm/bridge: ti-sn65dsi86: Train at faster rates if slower ones fail drm/bridge: ti-sn65dsi86: Avoid invalid rates drivers/gpu/drm/bridge/ti-sn65dsi86.c | 259 +- 1 file changed, 216 insertions(+), 43 deletions(-) -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 2/9] drm/bridge: ti-sn65dsi86: zero is never greater than an unsigned int
When we iterate over ti_sn_bridge_dp_rate_lut, there's no reason to start at index 0 which always contains the value 0. 0 is not a valid link rate. This change should have no real effect but is a small cleanup. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/ti-sn65dsi86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 2fb9370a76e6..7b596af265e4 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -458,7 +458,7 @@ static void ti_sn_bridge_set_dp_rate(struct ti_sn_bridge *pdata) /* set DP data rate */ dp_rate_mhz = ((bit_rate_mhz / pdata->dsi->lanes) * DP_CLK_FUDGE_NUM) / DP_CLK_FUDGE_DEN; - for (i = 0; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; i++) + for (i = 1; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; i++) if (ti_sn_bridge_dp_rate_lut[i] > dp_rate_mhz) break; -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 7/9] drm/bridge: ti-sn65dsi86: Group DP link training bits in a function
We'll re-organize the ti_sn_bridge_enable() function a bit to group together all the parts relating to link training and split them into a sub-function. This is not intended to have any functional change and is in preparation for trying link training several times at different rates. One small side effect here is that if link training fails we'll now leave the DP PLL disabled, but that seems like a sane thing to do. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/ti-sn65dsi86.c | 86 --- 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index d5990a0947b9..48fb4dc72e1c 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -530,6 +530,46 @@ static unsigned int ti_sn_get_max_lanes(struct ti_sn_bridge *pdata) return data & DP_LANE_COUNT_MASK; } +static int ti_sn_link_training(struct ti_sn_bridge *pdata) +{ + unsigned int val; + int ret; + + /* set dp clk frequency value */ + ti_sn_bridge_set_dp_rate(pdata); + + /* enable DP PLL */ + regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 1); + + ret = regmap_read_poll_timeout(pdata->regmap, SN_DPPLL_SRC_REG, val, + val & DPPLL_SRC_DP_PLL_LOCK, 1000, + 50 * 1000); + if (ret) { + DRM_ERROR("DP_PLL_LOCK polling failed (%d)\n", ret); + goto exit; + } + + /* Semi auto link training mode */ + regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0x0A); + ret = regmap_read_poll_timeout(pdata->regmap, SN_ML_TX_MODE_REG, val, + val == ML_TX_MAIN_LINK_OFF || + val == ML_TX_NORMAL_MODE, 1000, + 500 * 1000); + if (ret) { + DRM_ERROR("Training complete polling failed (%d)\n", ret); + } else if (val == ML_TX_MAIN_LINK_OFF) { + DRM_ERROR("Link training failed, link is off\n"); + ret = -EIO; + } + +exit: + /* Disable the PLL if we failed */ + if (ret) + regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 0); + + return ret; +} + static void ti_sn_bridge_enable(struct drm_bridge *bridge) { struct ti_sn_bridge *pdata = bridge_to_ti_sn_bridge(bridge); @@ -555,29 +595,8 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge) regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, CHA_DSI_LANES_MASK, val); - /* Set the DP output format (18 bpp or 24 bpp) */ - val = (ti_sn_bridge_get_bpp(pdata) == 18) ? BPP_18_RGB : 0; - regmap_update_bits(pdata->regmap, SN_DATA_FORMAT_REG, BPP_18_RGB, val); - - /* DP lane config */ - val = DP_NUM_LANES(min(pdata->dp_lanes, 3)); - regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG, DP_NUM_LANES_MASK, - val); - - /* set dsi/dp clk frequency value */ + /* set dsi clk frequency value */ ti_sn_bridge_set_dsi_rate(pdata); - ti_sn_bridge_set_dp_rate(pdata); - - /* enable DP PLL */ - regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 1); - - ret = regmap_read_poll_timeout(pdata->regmap, SN_DPPLL_SRC_REG, val, - val & DPPLL_SRC_DP_PLL_LOCK, 1000, - 50 * 1000); - if (ret) { - DRM_ERROR("DP_PLL_LOCK polling failed (%d)\n", ret); - return; - } /** * The SN65DSI86 only supports ASSR Display Authentication method and @@ -588,19 +607,18 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge) drm_dp_dpcd_writeb(>aux, DP_EDP_CONFIGURATION_SET, DP_ALTERNATE_SCRAMBLER_RESET_ENABLE); - /* Semi auto link training mode */ - regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0x0A); - ret = regmap_read_poll_timeout(pdata->regmap, SN_ML_TX_MODE_REG, val, - val == ML_TX_MAIN_LINK_OFF || - val == ML_TX_NORMAL_MODE, 1000, - 500 * 1000); - if (ret) { - DRM_ERROR("Training complete polling failed (%d)\n", ret); - return; - } else if (val == ML_TX_MAIN_LINK_OFF) { - DRM_ERROR("Link training failed, link is off\n"); + /* Set the DP output format (18 bpp or 24 bpp) */ + val = (ti_sn_bridge_get_bpp(pdata) == 18) ? BPP_18_RGB : 0; + regmap_update_bits(pdata->regmap, SN_DATA_FORMAT_REG, BPP_18_RGB, val); + + /* DP lane config */ + val = DP_NUM_LANES(min(pdata->dp_lanes, 3)); + regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG,
[PATCH v3 3/9] drm/bridge: ti-sn65dsi86: Don't use MIPI variables for DP link
The ti-sn65dsi86 is a bridge from MIPI to DP and thus has two links: the MIPI link and the DP link. The two links do not need to have the same format or number of lanes. Stop using MIPI variables when talking about the DP link. This has zero functional change because: * currently we are hardcoding the MIPI link as unpacked RGB888 which requires 24 bits and currently we are not changing the DP link rate from the bridge's default of 8 bits per pixel. * currently we are hardcoding both the MIPI and DP as being 4 lanes. This is all in prep for fixing some of the above. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/ti-sn65dsi86.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 7b596af265e4..ab644baaf90c 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -100,6 +100,7 @@ struct ti_sn_bridge { struct drm_panel*panel; struct gpio_desc*enable_gpio; struct regulator_bulk_data supplies[SN_REGULATOR_SUPPLY_NUM]; + int dp_lanes; }; static const struct regmap_range ti_sn_bridge_volatile_ranges[] = { @@ -313,6 +314,7 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge) } /* TODO: setting to 4 lanes always for now */ + pdata->dp_lanes = 4; dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO; @@ -451,13 +453,17 @@ static void ti_sn_bridge_set_dp_rate(struct ti_sn_bridge *pdata) struct drm_display_mode *mode = >bridge.encoder->crtc->state->adjusted_mode; - /* set DSIA clk frequency */ - bit_rate_mhz = (mode->clock / 1000) * - mipi_dsi_pixel_format_to_bpp(pdata->dsi->format); + /* +* Calculate minimum bit rate based on our pixel clock. At +* the moment this driver never sets the DP_18BPP_EN bit in +* register 0x5b so we hardcode 24bpp. +*/ + bit_rate_mhz = (mode->clock / 1000) * 24; - /* set DP data rate */ - dp_rate_mhz = ((bit_rate_mhz / pdata->dsi->lanes) * DP_CLK_FUDGE_NUM) / + /* Calculate minimum DP data rate, taking 80% as per DP spec */ + dp_rate_mhz = ((bit_rate_mhz / pdata->dp_lanes) * DP_CLK_FUDGE_NUM) / DP_CLK_FUDGE_DEN; + for (i = 1; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; i++) if (ti_sn_bridge_dp_rate_lut[i] > dp_rate_mhz) break; @@ -517,7 +523,7 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge) CHA_DSI_LANES_MASK, val); /* DP lane config */ - val = DP_NUM_LANES(pdata->dsi->lanes - 1); + val = DP_NUM_LANES(pdata->dp_lanes - 1); regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG, DP_NUM_LANES_MASK, val); -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 9/9] drm/bridge: ti-sn65dsi86: Avoid invalid rates
Based on work by Bjorn Andersson , Jeffrey Hugo , and Rob Clark . Let's read the SUPPORTED_LINK_RATES and/or MAX_LINK_RATE (depending on the eDP version of the sink) to figure out what eDP rates are supported and pick the ideal one. NOTE: I have only personally tested this code on eDP panels that are 1.3 or older. Code reading SUPPORTED_LINK_RATES for DP 1.4+ was tested by hacking the code to pretend that a table was there. Signed-off-by: Douglas Anderson --- Changes in v3: - Init rate_valid table, don't rely on stack being 0 (oops). - Rename rate_times_200khz to rate_per_200khz. - Loop over the ti_sn_bridge_dp_rate_lut table, making code smaller. - Use 'true' instead of 1 for bools. - Added note to commit message noting DP 1.4+ isn't well tested. Changes in v2: - Patch ("Avoid invalid rates") replaces ("Skip non-standard DP rates") drivers/gpu/drm/bridge/ti-sn65dsi86.c | 100 +++--- 1 file changed, 75 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index e1b817ccd9c7..a57c6108cb1f 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -475,39 +475,85 @@ static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn_bridge *pdata) return i; } -static int ti_sn_bridge_get_max_dp_rate_idx(struct ti_sn_bridge *pdata) +static void ti_sn_bridge_read_valid_rates(struct ti_sn_bridge *pdata, + bool rate_valid[]) { - u8 data; + unsigned int rate_per_200khz; + unsigned int rate_mhz; + u8 dpcd_val; int ret; + int i, j; + + ret = drm_dp_dpcd_readb(>aux, DP_EDP_DPCD_REV, _val); + if (ret != 1) { + DRM_DEV_ERROR(pdata->dev, + "Can't read eDP rev (%d), assuming 1.1\n", ret); + dpcd_val = DP_EDP_11; + } + + if (dpcd_val >= DP_EDP_14) { + /* eDP 1.4 devices must provide a custom table */ + __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; + + ret = drm_dp_dpcd_read(>aux, DP_SUPPORTED_LINK_RATES, + sink_rates, sizeof(sink_rates)); + + if (ret != sizeof(sink_rates)) { + DRM_DEV_ERROR(pdata->dev, + "Can't read supported rate table (%d)\n", ret); + + /* By zeroing we'll fall back to DP_MAX_LINK_RATE. */ + memset(sink_rates, 0, sizeof(sink_rates)); + } + + for (i = 0; i < ARRAY_SIZE(sink_rates); i++) { + rate_per_200khz = le16_to_cpu(sink_rates[i]); + + if (!rate_per_200khz) + break; + + rate_mhz = rate_per_200khz * 200 / 1000; + for (j = 0; +j < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut); +j++) { + if (ti_sn_bridge_dp_rate_lut[j] == rate_mhz) + rate_valid[j] = true; + } + } + + for (i = 0; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut); i++) { + if (rate_valid[i]) + return; + } + DRM_DEV_ERROR(pdata->dev, + "No matching eDP rates in table; falling back\n"); + } - ret = drm_dp_dpcd_readb(>aux, DP_MAX_LINK_RATE, ); + /* On older versions best we can do is use DP_MAX_LINK_RATE */ + ret = drm_dp_dpcd_readb(>aux, DP_MAX_LINK_RATE, _val); if (ret != 1) { DRM_DEV_ERROR(pdata->dev, "Can't read max rate (%d); assuming 5.4 GHz\n", ret); - return ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; + dpcd_val = DP_LINK_BW_5_4; } - /* -* Return an index into ti_sn_bridge_dp_rate_lut. Just hardcode -* these indicies since it's not like the register spec is ever going -* to change and a loop would just be more complicated. Apparently -* the DP sink can only return these few rates as supported even -* though the bridge allows some rates in between. -*/ - switch (data) { - case DP_LINK_BW_1_62: - return 1; - case DP_LINK_BW_2_7: - return 4; + switch (dpcd_val) { + default: + DRM_DEV_ERROR(pdata->dev, + "Unexpected max rate (%#x); assuming 5.4 GHz\n", + (int)dpcd_val); + /* fall through */ case DP_LINK_BW_5_4: - return 7; + rate_valid[7] = 1; + /* fall through */ + case DP_LINK_BW_2_7: + rate_valid[4] = 1; + /* fall through */ +
[PATCH v3 8/9] drm/bridge: ti-sn65dsi86: Train at faster rates if slower ones fail
If we fail training at a lower DP link rate let's now keep trying until we run out of rates to try. Basically the algorithm here is to start at the link rate that is the theoretical minimum and then slowly bump up until we run out of rates or hit the max rate of the sink. We query the sink using a DPCD read. This is, in fact, important in practice. Specifically at least one panel hooked up to the bridge (AUO B116XAK01) had a theoretical min rate more than 1.62 GHz (if run at 24 bpp) and fails to train at the next rate (2.16 GHz). It would train at 2.7 GHz, though. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: - Squash in maybe-uninitialized fix from Rob Clark. drivers/gpu/drm/bridge/ti-sn65dsi86.c | 71 ++- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 48fb4dc72e1c..e1b817ccd9c7 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -454,7 +454,7 @@ static const unsigned int ti_sn_bridge_dp_rate_lut[] = { 0, 1620, 2160, 2430, 2700, 3240, 4320, 5400 }; -static void ti_sn_bridge_set_dp_rate(struct ti_sn_bridge *pdata) +static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn_bridge *pdata) { unsigned int bit_rate_khz, dp_rate_mhz; unsigned int i; @@ -472,8 +472,42 @@ static void ti_sn_bridge_set_dp_rate(struct ti_sn_bridge *pdata) if (ti_sn_bridge_dp_rate_lut[i] > dp_rate_mhz) break; - regmap_update_bits(pdata->regmap, SN_DATARATE_CONFIG_REG, - DP_DATARATE_MASK, DP_DATARATE(i)); + return i; +} + +static int ti_sn_bridge_get_max_dp_rate_idx(struct ti_sn_bridge *pdata) +{ + u8 data; + int ret; + + ret = drm_dp_dpcd_readb(>aux, DP_MAX_LINK_RATE, ); + if (ret != 1) { + DRM_DEV_ERROR(pdata->dev, + "Can't read max rate (%d); assuming 5.4 GHz\n", + ret); + return ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; + } + + /* +* Return an index into ti_sn_bridge_dp_rate_lut. Just hardcode +* these indicies since it's not like the register spec is ever going +* to change and a loop would just be more complicated. Apparently +* the DP sink can only return these few rates as supported even +* though the bridge allows some rates in between. +*/ + switch (data) { + case DP_LINK_BW_1_62: + return 1; + case DP_LINK_BW_2_7: + return 4; + case DP_LINK_BW_5_4: + return 7; + } + + DRM_DEV_ERROR(pdata->dev, + "Unexpected max data rate (%#x); assuming 5.4 GHz\n", + (int)data); + return ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; } static void ti_sn_bridge_set_video_timings(struct ti_sn_bridge *pdata) @@ -530,13 +564,15 @@ static unsigned int ti_sn_get_max_lanes(struct ti_sn_bridge *pdata) return data & DP_LANE_COUNT_MASK; } -static int ti_sn_link_training(struct ti_sn_bridge *pdata) +static int ti_sn_link_training(struct ti_sn_bridge *pdata, int dp_rate_idx, + const char **last_err_str) { unsigned int val; int ret; /* set dp clk frequency value */ - ti_sn_bridge_set_dp_rate(pdata); + regmap_update_bits(pdata->regmap, SN_DATARATE_CONFIG_REG, + DP_DATARATE_MASK, DP_DATARATE(dp_rate_idx)); /* enable DP PLL */ regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 1); @@ -545,7 +581,7 @@ static int ti_sn_link_training(struct ti_sn_bridge *pdata) val & DPPLL_SRC_DP_PLL_LOCK, 1000, 50 * 1000); if (ret) { - DRM_ERROR("DP_PLL_LOCK polling failed (%d)\n", ret); + *last_err_str = "DP_PLL_LOCK polling failed"; goto exit; } @@ -556,9 +592,9 @@ static int ti_sn_link_training(struct ti_sn_bridge *pdata) val == ML_TX_NORMAL_MODE, 1000, 500 * 1000); if (ret) { - DRM_ERROR("Training complete polling failed (%d)\n", ret); + *last_err_str = "Training complete polling failed"; } else if (val == ML_TX_MAIN_LINK_OFF) { - DRM_ERROR("Link training failed, link is off\n"); + *last_err_str = "Link training failed, link is off"; ret = -EIO; } @@ -573,8 +609,11 @@ static int ti_sn_link_training(struct ti_sn_bridge *pdata) static void ti_sn_bridge_enable(struct drm_bridge *bridge) { struct ti_sn_bridge *pdata = bridge_to_ti_sn_bridge(bridge); + const char *last_err_str = "No supported
[PATCH v3 5/9] drm/bridge: ti-sn65dsi86: Read num lanes from the DP sink
At least one panel hooked up to the bridge (AUO B116XAK01) only supports 1 lane of DP. Let's read this information and stop hardcoding 4 DP lanes. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/ti-sn65dsi86.c | 32 +-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index d55d19759796..0fc9e97b2d98 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -313,8 +313,7 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge) goto err_dsi_host; } - /* TODO: setting to 4 lanes always for now */ - pdata->dp_lanes = 4; + /* TODO: setting to 4 MIPI lanes always for now */ dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO; @@ -511,12 +510,41 @@ static void ti_sn_bridge_set_video_timings(struct ti_sn_bridge *pdata) usleep_range(1, 10500); /* 10ms delay recommended by spec */ } +static unsigned int ti_sn_get_max_lanes(struct ti_sn_bridge *pdata) +{ + u8 data; + int ret; + + ret = drm_dp_dpcd_readb(>aux, DP_MAX_LANE_COUNT, ); + if (ret != 1) { + DRM_DEV_ERROR(pdata->dev, + "Can't read lane count (%d); assuming 4\n", ret); + return 4; + } + + return data & DP_LANE_COUNT_MASK; +} + static void ti_sn_bridge_enable(struct drm_bridge *bridge) { struct ti_sn_bridge *pdata = bridge_to_ti_sn_bridge(bridge); unsigned int val; int ret; + /* +* Run with the maximum number of lanes that the DP sink supports. +* +* Depending use cases, we might want to revisit this later because: +* - It's plausible that someone may have run fewer lines to the +* sink than the sink actually supports, assuming that the lines +* will just be driven at a higher rate. +* - The DP spec seems to indicate that it's more important to minimize +* the number of lanes than the link rate. +* +* If we do revisit, it would be important to measure the power impact. +*/ + pdata->dp_lanes = ti_sn_get_max_lanes(pdata); + /* DSI_A lane config */ val = CHA_DSI_LANES(4 - pdata->dsi->lanes); regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 4/9] drm/bridge: ti-sn65dsi86: Config number of DP lanes Mo' Betta
The driver used to say that the value to program into bridge register 0x93 was dp_lanes - 1. Looking at the datasheet for the bridge, this is wrong. The data sheet says: * 1 = 1 lane * 2 = 2 lanes * 3 = 4 lanes A more proper way to express this encoding is min(dp_lanes, 3). At the moment this change has zero effect because we've hardcoded the number of DP lanes to 4. ...and (4 - 1) == min(4, 3). How fortunate! ...but soon we'll stop hardcoding the number of lanes. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/ti-sn65dsi86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index ab644baaf90c..d55d19759796 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -523,7 +523,7 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge) CHA_DSI_LANES_MASK, val); /* DP lane config */ - val = DP_NUM_LANES(pdata->dp_lanes - 1); + val = DP_NUM_LANES(min(pdata->dp_lanes, 3)); regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG, DP_NUM_LANES_MASK, val); -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 6/9] drm/bridge: ti-sn65dsi86: Use 18-bit DP if we can
The current bridge driver always forced us to use 24 bits per pixel over the DP link. This is a waste if you are hooked up to a panel that only supports 6 bits per color or fewer, since in that case you ran run at 18 bits per pixel and thus end up at a lower DP clock rate. Let's support this. While at it, let's clean up the math in the function to avoid rounding errors (and round in the correct direction when we have to round). Numbers are sufficiently small (because mode->clock is in kHz) that we don't need to worry about integer overflow. Signed-off-by: Douglas Anderson Tested-by: Rob Clark Reviewed-by: Rob Clark --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/ti-sn65dsi86.c | 27 ++- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 0fc9e97b2d98..d5990a0947b9 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -51,6 +51,7 @@ #define SN_ENH_FRAME_REG 0x5A #define VSTREAM_ENABLEBIT(3) #define SN_DATA_FORMAT_REG 0x5B +#define BPP_18_RGBBIT(0) #define SN_HPD_DISABLE_REG 0x5C #define HPD_DISABLE BIT(0) #define SN_AUX_WDATA_REG(x)(0x64 + (x)) @@ -436,6 +437,14 @@ static void ti_sn_bridge_set_dsi_rate(struct ti_sn_bridge *pdata) regmap_write(pdata->regmap, SN_DSIA_CLK_FREQ_REG, val); } +static unsigned int ti_sn_bridge_get_bpp(struct ti_sn_bridge *pdata) +{ + if (pdata->connector.display_info.bpc <= 6) + return 18; + else + return 24; +} + /** * LUT index corresponds to register value and * LUT values corresponds to dp data rate supported @@ -447,21 +456,17 @@ static const unsigned int ti_sn_bridge_dp_rate_lut[] = { static void ti_sn_bridge_set_dp_rate(struct ti_sn_bridge *pdata) { - unsigned int bit_rate_mhz, dp_rate_mhz; + unsigned int bit_rate_khz, dp_rate_mhz; unsigned int i; struct drm_display_mode *mode = >bridge.encoder->crtc->state->adjusted_mode; - /* -* Calculate minimum bit rate based on our pixel clock. At -* the moment this driver never sets the DP_18BPP_EN bit in -* register 0x5b so we hardcode 24bpp. -*/ - bit_rate_mhz = (mode->clock / 1000) * 24; + /* Calculate minimum bit rate based on our pixel clock. */ + bit_rate_khz = mode->clock * ti_sn_bridge_get_bpp(pdata); /* Calculate minimum DP data rate, taking 80% as per DP spec */ - dp_rate_mhz = ((bit_rate_mhz / pdata->dp_lanes) * DP_CLK_FUDGE_NUM) / - DP_CLK_FUDGE_DEN; + dp_rate_mhz = DIV_ROUND_UP(bit_rate_khz * DP_CLK_FUDGE_NUM, + 1000 * pdata->dp_lanes * DP_CLK_FUDGE_DEN); for (i = 1; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; i++) if (ti_sn_bridge_dp_rate_lut[i] > dp_rate_mhz) @@ -550,6 +555,10 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge) regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, CHA_DSI_LANES_MASK, val); + /* Set the DP output format (18 bpp or 24 bpp) */ + val = (ti_sn_bridge_get_bpp(pdata) == 18) ? BPP_18_RGB : 0; + regmap_update_bits(pdata->regmap, SN_DATA_FORMAT_REG, BPP_18_RGB, val); + /* DP lane config */ val = DP_NUM_LANES(min(pdata->dp_lanes, 3)); regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG, DP_NUM_LANES_MASK, -- 2.24.1.735.g03f4e72817-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 3/3] drm/udl: simplify gem object mapping.
On Wed, Dec 18, 2019 at 4:56 AM Gerd Hoffmann wrote: > > With shmem helpers allowing to update pgprot caching flags via > drm_gem_shmem_object.map_cached we can just use that and ditch > our own implementations of mmap() and vmap(). > > We also don't need a special case for imported objects, any map > requests are handled by the exporter not udl. > > Signed-off-by: Gerd Hoffmann > --- > drivers/gpu/drm/udl/udl_gem.c | 62 ++- > 1 file changed, 3 insertions(+), 59 deletions(-) > > diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c > index b6e26f98aa0a..7e3a88b25b6b 100644 > --- a/drivers/gpu/drm/udl/udl_gem.c > +++ b/drivers/gpu/drm/udl/udl_gem.c > @@ -17,72 +17,15 @@ > * GEM object funcs > */ > > -static int udl_gem_object_mmap(struct drm_gem_object *obj, > - struct vm_area_struct *vma) > -{ > - int ret; > - > - ret = drm_gem_shmem_mmap(obj, vma); > - if (ret) > - return ret; > - > - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); > - if (obj->import_attach) > - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); > - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); > - > - return 0; > -} > - > -static void *udl_gem_object_vmap(struct drm_gem_object *obj) > -{ > - struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); > - int ret; > - > - ret = mutex_lock_interruptible(>vmap_lock); > - if (ret) > - return ERR_PTR(ret); > - > - if (shmem->vmap_use_count++ > 0) > - goto out; > - > - ret = drm_gem_shmem_get_pages(shmem); > - if (ret) > - goto err_zero_use; > - > - if (obj->import_attach) > - shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); > - else > - shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, > - VM_MAP, PAGE_KERNEL); > - > - if (!shmem->vaddr) { > - DRM_DEBUG_KMS("Failed to vmap pages\n"); > - ret = -ENOMEM; > - goto err_put_pages; > - } > - > -out: > - mutex_unlock(>vmap_lock); > - return shmem->vaddr; > - > -err_put_pages: > - drm_gem_shmem_put_pages(shmem); > -err_zero_use: > - shmem->vmap_use_count = 0; > - mutex_unlock(>vmap_lock); > - return ERR_PTR(ret); > -} > - > static const struct drm_gem_object_funcs udl_gem_object_funcs = { > .free = drm_gem_shmem_free_object, > .print_info = drm_gem_shmem_print_info, > .pin = drm_gem_shmem_pin, > .unpin = drm_gem_shmem_unpin, > .get_sg_table = drm_gem_shmem_get_sg_table, > - .vmap = udl_gem_object_vmap, > + .vmap = drm_gem_shmem_vmap, > .vunmap = drm_gem_shmem_vunmap, > - .mmap = udl_gem_object_mmap, > + .mmap = drm_gem_shmem_mmap, > }; It looks like we can just use the default ops (drm_gem_shmem_funcs). With that, this series is Reviewed-by: Chia-I Wu . > > /* > @@ -101,6 +44,7 @@ struct drm_gem_object *udl_driver_gem_create_object(struct > drm_device *dev, > > obj = >base; > obj->funcs = _gem_object_funcs; > + shmem->map_cached = true; > > return obj; > } > -- > 2.18.1 > > ___ > 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
Re: [RFC v2 06/12] drm/i915/svm: Device memory support
On Tue, Dec 17, 2019 at 08:35:47PM +, Jason Gunthorpe wrote: On Fri, Dec 13, 2019 at 01:56:08PM -0800, Niranjana Vishwanathapura wrote: @@ -169,6 +170,11 @@ static int i915_range_fault(struct svm_notifier *sn, return ret; } + /* For dgfx, ensure the range is in device local memory only */ + regions = i915_dmem_convert_pfn(vm->i915, ); + if (!regions || (IS_DGFX(vm->i915) && (regions & REGION_SMEM))) + return -EINVAL; + This is not OK, as I said before, the driver cannot de-reference pfns before doing the retry check, under lock. Thanks. Ok, will push it down and do it after validating the range. + +int i915_dmem_convert_pfn(struct drm_i915_private *dev_priv, + struct hmm_range *range) +{ + unsigned long i, npages; + int regions = 0; + + npages = (range->end - range->start) >> PAGE_SHIFT; + for (i = 0; i < npages; ++i) { + struct i915_buddy_block *block; + struct intel_memory_region *mem; + struct page *page; + u64 addr; + + page = hmm_device_entry_to_page(range, range->pfns[i]); ^^ For instance, that cannot be done on a speculatively loaded page. This also looks like it suffers from the same bug as Ok. + if (!page) + continue; + + if (!(range->pfns[i] & range->flags[HMM_PFN_DEVICE_PRIVATE])) { + regions |= REGION_SMEM; + continue; + } + + if (!i915_dmem_page(dev_priv, page)) { + WARN(1, "Some unknown device memory !\n"); Why is that a WARN? The user could put other device memory in the address space. You need to 'segfault' the GPU execution if this happens. OK, will return an error here if user is trying to bind here. I agree, we need to segfault the GPU if it is GPU fault handling. + range->pfns[i] = 0; + continue; + } + + regions |= REGION_LMEM; + block = page->zone_device_data; + mem = block->private; + addr = mem->region.start + + i915_buddy_block_offset(block); + addr += (page_to_pfn(page) - block->pfn_first) << PAGE_SHIFT; + + range->pfns[i] &= ~range->flags[HMM_PFN_DEVICE_PRIVATE]; + range->pfns[i] &= ((1UL << range->pfn_shift) - 1); + range->pfns[i] |= (addr >> PAGE_SHIFT) << range->pfn_shift; This makes more sense as a direct manipulation of the sgl, not sure why this routine is split out from the sgl builder? Ok, yah, let me merge it with sgl building. Thanks, Niranjana Jason ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v11 01/25] mm/gup: factor out duplicate code from four routines
On 12/18/19 7:52 AM, Kirill A. Shutemov wrote: On Mon, Dec 16, 2019 at 02:25:13PM -0800, John Hubbard wrote: +static void put_compound_head(struct page *page, int refs) +{ + /* Do a get_page() first, in case refs == page->_refcount */ + get_page(page); + page_ref_sub(page, refs); + put_page(page); +} It's not terribly efficient. Maybe something like: VM_BUG_ON_PAGE(page_ref_count(page) < ref, page); if (refs > 2) page_ref_sub(page, refs - 1); put_page(page); ? OK, but how about this instead? I don't see the need for a "2", as that is a magic number that requires explanation. Whereas "1" is not a magic number--here it means: either there are "many" (>1) refs, or not. And the routine won't be called with refs less than about 32 (2MB huge page, 64KB base page == 32 subpages) anyway. VM_BUG_ON_PAGE(page_ref_count(page) < refs, page); /* * Calling put_page() for each ref is unnecessarily slow. Only the last * ref needs a put_page(). */ if (refs > 1) page_ref_sub(page, refs - 1); put_page(page); thanks, -- John Hubbard NVIDIA ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v11 06/25] mm: fix get_user_pages_remote()'s handling of FOLL_LONGTERM
On 12/18/19 8:19 AM, Kirill A. Shutemov wrote: ... diff --git a/mm/gup.c b/mm/gup.c index 3ecce297a47f..c0c56888e7cc 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -29,6 +29,13 @@ struct follow_page_context { unsigned int page_mask; }; +static __always_inline long __gup_longterm_locked(struct task_struct *tsk, + struct mm_struct *mm, + unsigned long start, + unsigned long nr_pages, + struct page **pages, + struct vm_area_struct **vmas, + unsigned int flags); Any particular reason for the forward declaration? Maybe move get_user_pages_remote() down? Yes, that's exactly why: I was thinking it would be cleaner to put in the forward declaration, rather than moving code blocks, but either way seems reasonable. I'll go ahead and move the code blocks and delete the forward declaration, now that someone has weighed in in favor of that. thanks, -- John Hubbard NVIDIA ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/1] drm/sun4i: hdmi: Remove duplicate cleanup calls
On Tue, Dec 17, 2019 at 02:46:32PM +0200, Stefan Mavrodiev wrote: > When the HDMI unbinds drm_connector_cleanup() and drm_encoder_cleanup() > are called. This also happens when the connector and the encoder are > destroyed. This double call triggers a NULL pointer exception. > > The patch fixes this by removing the cleanup calls in the unbind > function. > > Signed-off-by: Stefan Mavrodiev Added a fixes tag, and cc'd stable, and applied, thanks! Maxime signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v13 4/7] drm/sun4i: dsi: Handle bus clock via regmap_mmio_attach_clk
On Thu, Dec 19, 2019 at 12:40:14AM +0530, Jagan Teki wrote: > regmap has special API to enable the controller bus clock while > initializing register space, and current driver is using > devm_regmap_init_mmio_clk which require to specify bus > clk_id argument as "bus" > > But, the usage of clocks are varies between different Allwinner > DSI controllers. Clocking in A33 would need bus and mod clocks > where as A64 would need only bus clock. > > Since A64 support only single bus clock, it is optional to > specify the clock-names on the controller device tree node. > So using NULL on clk_id would get the attached clock. > > To support clk_id as "bus" and "NULL" during clock enablement > between controllers, this patch add generic code to handle > the bus clock using regmap_mmio_attach_clk with associated > regmap APIs. > > Signed-off-by: Jagan Teki > --- > Changes for v13: > - update the changes since has_mod_clk is dropped in previous patch > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 45 +- > 1 file changed, 37 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c > index 68b88a3dc4c5..de8955fbeb00 100644 > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c > @@ -1081,6 +1081,7 @@ static const struct component_ops sun6i_dsi_ops = { > static int sun6i_dsi_probe(struct platform_device *pdev) > { > struct device *dev = >dev; > + const char *bus_clk_name = NULL; > struct sun6i_dsi *dsi; > struct resource *res; > void __iomem *base; > @@ -1094,6 +1095,10 @@ static int sun6i_dsi_probe(struct platform_device > *pdev) > dsi->host.ops = _dsi_host_ops; > dsi->host.dev = dev; > > + if (of_device_is_compatible(dev->of_node, > + "allwinner,sun6i-a31-mipi-dsi")) > + bus_clk_name = "bus"; > + > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > base = devm_ioremap_resource(dev, res); > if (IS_ERR(base)) { > @@ -1107,25 +1112,36 @@ static int sun6i_dsi_probe(struct platform_device > *pdev) > return PTR_ERR(dsi->regulator); > } > > - dsi->regs = devm_regmap_init_mmio_clk(dev, "bus", base, > - _dsi_regmap_config); > - if (IS_ERR(dsi->regs)) { > - dev_err(dev, "Couldn't create the DSI encoder regmap\n"); > - return PTR_ERR(dsi->regs); > - } > - > dsi->reset = devm_reset_control_get_shared(dev, NULL); > if (IS_ERR(dsi->reset)) { > dev_err(dev, "Couldn't get our reset line\n"); > return PTR_ERR(dsi->reset); > } > > + dsi->regs = devm_regmap_init_mmio(dev, base, _dsi_regmap_config); > + if (IS_ERR(dsi->regs)) { > + dev_err(dev, "Couldn't init regmap\n"); > + return PTR_ERR(dsi->regs); > + } > + > + dsi->bus_clk = devm_clk_get(dev, bus_clk_name); > + if (IS_ERR(dsi->bus_clk)) { > + dev_err(dev, "Couldn't get the DSI bus clock\n"); > + ret = PTR_ERR(dsi->bus_clk); > + goto err_regmap; > + } else { > + ret = regmap_mmio_attach_clk(dsi->regs, dsi->bus_clk); > + if (ret) > + goto err_bus_clk; > + } > + > if (of_device_is_compatible(dev->of_node, > "allwinner,sun6i-a31-mipi-dsi")) { > dsi->mod_clk = devm_clk_get(dev, "mod"); > if (IS_ERR(dsi->mod_clk)) { > dev_err(dev, "Couldn't get the DSI mod clock\n"); > - return PTR_ERR(dsi->mod_clk); > + ret = PTR_ERR(dsi->mod_clk); > + goto err_attach_clk; > } > } > > @@ -1164,6 +1180,14 @@ static int sun6i_dsi_probe(struct platform_device > *pdev) > pm_runtime_disable(dev); > err_unprotect_clk: > clk_rate_exclusive_put(dsi->mod_clk); > +err_attach_clk: > + if (!IS_ERR(dsi->bus_clk)) > + regmap_mmio_detach_clk(dsi->regs); > +err_bus_clk: > + if (!IS_ERR(dsi->bus_clk)) > + clk_put(dsi->bus_clk); You still have an unbalanced clk_get / clk_put here > +err_regmap: > + regmap_exit(dsi->regs); That's not needed. > return ret; > } > > @@ -1177,6 +1201,11 @@ static int sun6i_dsi_remove(struct platform_device > *pdev) > pm_runtime_disable(dev); > clk_rate_exclusive_put(dsi->mod_clk); > > + if (!IS_ERR(dsi->bus_clk)) > + regmap_mmio_detach_clk(dsi->regs); > + > + regmap_exit(dsi->regs); Same thing here. Maxime signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 2/3] dt-bindings: display: panel: Add binding document for Xinpeng XPP055C272
On Tue, 17 Dec 2019 23:29:05 +0100, Heiko Stuebner wrote: > From: Heiko Stuebner > > The XPP055C272 is a 5.5" 720x1280 DSI display. > > changes in v4: > - fix id (Maxime) > - drop port (Maxime) > changes in v2: > - add size info into binding title (Sam) > - add more required properties (Sam) > > Signed-off-by: Heiko Stuebner > Reviewed-by: Sam Ravnborg > --- > .../display/panel/xinpeng,xpp055c272.yaml | 47 +++ > 1 file changed, 47 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml > Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 1/3] dt-bindings: Add vendor prefix for Xinpeng Technology
On Tue, 17 Dec 2019 23:29:04 +0100, Heiko Stuebner wrote: > From: Heiko Stuebner > > Shenzhen Xinpeng Technology Co., Ltd produces for example display panels. > > Signed-off-by: Heiko Stuebner > Acked-by: Sam Ravnborg > --- > Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ > 1 file changed, 2 insertions(+) > Acked-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 1/8] dt-bindings: add img,pvrsgx.yaml for Imagination GPUs
On Tue, Dec 17, 2019 at 07:01:59PM +0100, H. Nikolaus Schaller wrote: > The Imagination PVR/SGX GPU is part of several SoC from > multiple vendors, e.g. TI OMAP, Ingenic JZ4780, Intel Poulsbo > and others. > > With this binding, we describe how the SGX processor is > interfaced to the SoC (registers, interrupt etc.). > > In most cases, Clock, Reset and power management is handled > by a parent node or elsewhere. > > Tested by make dt_binding_check dtbs_check I'm surprised that worked... (Not for long if it did). > > Signed-off-by: H. Nikolaus Schaller > --- > .../devicetree/bindings/gpu/img,pvrsgx.yaml | 80 +++ > 1 file changed, 80 insertions(+) > create mode 100644 Documentation/devicetree/bindings/gpu/img,pvrsgx.yaml > > diff --git a/Documentation/devicetree/bindings/gpu/img,pvrsgx.yaml > b/Documentation/devicetree/bindings/gpu/img,pvrsgx.yaml > new file mode 100644 > index ..44799774e34d > --- /dev/null > +++ b/Documentation/devicetree/bindings/gpu/img,pvrsgx.yaml > @@ -0,0 +1,80 @@ > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/gpu/img,pvrsgx.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Imagination PVR/SGX GPU > + > +maintainers: > + - H. Nikolaus Schaller > + > +description: |+ > + This binding describes the Imagination SGX5 series of 3D accelerators which > + are found in several different SoC like TI OMAP, Sitara, Ingenic JZ4780, > + Allwinner A83, and Intel Poulsbo and CedarView and more. > + > + For an almost complete list see: > https://en.wikipedia.org/wiki/PowerVR#Implementations > + > + Only the Imagination SGX530, SGX540 and SGX544 GPUs are currently covered > by > + this binding but the extension of the pattern is straightforward. > + > + The SGX node is usually a child node of some DT node belonging to the SoC > + which handles clocks, reset and general address space mapping of the SGX > + register area. > + > +properties: > + compatible: > +enum: > +# Example: BeagleBoard A/B/C, OpenPandora 600MHz > + - ti,omap3-sgx530-121, img,sgx530-121, img,sgx530 Didn't I comment before this is not valid. You are defining the compatible string is: 'ti,omap3-sgx530-121, img,sgx530-121, img,sgx530' You need: compatible: oneOf: - description: BeagleBoard A/B/C, OpenPandora 600MHz items: - const: ti,omap3-sgx530-121 - const: img,sgx530-121 - const: img,sgx530 And so on for each of the rest. > +# Example: BeagleBoard XM, GTA04, OpenPandora 1GHz > + - ti,omap3-sgx530-125, img,sgx530-125, img,sgx530 > +# Example: BeagleBone Black > + - ti,am3352-sgx530-125, img,sgx530-125, img,sgx530 These 2 could be combined using 'enum' for the first item. Basically, you can group ones where the last 2 strings are the same. > +# Example: Pandaboard, Pandaboard ES > + - ti,omap4-sgx540-120, img,sgx540-120, img,sgx540 > + - ti,omap4-sgx544-112, img,sgx544-112, img,sgx544 > +# Example: OMAP5 UEVM, Pyra Handheld > + - ti,omap5-sgx544-116, img,sgx544-116, img,sgx544 > + - ti,dra7-sgx544-116, img,sgx544-116, img,sgx544 > +# Example: CI20 > + - ingenic,jz4780-sgx540-120, img,sgx540-120, img,sgx540 > +# the following entries are not validated with real hardware What am I supposed to do with that? You're just defining some strings. If you're not sure they are okay, then don't define them. > +# more TI SoC > + - ti,am3517-sgx530-125, img,sgx530-125, img,sgx530 > + - ti,am4-sgx530-125, img,sgx530-125, img,sgx530 > + - ti,ti81xx-sgx530-125, img,sgx530-125, img,sgx530 > +# Example: Banana-Pi-M3 (Allwinner A83T) > + - allwinner,sun8i-a83t-sgx544-116, img,sgx544-116, img,sgx544 > +# Example: Atom Z5xx > + - intel,poulsbo-gma500-sgx535, img,sgx535-116, img,sgx535 > +# Example: Atom Z24xx > + - intel,medfield-gma-sgx540, img,sgx540-116, img,sgx540 > +# Example: Atom N2600, D2500 > + - intel,cedarview-gma3600-sgx545, img,sgx545-116, img,sgx545 > + > + reg: > +maxItems: 1 > + > + interrupts: > +maxItems: 1 > + > +required: > + - compatible > + - reg > + - interrupts > + > +additionalProperties: false > + > +examples: > + - |+ > +#include > + > +gpu@fe00 { > + compatible = "ti,omap-omap5-sgx544-116", "img,sgx544-116", > "img,sgx544", "img,sgx5"; Doesn't match the schema. > + reg = <0xfe00 0x200>; > + interrupts = ; > +}; > + > +... > -- > 2.23.0 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 3/4] dt-bindings: Add binding for IT6505.
On Sat, Dec 14, 2019 at 09:21:45AM +0100, Sam Ravnborg wrote: > Hi Allen. > > On Tue, Dec 10, 2019 at 01:53:41PM +0800, allen wrote: > > Add a DT binding documentation for IT6505. > > > > Signed-off-by: Allen Chen > > Signed-off-by: Pi-Hsun Shih > > --- > > .../bindings/display/bridge/ite,it6505.yaml| 99 > > ++ > > 1 file changed, 99 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml > > > > diff --git > > a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml > > b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml > > new file mode 100644 > > index ..23a106a > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml > > @@ -0,0 +1,99 @@ > > +# SPDX-License-Identifier: GPL-2.0 > Please dual license new bindings like this: > > (GPL-2.0-only OR BSD-2-Clause) > > > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/display/ite,it6505.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: ITE it6505 Device Tree Bindings > > + > > +maintainers: > > + - Allen Chen > > + > > +description: | > > + The IT6505 is a high-performance DisplayPort 1.1a transmitter, > > +fully compliant with DisplayPort 1.1a, HDCP 1.3 specifications. > > +The IT6505 supports color depth of up to 36 bits (12 bits/color) > > +and ensures robust transmission of high-quality uncompressed video > > +content, along with uncompressed and compressed digital audio content. > Can we get consistent indent of the text here. Pretty sure that's not even valid YAML. > With this fixed: > Acked-by: Sam Ravnborg > > > + > > + Aside from the various video output formats supported, the IT6505 > > +also encodes and transmits up to 8 channels of I2S digital audio, > > +with sampling rate up to 192kHz and sample size up to 24 bits. > > +In addition, an S/PDIF input port takes in compressed audio of up to > > +192kHz frame rate. > > + > > + Each IT6505 chip comes preprogrammed with an unique HDCP key, > > +in compliance with the HDCP 1.3 standard so as to provide secure > > +transmission of high-definition content. Users of the IT6505 need not > > +purchase any HDCP keys or ROMs. > > + > > +properties: > > + compatible: > > +const: ite,it6505 > > + > > + reg: > > +- maxItems: 1 > > +- description: i2c address of the bridge And this is not valid json-schema. The '-' means list and properties aren't lists. Run 'make dt_binding_check' and fix all the errors. See Documentation/devicetree/bindings/writing-schema.rst. > > + > > + ovdd-supply: > > +- maxItems: 1 > > +- description: I/O voltage > > + > > + pwr18-supply: > > +- maxItems: 1 > > +- description: core voltage > > + > > + interrupts: > > +- maxItems: 1 > > +- description: interrupt specifier of INT pin > > + > > + reset-gpios: > > +- maxItems: 1 > > +- description: gpio specifier of RESET pin > > + > > + hpd-gpios: Is HPD attached to the DP bridge or the DP connector. For the latter, then this property goes in a connector node. > > +- maxItems: 1 > > +- description: > > +- Hotplug detect GPIO > > +- Indicates which GPIO should be used for hotplug detection > > + > > + extcon: Don't use extcon. Deprecated. > > +- maxItems: 1 > > +- description: extcon specifier for the Power Delivery > > + > > + port: > > +- type: object > > +- description: A port node pointing to DPI host port node > > + > > +required: > > + - compatible > > + - reg > > + - ovdd-supply > > + - pwr18-supply > > + - interrupts > > + - reset-gpios > > + - hpd-gpios > > + - extcon > > + > > +examples: > > + - | > > +dp-bridge@5c { > > +compatible = "ite,it6505"; > > +interrupts = <152 IRQ_TYPE_EDGE_RISING 152 0>; > > +reg = <0x5c>; > > +pinctrl-names = "default"; > > +pinctrl-0 = <_pins>; > > +ovdd-supply = <_vsim1_reg>; > > +pwr18-supply = <_pp18_reg>; > > +reset-gpios = < 179 1>; > > +hpd-gpios = < 9 0>; > > +extcon = <_extcon>; > > + > > +port { > > +it6505_in: endpoint { > > +remote-endpoint = <_out>; > > +}; > > +}; > > +}; > > + > > +--- ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 5/6] dt-bindings: display: Add idk-2121wr binding
On Tue, Dec 17, 2019 at 01:46:00PM +, Fabrizio Castro wrote: > Add binding for the idk-2121wr LVDS panel from Advantech. > > Some panel-specific documentation can be found here: > https://buy.advantech.eu/Displays/Embedded-LCD-Kits-High-Brightness/model-IDK-2121WR-K2FHA2E.htm > > Signed-off-by: Fabrizio Castro > Reviewed-by: Laurent Pinchart > > --- > v5->v6: > * No change > > v4->v5: > * No change > > v3->v4: > * Absorbed patch "dt-bindings: display: Add bindings for LVDS > bus-timings" > * Big restructuring after Rob's and Laurent's comments > > v2->v3: > * New patch > --- > .../display/panel/advantech,idk-2121wr.yaml| 128 > + > 1 file changed, 128 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > > diff --git > a/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > b/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > new file mode 100644 > index 000..24cd38b > --- /dev/null > +++ > b/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > @@ -0,0 +1,128 @@ > +# SPDX-License-Identifier: GPL-2.0 Also, dual license new bindings: (GPL-2.0-only OR BSD-2-Clause) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 5/6] dt-bindings: display: Add idk-2121wr binding
On Tue, Dec 17, 2019 at 01:46:00PM +, Fabrizio Castro wrote: > Add binding for the idk-2121wr LVDS panel from Advantech. > > Some panel-specific documentation can be found here: > https://buy.advantech.eu/Displays/Embedded-LCD-Kits-High-Brightness/model-IDK-2121WR-K2FHA2E.htm > > Signed-off-by: Fabrizio Castro > Reviewed-by: Laurent Pinchart > > --- > v5->v6: > * No change > > v4->v5: > * No change > > v3->v4: > * Absorbed patch "dt-bindings: display: Add bindings for LVDS > bus-timings" > * Big restructuring after Rob's and Laurent's comments > > v2->v3: > * New patch > --- > .../display/panel/advantech,idk-2121wr.yaml| 128 > + > 1 file changed, 128 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > > diff --git > a/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > b/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > new file mode 100644 > index 000..24cd38b > --- /dev/null > +++ > b/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml > @@ -0,0 +1,128 @@ > +# SPDX-License-Identifier: GPL-2.0 > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/panel/advantech,idk-2121wr.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Advantech IDK-2121WR 21.5" Full-HD dual-LVDS panel > + > +maintainers: > + - Fabrizio Castro > + - Thierry Reding > + > +description: | > + The IDK-2121WR from Advantech is a Full-HD dual-LVDS panel. > + A dual-LVDS interface is a dual-link connection with even pixels traveling > + on one link, and with odd pixels traveling on the other link. > + > + The panel expects odd pixels on the first port, and even pixels on the > + second port, therefore the ports must be marked accordingly (with either > + dual-lvds-odd-pixels or dual-lvds-even-pixels). > + Needs to reference lvds.yaml here. > +properties: > + compatible: > +items: > + - const: advantech,idk-2121wr > + - {} # panel-lvds, but not listed here to avoid false select > + > + width-mm: > +const: 476 > + > + height-mm: > +const: 268 > + > + data-mapping: > +const: vesa-24 > + > + ports: > +type: object > +properties: > + "#address-cells": > +const: 1 > + > + "#size-cells": > +const: 0 No need for these 2. Can assume they are defined in common binding. > + > + port@0: > +type: object > +description: The sink for odd pixels. > +properties: > + reg: > +const: 0 > + > + dual-lvds-odd-pixels: true > + > +required: > + - reg > + - dual-lvds-odd-pixels > + > + port@1: > +type: object > +description: The sink for even pixels. > +properties: > + reg: > +const: 1 > + > + dual-lvds-even-pixels: true > + > +required: > + - reg > + - dual-lvds-even-pixels port@0 and port@1 both required? > + > + panel-timing: true > + > +additionalProperties: false > + > +required: > + - compatible > + - width-mm > + - height-mm > + - data-mapping > + - panel-timing > + - ports No need to repeat what's required by lvds.yaml. > + > +examples: > + - |+ > +panel-lvds { > + compatible = "advantech,idk-2121wr", "panel-lvds"; > + > + width-mm = <476>; > + height-mm = <268>; > + > + data-mapping = "vesa-24"; > + > + panel-timing { > +clock-frequency = <14850>; > +hactive = <1920>; > +vactive = <1080>; > +hsync-len = <44>; > +hfront-porch = <88>; > +hback-porch = <148>; > +vfront-porch = <4>; > +vback-porch = <36>; > +vsync-len = <5>; > + }; > + > + ports { > +#address-cells = <1>; > +#size-cells = <0>; > + > +port@0 { > + reg = <0>; > + dual-lvds-odd-pixels; > + panel_in0: endpoint { > +remote-endpoint = <_out>; > + }; > +}; > + > +port@1 { > + reg = <1>; > + dual-lvds-even-pixels; > + panel_in1: endpoint { > +remote-endpoint = <_out>; > + }; > +}; > + }; > +}; > + > +... > -- > 2.7.4 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] gpu: drm: dead code elimination
On Wed, Dec 18, 2019 at 3:14 AM Pan Zhang wrote: > > this set adds support for removal of gpu drm dead code. > > patch3 is similar with patch 1: > `num` is a data of u8 type and ATOM_MAX_HW_I2C_READ == 255, > > so there is a impossible condition '(num > 255) => (0-255 > 255)'. > > Signed-off-by: Pan Zhang Applied. thanks! Alex > --- > drivers/gpu/drm/radeon/atombios_i2c.c | 5 - > 1 file changed, 5 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c > b/drivers/gpu/drm/radeon/atombios_i2c.c > index a570ce4..ab4d210 100644 > --- a/drivers/gpu/drm/radeon/atombios_i2c.c > +++ b/drivers/gpu/drm/radeon/atombios_i2c.c > @@ -68,11 +68,6 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan > *chan, > memcpy(, [1], num); > args.lpI2CDataOut = cpu_to_le16(out); > } else { > - if (num > ATOM_MAX_HW_I2C_READ) { > - DRM_ERROR("hw i2c: tried to read too many bytes (%d > vs 255)\n", num); > - r = -EINVAL; > - goto done; > - } > args.ucRegIndex = 0; > args.lpI2CDataOut = 0; > } > -- > 2.7.4 > > ___ > 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
Re: [PATCH 1/3] gpu: drm: dead code elimination
On Wed, Dec 18, 2019 at 3:13 AM Pan Zhang wrote: > > this set adds support for removal of gpu drm dead code. > > patch1: > `num` is a data of u8 type and ATOM_MAX_HW_I2C_READ == 255, > > so there is a impossible condition '(num > 255) => (0-255 > 255)'. > > Signed-off-by: Pan Zhang This change was already made by someone else. Alex > --- > drivers/gpu/drm/amd/amdgpu/atombios_i2c.c | 5 - > 1 file changed, 5 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_i2c.c > b/drivers/gpu/drm/amd/amdgpu/atombios_i2c.c > index 980c363..b4cc7c5 100644 > --- a/drivers/gpu/drm/amd/amdgpu/atombios_i2c.c > +++ b/drivers/gpu/drm/amd/amdgpu/atombios_i2c.c > @@ -76,11 +76,6 @@ static int amdgpu_atombios_i2c_process_i2c_ch(struct > amdgpu_i2c_chan *chan, > } > args.lpI2CDataOut = cpu_to_le16(out); > } else { > - if (num > ATOM_MAX_HW_I2C_READ) { > - DRM_ERROR("hw i2c: tried to read too many bytes (%d > vs 255)\n", num); > - r = -EINVAL; > - goto done; > - } > args.ucRegIndex = 0; > args.lpI2CDataOut = 0; > } > -- > 2.7.4 > > ___ > 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
Re: [GIT PULL] Please pull hmm changes
On Wed, Dec 18, 2019 at 10:37 AM Jason Gunthorpe wrote: > > I think this is what you are looking for? I think that with these names, I would have had an easier time reading the original patch that made me go "Eww", yes. Of course, now that it's just a rename patch, it's not like the patch is all that legible, but yeah, I think the naming is saner. Linus ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v13 5/7] drm/sun4i: dsi: Add Allwinner A64 MIPI DSI support
The MIPI DSI controller in Allwinner A64 is similar to A33. But unlike A33, A64 doesn't have DSI_SCLK gating so add compatible for Allwinner A64 with uninitialized has_mod_clk driver. Signed-off-by: Jagan Teki Tested-by: Merlijn Wajer --- Changes for v13: - update the changes since has_mod_clk is dropped in previous patch drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index de8955fbeb00..8669d5f0e744 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -1264,6 +1264,7 @@ static const struct dev_pm_ops sun6i_dsi_pm_ops = { static const struct of_device_id sun6i_dsi_of_table[] = { { .compatible = "allwinner,sun6i-a31-mipi-dsi" }, + { .compatible = "allwinner,sun50i-a64-mipi-dsi" }, { } }; MODULE_DEVICE_TABLE(of, sun6i_dsi_of_table); -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v13 3/7] drm/sun4i: dsi: Get the mod clock for A31
As per the user manual, look like mod clock is not mandatory for all Allwinner MIPI DSI controllers, it is connected to CLK_DSI_SCLK for A31 and not available in A64. So, add compatible check for A31 and get mod clock accordingly. Tested-by: Merlijn Wajer Signed-off-by: Jagan Teki --- Changes for v13: - Drop has_mod_clk quirk as commented by Chen-Yu drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index c958ca9bae63..68b88a3dc4c5 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -1120,10 +1120,13 @@ static int sun6i_dsi_probe(struct platform_device *pdev) return PTR_ERR(dsi->reset); } - dsi->mod_clk = devm_clk_get(dev, "mod"); - if (IS_ERR(dsi->mod_clk)) { - dev_err(dev, "Couldn't get the DSI mod clock\n"); - return PTR_ERR(dsi->mod_clk); + if (of_device_is_compatible(dev->of_node, + "allwinner,sun6i-a31-mipi-dsi")) { + dsi->mod_clk = devm_clk_get(dev, "mod"); + if (IS_ERR(dsi->mod_clk)) { + dev_err(dev, "Couldn't get the DSI mod clock\n"); + return PTR_ERR(dsi->mod_clk); + } } /* -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v13 2/7] dt-bindings: sun6i-dsi: Add A64 DPHY compatible (w/ A31 fallback)
The MIPI DSI PHY controller on Allwinner A64 is similar on the one on A31. Add A64 compatible and append A31 compatible as fallback. Reviewed-by: Rob Herring Signed-off-by: Jagan Teki --- Changes for v13: - collect Rob review tag .../bindings/phy/allwinner,sun6i-a31-mipi-dphy.yaml | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-mipi-dphy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-mipi-dphy.yaml index fa46670de299..8841938050b2 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-mipi-dphy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-mipi-dphy.yaml @@ -15,7 +15,11 @@ properties: const: 0 compatible: -const: allwinner,sun6i-a31-mipi-dphy +oneOf: + - const: allwinner,sun6i-a31-mipi-dphy + - items: + - const: allwinner,sun50i-a64-mipi-dphy + - const: allwinner,sun6i-a31-mipi-dphy reg: maxItems: 1 -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[DO NOT MERGE] [PATCH v13 7/7] arm64: dts: allwinner: bananapi-m64: Enable Bananapi S070WV20-CT16 DSI panel
This patch add support for Bananapi S070WV20-CT16 DSI panel to BPI-M64 board. DSI panel connected via board DSI port with, - DLDO1 as VCC-DSI supply - DCDC1 as VDD supply - PD7 gpio for lcd enable pin - PD6 gpio for lcd reset pin - PD5 gpio for backlight enable pin Signed-off-by: Jagan Teki --- .../dts/allwinner/sun50i-a64-bananapi-m64.dts | 31 +++ 1 file changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts index 208373efee49..6beaecdd802a 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts @@ -45,6 +45,7 @@ #include "sun50i-a64.dtsi" #include +#include / { model = "BananaPi-M64"; @@ -56,6 +57,14 @@ serial1 = }; + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <_pwm 0 5 PWM_POLARITY_INVERTED>; + brightness-levels = <1 2 4 8 16 32 64 128 255>; + default-brightness-level = <2>; + enable-gpios = < 3 5 GPIO_ACTIVE_HIGH>; /* LCD-BL-EN: PD5 */ + }; + chosen { stdout-path = "serial0:115200n8"; }; @@ -116,6 +125,24 @@ status = "okay"; }; + { + status = "okay"; +}; + + { + vcc-dsi-supply = <_dldo1>; /* VCC3V3-DSI */ + status = "okay"; + + panel@0 { + compatible = "bananapi,s070wv20-ct16-icn6211"; + reg = <0>; + enable-gpios = < 3 7 GPIO_ACTIVE_HIGH>; /* LCD-PWR-EN: PD7 */ + reset-gpios = < 3 6 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD6 */ + vdd-supply = <_dcdc1>; + backlight = <>; + }; +}; + { status = "okay"; }; @@ -206,6 +233,10 @@ status = "okay"; }; +_pwm { + status = "okay"; +}; + _rsb { status = "okay"; -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v13 1/7] dt-bindings: sun6i-dsi: Document A64 MIPI-DSI controller
The MIPI DSI controller in Allwinner A64 is similar to A33. But unlike A33, A64 doesn't have DSI_SCLK gating so it is valid to have separate compatible for A64 on the same driver. DSI_SCLK uses mod clock-names on dt-bindings, so the same is not required for A64. On that note - A64 require minimum of 1 clock like the bus clock - A33 require minimum of 2 clocks like both bus, mod clocks So, update dt-bindings so-that it can document both A33, A64 bindings requirements. Reviewed-by: Rob Herring Signed-off-by: Jagan Teki --- Changes for v13: - Add if statement for A64 with single clock .../display/allwinner,sun6i-a31-mipi-dsi.yaml | 33 +-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml index dafc0980c4fa..d41ecb5e7f7c 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml @@ -15,7 +15,9 @@ properties: "#size-cells": true compatible: -const: allwinner,sun6i-a31-mipi-dsi +enum: + - allwinner,sun6i-a31-mipi-dsi + - allwinner,sun50i-a64-mipi-dsi reg: maxItems: 1 @@ -24,6 +26,8 @@ properties: maxItems: 1 clocks: +minItems: 1 +maxItems: 2 items: - description: Bus Clock - description: Module Clock @@ -63,13 +67,38 @@ required: - reg - interrupts - clocks - - clock-names - phys - phy-names - resets - vcc-dsi-supply - port +allOf: + - if: + properties: + compatible: + contains: + const: allwinner,sun6i-a31-mipi-dsi + +then: +properties: + clocks: +minItems: 2 + +required: + - clock-names + + - if: + properties: + compatible: + contains: + const: allwinner,sun50i-a64-mipi-dsi + +then: +properties: + clocks: +minItems: 1 + additionalProperties: false examples: -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v13 6/7] arm64: dts: allwinner: a64: Add MIPI DSI pipeline
Add MIPI DSI pipeline for Allwinner A64. - dsi node, with A64 compatible since it doesn't support DSI_SCLK gating unlike A33 - dphy node, with A64 compatible with A33 fallback since DPHY on A64 and A33 is similar - finally, attach the dsi_in to tcon0 for complete MIPI DSI Signed-off-by: Jagan Teki Tested-by: Merlijn Wajer --- Changes for v13: - none arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 37 +++ 1 file changed, 37 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 27e48234f1c2..1db8378f59a4 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -382,6 +382,12 @@ #address-cells = <1>; #size-cells = <0>; reg = <1>; + + tcon0_out_dsi: endpoint@1 { + reg = <1>; + remote-endpoint = <_in_tcon0>; + allwinner,tcon-channel = <1>; + }; }; }; }; @@ -1014,6 +1020,37 @@ status = "disabled"; }; + dsi: dsi@1ca { + compatible = "allwinner,sun50i-a64-mipi-dsi"; + reg = <0x01ca 0x1000>; + interrupts = ; + clocks = < CLK_BUS_MIPI_DSI>; + resets = < RST_BUS_MIPI_DSI>; + phys = <>; + phy-names = "dphy"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + + port { + dsi_in_tcon0: endpoint { + remote-endpoint = <_out_dsi>; + }; + }; + }; + + dphy: d-phy@1ca1000 { + compatible = "allwinner,sun50i-a64-mipi-dphy", +"allwinner,sun6i-a31-mipi-dphy"; + reg = <0x01ca1000 0x1000>; + clocks = < CLK_BUS_MIPI_DSI>, +< CLK_DSI_DPHY>; + clock-names = "bus", "mod"; + resets = < RST_BUS_MIPI_DSI>; + status = "disabled"; + #phy-cells = <0>; + }; + hdmi: hdmi@1ee { compatible = "allwinner,sun50i-a64-dw-hdmi", "allwinner,sun8i-a83t-dw-hdmi"; -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v13 0/7] drm/sun4i: Allwinner A64 MIPI-DSI support
This is v13 version for Allwinner A64 MIPI-DSI support and here is the previous version set[1] Changes for v13: - update dt-bindings for A64 - drop has_mod_clk variant - use regmap bus clock properly Changes for v12: - use enum insted of oneOf+const - handle bus clock using regmap attach clk - tested on A64, A33 boards. Changes for v11: - fix dt-bindings for dphy - fix dt-bindings for dsi controller - add bus clock handling code - tested on A64, A33 boards. Changes for v10: - updated dt-bindings as per .yaml format - rebased on drm-misc/for-linux-next Changes for v9: - moved dsi fixes in separate series on top of A33 - rebase on linux-next Changes for v8: - rebased on drm-misc change along with linux-next - reworked video start delay patch - tested on 4 different dsi panels - reworked commit messages Changes for v7: - moved vcc-dsi binding to required filed. - drop quotes on fallback dphy bindings. - drop min_rate clock pll-mipi patches. - introduce dclk divider computation as like A64 BSP. - add A64 DSI quark patches. - fixed A64 DSI pipeline. - add proper commit messages. - collect Merlijn Wajer Tested-by credits. Changes for v6: - dropped unneeded changes, patches - fixed all burst mode patches as per previous version comments - rebase on master - update proper commit message - dropped unneeded comments - order the patches that make review easy Changes for v5: - collect Rob, Acked-by - droped "Fix VBP size calculation" patch - updated vblk timing calculation. - droped techstar, bananapi dsi panel drivers which may require bridge or other setup. it's under discussion. Changes for v4: - droppoed untested CCU_FEATURE_FIXED_POSTDIV check code in nkm min, max rate patches - create two patches for "Add Allwinner A64 MIPI DSI support" one for has_mod_clk quirk and other one for A64 support - use existing driver code construct for hblk computation - dropped "Increase hfp packet overhead" patch [2], though BSP added this but we have no issues as of now. (no issues on panel side w/o this change) - create separate function for vblk computation - enable vcc-dsi regulator in dsi_runtime_resume - collect Rob, Acked-by - update MAINTAINERS file for panel drivers - cleanup commit messages - fixed checkpatch warnings/errors [1] https://patchwork.freedesktop.org/series/70361/ Any inputs? Jagan. Jagan Teki (7): dt-bindings: sun6i-dsi: Document A64 MIPI-DSI controller dt-bindings: sun6i-dsi: Add A64 DPHY compatible (w/ A31 fallback) drm/sun4i: dsi: Get the mod clock for A31 drm/sun4i: dsi: Handle bus clock via regmap_mmio_attach_clk drm/sun4i: dsi: Add Allwinner A64 MIPI DSI support arm64: dts: allwinner: a64: Add MIPI DSI pipeline [DO NOT MERGE] arm64: dts: allwinner: bananapi-m64: Enable Bananapi S070WV20-CT16 DSI panel .../display/allwinner,sun6i-a31-mipi-dsi.yaml | 33 ++- .../phy/allwinner,sun6i-a31-mipi-dphy.yaml| 6 +- .../dts/allwinner/sun50i-a64-bananapi-m64.dts | 31 +++ arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 37 + drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c| 55 +++ 5 files changed, 148 insertions(+), 14 deletions(-) -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v13 4/7] drm/sun4i: dsi: Handle bus clock via regmap_mmio_attach_clk
regmap has special API to enable the controller bus clock while initializing register space, and current driver is using devm_regmap_init_mmio_clk which require to specify bus clk_id argument as "bus" But, the usage of clocks are varies between different Allwinner DSI controllers. Clocking in A33 would need bus and mod clocks where as A64 would need only bus clock. Since A64 support only single bus clock, it is optional to specify the clock-names on the controller device tree node. So using NULL on clk_id would get the attached clock. To support clk_id as "bus" and "NULL" during clock enablement between controllers, this patch add generic code to handle the bus clock using regmap_mmio_attach_clk with associated regmap APIs. Signed-off-by: Jagan Teki --- Changes for v13: - update the changes since has_mod_clk is dropped in previous patch drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 45 +- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index 68b88a3dc4c5..de8955fbeb00 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -1081,6 +1081,7 @@ static const struct component_ops sun6i_dsi_ops = { static int sun6i_dsi_probe(struct platform_device *pdev) { struct device *dev = >dev; + const char *bus_clk_name = NULL; struct sun6i_dsi *dsi; struct resource *res; void __iomem *base; @@ -1094,6 +1095,10 @@ static int sun6i_dsi_probe(struct platform_device *pdev) dsi->host.ops = _dsi_host_ops; dsi->host.dev = dev; + if (of_device_is_compatible(dev->of_node, + "allwinner,sun6i-a31-mipi-dsi")) + bus_clk_name = "bus"; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) { @@ -1107,25 +1112,36 @@ static int sun6i_dsi_probe(struct platform_device *pdev) return PTR_ERR(dsi->regulator); } - dsi->regs = devm_regmap_init_mmio_clk(dev, "bus", base, - _dsi_regmap_config); - if (IS_ERR(dsi->regs)) { - dev_err(dev, "Couldn't create the DSI encoder regmap\n"); - return PTR_ERR(dsi->regs); - } - dsi->reset = devm_reset_control_get_shared(dev, NULL); if (IS_ERR(dsi->reset)) { dev_err(dev, "Couldn't get our reset line\n"); return PTR_ERR(dsi->reset); } + dsi->regs = devm_regmap_init_mmio(dev, base, _dsi_regmap_config); + if (IS_ERR(dsi->regs)) { + dev_err(dev, "Couldn't init regmap\n"); + return PTR_ERR(dsi->regs); + } + + dsi->bus_clk = devm_clk_get(dev, bus_clk_name); + if (IS_ERR(dsi->bus_clk)) { + dev_err(dev, "Couldn't get the DSI bus clock\n"); + ret = PTR_ERR(dsi->bus_clk); + goto err_regmap; + } else { + ret = regmap_mmio_attach_clk(dsi->regs, dsi->bus_clk); + if (ret) + goto err_bus_clk; + } + if (of_device_is_compatible(dev->of_node, "allwinner,sun6i-a31-mipi-dsi")) { dsi->mod_clk = devm_clk_get(dev, "mod"); if (IS_ERR(dsi->mod_clk)) { dev_err(dev, "Couldn't get the DSI mod clock\n"); - return PTR_ERR(dsi->mod_clk); + ret = PTR_ERR(dsi->mod_clk); + goto err_attach_clk; } } @@ -1164,6 +1180,14 @@ static int sun6i_dsi_probe(struct platform_device *pdev) pm_runtime_disable(dev); err_unprotect_clk: clk_rate_exclusive_put(dsi->mod_clk); +err_attach_clk: + if (!IS_ERR(dsi->bus_clk)) + regmap_mmio_detach_clk(dsi->regs); +err_bus_clk: + if (!IS_ERR(dsi->bus_clk)) + clk_put(dsi->bus_clk); +err_regmap: + regmap_exit(dsi->regs); return ret; } @@ -1177,6 +1201,11 @@ static int sun6i_dsi_remove(struct platform_device *pdev) pm_runtime_disable(dev); clk_rate_exclusive_put(dsi->mod_clk); + if (!IS_ERR(dsi->bus_clk)) + regmap_mmio_detach_clk(dsi->regs); + + regmap_exit(dsi->regs); + return 0; } -- 2.18.0.321.gffc6fa0e3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v21 2/2] drm/bridge: Add I2C based driver for ps8640 bridge
On Wed, 2019-12-18 at 16:21 +0100, Enric Balletbo i Serra wrote: > Hi Ezequiel, > > Many thanks for the review, I am just preparing the next version to send. > [..] > > > + > > > +#define PAGE1_VSTART 0x6b > > > +#define PAGE2_SPI_CFG3 0x82 > > > +#define I2C_TO_SPI_RESET 0x20 > > > +#define PAGE2_ROMADD_BYTE1 0x8e > > > +#define PAGE2_ROMADD_BYTE2 0x8f > > > +#define PAGE2_SWSPI_WDATA0x90 > > > +#define PAGE2_SWSPI_RDATA0x91 > > > +#define PAGE2_SWSPI_LEN 0x92 > > > +#define PAGE2_SWSPI_CTL 0x93 > > > +#define TRIGGER_NO_READBACK 0x05 > > > +#define TRIGGER_READBACK 0x01 > > > +#define PAGE2_SPI_STATUS 0x9e > > > +#define SPI_READY0x0c > > > +#define PAGE2_GPIO_L 0xa6 > > > +#define PAGE2_GPIO_H 0xa7 > > > +#define PS_GPIO9 BIT(1) > > > +#define PAGE2_IROM_CTRL 0xb0 > > > +#define IROM_ENABLE 0xc0 > > > +#define IROM_DISABLE 0x80 > > > +#define PAGE2_SW_RESET 0xbc > > > +#define SPI_SW_RESET BIT(7) > > > +#define MPU_SW_RESET BIT(6) > > > +#define PAGE2_ENCTLSPI_WR0xda > > > +#define PAGE2_I2C_BYPASS 0xea > > > +#define I2C_BYPASS_EN0xd0 > > > +#define PAGE2_MCS_EN 0xf3 > > > +#define MCS_EN BIT(0) > > > +#define PAGE3_SET_ADD0xfe > > > +#define PAGE3_SET_VAL0xff > > > +#define VDO_CTL_ADD 0x13 > > > +#define VDO_DIS 0x18 > > > +#define VDO_EN 0x1c > > > +#define PAGE4_REV_L 0xf0 > > > +#define PAGE4_REV_H 0xf1 > > > +#define PAGE4_CHIP_L 0xf2 > > > +#define PAGE4_CHIP_H 0xf3 > > > + > > > +#define PAGE0_DP_CNTL0 > > > > Unused macro. > > > > > +#define PAGE1_VDO_BDG1 > > > +#define PAGE2_TOP_CNTL 2 > > > +#define PAGE3_DSI_CNTL1 3 > > > +#define PAGE4_MIPI_PHY 4 > > > > Ditto... maybe others as well? > > > > I removed all the unused macros. > In this case, given these PAGEX_XXX refer to the I2C ancillaries, maybe you can leave them. Moreover, I'd put them in an enum, to emphasize their relationship. Regards, Ezequiel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [resend PATCH v6 02/12] dt-bindings: mediatek: Add compatible for mt7623
On Sat, 7 Dec 2019 23:47:30 +0100, matthias@kernel.org wrote: > From: Matthias Brugger > > MediaTek mt7623 uses the mt2701 binings as fallback. > Document this in the binding description. > > Signed-off-by: Matthias Brugger > --- > .../devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 ++ > 1 file changed, 2 insertions(+) > Acked-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL] Please pull hmm changes
On Wed, Dec 18, 2019 at 6:59 AM Jason Gunthorpe wrote: > > Do you think calling it 'mmn_subscriptions' is clear? Why do you want that "mmn"? Guys, the "mmn" part is clear from the _context_. The function name is When the function name is something like "mmu_interval_read_begin()", and the filename is "mm/mmu_notifier.c", you do NOT NEED silly prefixes like "mmn" for local variables. They add NOTHING. And they make the code an illegible mess. Yes, global function names need to be unique, and if they aren't really core, they want some prefix that explains the context, because global functions are called from _outside_ the context that explains them. But if it's a "struct mmu_interval_notifier" pointer, and it's inside a file that is all about these pointers, it shouldn't be called "mmn_xyz". That's not a name. That's line noise. So call it a "notifier". Maybe even an "interval_notifier" if you don't mind the typing. Name it by something _descriptive_. And if you want. And "subscriptions" is a lovely name. What does the "mmn" buy you? Just to clarify: the names I really hated were the local variable names (and the argument names) that were all entirely within the context of mm/mmu_notifier.c. Calling something "mmn_mm" is a random jumble of letters that looks more like you're humming than you're speaking. Don't mumble. Speak _clearly_. The other side of "short names" is that some non-local conventions exist because they are _so_ global. So if it's just a mm pointer, call it "mm". We do have some very core concepts in the kernel that permeate _everything_, and those core things we tend to have very short names for. So whenever you're working with VM code, you'll see lots of small names like "mm", "vma", "pte" etc. They aren't exactly clear, but they are _globally_ something you read and learn when you work on the Linux VM code. That's very diofferent from "mmn" - the "mmn" thing isn't some global shorthand, it is just a local abomination. So "notifier_mm" makes sense - it's the mm for a notifier. But "mmn_notifier" does not, because "mmn" only makes sense in a local context, and in that local context it's not any new information at all. See the difference? Two shorthands, but one makes sense and adds information, while the other is just unnecessary and pointless and doesn't add anything at all. Linus ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [resend PATCH v6 01/12] dt-bindings: display: mediatek: Add mmsys binding description
On Sat, Dec 07, 2019 at 11:47:29PM +0100, matthias@kernel.org wrote: > From: Matthias Brugger > > The MediaTek DRM has a block called mmsys, which sets > the routing and enalbes the different blocks. typo > This patch adds one line for the mmsys bindings description. > > Signed-off-by: Matthias Brugger > --- > .../display/mediatek/mediatek,disp.txt| 28 ++- > 1 file changed, 15 insertions(+), 13 deletions(-) Otherwise, Acked-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 2/9] drm/amd/display: Fix compilation issue.
On 2019-12-18 11:13 a.m., Manna, Animesh wrote: > > On 18-12-2019 21:12, Harry Wentland wrote: >> On 2019-12-18 10:13 a.m., Animesh Manna wrote: >>> [Why]: >>> Aligh with DP spec wanted to follow same naming convention. >>> >>> [How]: >>> Changed the macro name of the dpcd address used for getting requested >>> test-pattern. >>> >> Please roll this into your patch that renames the definition. All >> patches should compile on their own. > > > Thanks Harry for review, wanted to follow similar commit-description > format followed in amd-driver compare to i915 and created a separate > patch. Maybe is it good idea to change the patch sequence and make it as > first patch. > Thanks for looking to follow the commit style from the rest of the amd driver but in this case we need to combine them or you'll be left with one patch in the sequence that won't build on its own. Harry > Regards, > Animesh > >> >> Thanks, >> Harry >> >>> Cc: Harry Wentland >>> Cc: Alex Deucher >>> Signed-off-by: Animesh Manna >>> --- >>> drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c >>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c >>> index 42aa889fd0f5..1a6109be2fce 100644 >>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c >>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c >>> @@ -2491,7 +2491,7 @@ static void >>> dp_test_send_phy_test_pattern(struct dc_link *link) >>> /* get phy test pattern and pattern parameters from DP receiver */ >>> core_link_read_dpcd( >>> link, >>> - DP_TEST_PHY_PATTERN, >>> + DP_PHY_TEST_PATTERN, >>> _test_pattern.raw, >>> sizeof(dpcd_test_pattern)); >>> core_link_read_dpcd( >>> ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v11 06/25] mm: fix get_user_pages_remote()'s handling of FOLL_LONGTERM
On Mon, Dec 16, 2019 at 02:25:18PM -0800, John Hubbard wrote: > As it says in the updated comment in gup.c: current FOLL_LONGTERM > behavior is incompatible with FAULT_FLAG_ALLOW_RETRY because of the > FS DAX check requirement on vmas. > > However, the corresponding restriction in get_user_pages_remote() was > slightly stricter than is actually required: it forbade all > FOLL_LONGTERM callers, but we can actually allow FOLL_LONGTERM callers > that do not set the "locked" arg. > > Update the code and comments to loosen the restriction, allowing > FOLL_LONGTERM in some cases. > > Also, copy the DAX check ("if a VMA is DAX, don't allow long term > pinning") from the VFIO call site, all the way into the internals > of get_user_pages_remote() and __gup_longterm_locked(). That is: > get_user_pages_remote() calls __gup_longterm_locked(), which in turn > calls check_dax_vmas(). This check will then be removed from the VFIO > call site in a subsequent patch. > > Thanks to Jason Gunthorpe for pointing out a clean way to fix this, > and to Dan Williams for helping clarify the DAX refactoring. > > Tested-by: Alex Williamson > Acked-by: Alex Williamson > Reviewed-by: Jason Gunthorpe > Reviewed-by: Ira Weiny > Suggested-by: Jason Gunthorpe > Cc: Dan Williams > Cc: Jerome Glisse > Signed-off-by: John Hubbard > --- > mm/gup.c | 27 ++- > 1 file changed, 22 insertions(+), 5 deletions(-) > > diff --git a/mm/gup.c b/mm/gup.c > index 3ecce297a47f..c0c56888e7cc 100644 > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -29,6 +29,13 @@ struct follow_page_context { > unsigned int page_mask; > }; > > +static __always_inline long __gup_longterm_locked(struct task_struct *tsk, > + struct mm_struct *mm, > + unsigned long start, > + unsigned long nr_pages, > + struct page **pages, > + struct vm_area_struct **vmas, > + unsigned int flags); Any particular reason for the forward declaration? Maybe move get_user_pages_remote() down? > /* > * Return the compound head page with ref appropriately incremented, > * or NULL if that failed. > @@ -1179,13 +1186,23 @@ long get_user_pages_remote(struct task_struct *tsk, > struct mm_struct *mm, > struct vm_area_struct **vmas, int *locked) > { > /* > - * FIXME: Current FOLL_LONGTERM behavior is incompatible with > + * Parts of FOLL_LONGTERM behavior are incompatible with >* FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on > - * vmas. As there are no users of this flag in this call we simply > - * disallow this option for now. > + * vmas. However, this only comes up if locked is set, and there are > + * callers that do request FOLL_LONGTERM, but do not set locked. So, > + * allow what we can. >*/ > - if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM)) > - return -EINVAL; > + if (gup_flags & FOLL_LONGTERM) { > + if (WARN_ON_ONCE(locked)) > + return -EINVAL; > + /* > + * This will check the vmas (even if our vmas arg is NULL) > + * and return -ENOTSUPP if DAX isn't allowed in this case: > + */ > + return __gup_longterm_locked(tsk, mm, start, nr_pages, pages, > + vmas, gup_flags | FOLL_TOUCH | > + FOLL_REMOTE); > + } > > return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, > locked, > -- > 2.24.1 > -- Kirill A. Shutemov ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 2/9] drm/amd/display: Fix compilation issue.
On 18-12-2019 21:12, Harry Wentland wrote: On 2019-12-18 10:13 a.m., Animesh Manna wrote: [Why]: Aligh with DP spec wanted to follow same naming convention. [How]: Changed the macro name of the dpcd address used for getting requested test-pattern. Please roll this into your patch that renames the definition. All patches should compile on their own. Thanks Harry for review, wanted to follow similar commit-description format followed in amd-driver compare to i915 and created a separate patch. Maybe is it good idea to change the patch sequence and make it as first patch. Regards, Animesh Thanks, Harry Cc: Harry Wentland Cc: Alex Deucher Signed-off-by: Animesh Manna --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 42aa889fd0f5..1a6109be2fce 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2491,7 +2491,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) /* get phy test pattern and pattern parameters from DP receiver */ core_link_read_dpcd( link, - DP_TEST_PHY_PATTERN, + DP_PHY_TEST_PATTERN, _test_pattern.raw, sizeof(dpcd_test_pattern)); core_link_read_dpcd( ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v11 04/25] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On Mon, Dec 16, 2019 at 02:25:16PM -0800, John Hubbard wrote: > An upcoming patch changes and complicates the refcounting and > especially the "put page" aspects of it. In order to keep > everything clean, refactor the devmap page release routines: > > * Rename put_devmap_managed_page() to page_is_devmap_managed(), > and limit the functionality to "read only": return a bool, > with no side effects. > > * Add a new routine, put_devmap_managed_page(), to handle checking > what kind of page it is, and what kind of refcount handling it > requires. > > * Rename __put_devmap_managed_page() to free_devmap_managed_page(), > and limit the functionality to unconditionally freeing a devmap > page. What the reason to separate put_devmap_managed_page() from free_devmap_managed_page() if free_devmap_managed_page() has exacly one caller? Is it preparation for the next patches? > This is originally based on a separate patch by Ira Weiny, which > applied to an early version of the put_user_page() experiments. > Since then, Jérôme Glisse suggested the refactoring described above. > > Cc: Christoph Hellwig > Suggested-by: Jérôme Glisse > Reviewed-by: Dan Williams > Reviewed-by: Jan Kara > Signed-off-by: Ira Weiny > Signed-off-by: John Hubbard > --- > include/linux/mm.h | 17 + > mm/memremap.c | 16 ++-- > mm/swap.c | 24 > 3 files changed, 39 insertions(+), 18 deletions(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index c97ea3b694e6..77a4df06c8a7 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -952,9 +952,10 @@ static inline bool is_zone_device_page(const struct page > *page) > #endif > > #ifdef CONFIG_DEV_PAGEMAP_OPS > -void __put_devmap_managed_page(struct page *page); > +void free_devmap_managed_page(struct page *page); > DECLARE_STATIC_KEY_FALSE(devmap_managed_key); > -static inline bool put_devmap_managed_page(struct page *page) > + > +static inline bool page_is_devmap_managed(struct page *page) > { > if (!static_branch_unlikely(_managed_key)) > return false; > @@ -963,7 +964,6 @@ static inline bool put_devmap_managed_page(struct page > *page) > switch (page->pgmap->type) { > case MEMORY_DEVICE_PRIVATE: > case MEMORY_DEVICE_FS_DAX: > - __put_devmap_managed_page(page); > return true; > default: > break; > @@ -971,7 +971,14 @@ static inline bool put_devmap_managed_page(struct page > *page) > return false; > } > > +bool put_devmap_managed_page(struct page *page); > + > #else /* CONFIG_DEV_PAGEMAP_OPS */ > +static inline bool page_is_devmap_managed(struct page *page) > +{ > + return false; > +} > + > static inline bool put_devmap_managed_page(struct page *page) > { > return false; > @@ -1028,8 +1035,10 @@ static inline void put_page(struct page *page) >* need to inform the device driver through callback. See >* include/linux/memremap.h and HMM for details. >*/ > - if (put_devmap_managed_page(page)) > + if (page_is_devmap_managed(page)) { > + put_devmap_managed_page(page); put_devmap_managed_page() has yet another page_is_devmap_managed() check inside. It looks strange. > return; > + } > > if (put_page_testzero(page)) > __put_page(page); > diff --git a/mm/memremap.c b/mm/memremap.c > index e899fa876a62..2ba773859031 100644 > --- a/mm/memremap.c > +++ b/mm/memremap.c > @@ -411,20 +411,8 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn, > EXPORT_SYMBOL_GPL(get_dev_pagemap); > > #ifdef CONFIG_DEV_PAGEMAP_OPS > -void __put_devmap_managed_page(struct page *page) > +void free_devmap_managed_page(struct page *page) > { > - int count = page_ref_dec_return(page); > - > - /* still busy */ > - if (count > 1) > - return; > - > - /* only triggered by the dev_pagemap shutdown path */ > - if (count == 0) { > - __put_page(page); > - return; > - } > - > /* notify page idle for dax */ > if (!is_device_private_page(page)) { > wake_up_var(>_refcount); > @@ -461,5 +449,5 @@ void __put_devmap_managed_page(struct page *page) > page->mapping = NULL; > page->pgmap->ops->page_free(page); > } > -EXPORT_SYMBOL(__put_devmap_managed_page); > +EXPORT_SYMBOL(free_devmap_managed_page); > #endif /* CONFIG_DEV_PAGEMAP_OPS */ > diff --git a/mm/swap.c b/mm/swap.c > index 5341ae93861f..49f7c2eea0ba 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -1102,3 +1102,27 @@ void __init swap_setup(void) >* _really_ don't want to cluster much more >*/ > } > + > +#ifdef CONFIG_DEV_PAGEMAP_OPS > +bool put_devmap_managed_page(struct page *page) > +{ > + bool is_devmap = page_is_devmap_managed(page); > + > + if (is_devmap) { Reversing the condition would save you an indentation level. > + int count =
Re: [PATCH v11 01/25] mm/gup: factor out duplicate code from four routines
On Mon, Dec 16, 2019 at 02:25:13PM -0800, John Hubbard wrote: > +static void put_compound_head(struct page *page, int refs) > +{ > + /* Do a get_page() first, in case refs == page->_refcount */ > + get_page(page); > + page_ref_sub(page, refs); > + put_page(page); > +} It's not terribly efficient. Maybe something like: VM_BUG_ON_PAGE(page_ref_count(page) < ref, page); if (refs > 2) page_ref_sub(page, refs - 1); put_page(page); ? -- Kirill A. Shutemov ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 02/10] drm/bridge: dw-hdmi: add max bpc connector property
Hi Neil and Jonas, Thank you for the patch. On Wed, Dec 18, 2019 at 04:46:29PM +0100, Neil Armstrong wrote: > From: Jonas Karlman > > Add the max_bpc property to the dw-hdmi connector to prepare support > for 10, 12 & 16bit output support. > > Signed-off-by: Jonas Karlman > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index 6a0b4b3a6739..e7a0600f8cc5 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -2368,6 +2368,10 @@ static int dw_hdmi_bridge_attach(struct drm_bridge > *bridge) > DRM_MODE_CONNECTOR_HDMIA, > hdmi->ddc); > > + drm_atomic_helper_connector_reset(connector); > + > + drm_connector_attach_max_bpc_property(connector, 8, 16); > + I'm not asking you to rework this, but have you given any thought on how we would be able to support this feature in a model where the bridge wouldn't create a connector anymore (as done in the latest version of the omapdrm series) ? > if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) > drm_object_attach_property(>base, > > connector->dev->mode_config.hdr_output_metadata_property, 0); -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 06/10] drm/meson: meson_dw_hdmi: add bridge and switch to drm_bridge_funcs
Switch the dw-hdmi driver to drm_bridge_funcs by implementing a new local bridge, connecting it to the dw-hdmi bridge, then implement the atomic_get_input_bus_fmts/atomic_get_output_bus_fmts. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 98 ++- 1 file changed, 80 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 3bb7ffe5fc39..8729575777d5 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -135,6 +136,7 @@ struct meson_dw_hdmi_data { struct meson_dw_hdmi { struct drm_encoder encoder; + struct drm_bridge bridge; struct dw_hdmi_plat_data dw_plat_data; struct meson_drm *priv; struct device *dev; @@ -151,6 +153,8 @@ struct meson_dw_hdmi { }; #define encoder_to_meson_dw_hdmi(x) \ container_of(x, struct meson_dw_hdmi, encoder) +#define bridge_to_meson_dw_hdmi(x) \ + container_of(x, struct meson_dw_hdmi, bridge) static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, const char *compat) @@ -368,7 +372,7 @@ static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) } static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, -struct drm_display_mode *mode) +const struct drm_display_mode *mode) { struct meson_drm *priv = dw_hdmi->priv; int vic = drm_match_cea_mode(mode); @@ -663,6 +667,10 @@ dw_hdmi_mode_valid(struct drm_connector *connector, /* Encoder */ +static const u32 meson_dw_hdmi_out_bus_fmts[] = { + MEDIA_BUS_FMT_YUV8_1X24, +}; + static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); @@ -672,16 +680,63 @@ static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = { .destroy= meson_venc_hdmi_encoder_destroy, }; -static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder, +static u32 * +meson_venc_hdmi_encoder_get_out_bus_fmts(struct drm_bridge *bridge, +struct drm_bridge_state *bridge_state, +struct drm_crtc_state *crtc_state, +struct drm_connector_state *conn_state, +unsigned int *num_output_fmts) +{ + u32 *output_fmts; + + *num_output_fmts = ARRAY_SIZE(meson_dw_hdmi_out_bus_fmts); + output_fmts = kcalloc(*num_output_fmts, sizeof(*output_fmts), + GFP_KERNEL); + if (!output_fmts) + return NULL; + + memcpy(output_fmts, meson_dw_hdmi_out_bus_fmts, *num_output_fmts); + + return output_fmts; +} + +static u32 * +meson_venc_hdmi_encoder_get_inp_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts = NULL; + + if (output_fmt == meson_dw_hdmi_out_bus_fmts[0]) { + *num_input_fmts = 1; + input_fmts = kcalloc(*num_input_fmts, +sizeof(*input_fmts), +GFP_KERNEL); + if (!input_fmts) + return NULL; + + input_fmts[0] = output_fmt; + } else { + *num_input_fmts = 0; + } + + return input_fmts; +} + +static int meson_venc_hdmi_encoder_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { return 0; } -static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder) +static void meson_venc_hdmi_encoder_disable(struct drm_bridge *bridge) { - struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); + struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); struct meson_drm *priv = dw_hdmi->priv; DRM_DEBUG_DRIVER("\n"); @@ -693,9 +748,9 @@ static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder) writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); } -static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder) +static void meson_venc_hdmi_encoder_enable(struct drm_bridge *bridge) { - struct meson_dw_hdmi *dw_hdmi =
[PATCH v3 10/10] drm/meson: Add YUV420 output support
This patch adds support for the YUV420 output from the Amlogic Meson SoCs Video Processing Unit to the HDMI Controller. The YUV420 is obtained by generating a YUV444 pixel stream like the classic HDMI display modes, but then the Video Encoder output can be configured to down-sample the YUV444 pixel stream to a YUV420 stream. In addition if pixel stream down-sampling, the Y Cb Cr components must also be mapped differently to align with the HDMI2.0 specifications. This mode needs a different clock generation scheme since the TMDS PHY clock must match the 10x ration with the YUV420 pixel clock, but the video encoder must run at 2x the pixel clock. This patch enables the bridge bus format negotiation, and handles the YUV420 case if selected by the negotiation. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 91 --- 1 file changed, 70 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index ce27dfde509e..90ec4553ed51 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -150,6 +150,7 @@ struct meson_dw_hdmi { struct regulator *hdmi_supply; u32 irq_stat; struct dw_hdmi *hdmi; + unsigned long output_bus_fmt; }; #define encoder_to_meson_dw_hdmi(x) \ container_of(x, struct meson_dw_hdmi, encoder) @@ -301,6 +302,10 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, struct meson_drm *priv = dw_hdmi->priv; unsigned int pixel_clock = mode->clock; + /* For 420, pixel clock is half unlike venc clock */ + if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + pixel_clock /= 2; + if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { if (pixel_clock >= 371250) { @@ -383,6 +388,10 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, vclk_freq = mode->clock; + /* For 420, pixel clock is half unlike venc clock */ + if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + vclk_freq /= 2; + /* TMDS clock is pixel_clock * 10 */ phy_freq = vclk_freq * 10; @@ -392,13 +401,16 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, return; } + /* 480i/576i needs global pixel doubling */ if (mode->flags & DRM_MODE_FLAG_DBLCLK) vclk_freq *= 2; venc_freq = vclk_freq; hdmi_freq = vclk_freq; - if (meson_venc_hdmi_venc_repeat(vic)) + /* VENC double pixels for 1080i, 720p and YUV420 modes */ + if (meson_venc_hdmi_venc_repeat(vic) || + dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) venc_freq *= 2; vclk_freq = max(venc_freq, hdmi_freq); @@ -445,8 +457,9 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, /* Enable normal output to PHY */ dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); - /* TMDS pattern setup (TOFIX Handle the YUV420 case) */ - if (mode->clock > 34) { + /* TMDS pattern setup */ + if (mode->clock > 34 && + dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_YUV8_1X24) { dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0); dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, @@ -621,6 +634,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode) { struct meson_drm *priv = connector->dev->dev_private; + bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported; unsigned int phy_freq; unsigned int vclk_freq; unsigned int venc_freq; @@ -630,9 +644,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector, DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); - /* If sink max TMDS clock, we reject the mode */ + /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */ if (connector->display_info.max_tmds_clock && - mode->clock > connector->display_info.max_tmds_clock) + mode->clock > connector->display_info.max_tmds_clock && + !drm_mode_is_420_only(>display_info, mode) && + !drm_mode_is_420_also(>display_info, mode)) return MODE_BAD; /* Check against non-VIC supported modes */ @@ -648,6 +664,12 @@ dw_hdmi_mode_valid(struct drm_connector *connector, vclk_freq = mode->clock; + /* For 420, pixel clock is half unlike venc clock */ + if (drm_mode_is_420_only(>display_info, mode) || + (!is_hdmi2_sink && +drm_mode_is_420_also(>display_info, mode))) + vclk_freq /= 2; + /* TMDS
[PATCH v3 02/10] drm/bridge: dw-hdmi: add max bpc connector property
From: Jonas Karlman Add the max_bpc property to the dw-hdmi connector to prepare support for 10, 12 & 16bit output support. Signed-off-by: Jonas Karlman Signed-off-by: Neil Armstrong --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 6a0b4b3a6739..e7a0600f8cc5 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2368,6 +2368,10 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) DRM_MODE_CONNECTOR_HDMIA, hdmi->ddc); + drm_atomic_helper_connector_reset(connector); + + drm_connector_attach_max_bpc_property(connector, 8, 16); + if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) drm_object_attach_property(>base, connector->dev->mode_config.hdr_output_metadata_property, 0); -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 03/10] drm/bridge: synopsys: dw-hdmi: add bus format negociation
Add the atomic_get_output_bus_fmts, atomic_get_input_bus_fmts to negociate the possible output and input formats for the current mode and monitor, and use the negotiated formats in a basic atomic_check callback. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 272 +- 1 file changed, 268 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index e7a0600f8cc5..8c1f7e5e6698 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2069,11 +2069,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; - /* TOFIX: Get input format from plat data or fallback to RGB888 */ if (hdmi->plat_data->input_bus_format) hdmi->hdmi_data.enc_in_bus_format = hdmi->plat_data->input_bus_format; - else + else if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED) hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24; /* TOFIX: Get input encoding from plat data or fallback to none */ @@ -2083,8 +2082,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) else hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT; - /* TOFIX: Default to RGB888 output format */ - hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; + if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED) + hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; hdmi->hdmi_data.pix_repet_factor = 0; hdmi->hdmi_data.hdcp_enable = 0; @@ -2350,6 +2349,267 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = .atomic_check = dw_hdmi_connector_atomic_check, }; +/* + * Possible output formats : + * - MEDIA_BUS_FMT_UYYVYY16_0_5X48, + * - MEDIA_BUS_FMT_UYYVYY12_0_5X36, + * - MEDIA_BUS_FMT_UYYVYY10_0_5X30, + * - MEDIA_BUS_FMT_UYYVYY8_0_5X24, + * - MEDIA_BUS_FMT_YUV16_1X48, + * - MEDIA_BUS_FMT_RGB161616_1X48, + * - MEDIA_BUS_FMT_UYVY12_1X24, + * - MEDIA_BUS_FMT_YUV12_1X36, + * - MEDIA_BUS_FMT_RGB121212_1X36, + * - MEDIA_BUS_FMT_UYVY10_1X20, + * - MEDIA_BUS_FMT_YUV10_1X30, + * - MEDIA_BUS_FMT_RGB101010_1X30, + * - MEDIA_BUS_FMT_UYVY8_1X16, + * - MEDIA_BUS_FMT_YUV8_1X24, + * - MEDIA_BUS_FMT_RGB888_1X24, + */ + +/* Can return a maximum of 12 possible output formats for a mode/connector */ +#define MAX_OUTPUT_SEL_FORMATS 12 + +static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + unsigned int *num_output_fmts) +{ + struct drm_connector *conn = conn_state->connector; + struct drm_display_info *info = >display_info; + struct drm_display_mode *mode = _state->mode; + u8 max_bpc = conn_state->max_requested_bpc; + bool is_hdmi2_sink = info->hdmi.scdc.supported || +(info->color_formats & DRM_COLOR_FORMAT_YCRCB420); + u32 *output_fmts; + int i = 0; + + *num_output_fmts = 0; + + output_fmts = kcalloc(MAX_OUTPUT_SEL_FORMATS, sizeof(*output_fmts), + GFP_KERNEL); + if (!output_fmts) + return NULL; + + /* +* If the current mode enforces 4:2:0, force the output but format +* to 4:2:0 and do not add the YUV422/444/RGB formats +*/ + if (conn->ycbcr_420_allowed && + (drm_mode_is_420_only(info, mode) || +(is_hdmi2_sink && drm_mode_is_420_also(info, mode { + + /* Order bus formats from 16bit to 8bit if supported */ + if (max_bpc >= 16 && info->bpc == 16 && + (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY16_0_5X48; + + if (max_bpc >= 12 && info->bpc >= 12 && + (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY12_0_5X36; + + if (max_bpc >= 10 && info->bpc >= 10 && + (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; + + /* Default 8bit fallback */ + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; + + *num_output_fmts = i; + + return output_fmts; + } + + /* +* Order bus formats from 16bit to 8bit and from YUV422 to
[PATCH v3 08/10] drm/meson: venc: add support for YUV420 setup
This patch adds encoding support for the YUV420 output from the Amlogic Meson SoCs Video Processing Unit to the HDMI Controller. The YUV420 is obtained by generating a YUV444 pixel stream like the classic HDMI display modes, but then the Video Encoder output can be configured to down-sample the YUV444 pixel stream to a YUV420 stream. In addition if pixel stream down-sampling, the Y Cb Cr components must also be mapped differently to align with the HDMI2.0 specifications. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 3 ++- drivers/gpu/drm/meson/meson_venc.c| 8 +--- drivers/gpu/drm/meson/meson_venc.h| 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 69926d5d8756..75c133a048d3 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -772,7 +772,8 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_bridge *bridge, DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); /* VENC + VENC-DVI Mode setup */ - meson_venc_hdmi_mode_set(priv, vic, mode); + meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, false, +VPU_HDMI_OUTPUT_CBYCR); /* VCLK Set clock */ dw_hdmi_set_vclk(dw_hdmi, mode); diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c index a9ab78970bfe..f93c725b6f02 100644 --- a/drivers/gpu/drm/meson/meson_venc.c +++ b/drivers/gpu/drm/meson/meson_venc.c @@ -946,6 +946,8 @@ bool meson_venc_hdmi_venc_repeat(int vic) EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat); void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, + unsigned int ycrcb_map, + bool yuv420_mode, const struct drm_display_mode *mode) { union meson_hdmi_venc_mode *vmode = NULL; @@ -1528,14 +1530,14 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, if (mode->flags & DRM_MODE_FLAG_PVSYNC) reg |= VPU_HDMI_INV_VSYNC; - /* Output data format: CbYCr */ - reg |= VPU_HDMI_OUTPUT_CBYCR; + /* Output data format */ + reg |= ycrcb_map; /* * Write rate to the async FIFO between VENC and HDMI. * One write every 2 wr_clk. */ - if (venc_repeat) + if (venc_repeat || yuv420_mode) reg |= VPU_HDMI_WR_RATE(2); /* diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h index 1abdcbdf51c0..9138255ffc9e 100644 --- a/drivers/gpu/drm/meson/meson_venc.h +++ b/drivers/gpu/drm/meson/meson_venc.h @@ -60,6 +60,8 @@ extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc; void meson_venci_cvbs_mode_set(struct meson_drm *priv, struct meson_cvbs_enci_mode *mode); void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, + unsigned int ycrcb_map, + bool yuv420_mode, const struct drm_display_mode *mode); unsigned int meson_venci_get_field(struct meson_drm *priv); -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 07/10] drm/meson: dw-hdmi: stop enforcing input_bus_format
To allow using formats from negotiation, stop enforcing input_bus_format in the private dw-plat-data struct. Signed-off-by: Neil Armstrong Reviewed-by: Boris Brezillon --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 8729575777d5..69926d5d8756 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -1032,7 +1032,6 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, dw_plat_data->phy_ops = _dw_hdmi_phy_ops; dw_plat_data->phy_name = "meson_dw_hdmi_phy"; dw_plat_data->phy_data = meson_dw_hdmi; - dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 05/10] drm/meson: venc: make drm_display_mode const
Before switching to bridge funcs, make sure drm_display_mode is passed as const to the venc functions. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/meson_venc.c | 2 +- drivers/gpu/drm/meson/meson_venc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c index 4efd7864d5bf..a9ab78970bfe 100644 --- a/drivers/gpu/drm/meson/meson_venc.c +++ b/drivers/gpu/drm/meson/meson_venc.c @@ -946,7 +946,7 @@ bool meson_venc_hdmi_venc_repeat(int vic) EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat); void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { union meson_hdmi_venc_mode *vmode = NULL; union meson_hdmi_venc_mode vmode_dmt; diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h index 576768bdd08d..1abdcbdf51c0 100644 --- a/drivers/gpu/drm/meson/meson_venc.h +++ b/drivers/gpu/drm/meson/meson_venc.h @@ -60,7 +60,7 @@ extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc; void meson_venci_cvbs_mode_set(struct meson_drm *priv, struct meson_cvbs_enci_mode *mode); void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, - struct drm_display_mode *mode); + const struct drm_display_mode *mode); unsigned int meson_venci_get_field(struct meson_drm *priv); void meson_venc_enable_vsync(struct meson_drm *priv); -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 09/10] drm/meson: vclk: add support for YUV420 setup
This patch adds clocking support for the YUV420 output from the Amlogic Meson SoCs Video Processing Unit to the HDMI Controller. The YUV420 is obtained by generating a YUV444 pixel stream like the classic HDMI display modes, but then the Video Encoder output can be configured to down-sample the YUV444 pixel stream to a YUV420 stream. This mode needs a different clock generation scheme since the TMDS PHY clock must match the 10x ratio with the YUV420 pixel clock, but the video encoder must run at 2x the pixel clock. This patch adds the TMDS PHY clock value in all the video clock setup in order to better support these specific uses cases and switch to the Common Clock framework for clocks handling in the future. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 24 --- drivers/gpu/drm/meson/meson_vclk.c | 93 +++-- drivers/gpu/drm/meson/meson_vclk.h | 7 +- drivers/gpu/drm/meson/meson_venc_cvbs.c | 3 +- 4 files changed, 93 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 75c133a048d3..ce27dfde509e 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -376,15 +376,19 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, { struct meson_drm *priv = dw_hdmi->priv; int vic = drm_match_cea_mode(mode); + unsigned int phy_freq; unsigned int vclk_freq; unsigned int venc_freq; unsigned int hdmi_freq; vclk_freq = mode->clock; + /* TMDS clock is pixel_clock * 10 */ + phy_freq = vclk_freq * 10; + if (!vic) { - meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq, -vclk_freq, vclk_freq, false); + meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq, +vclk_freq, vclk_freq, vclk_freq, false); return; } @@ -402,11 +406,11 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2; - DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n", - vclk_freq, venc_freq, hdmi_freq, + DRM_DEBUG_DRIVER("vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", + phy_freq, vclk_freq, venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); - meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq, + meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq, venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); } @@ -617,6 +621,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode) { struct meson_drm *priv = connector->dev->dev_private; + unsigned int phy_freq; unsigned int vclk_freq; unsigned int venc_freq; unsigned int hdmi_freq; @@ -643,6 +648,9 @@ dw_hdmi_mode_valid(struct drm_connector *connector, vclk_freq = mode->clock; + /* TMDS clock is pixel_clock * 10 */ + phy_freq = vclk_freq * 10; + /* 480i/576i needs global pixel doubling */ if (mode->flags & DRM_MODE_FLAG_DBLCLK) vclk_freq *= 2; @@ -659,10 +667,10 @@ dw_hdmi_mode_valid(struct drm_connector *connector, if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2; - dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, - vclk_freq, venc_freq, hdmi_freq); + dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", + __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); - return meson_vclk_vic_supported_freq(vclk_freq); + return meson_vclk_vic_supported_freq(phy_freq, vclk_freq); } /* Encoder */ diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index f690793ae2d5..fdf26dac9fa8 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -354,12 +354,17 @@ enum { /* 2970 /1 /1 /1 /5 /2 => /1 /1 */ MESON_VCLK_HDMI_297000, /* 5940 /1 /1 /2 /5 /1 => /1 /1 */ - MESON_VCLK_HDMI_594000 + MESON_VCLK_HDMI_594000, +/* 2970 /1 /1 /1 /5 /1 => /1 /2 */ + MESON_VCLK_HDMI_594000_YUV420, }; struct meson_vclk_params { + unsigned int pll_freq; + unsigned int phy_freq; + unsigned int vclk_freq; + unsigned int venc_freq; unsigned int pixel_freq; - unsigned int pll_base_freq; unsigned int pll_od1; unsigned int pll_od2; unsigned int pll_od3; @@ -367,8 +372,11 @@ struct meson_vclk_params { unsigned int vclk_div; } params[] = { [MESON_VCLK_HDMI_ENCI_54000] = { + .pll_freq = 432, + .phy_freq = 27, + .vclk_freq = 54000, + .venc_freq = 54000,
[PATCH v3 01/10] drm/bridge: dw-hdmi: set mtmdsclock for deep color
From: Jonas Karlman Configure the correct mtmdsclock for deep colors to prepare support for 10, 12 & 16bit output. Signed-off-by: Jonas Karlman Signed-off-by: Neil Armstrong --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index dbe38a54870b..6a0b4b3a6739 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1792,9 +1792,26 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); + if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { + switch (hdmi_bus_fmt_color_depth( + hdmi->hdmi_data.enc_out_bus_format)) { + case 16: + vmode->mtmdsclock = (u64)vmode->mpixelclock * 2; + break; + case 12: + vmode->mtmdsclock = (u64)vmode->mpixelclock * 3 / 2; + break; + case 10: + vmode->mtmdsclock = (u64)vmode->mpixelclock * 5 / 4; + break; + } + } + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) vmode->mtmdsclock /= 2; + dev_dbg(hdmi->dev, "final tmdsclk = %d\n", vmode->mtmdsclock); + /* Set up HDMI_FC_INVIDCONF */ inv_val = (hdmi->hdmi_data.hdcp_enable || (dw_hdmi_support_scdc(hdmi) && -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 04/10] drm/bridge: synopsys: dw-hdmi: allow ycbcr420 modes for >= 0x200a
Now the DW-HDMI Controller supports the HDMI2.0 modes, enable support for these modes in the connector if the platform supports them. We limit these modes to DW-HDMI IP version >= 0x200a which are designed to support HDMI2.0 display modes. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 6 ++ include/drm/bridge/dw_hdmi.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 8c1f7e5e6698..bb87b87c752e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -3189,6 +3189,12 @@ __dw_hdmi_probe(struct platform_device *pdev, hdmi->bridge.of_node = pdev->dev.of_node; #endif + if (hdmi->version >= 0x200a) + hdmi->connector.ycbcr_420_allowed = + hdmi->plat_data->ycbcr_420_allowed; + else + hdmi->connector.ycbcr_420_allowed = false; + memset(, 0, sizeof(pdevinfo)); pdevinfo.parent = dev; pdevinfo.id = PLATFORM_DEVID_AUTO; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index fbf3812c4326..19e30cdd35bf 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -127,6 +127,7 @@ struct dw_hdmi_plat_data { unsigned long input_bus_format; unsigned long input_bus_encoding; bool use_drm_infoframe; + bool ycbcr_420_allowed; /* Vendor PHY support */ const struct dw_hdmi_phy_ops *phy_ops; -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 00/10] drm/bridge: dw-hdmi: implement bus-format negotiation and YUV420 support
This patchset is based on Boris's v4 "drm: Add support for bus-format negotiation" at [1] patchset to implement full bus-format negotiation for DW-HDMI, including YUV420 support and 10/12/16bit YUV444, YUV422 and RGB. The Color Space Converter support is already implemented. And the counterpart implementation in the Amlogic Meson VPU dw-hdmi glue : - basic bus-format negotiation to select YUV444 bus-format as DW-HDMI input - YUV420 support when HDMI2.0 YUV420 modeset This is a follow-up from the previous attempts : - "drm/meson: Add support for HDMI2.0 YUV420 4k60" at [2] - "drm/meson: Add support for HDMI2.0 4k60" at [3] Changes since RFC v2 at [5]: - Added fixes from Jonas, who tested and integrated it for Rockchip SoCs - Added support for 10/12/16bit tmds clock calculation - Added support for max_bcp connector property - Adapted to Boris's v4 patchset - Fixed typos reported by boris Changes since RFC v1 at [4]: - Rewrote negociation using the v2 patchset, including full DW-HDMI fmt negociation [1] https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-1-boris.brezil...@collabora.com [2] https://patchwork.freedesktop.org/patch/msgid/20190520133753.23871-1-narmstr...@baylibre.com [3] https://patchwork.freedesktop.org/patch/msgid/1549022873-40549-1-git-send-email-narmstr...@baylibre.com [4] https://patchwork.freedesktop.org/patch/msgid/20190820084109.24616-1-narmstr...@baylibre.com [5] https://patchwork.freedesktop.org/patch/msgid/ 20190827081425.15011-1-narmstr...@baylibre.com Jonas Karlman (2): drm/bridge: dw-hdmi: set mtmdsclock for deep color drm/bridge: dw-hdmi: add max bpc connector property Neil Armstrong (8): drm/bridge: synopsys: dw-hdmi: add bus format negociation drm/bridge: synopsys: dw-hdmi: allow ycbcr420 modes for >= 0x200a drm/meson: venc: make drm_display_mode const drm/meson: meson_dw_hdmi: add bridge and switch to drm_bridge_funcs drm/meson: dw-hdmi: stop enforcing input_bus_format drm/meson: venc: add support for YUV420 setup drm/meson: vclk: add support for YUV420 setup drm/meson: Add YUV420 output support drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 299 +- drivers/gpu/drm/meson/meson_dw_hdmi.c | 193 +++--- drivers/gpu/drm/meson/meson_vclk.c| 93 +-- drivers/gpu/drm/meson/meson_vclk.h| 7 +- drivers/gpu/drm/meson/meson_venc.c| 10 +- drivers/gpu/drm/meson/meson_venc.h| 4 +- drivers/gpu/drm/meson/meson_venc_cvbs.c | 3 +- include/drm/bridge/dw_hdmi.h | 1 + 8 files changed, 538 insertions(+), 72 deletions(-) -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 2/9] drm/amd/display: Fix compilation issue.
On 2019-12-18 10:13 a.m., Animesh Manna wrote: > [Why]: > Aligh with DP spec wanted to follow same naming convention. > > [How]: > Changed the macro name of the dpcd address used for getting requested > test-pattern. > Please roll this into your patch that renames the definition. All patches should compile on their own. Thanks, Harry > Cc: Harry Wentland > Cc: Alex Deucher > Signed-off-by: Animesh Manna > --- > drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > index 42aa889fd0f5..1a6109be2fce 100644 > --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > @@ -2491,7 +2491,7 @@ static void dp_test_send_phy_test_pattern(struct > dc_link *link) > /* get phy test pattern and pattern parameters from DP receiver */ > core_link_read_dpcd( > link, > - DP_TEST_PHY_PATTERN, > + DP_PHY_TEST_PATTERN, > _test_pattern.raw, > sizeof(dpcd_test_pattern)); > core_link_read_dpcd( > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 00/50] drm/omap: Replace custom display drivers with drm_bridge and drm_panel
On 18/12/2019 16:46, Laurent Pinchart wrote: Hi Tomi, On Wed, Dec 18, 2019 at 09:07:52AM +0200, Tomi Valkeinen wrote: On 18/12/2019 04:03, Laurent Pinchart wrote: Hopefully we can soon have this series landed so we can start working on top of the new bridge/connector handling. I assume it will be applied direct to drm-misc-next, so we do not have to wait extra time to get it. Tomi, how would you like to proceed ? The core patches are ready in my opinion. I can post a v4 without the omapdrm patches, which could be merged to drm-misc already while you finish reviewing patches 30/50 onwards. This sounds good to me. I have tested your branch on AM5 EMV, AM4 EVM and Panda, without any issues. But that's with the omapdrm patches, and things will be slightly different without them. You add TPD12S015 and OPA362 driver in the earlier part. Should those be moved to the omapdrm side? In theory there won't be any issues, but having multiple drivers for the same device can create conflicts. Indeed, although if they're not selected it shouldn't be a problem. On the other hand you've reviewed the omapdrm patches up to "drm/omap: Switch the HDMI and VENC outputs to drm_bridge" which removes the old drivers, the rest being just cleanups. We could thus merge up to that patch in one go. What's your preference ? I'll finish the reviews tomorrow, the rest of the patches look like quick to review. Tomi -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 3/9] drm/i915/dp: Move vswing/pre-emphasis adjustment calculation
vswing/pre-emphasis adjustment calculation is needed in processing of auto phy compliance request other than link training, so moved the same function in intel_dp.c. No functional change. Signed-off-by: Animesh Manna --- drivers/gpu/drm/i915/display/intel_dp.c | 32 +++ drivers/gpu/drm/i915/display/intel_dp.h | 3 ++ .../drm/i915/display/intel_dp_link_training.c | 32 --- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2f31d226c6eb..ca82835b6dcf 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4110,6 +4110,38 @@ ivb_cpu_edp_signal_levels(u8 train_set) } } +void +intel_get_adjust_train(struct intel_dp *intel_dp, + const u8 *link_status) +{ + u8 v = 0; + u8 p = 0; + int lane; + u8 voltage_max; + u8 preemph_max; + + for (lane = 0; lane < intel_dp->lane_count; lane++) { + u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane); + u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane); + + if (this_v > v) + v = this_v; + if (this_p > p) + p = this_p; + } + + voltage_max = intel_dp_voltage_max(intel_dp); + if (v >= voltage_max) + v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; + + preemph_max = intel_dp_pre_emphasis_max(intel_dp, v); + if (p >= preemph_max) + p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; + + for (lane = 0; lane < 4; lane++) + intel_dp->train_set[lane] = v | p; +} + void intel_dp_set_signal_levels(struct intel_dp *intel_dp) { diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 3da166054788..0d0cb692f701 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -91,6 +91,9 @@ void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, u8 dp_train_pat); void +intel_get_adjust_train(struct intel_dp *intel_dp, + const u8 *link_status); +void intel_dp_set_signal_levels(struct intel_dp *intel_dp); void intel_dp_set_idle_link_train(struct intel_dp *intel_dp); u8 diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 2a1130dd1ad0..1e38584e7d56 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -34,38 +34,6 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE]) link_status[3], link_status[4], link_status[5]); } -static void -intel_get_adjust_train(struct intel_dp *intel_dp, - const u8 link_status[DP_LINK_STATUS_SIZE]) -{ - u8 v = 0; - u8 p = 0; - int lane; - u8 voltage_max; - u8 preemph_max; - - for (lane = 0; lane < intel_dp->lane_count; lane++) { - u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane); - u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane); - - if (this_v > v) - v = this_v; - if (this_p > p) - p = this_p; - } - - voltage_max = intel_dp_voltage_max(intel_dp); - if (v >= voltage_max) - v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; - - preemph_max = intel_dp_pre_emphasis_max(intel_dp, v); - if (p >= preemph_max) - p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; - - for (lane = 0; lane < 4; lane++) - intel_dp->train_set[lane] = v | p; -} - static bool intel_dp_set_link_train(struct intel_dp *intel_dp, u8 dp_train_pat) -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 6/9] drm/i915/dp: Add debugfs entry for DP phy compliance.
These debugfs entry will help testapp to understand the test request during dp phy compliance mode. Acked-by: Manasi Navare Signed-off-by: Animesh Manna --- drivers/gpu/drm/i915/i915_debugfs.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d28468eaed57..715a6c26d0c9 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3173,6 +3173,16 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data) intel_dp->compliance.test_data.vdisplay); seq_printf(m, "bpc: %u\n", intel_dp->compliance.test_data.bpc); + } else if (intel_dp->compliance.test_type == + DP_TEST_LINK_PHY_TEST_PATTERN) { + seq_printf(m, "pattern: %d\n", + intel_dp->compliance.test_data.phytest.phy_pattern); + seq_printf(m, "Number of lanes: %d\n", + intel_dp->compliance.test_data.phytest.num_lanes); + seq_printf(m, "Link Rate: %d\n", + intel_dp->compliance.test_data.phytest.link_rate); + seq_printf(m, "level: %02x\n", + intel_dp->train_set[0]); } } else seq_puts(m, "0"); @@ -3205,7 +3215,7 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data) if (encoder && connector->status == connector_status_connected) { intel_dp = enc_to_intel_dp(>base); - seq_printf(m, "%02lx", intel_dp->compliance.test_type); + seq_printf(m, "%02lx\n", intel_dp->compliance.test_type); } else seq_puts(m, "0"); } -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 5/9] drm/i915/dsb: Send uevent to testapp.
Send uevent to testapp and set test_active flag. To align with link compliance design existing intel_dp_compliance tool will be used to get the phy request in userspace through uevent. Signed-off-by: Animesh Manna --- drivers/gpu/drm/i915/display/intel_dp.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a871834b90d9..81eeb9bbb050 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5011,6 +5011,9 @@ static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) if (test_result != DP_TEST_ACK) DRM_ERROR("Phy test preparation failed\n"); + /* Set test active flag here so userspace doesn't interrupt things */ + intel_dp->compliance.test_active = 1; + return test_result; } @@ -5336,8 +5339,11 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_psr_short_pulse(intel_dp); - if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { - DRM_DEBUG_KMS("Link Training Compliance Test requested\n"); + if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING || + intel_dp->compliance.test_type == + DP_TEST_LINK_PHY_TEST_PATTERN) { + DRM_DEBUG_KMS("Compliance Test requested, test-type = 0x%lx\n", + intel_dp->compliance.test_type); /* Send a Hotplug Uevent to userspace to start modeset */ drm_kms_helper_hotplug_event(_priv->drm); } -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 7/9] drm/i915/dp: Register definition for DP compliance register
DP_COMP_CTL and DP_COMP_PAT register used to program DP compliance pattern. Reviewed-by: Manasi Navare Signed-off-by: Animesh Manna --- drivers/gpu/drm/i915/i915_reg.h | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cbb4689af432..fc54143bd4a4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9788,6 +9788,26 @@ enum skl_power_gate { #define DDI_BUF_BALANCE_LEG_ENABLE(1 << 31) #define DDI_BUF_TRANS_HI(port, i) _MMIO(_PORT(port, _DDI_BUF_TRANS_A, _DDI_BUF_TRANS_B) + (i) * 8 + 4) +/* DDI DP Compliance Control */ +#define DDI_DP_COMP_CTL_A 0x605F0 +#define DDI_DP_COMP_CTL_B 0x615F0 +#define DDI_DP_COMP_CTL(port) _MMIO_PORT(port, DDI_DP_COMP_CTL_A, \ +DDI_DP_COMP_CTL_B) +#define DDI_DP_COMP_CTL_ENABLE(1 << 31) +#define DDI_DP_COMP_CTL_D10_2 (0 << 28) +#define DDI_DP_COMP_CTL_SCRAMBLED_0 (1 << 28) +#define DDI_DP_COMP_CTL_PRBS7 (2 << 28) +#define DDI_DP_COMP_CTL_CUSTOM80 (3 << 28) +#define DDI_DP_COMP_CTL_HBR2 (4 << 28) +#define DDI_DP_COMP_CTL_SCRAMBLED_1 (5 << 28) +#define DDI_DP_COMP_CTL_HBR2_RESET(0xFC << 0) + +/* DDI DP Compliance Pattern */ +#define DDI_DP_COMP_PAT_A 0x605F4 +#define DDI_DP_COMP_PAT_B 0x615F4 +#define DDI_DP_COMP_PAT(port, i) _MMIO(_PORT(port, DDI_DP_COMP_PAT_A, \ +DDI_DP_COMP_PAT_B) + (i) * 4) + /* Sideband Interface (SBI) is programmed indirectly, via * SBI_ADDR, which contains the register offset; and SBI_DATA, * which contains the payload */ -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 8/9] drm/i915/dp: Update the pattern as per request
As per request from DP phy compliance test few special test pattern need to set by source. Added function to set pattern in DP_COMP_CTL register. It will be called along with other test parameters like vswing, pre-emphasis programming in atomic_commit_tail path. Signed-off-by: Animesh Manna --- drivers/gpu/drm/i915/display/intel_dp.c | 55 + 1 file changed, 55 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 81eeb9bbb050..f38929db1f2e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5003,6 +5003,61 @@ static u8 intel_dp_prepare_phytest(struct intel_dp *intel_dp) return DP_TEST_ACK; } +static inline void intel_dp_phy_pattern_update(struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = + to_i915(dp_to_dig_port(intel_dp)->base.base.dev); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_dp_phy_test_params *data = + _dp->compliance.test_data.phytest; + u32 temp; + + switch (data->phy_pattern) { + case DP_PHY_TEST_PATTERN_NONE: + DRM_DEBUG_KMS("Disable Phy Test Pattern\n"); + I915_WRITE(DDI_DP_COMP_CTL(intel_dig_port->base.port), 0x0); + break; + case DP_PHY_TEST_PATTERN_D10_2: + DRM_DEBUG_KMS("Set D10.2 Phy Test Pattern\n"); + I915_WRITE(DDI_DP_COMP_CTL(intel_dig_port->base.port), + DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); + break; + case DP_PHY_TEST_PATTERN_ERROR_COUNT: + DRM_DEBUG_KMS("Set Error Count Phy Test Pattern\n"); + I915_WRITE(DDI_DP_COMP_CTL(intel_dig_port->base.port), + DDI_DP_COMP_CTL_ENABLE | + DDI_DP_COMP_CTL_SCRAMBLED_0); + break; + case DP_PHY_TEST_PATTERN_PRBS7: + DRM_DEBUG_KMS("Set PRBS7 Phy Test Pattern\n"); + I915_WRITE(DDI_DP_COMP_CTL(intel_dig_port->base.port), + DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); + break; + case DP_PHY_TEST_PATTERN_80BIT_CUSTOM: + DRM_DEBUG_KMS("Set 80Bit Custom Phy Test Pattern\n"); + temp = ((data->custom80[0] << 24) | (data->custom80[1] << 16) | + (data->custom80[2] << 8) | (data->custom80[3])); + I915_WRITE(DDI_DP_COMP_PAT(intel_dig_port->base.port, 0), temp); + temp = ((data->custom80[4] << 24) | (data->custom80[5] << 16) | + (data->custom80[6] << 8) | (data->custom80[7])); + I915_WRITE(DDI_DP_COMP_PAT(intel_dig_port->base.port, 1), temp); + temp = ((data->custom80[8] << 8) | data->custom80[9]); + I915_WRITE(DDI_DP_COMP_PAT(intel_dig_port->base.port, 2), temp); + I915_WRITE(DDI_DP_COMP_CTL(intel_dig_port->base.port), + DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_CUSTOM80); + break; + case DP_PHY_TEST_PATTERN_CP2520: + DRM_DEBUG_KMS("Set HBR2 compliance Phy Test Pattern\n"); + temp = ((data->hbr2_reset[1] << 8) | data->hbr2_reset[0]); + I915_WRITE(DDI_DP_COMP_CTL(intel_dig_port->base.port), + DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | + temp); + break; + default: + WARN(1, "Invalid Phy Test PAttern\n"); + } +} + static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) { u8 test_result = DP_TEST_NAK; -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 9/9] drm/i915/dp: [FIXME] Program vswing, pre-emphasis, test-pattern
This patch process phy compliance request by programming requested vswing, pre-emphasis and test pattern. Note: FIXME tag added as design discusion is ongoing in previous patch series. Some temporary fix added and the patch is under-development, not for review. Signed-off-by: Animesh Manna --- drivers/gpu/drm/i915/display/intel_display.c | 24 ++- drivers/gpu/drm/i915/display/intel_dp.c | 74 drivers/gpu/drm/i915/display/intel_dp.h | 2 + drivers/gpu/drm/i915/i915_drv.h | 2 + 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e18ee1f17d6e..2d58ed249452 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -14084,6 +14084,9 @@ static int intel_atomic_check(struct drm_device *dev, int ret, i; bool any_ms = false; + if (dev_priv->dp_phy_comp) + return 0; + /* Catch I915_MODE_FLAG_INHERITED */ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { @@ -14692,10 +14695,23 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; + const struct drm_connector_state *conn_state; + struct drm_connector *conn; u64 put_domains[I915_MAX_PIPES] = {}; intel_wakeref_t wakeref = 0; int i; + if(dev_priv->dp_phy_comp) { + for_each_new_connector_in_state(>base, conn, conn_state, i) { + struct intel_encoder *encoder = + to_intel_encoder(conn_state->best_encoder); + struct intel_dp *intel_dp = enc_to_intel_dp(>base); + + intel_dp_process_phy_request(intel_dp); + } + goto dp_phy_comp1; + } + intel_atomic_commit_fence_wait(state); drm_atomic_helper_wait_for_dependencies(>base); @@ -14830,6 +14846,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) if (state->modeset && intel_can_enable_sagv(state)) intel_enable_sagv(dev_priv); +dp_phy_comp1: drm_atomic_helper_commit_hw_done(>base); if (state->modeset) { @@ -14921,6 +14938,7 @@ static int intel_atomic_commit(struct drm_device *dev, state->wakeref = intel_runtime_pm_get(_priv->runtime_pm); drm_atomic_state_get(>base); + if (!dev_priv->dp_phy_comp) { i915_sw_fence_init(>commit_ready, intel_atomic_commit_ready); @@ -14959,11 +14977,13 @@ static int intel_atomic_commit(struct drm_device *dev, intel_runtime_pm_put(_priv->runtime_pm, state->wakeref); return ret; } + } ret = drm_atomic_helper_setup_commit(>base, nonblock); if (!ret) ret = drm_atomic_helper_swap_state(>base, true); + if (!dev_priv->dp_phy_comp) { if (ret) { i915_sw_fence_commit(>commit_ready); @@ -14974,6 +14994,7 @@ static int intel_atomic_commit(struct drm_device *dev, dev_priv->wm.distrust_bios_wm = false; intel_shared_dpll_swap_state(state); intel_atomic_track_fbs(state); + } if (state->global_state_changed) { assert_global_state_locked(dev_priv); @@ -14990,8 +15011,9 @@ static int intel_atomic_commit(struct drm_device *dev, drm_atomic_state_get(>base); INIT_WORK(>base.commit_work, intel_atomic_commit_work); - + if (!dev_priv->dp_phy_comp) { i915_sw_fence_commit(>commit_ready); + } if (nonblock && state->modeset) { queue_work(dev_priv->modeset_wq, >base.commit_work); } else if (nonblock) { diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f38929db1f2e..4b4fa9074d18 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5058,9 +5058,82 @@ static inline void intel_dp_phy_pattern_update(struct intel_dp *intel_dp) } } +static void +intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + enum port port = intel_dig_port->base.port; + u32 ddi_buf_ctl_value, dp_tp_ctl_value, trans_ddi_func_ctl_value; + + ddi_buf_ctl_value = I915_READ(DDI_BUF_CTL(port)); + dp_tp_ctl_value = I915_READ(TGL_DP_TP_CTL(port)); + trans_ddi_func_ctl_value = I915_READ(TRANS_DDI_FUNC_CTL(port)); + +
[PATCH v2 4/9] drm/i915/dp: Preparation for DP phy compliance auto test
During DP phy compliance auto test mode, sink will request combination of different test pattern with differnt level of vswing, pre-emphasis. Function added to prepare for it. Reviewed-by: Manasi Navare Signed-off-by: Animesh Manna --- .../drm/i915/display/intel_display_types.h| 1 + drivers/gpu/drm/i915/display/intel_dp.c | 24 +++ 2 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 83ea04149b77..c17866f126c9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1205,6 +1205,7 @@ struct intel_dp_compliance_data { u8 video_pattern; u16 hdisplay, vdisplay; u8 bpc; + struct drm_dp_phy_test_params phytest; }; struct intel_dp_compliance { diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index ca82835b6dcf..a871834b90d9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4984,9 +4984,33 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) return test_result; } +static u8 intel_dp_prepare_phytest(struct intel_dp *intel_dp) +{ + struct drm_dp_phy_test_params *data = + _dp->compliance.test_data.phytest; + + if (drm_dp_get_phy_test_pattern(_dp->aux, data)) { + DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n"); + return DP_TEST_NAK; + } + + /* +* link_mst is set to false to avoid executing mst related code +* during compliance testing. +*/ + intel_dp->link_mst = false; + + return DP_TEST_ACK; +} + static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) { u8 test_result = DP_TEST_NAK; + + test_result = intel_dp_prepare_phytest(intel_dp); + if (test_result != DP_TEST_ACK) + DRM_ERROR("Phy test preparation failed\n"); + return test_result; } -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/9] drm/amd/display: Fix compilation issue.
[Why]: Aligh with DP spec wanted to follow same naming convention. [How]: Changed the macro name of the dpcd address used for getting requested test-pattern. Cc: Harry Wentland Cc: Alex Deucher Signed-off-by: Animesh Manna --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 42aa889fd0f5..1a6109be2fce 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2491,7 +2491,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) /* get phy test pattern and pattern parameters from DP receiver */ core_link_read_dpcd( link, - DP_TEST_PHY_PATTERN, + DP_PHY_TEST_PATTERN, _test_pattern.raw, sizeof(dpcd_test_pattern)); core_link_read_dpcd( -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 1/9] drm/dp: get/set phy compliance pattern
During phy compliance auto test mode source need to read requested test pattern from sink through DPCD. After processing the request source need to set the pattern. So set/get method added in drm layer as it is DP protocol. v2: As per review feedback from Manasi on RFC version, - added dp revision as function argument in set_phy_pattern api. - used int for link_rate and u8 for lane_count to align with existing code. Signed-off-by: Animesh Manna --- drivers/gpu/drm/drm_dp_helper.c | 93 + include/drm/drm_dp_helper.h | 33 +++- 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 2c7870aef469..91c80973aa83 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -1371,3 +1371,96 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_S return num_bpc; } EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs); + +/** + * drm_dp_get_phy_test_pattern() - get the requested pattern from the sink. + * @aux: DisplayPort AUX channel + * @data: DP phy compliance test parameters. + * + * Returns 0 on success or a negative error code on failure. + */ +int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux, + struct drm_dp_phy_test_params *data) +{ + int err; + u8 rate, lanes; + + err = drm_dp_dpcd_readb(aux, DP_TEST_LINK_RATE, ); + if (err < 0) + return err; + data->link_rate = drm_dp_bw_code_to_link_rate(rate); + + err = drm_dp_dpcd_readb(aux, DP_TEST_LANE_COUNT, ); + if (err < 0) + return err; + data->num_lanes = lanes & DP_MAX_LANE_COUNT_MASK; + + if (lanes & DP_ENHANCED_FRAME_CAP) + data->enahanced_frame_cap = true; + + err = drm_dp_dpcd_readb(aux, DP_PHY_TEST_PATTERN, >phy_pattern); + if (err < 0) + return err; + + switch (data->phy_pattern) { + case DP_PHY_TEST_PATTERN_80BIT_CUSTOM: + err = drm_dp_dpcd_read(aux, DP_TEST_80BIT_CUSTOM_PATTERN_7_0, + >custom80, 10); + if (err < 0) + return err; + + break; + case DP_PHY_TEST_PATTERN_CP2520: + err = drm_dp_dpcd_read(aux, DP_TEST_HBR2_SCRAMBLER_RESET, + >hbr2_reset, 2); + if (err < 0) + return err; + } + + return 0; +} +EXPORT_SYMBOL(drm_dp_get_phy_test_pattern); + +/** + * drm_dp_set_phy_test_pattern() - set the pattern to the sink. + * @aux: DisplayPort AUX channel + * @data: DP phy compliance test parameters. + * + * Returns 0 on success or a negative error code on failure. + */ +int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux, + struct drm_dp_phy_test_params *data, u8 dp_rev) +{ + int err, i; + u8 link_config[2]; + u8 test_pattern; + + link_config[0] = drm_dp_link_rate_to_bw_code(data->link_rate); + link_config[1] = data->num_lanes; + if (data->enahanced_frame_cap) + link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; + err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, link_config, 2); + if (err < 0) + return err; + + test_pattern = data->phy_pattern; + if (dp_rev < 0x12) { + test_pattern = (test_pattern << 2) & + DP_LINK_QUAL_PATTERN_11_MASK; + err = drm_dp_dpcd_writeb(aux, DP_TRAINING_PATTERN_SET, +test_pattern); + if (err < 0) + return err; + } else { + for (i = 0; i < data->num_lanes; i++) { + err = drm_dp_dpcd_writeb(aux, +DP_LINK_QUAL_LANE0_SET + i, +test_pattern); + if (err < 0) + return err; + } + } + + return 0; +} +EXPORT_SYMBOL(drm_dp_set_phy_test_pattern); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 8f8f3632e697..42a364748308 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -699,7 +699,16 @@ # define DP_TEST_CRC_SUPPORTED (1 << 5) # define DP_TEST_COUNT_MASK0xf -#define DP_TEST_PHY_PATTERN 0x248 +#define DP_PHY_TEST_PATTERN 0x248 +# define DP_PHY_TEST_PATTERN_SEL_MASK 0x7 +# define DP_PHY_TEST_PATTERN_NONE 0x0 +# define DP_PHY_TEST_PATTERN_D10_2 0x1 +# define DP_PHY_TEST_PATTERN_ERROR_COUNT0x2 +# define DP_PHY_TEST_PATTERN_PRBS7 0x3 +# define DP_PHY_TEST_PATTERN_80BIT_CUSTOM 0x4 +# define DP_PHY_TEST_PATTERN_CP2520 0x5 + +#define DP_TEST_HBR2_SCRAMBLER_RESET0x24A
[PATCH v2 0/9] DP Phy compliance auto test
Driver changes mainly to process the request coming from Test equipment as short pulse hpd interrupt to change link-pattern/v-swing/pre-emphasis Complete auto test suite takes much lesser time than manual run. Overall design: -- Automate test request will come to source device as HDP short pulse interrupt from test scope. Read DPCD 0x201, Check for bit 1 for automated test request. If set continue and read DPCD 0x218. Check for bit 3 for phy test pattern, If set continue. Get the requested test pattern through DPCD 0x248. Compute requested voltage swing level and pre-emphasis level from DPCD 0x206 and 0x207 Set signal level through vswing programming sequence. Write DDI_COMP_CTL and DDI_COMP_PATx as per requested pattern. Configure the link and write the new test pattern through DPCD. High level patch description. - patch 1: drm level api added to get/set test pattern as per vesa DP spec. This maybe useful for other driver so added in drm layer. patch 2: Fix for a compilation issue. patch 3: vswing/preemphasis adjustment calculation is needed during phy compliance request processing along with existing link training process, so moved the same function in intel_dp.c. patch 4: Parse the test scope request regarding rquested test pattern, vswing level, preemphasis level. patch 5: Notify testapp through uevent. patch 6: Added debugfs entry for phy compliance. patch 7: Register difnition of DP compliance register added. patch 8: Function added to update the pattern in source side. patch 9: This patch os mainly processing the request. Currently through prototyping patch able to run DP compliance where vswing, preemphasis and test pattern is changing fine but complete test is under process. As per feedback redesigned the code. Could not test due to unavailability of test scope, so sending as RFC again to get design feedback. v1: Redesigned the code as per review feedback from Manasi on RFC. v2: Addressed review comments from Manasi. Animesh Manna (9): drm/dp: get/set phy compliance pattern drm/amd/display: Fix compilation issue. drm/i915/dp: Move vswing/pre-emphasis adjustment calculation drm/i915/dp: Preparation for DP phy compliance auto test drm/i915/dsb: Send uevent to testapp. drm/i915/dp: Add debugfs entry for DP phy compliance. drm/i915/dp: Register definition for DP compliance register drm/i915/dp: Update the pattern as per request drm/i915/dp: [FIXME] Program vswing, pre-emphasis, test-pattern .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- drivers/gpu/drm/drm_dp_helper.c | 93 + drivers/gpu/drm/i915/display/intel_display.c | 24 ++- .../drm/i915/display/intel_display_types.h| 1 + drivers/gpu/drm/i915/display/intel_dp.c | 195 +- drivers/gpu/drm/i915/display/intel_dp.h | 5 + .../drm/i915/display/intel_dp_link_training.c | 32 --- drivers/gpu/drm/i915/i915_debugfs.c | 12 +- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 20 ++ include/drm/drm_dp_helper.h | 33 ++- 11 files changed, 381 insertions(+), 38 deletions(-) -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL FOR v5.6] R-Car DU new features
On Wed, Dec 18, 2019 at 05:17:10PM +0200, Laurent Pinchart wrote: > Hi Dave and Daniel, > > The following changes since commit d1eef1c619749b2a57e514a3fa67d9a516ffa919: > > Linux 5.5-rc2 (2019-12-15 15:16:08 -0800) > > are available in the Git repository at: > > git://linuxtv.org/pinchartl/media.git tags/du-next-20191218 > > for you to fetch changes up to c267782c5f0efbd20c560101738e68bb30d4fad5: > > drm: rcar-du: Add r8a77980 support (2019-12-18 02:40:29 +0200) > > > R-Car Display Unit changes: > > - Color Management Module support > - LVDS encoder dual-link support enhancements > - R8A77980 support Thanks for respinning, applied to drm-next. -Daniel > > > Fabrizio Castro (4): > drm: of: Add drm_of_lvds_get_dual_link_pixel_order > drm: rcar-du: lvds: Improve identification of panels > drm: rcar-du: lvds: Get dual link configuration from DT > drm: rcar-du: lvds: Allow for even and odd pixels swap > > Geert Uytterhoeven (2): > dt-bindings: display: renesas: du: Add vendor prefix to vsps property > drm: rcar-du: Recognize "renesas,vsps" in addition to "vsps" > > Jacopo Mondi (6): > dt-bindings: display: renesas,cmm: Add R-Car CMM documentation > dt-bindings: display: renesas,du: Document cmms property > drm: rcar-du: Add support for CMM > drm: rcar-du: kms: Initialize CMM instances > drm: rcar-du: crtc: Control CMM operations > drm: rcar-du: crtc: Register GAMMA_LUT properties > > Kieran Bingham (1): > drm: rcar-du: Add r8a77980 support > > Laurent Pinchart (1): > drm: rcar-du: lvds: Get mode from state > > (with all patches properly signed this time) > > .../devicetree/bindings/display/renesas,cmm.yaml | 67 + > .../devicetree/bindings/display/renesas,du.txt | 15 +- > drivers/gpu/drm/drm_of.c | 116 > drivers/gpu/drm/rcar-du/Kconfig| 8 + > drivers/gpu/drm/rcar-du/Makefile | 1 + > drivers/gpu/drm/rcar-du/rcar_cmm.c | 217 ++ > drivers/gpu/drm/rcar-du/rcar_cmm.h | 58 > drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 71 + > drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 + > drivers/gpu/drm/rcar-du/rcar_du_drv.c | 6 +- > drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 + > drivers/gpu/drm/rcar-du/rcar_du_group.c| 10 + > drivers/gpu/drm/rcar-du/rcar_du_group.h| 2 + > drivers/gpu/drm/rcar-du/rcar_du_kms.c | 93 +- > drivers/gpu/drm/rcar-du/rcar_du_regs.h | 5 + > drivers/gpu/drm/rcar-du/rcar_lvds.c| 318 > +++-- > include/drm/drm_of.h | 20 ++ > 17 files changed, 856 insertions(+), 155 deletions(-) > create mode 100644 Documentation/devicetree/bindings/display/renesas,cmm.yaml > create mode 100644 drivers/gpu/drm/rcar-du/rcar_cmm.c > create mode 100644 drivers/gpu/drm/rcar-du/rcar_cmm.h > > -- > Regards, > > Laurent Pinchart -- 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
[GIT PULL FOR v5.6] R-Car DU new features
Hi Dave and Daniel, The following changes since commit d1eef1c619749b2a57e514a3fa67d9a516ffa919: Linux 5.5-rc2 (2019-12-15 15:16:08 -0800) are available in the Git repository at: git://linuxtv.org/pinchartl/media.git tags/du-next-20191218 for you to fetch changes up to c267782c5f0efbd20c560101738e68bb30d4fad5: drm: rcar-du: Add r8a77980 support (2019-12-18 02:40:29 +0200) R-Car Display Unit changes: - Color Management Module support - LVDS encoder dual-link support enhancements - R8A77980 support Fabrizio Castro (4): drm: of: Add drm_of_lvds_get_dual_link_pixel_order drm: rcar-du: lvds: Improve identification of panels drm: rcar-du: lvds: Get dual link configuration from DT drm: rcar-du: lvds: Allow for even and odd pixels swap Geert Uytterhoeven (2): dt-bindings: display: renesas: du: Add vendor prefix to vsps property drm: rcar-du: Recognize "renesas,vsps" in addition to "vsps" Jacopo Mondi (6): dt-bindings: display: renesas,cmm: Add R-Car CMM documentation dt-bindings: display: renesas,du: Document cmms property drm: rcar-du: Add support for CMM drm: rcar-du: kms: Initialize CMM instances drm: rcar-du: crtc: Control CMM operations drm: rcar-du: crtc: Register GAMMA_LUT properties Kieran Bingham (1): drm: rcar-du: Add r8a77980 support Laurent Pinchart (1): drm: rcar-du: lvds: Get mode from state (with all patches properly signed this time) .../devicetree/bindings/display/renesas,cmm.yaml | 67 + .../devicetree/bindings/display/renesas,du.txt | 15 +- drivers/gpu/drm/drm_of.c | 116 drivers/gpu/drm/rcar-du/Kconfig| 8 + drivers/gpu/drm/rcar-du/Makefile | 1 + drivers/gpu/drm/rcar-du/rcar_cmm.c | 217 ++ drivers/gpu/drm/rcar-du/rcar_cmm.h | 58 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 71 + drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 6 +- drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 + drivers/gpu/drm/rcar-du/rcar_du_group.c| 10 + drivers/gpu/drm/rcar-du/rcar_du_group.h| 2 + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 93 +- drivers/gpu/drm/rcar-du/rcar_du_regs.h | 5 + drivers/gpu/drm/rcar-du/rcar_lvds.c| 318 +++-- include/drm/drm_of.h | 20 ++ 17 files changed, 856 insertions(+), 155 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/renesas,cmm.yaml create mode 100644 drivers/gpu/drm/rcar-du/rcar_cmm.c create mode 100644 drivers/gpu/drm/rcar-du/rcar_cmm.h -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 1/5] drm: Add __drm_atomic_helper_crtc_state_reset() & co.
On Fri, Dec 13, 2019 at 03:38:53PM -0800, Lucas De Marchi wrote: > On Thu, Nov 07, 2019 at 04:24:13PM +0200, Ville Syrjälä wrote: > >From: Ville Syrjälä > > > >Annoyingly __drm_atomic_helper_crtc_reset() does two > >totally separate things: > >a) reset the state to defaults values > >b) assign the crtc->state pointer > > > >I just want a) without the b) so let's split out part > >a) into __drm_atomic_helper_crtc_state_reset(). And > >of course we'll do the same thing for planes and connectors. > > > >Signed-off-by: Ville Syrjälä > >--- > > drivers/gpu/drm/drm_atomic_state_helper.c | 70 --- > > include/drm/drm_atomic_state_helper.h | 6 ++ > > 2 files changed, 67 insertions(+), 9 deletions(-) > > > >diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c > >b/drivers/gpu/drm/drm_atomic_state_helper.c > >index d0a937fb0c56..a972068d58cf 100644 > >--- a/drivers/gpu/drm/drm_atomic_state_helper.c > >+++ b/drivers/gpu/drm/drm_atomic_state_helper.c > >@@ -57,6 +57,22 @@ > > * for these functions. > > */ > > > >+/** > >+ * __drm_atomic_helper_crtc_state_reset - reset the CRTC state > >+ * @crtc_state: atomic CRTC state, must not be NULL > >+ * @crtc: CRTC object, must not be NULL > >+ * > >+ * Initializes the newly allocated @crtc_state with default > >+ * values. This is useful for drivers that subclass the CRTC state. > >+ */ > >+void > >+__drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state, > >+ struct drm_crtc *crtc) > >+{ > >+crtc_state->crtc = crtc; > >+} > >+EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset); > >+ > > /** > > * __drm_atomic_helper_crtc_reset - reset state on CRTC > > * @crtc: drm CRTC > >@@ -74,7 +90,7 @@ __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, > >struct drm_crtc_state *crtc_state) > > { > > if (crtc_state) > >-crtc_state->crtc = crtc; > >+__drm_atomic_helper_crtc_state_reset(crtc_state, crtc); > > > > crtc->state = crtc_state; > > } > >@@ -212,23 +228,43 @@ void drm_atomic_helper_crtc_destroy_state(struct > >drm_crtc *crtc, > > EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); > > > > /** > >- * __drm_atomic_helper_plane_reset - resets planes state to default values > >+ * __drm_atomic_helper_plane_state_reset - resets plane state to default > >values > >+ * @plane_state: atomic plane state, must not be NULL > > * @plane: plane object, must not be NULL > >- * @state: atomic plane state, must not be NULL > > * > >- * Initializes plane state to default. This is useful for drivers that > >subclass > >- * the plane state. > >+ * Initializes the newly allocated @plane_state with default > >+ * values. This is useful for drivers that subclass the CRTC state. > > */ > >-void __drm_atomic_helper_plane_reset(struct drm_plane *plane, > >- struct drm_plane_state *state) > >+void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *state, > >+ struct drm_plane *plane) > > { > > state->plane = plane; > > state->rotation = DRM_MODE_ROTATE_0; > > > > state->alpha = DRM_BLEND_ALPHA_OPAQUE; > > state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; > >+} > >+EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset); > > > >-plane->state = state; > >+/** > >+ * __drm_atomic_helper_plane_reset - reset state on plane > >+ * @plane: drm plane > >+ * @plane_state: plane state to assign > >+ * > >+ * Initializes the newly allocated @plane_state and assigns it to > >+ * the _crtc->state pointer of @plane, usually required when > >+ * initializing the drivers or when called from the _plane_funcs.reset > >+ * hook. > >+ * > >+ * This is useful for drivers that subclass the plane state. > >+ */ > >+void __drm_atomic_helper_plane_reset(struct drm_plane *plane, > >+ struct drm_plane_state *plane_state) > >+{ > >+if (plane_state) > >+__drm_atomic_helper_plane_state_reset(plane_state, plane); > >+ > >+plane->state = plane_state; > > } > > EXPORT_SYMBOL(__drm_atomic_helper_plane_reset); > > > >@@ -335,6 +371,22 @@ void drm_atomic_helper_plane_destroy_state(struct > >drm_plane *plane, > > } > > EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); > > > >+/** > >+ * __drm_atomic_helper_connector_state_reset - reset the connector state > >+ * @conn__state: atomic connector state, must not be NULL > > typo here, otherwise Thanks for catching that. Made me run a doc build that found a mismatch between kerneldoc vs. code for the plane function, so I fixed that up while pushing. Entire series pushed to dinq with Daniel's ack for the first patch. Though in hindsight I could have just pushed that one to drm-misc eons ago. Oh well. Thanks for the reviews. -- Ville Syrjälä Intel ___ dri-devel mailing list dri-devel@lists.freedesktop.org
Re: [PATCH v3 00/50] drm/omap: Replace custom display drivers with drm_bridge and drm_panel
Hi Tomi, On Wed, Dec 18, 2019 at 09:07:52AM +0200, Tomi Valkeinen wrote: > On 18/12/2019 04:03, Laurent Pinchart wrote: > >> Hopefully we can soon have this series landed so we can start > >> working on top of the new bridge/connector handling. > >> > >> I assume it will be applied direct to drm-misc-next, so we do not > >> have to wait extra time to get it. > > > > Tomi, how would you like to proceed ? The core patches are ready in my > > opinion. I can post a v4 without the omapdrm patches, which could be > > merged to drm-misc already while you finish reviewing patches 30/50 > > onwards. > > This sounds good to me. > > I have tested your branch on AM5 EMV, AM4 EVM and Panda, without any issues. > But that's with the > omapdrm patches, and things will be slightly different without them. > > You add TPD12S015 and OPA362 driver in the earlier part. Should those be > moved to the omapdrm side? > In theory there won't be any issues, but having multiple drivers for the same > device can create > conflicts. Indeed, although if they're not selected it shouldn't be a problem. On the other hand you've reviewed the omapdrm patches up to "drm/omap: Switch the HDMI and VENC outputs to drm_bridge" which removes the old drivers, the rest being just cleanups. We could thus merge up to that patch in one go. What's your preference ? -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH RESEND] drm/msm/adreno: Do not print error on "qcom,gpu-pwrlevels" absence
Hi Rob, On Tue, Dec 10, 2019 at 8:12 PM Fabio Estevam wrote: > > Booting the adreno driver on a imx53 board leads to the following > error message: > > adreno 3000.gpu: [drm:adreno_gpu_init] *ERROR* Could not find the GPU > powerlevels > > As the "qcom,gpu-pwrlevels" property is optional and never present on > i.MX5, turn the message into debug level instead. > > Signed-off-by: Fabio Estevam > Reviewed-by: Jeffrey Hugo > Reviewed-by: Jordan Crouse > --- > Trying once again :-) > > drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > index 0783e4b5486a..5d7bdb4c83cc 100644 > --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > @@ -826,7 +826,7 @@ static int adreno_get_legacy_pwrlevels(struct device *dev) > > node = of_get_compatible_child(dev->of_node, "qcom,gpu-pwrlevels"); > if (!node) { > - DRM_DEV_ERROR(dev, "Could not find the GPU powerlevels\n"); > + DRM_DEV_DEBUG(dev, "Could not find the GPU powerlevels\n"); A gentle ping... ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 36/50] drm/omap: Switch the HDMI and VENC outputs to drm_bridge
On 11/12/2019 00:57, Laurent Pinchart wrote: The TPD12S015, OPA362 and analog and HDMI connectors are now supported by DRM bridge drivers, and the omapdrm HDMI and VENC outputs can be handled through the drm_bridge API. Switch the outputs to drm_bridge by making the next bridge mandatory and removing the related omapdrm-specific display drivers. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/displays/Kconfig | 22 -- drivers/gpu/drm/omapdrm/displays/Makefile | 4 - .../omapdrm/displays/connector-analog-tv.c| 97 .../gpu/drm/omapdrm/displays/connector-hdmi.c | 183 --- .../gpu/drm/omapdrm/displays/encoder-opa362.c | 137 --- .../drm/omapdrm/displays/encoder-tpd12s015.c | 217 -- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 4 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 4 +- .../gpu/drm/omapdrm/dss/omapdss-boot-init.c | 5 - drivers/gpu/drm/omapdrm/dss/output.c | 5 + drivers/gpu/drm/omapdrm/dss/venc.c| 4 +- 11 files changed, 11 insertions(+), 671 deletions(-) delete mode 100644 drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c delete mode 100644 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c delete mode 100644 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c delete mode 100644 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c I think it would be good to also change the omap2plus_defconfig in the same commit, to keep everything working. Other than that: Reviewed-by: Tomi Valkeinen Tomi -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: panel: Fix typo in drm_panel_bridge_add docs
Hi Enric, Thank you for the patch. On Wed, Dec 18, 2019 at 01:12:23PM +0100, Enric Balletbo i Serra wrote: > Fix the 'manged' typo with 'managed' in the drm_panel_bridge_add > kernel-doc documentation. > > Signed-off-by: Enric Balletbo i Serra Reviewed-by: Laurent Pinchart > --- > > drivers/gpu/drm/bridge/panel.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c > index f4e293e7cf64..fcda954bbfec 100644 > --- a/drivers/gpu/drm/bridge/panel.c > +++ b/drivers/gpu/drm/bridge/panel.c > @@ -151,7 +151,7 @@ static const struct drm_bridge_funcs > panel_bridge_bridge_funcs = { > * known type. Calling this function with a panel whose connector type is > * DRM_MODE_CONNECTOR_Unknown will return NULL. > * > - * See devm_drm_panel_bridge_add() for an automatically manged version of > this > + * See devm_drm_panel_bridge_add() for an automatically managed version of > this > * function. > */ > struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel) -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL FOR v5.6] R-Car DU & LVDS decoder
Hi Neil, On Wed, Dec 18, 2019 at 12:55:24PM +0100, Neil Armstrong wrote: > On 18/12/2019 12:22, Neil Armstrong wrote: > > On 18/12/2019 01:44, Laurent Pinchart wrote: > >> On Tue, Dec 17, 2019 at 02:23:57PM +0100, Neil Armstrong wrote: > >>> On 17/12/2019 13:43, Daniel Vetter wrote: > On Thu, Nov 28, 2019 at 04:45:24AM +0200, Laurent Pinchart wrote: > > Hi Dave, > > > > The following changes since commit > > acc61b8929365e63a3e8c8c8913177795aa45594: > > > > Merge tag 'drm-next-5.5-2019-11-22' of > > git://people.freedesktop.org/~agd5f/linux into drm-next (2019-11-26 > > 08:40:23 +1000) > > > > are available in the Git repository at: > > > > git://linuxtv.org/pinchartl/media.git tags/du-next-20191128 > > > > for you to fetch changes up to c43bcd64c7c703ff7196f74cb6bfc67e35b562d9: > > > > dt-bindings: display: bridge: lvds-codec: Document ti,ds90cf384a > > (2019-11-28 03:55:56 +0200) > > > > > > - R-Car DU Color Management Module support > > - LVDS decoder support > > > > > > Fabrizio Castro (9): > > dt-bindings: display: bridge: Convert lvds-transmitter binding to > > json-schema > > dt-bindings: display: bridge: lvds-transmitter: Document > > powerdown-gpios > > dt-bindings: display: bridge: lvds-transmitter: Absorb > > ti,ds90c185.txt > > dt-bindings: display: bridge: lvds-transmitter: Document > > "ti,sn75lvds83" > > drm/bridge: Repurpose lvds-encoder.c > > drm/bridge: lvds-codec: Add "lvds-decoder" support > > drm/bridge: lvds-codec: Simplify panel DT node localisation > > dt-bindings: display: bridge: Repurpose lvds-encoder > > dt-bindings: display: bridge: lvds-codec: Document ti,ds90cf384a > > Why bridge stuff not in drm-misc? > > Also, and the reason I've not pulled this: > > dim: c43bcd64c7c7 ("dt-bindings: display: bridge: lvds-codec: Document > ti,ds90cf384a"): committer Signed-off-by missing. > dim: bb29b64ac196 ("dt-bindings: display: bridge: Repurpose > lvds-encoder"): committer Signed-off-by missing. > dim: 5db8ae664da4 ("drm/bridge: lvds-codec: Simplify panel DT node > localisation"): committer Signed-off-by missing. > dim: e94bb2bf88e2 ("drm/bridge: lvds-codec: Add "lvds-decoder" > support"): committer Signed-off-by missing. > dim: b6fafff0c335 ("drm/bridge: Repurpose lvds-encoder.c"): committer > Signed-off-by missing. > dim: 1c060450177f ("dt-bindings: display: bridge: lvds-transmitter: > Document "ti,sn75lvds83""): committer Signed-off-by missing. > dim: d2f2a148ba7c ("dt-bindings: display: bridge: lvds-transmitter: > Absorb ti,ds90c185.txt"): committer Signed-off-by missing. > dim: 07e5c8731999 ("dt-bindings: display: bridge: lvds-transmitter: > Document powerdown-gpios"): committer Signed-off-by missing. > dim: 0fa9d2323ed3 ("dt-bindings: display: bridge: Convert > lvds-transmitter binding to json-schema"): committer Signed-off-by > missing. > dim: ERROR: issues in commits detected, aborting > >>> > >>> Laurent, I can push them into drm-misc if needed, so it will unlock boris. > >> > >> Thanks for the offer. I've gathered all the bridge patches that are not > >> specific to Renesas in > >> > >> The following changes since commit > >> d1eef1c619749b2a57e514a3fa67d9a516ffa919: > >> > >> Linux 5.5-rc2 (2019-12-15 15:16:08 -0800) > >> > >> are available in the Git repository at: > >> > >> git://linuxtv.org/pinchartl/media.git drm/bridge/next > >> > >> for you to fetch changes up to efe52545bccf56d62c1fd1704937a971fa2d24f8: > >> > >> dt-bindings: display: bridge: lvds-codec: Absorb thine,thc63lvdm83d.txt > >> (2019-12-18 02:37:47 +0200) > >> > >> > >> Fabrizio Castro (10): > >> dt-bindings: display: bridge: Convert lvds-transmitter binding to > >> json-schema > >> dt-bindings: display: bridge: lvds-transmitter: Document > >> powerdown-gpios > >> dt-bindings: display: bridge: lvds-transmitter: Absorb > >> ti,ds90c185.txt > >> dt-bindings: display: bridge: lvds-transmitter: Document > >> "ti,sn75lvds83" > >> drm/bridge: Repurpose lvds-encoder.c > >> drm/bridge: lvds-codec: Add "lvds-decoder" support > >> drm/bridge: lvds-codec: Simplify panel DT node localisation > >> dt-bindings: display: bridge: Repurpose lvds-encoder > >> dt-bindings: display: bridge: lvds-codec: Document ti,ds90cf384a > >> dt-bindings: display: bridge: lvds-codec: Absorb > >> thine,thc63lvdm83d.txt > >> > >> .../bindings/display/bridge/lvds-codec.yaml| 131 + > >>
[PATCH v4 1/3] drm/shmem: add support for per object caching flags.
Add map_cached bool to drm_gem_shmem_object, to request cached mappings on a per-object base. Check the flag before adding writecombine to pgprot bits. Signed-off-by: Gerd Hoffmann --- include/drm/drm_gem_shmem_helper.h | 5 + drivers/gpu/drm/drm_gem_shmem_helper.c | 12 +--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h index 6748379a0b44..e69f58d467c6 100644 --- a/include/drm/drm_gem_shmem_helper.h +++ b/include/drm/drm_gem_shmem_helper.h @@ -83,6 +83,11 @@ struct drm_gem_shmem_object { * The address are un-mapped when the count reaches zero. */ unsigned int vmap_use_count; + + /** +* @map_cached: map object cached (instead of using writecombine). +*/ + bool map_cached; }; #define to_drm_gem_shmem_obj(obj) \ diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index a421a2eed48a..443265a4fc5a 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -256,9 +256,13 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem) if (obj->import_attach) shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); - else + else { + pgprot_t prot = PAGE_KERNEL; + if (!shmem->map_cached) + prot = pgprot_writecombine(prot); shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, - VM_MAP, pgprot_writecombine(PAGE_KERNEL)); + VM_MAP, prot); + } if (!shmem->vaddr) { DRM_DEBUG_KMS("Failed to vmap pages\n"); @@ -540,7 +544,9 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) } vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; - vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + if (!shmem->map_cached) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); vma->vm_ops = _gem_shmem_vm_ops; -- 2.18.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 3/3] drm/udl: simplify gem object mapping.
With shmem helpers allowing to update pgprot caching flags via drm_gem_shmem_object.map_cached we can just use that and ditch our own implementations of mmap() and vmap(). We also don't need a special case for imported objects, any map requests are handled by the exporter not udl. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/udl/udl_gem.c | 62 ++- 1 file changed, 3 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index b6e26f98aa0a..7e3a88b25b6b 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -17,72 +17,15 @@ * GEM object funcs */ -static int udl_gem_object_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma) -{ - int ret; - - ret = drm_gem_shmem_mmap(obj, vma); - if (ret) - return ret; - - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - if (obj->import_attach) - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); - - return 0; -} - -static void *udl_gem_object_vmap(struct drm_gem_object *obj) -{ - struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); - int ret; - - ret = mutex_lock_interruptible(>vmap_lock); - if (ret) - return ERR_PTR(ret); - - if (shmem->vmap_use_count++ > 0) - goto out; - - ret = drm_gem_shmem_get_pages(shmem); - if (ret) - goto err_zero_use; - - if (obj->import_attach) - shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); - else - shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, - VM_MAP, PAGE_KERNEL); - - if (!shmem->vaddr) { - DRM_DEBUG_KMS("Failed to vmap pages\n"); - ret = -ENOMEM; - goto err_put_pages; - } - -out: - mutex_unlock(>vmap_lock); - return shmem->vaddr; - -err_put_pages: - drm_gem_shmem_put_pages(shmem); -err_zero_use: - shmem->vmap_use_count = 0; - mutex_unlock(>vmap_lock); - return ERR_PTR(ret); -} - static const struct drm_gem_object_funcs udl_gem_object_funcs = { .free = drm_gem_shmem_free_object, .print_info = drm_gem_shmem_print_info, .pin = drm_gem_shmem_pin, .unpin = drm_gem_shmem_unpin, .get_sg_table = drm_gem_shmem_get_sg_table, - .vmap = udl_gem_object_vmap, + .vmap = drm_gem_shmem_vmap, .vunmap = drm_gem_shmem_vunmap, - .mmap = udl_gem_object_mmap, + .mmap = drm_gem_shmem_mmap, }; /* @@ -101,6 +44,7 @@ struct drm_gem_object *udl_driver_gem_create_object(struct drm_device *dev, obj = >base; obj->funcs = _gem_object_funcs; + shmem->map_cached = true; return obj; } -- 2.18.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 2/3] drm/virtio: fix mmap page attributes
virtio-gpu uses cached mappings, set drm_gem_shmem_object.map_cached accordingly. Reported-by: Gurchetan Singh Signed-off-by: Gerd Hoffmann virtio fixup --- drivers/gpu/drm/virtio/virtgpu_object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 017a9e0fc3bb..7f991e03ea2c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -99,6 +99,7 @@ struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, return NULL; bo->base.base.funcs = _gpu_gem_funcs; + bo->base.map_cached = true; return >base.base; } -- 2.18.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel