From ddb24fc525ddaf35130d96478f3f18682a9d5926 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 4 Apr 2023 16:30:56 +0200 Subject: drm/i915/ttm: Add I915_BO_PREALLOC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a mechanism to preserve existing data when creating a TTM object with the I915_BO_ALLOC_USER flag. This will be used in the subsequent patch where the I915_BO_ALLOC_USER flag will be applied to the framebuffer object. For a pre-allocated framebuffer without the I915_BO_PREALLOC flag. TTM would clear the content, which is not desirable. Cc: Matthew Auld Cc: Andi Shyti Cc: Andrzej Hajda Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das Reviewed-by: Andrzej Hajda Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20230404143100.10452-1-nirmoy.das@intel.com --- drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 15 +++++++++++---- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 5 +++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 19c9bdd8f905..8540edff164b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -328,6 +328,12 @@ struct drm_i915_gem_object { */ #define I915_BO_ALLOC_GPU_ONLY BIT(6) #define I915_BO_ALLOC_CCS_AUX BIT(7) +/* + * Object is allowed to retain its initial data and will not be cleared on first + * access if used along with I915_BO_ALLOC_USER. This is mainly to keep + * preallocated framebuffer data intact while transitioning it to i915drmfb. + */ +#define I915_BO_PREALLOC BIT(8) #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \ I915_BO_ALLOC_VOLATILE | \ I915_BO_ALLOC_CPU_CLEAR | \ @@ -335,10 +341,11 @@ struct drm_i915_gem_object { I915_BO_ALLOC_PM_VOLATILE | \ I915_BO_ALLOC_PM_EARLY | \ I915_BO_ALLOC_GPU_ONLY | \ - I915_BO_ALLOC_CCS_AUX) -#define I915_BO_READONLY BIT(8) -#define I915_TILING_QUIRK_BIT 9 /* unknown swizzling; do not release! */ -#define I915_BO_PROTECTED BIT(10) + I915_BO_ALLOC_CCS_AUX | \ + I915_BO_PREALLOC) +#define I915_BO_READONLY BIT(9) +#define I915_TILING_QUIRK_BIT 10 /* unknown swizzling; do not release! */ +#define I915_BO_PROTECTED BIT(11) /** * @mem_flags - Mutable placement-related flags * diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 6e3de0f33add..46b398ccd250 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -560,7 +560,7 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, struct dma_fence *migration_fence = NULL; struct ttm_tt *ttm = bo->ttm; struct i915_refct_sgt *dst_rsgt; - bool clear; + bool clear, prealloc_bo; int ret; if (GEM_WARN_ON(i915_ttm_is_ghost_object(bo))) { @@ -590,7 +590,8 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, return PTR_ERR(dst_rsgt); clear = !i915_ttm_cpu_maps_iomem(bo->resource) && (!ttm || !ttm_tt_is_populated(ttm)); - if (!(clear && ttm && !(ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC))) { + prealloc_bo = obj->flags & I915_BO_PREALLOC; + if (!(clear && ttm && !((ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) && !prealloc_bo))) { struct i915_deps deps; i915_deps_init(&deps, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); -- cgit From ddb78a51fac65e8db2316ded59e27ab621aea856 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 4 Apr 2023 16:30:57 +0200 Subject: drm/i915/display: Set I915_BO_ALLOC_USER for fb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Framebuffer is exposed to userspace so make sure we set proper flags for it. Set I915_BO_PREALLOC for prealloced fb so that ttm won't clear existing data. Cc: Matthew Auld Cc: Andi Shyti Cc: Andrzej Hajda Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das Reviewed-by: Andi Shyti Reviewed-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20230404143100.10452-2-nirmoy.das@intel.com --- drivers/gpu/drm/i915/display/intel_fbdev.c | 3 ++- drivers/gpu/drm/i915/display/intel_plane_initial.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 03ed4607a46d..9ea49aaa33ca 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -163,7 +163,8 @@ static int intelfb_alloc(struct drm_fb_helper *helper, obj = ERR_PTR(-ENODEV); if (HAS_LMEM(dev_priv)) { obj = i915_gem_object_create_lmem(dev_priv, size, - I915_BO_ALLOC_CONTIGUOUS); + I915_BO_ALLOC_CONTIGUOUS | + I915_BO_ALLOC_USER); } else { /* * If the FB is too big, just don't use it since fbdev is not very diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c index 76be796df255..3a95d24eab74 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c @@ -110,7 +110,9 @@ initial_plane_vma(struct drm_i915_private *i915, size * 2 > i915->stolen_usable_size) return NULL; - obj = i915_gem_object_create_region_at(mem, phys_base, size, 0); + obj = i915_gem_object_create_region_at(mem, phys_base, size, + I915_BO_ALLOC_USER | + I915_BO_PREALLOC); if (IS_ERR(obj)) return NULL; -- cgit From eaee1c08586395182e0004b3512a2f83570ea461 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 4 Apr 2023 16:30:58 +0200 Subject: drm/i915: Add a function to mmap framebuffer obj MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement i915_gem_fb_mmap() to enable fb_ops.fb_mmap() callback for i915's framebuffer objects. v2: add a comment why i915_gem_object_get() needed(Andi). v3: mmap also ttm objects. Cc: Matthew Auld Cc: Andi Shyti Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20230404143100.10452-3-nirmoy.das@intel.com --- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 137 +++++++++++++++++++++---------- drivers/gpu/drm/i915/gem/i915_gem_mman.h | 2 +- 2 files changed, 93 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 4f69bff63068..d036ef2dcdba 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -927,53 +927,15 @@ static struct file *mmap_singleton(struct drm_i915_private *i915) return file; } -/* - * This overcomes the limitation in drm_gem_mmap's assignment of a - * drm_gem_object as the vma->vm_private_data. Since we need to - * be able to resolve multiple mmap offsets which could be tied - * to a single gem object. - */ -int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) +static int +i915_gem_object_mmap(struct drm_i915_gem_object *obj, + struct i915_mmap_offset *mmo, + struct vm_area_struct *vma) { - struct drm_vma_offset_node *node; - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_i915_gem_object *obj = NULL; - struct i915_mmap_offset *mmo = NULL; + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct drm_device *dev = &i915->drm; struct file *anon; - if (drm_dev_is_unplugged(dev)) - return -ENODEV; - - rcu_read_lock(); - drm_vma_offset_lock_lookup(dev->vma_offset_manager); - node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager, - vma->vm_pgoff, - vma_pages(vma)); - if (node && drm_vma_node_is_allowed(node, priv)) { - /* - * Skip 0-refcnted objects as it is in the process of being - * destroyed and will be invalid when the vma manager lock - * is released. - */ - if (!node->driver_private) { - mmo = container_of(node, struct i915_mmap_offset, vma_node); - obj = i915_gem_object_get_rcu(mmo->obj); - - GEM_BUG_ON(obj && obj->ops->mmap_ops); - } else { - obj = i915_gem_object_get_rcu - (container_of(node, struct drm_i915_gem_object, - base.vma_node)); - - GEM_BUG_ON(obj && !obj->ops->mmap_ops); - } - } - drm_vma_offset_unlock_lookup(dev->vma_offset_manager); - rcu_read_unlock(); - if (!obj) - return node ? -EACCES : -EINVAL; - if (i915_gem_object_is_readonly(obj)) { if (vma->vm_flags & VM_WRITE) { i915_gem_object_put(obj); @@ -1005,7 +967,7 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) if (obj->ops->mmap_ops) { vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags)); vma->vm_ops = obj->ops->mmap_ops; - vma->vm_private_data = node->driver_private; + vma->vm_private_data = obj->base.vma_node.driver_private; return 0; } @@ -1043,6 +1005,91 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) return 0; } +/* + * This overcomes the limitation in drm_gem_mmap's assignment of a + * drm_gem_object as the vma->vm_private_data. Since we need to + * be able to resolve multiple mmap offsets which could be tied + * to a single gem object. + */ +int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_vma_offset_node *node; + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_i915_gem_object *obj = NULL; + struct i915_mmap_offset *mmo = NULL; + + if (drm_dev_is_unplugged(dev)) + return -ENODEV; + + rcu_read_lock(); + drm_vma_offset_lock_lookup(dev->vma_offset_manager); + node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager, + vma->vm_pgoff, + vma_pages(vma)); + if (node && drm_vma_node_is_allowed(node, priv)) { + /* + * Skip 0-refcnted objects as it is in the process of being + * destroyed and will be invalid when the vma manager lock + * is released. + */ + if (!node->driver_private) { + mmo = container_of(node, struct i915_mmap_offset, vma_node); + obj = i915_gem_object_get_rcu(mmo->obj); + + GEM_BUG_ON(obj && obj->ops->mmap_ops); + } else { + obj = i915_gem_object_get_rcu + (container_of(node, struct drm_i915_gem_object, + base.vma_node)); + + GEM_BUG_ON(obj && !obj->ops->mmap_ops); + } + } + drm_vma_offset_unlock_lookup(dev->vma_offset_manager); + rcu_read_unlock(); + if (!obj) + return node ? -EACCES : -EINVAL; + + return i915_gem_object_mmap(obj, mmo, vma); +} + +int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct drm_device *dev = &i915->drm; + struct i915_mmap_offset *mmo = NULL; + enum i915_mmap_type mmap_type; + struct i915_ggtt *ggtt = to_gt(i915)->ggtt; + + if (drm_dev_is_unplugged(dev)) + return -ENODEV; + + /* handle ttm object */ + if (obj->ops->mmap_ops) { + /* + * ttm fault handler, ttm_bo_vm_fault_reserved() uses fake offset + * to calculate page offset so set that up. + */ + vma->vm_pgoff += drm_vma_node_start(&obj->base.vma_node); + } else { + /* handle stolen and smem objects */ + mmap_type = i915_ggtt_has_aperture(ggtt) ? I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_WC; + mmo = mmap_offset_attach(obj, mmap_type, NULL); + if (!mmo) + return -ENODEV; + } + + /* + * When we install vm_ops for mmap we are too late for + * the vm_ops->open() which increases the ref_count of + * this obj and then it gets decreased by the vm_ops->close(). + * To balance this increase the obj ref_count here. + */ + obj = i915_gem_object_get(obj); + return i915_gem_object_mmap(obj, mmo, vma); +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/i915_gem_mman.c" #endif diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h b/drivers/gpu/drm/i915/gem/i915_gem_mman.h index 1fa91b3033b3..196417fd0f5c 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.h @@ -29,5 +29,5 @@ void i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj); void i915_gem_object_runtime_pm_release_mmap_offset(struct drm_i915_gem_object *obj); void i915_gem_object_release_mmap_offset(struct drm_i915_gem_object *obj); - +int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma); #endif -- cgit From 63b685efaa4d6b9db388857a2e6f5f5f11454f8d Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 4 Apr 2023 16:30:59 +0200 Subject: drm/i915/display: Add helper func to get intel_fbdev from drm_fb_helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper function to retrieve struct intel_fbdev from struct drm_fb_helper. Cc: Matthew Auld Cc: Andi Shyti Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das Reviewed-by: Jani Nikula Reviewed-by: Andi Shyti Reviewed-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20230404143100.10452-4-nirmoy.das@intel.com --- drivers/gpu/drm/i915/display/intel_fbdev.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 9ea49aaa33ca..64971a8d5531 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -67,6 +67,11 @@ struct intel_fbdev { struct mutex hpd_lock; }; +static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) +{ + return container_of(fb_helper, struct intel_fbdev, helper); +} + static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev) { return ifbdev->fb->frontbuffer; @@ -79,9 +84,7 @@ static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev) static int intel_fbdev_set_par(struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_set_par(info); @@ -93,9 +96,7 @@ static int intel_fbdev_set_par(struct fb_info *info) static int intel_fbdev_blank(int blank, struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_blank(blank, info); @@ -108,9 +109,7 @@ static int intel_fbdev_blank(int blank, struct fb_info *info) static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_pan_display(var, info); @@ -136,8 +135,7 @@ static const struct fb_ops intelfb_ops = { static int intelfb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct intel_fbdev *ifbdev = - container_of(helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct drm_framebuffer *fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); @@ -194,8 +192,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, static int intelfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct intel_fbdev *ifbdev = - container_of(helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct intel_framebuffer *intel_fb = ifbdev->fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); -- cgit From e24e6d695377ca70008ffc39695c3975b3e177b6 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 4 Apr 2023 16:31:00 +0200 Subject: drm/i915/display: Implement fb_mmap callback function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If stolen memory allocation fails for fbdev, the driver will fallback to system memory. Calculation of smem_start is wrong for such framebuffer objs if the platform comes with no gmadr or no aperture. Solve this by adding fb_mmap callback which will use GTT if aperture is available otherwise will use cpu to access the framebuffer. v2: Use to_intel_fbdev() function(Jani) Cc: Matthew Auld Cc: Andi Shyti Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das Reviewed-by: Andi Shyti Reviewed-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20230404143100.10452-5-nirmoy.das@intel.com --- drivers/gpu/drm/i915/display/intel_fbdev.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 64971a8d5531..a44a5535db1b 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -40,8 +40,10 @@ #include #include #include +#include #include "gem/i915_gem_lmem.h" +#include "gem/i915_gem_mman.h" #include "i915_drv.h" #include "intel_display_types.h" @@ -119,6 +121,15 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, return ret; } +static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct intel_fbdev *fbdev = to_intel_fbdev(info->par); + struct drm_gem_object *bo = drm_gem_fb_get_obj(&fbdev->fb->base, 0); + struct drm_i915_gem_object *obj = to_intel_bo(bo); + + return i915_gem_fb_mmap(obj, vma); +} + static const struct fb_ops intelfb_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, @@ -130,6 +141,7 @@ static const struct fb_ops intelfb_ops = { .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = intel_fbdev_pan_display, .fb_blank = intel_fbdev_blank, + .fb_mmap = intel_fbdev_mmap, }; static int intelfb_alloc(struct drm_fb_helper *helper, -- cgit From 16fc9c08f0ec7b1c95f1ea4a16097acdb3fc943d Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Fri, 7 Apr 2023 12:32:37 +0300 Subject: drm/i915: disable sampler indirect state in bindless heap By default the indirect state sampler data (border colors) are stored in the same heap as the SAMPLER_STATE structure. For userspace drivers that can be 2 different heaps (dynamic state heap & bindless sampler state heap). This means that border colors have to copied in 2 different places so that the same SAMPLER_STATE structure find the right data. This change is forcing the indirect state sampler data to only be in the dynamic state pool (more convenient for userspace drivers, they only have to have one copy of the border colors). This is reproducing the behavior of the Windows drivers. BSpec: 46052 Signed-off-by: Lionel Landwerlin Cc: stable@vger.kernel.org Reviewed-by: Haridhar Kalvala Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20230407093237.3296286-1-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/i915/gt/intel_gt_regs.h | 1 + drivers/gpu/drm/i915/gt/intel_workarounds.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index 6115cc1805de..6903c66a4ed7 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -1147,6 +1147,7 @@ #define SC_DISABLE_POWER_OPTIMIZATION_EBB REG_BIT(9) #define GEN11_SAMPLER_ENABLE_HEADLESS_MSG REG_BIT(5) #define MTL_DISABLE_SAMPLER_SC_OOO REG_BIT(3) +#define GEN11_INDIRECT_STATE_BASE_ADDR_OVERRIDE REG_BIT(0) #define GEN9_HALF_SLICE_CHICKEN7 MCR_REG(0xe194) #define DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA REG_BIT(15) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index c0de5276b3d3..4e3cbeca9eec 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -3051,6 +3051,25 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li add_render_compute_tuning_settings(i915, wal); + if (GRAPHICS_VER(i915) >= 11) { + /* This is not a Wa (although referred to as + * WaSetInidrectStateOverride in places), this allows + * applications that reference sampler states through + * the BindlessSamplerStateBaseAddress to have their + * border color relative to DynamicStateBaseAddress + * rather than BindlessSamplerStateBaseAddress. + * + * Otherwise SAMPLER_STATE border colors have to be + * copied in multiple heaps (DynamicStateBaseAddress & + * BindlessSamplerStateBaseAddress) + * + * BSpec: 46052 + */ + wa_mcr_masked_en(wal, + GEN10_SAMPLER_MODE, + GEN11_INDIRECT_STATE_BASE_ADDR_OVERRIDE); + } + if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_B0, STEP_FOREVER) || IS_MTL_GRAPHICS_STEP(i915, P, STEP_B0, STEP_FOREVER)) /* Wa_14017856879 */ -- cgit From b90b044c64f669cb20919fb5e5673933de59c653 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 4 Apr 2023 20:13:42 +0200 Subject: drm/i915/mtl: Disable stolen memory backed FB for A0 Stolen memory is not usable for MTL A0 stepping beyond certain access size and we have no control over userspace access size of /dev/fb which can be backed by stolen memory. So disable stolen memory backed fb by setting i915->dsm.usable_size to zero. v2: remove hsdes reference and fix commit message(Andi) v3: use revid as we want to target SOC stepping(Radhakrishna) Cc: Matthew Auld Cc: Andi Shyti Cc: Daniele Ceraolo Spurio Cc: Lucas De Marchi Cc: Radhakrishna Sripada Signed-off-by: Nirmoy Das Reviewed-by: Andi Shyti Reviewed-by: Radhakrishna Sripada Link: https://patchwork.freedesktop.org/patch/msgid/20230404181342.23362-1-nirmoy.das@intel.com --- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index 8ac376c24aa2..ee492d823f1b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -535,6 +535,14 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem) /* Basic memrange allocator for stolen space. */ drm_mm_init(&i915->mm.stolen, 0, i915->dsm.usable_size); + /* + * Access to stolen lmem beyond certain size for MTL A0 stepping + * would crash the machine. Disable stolen lmem for userspace access + * by setting usable_size to zero. + */ + if (IS_METEORLAKE(i915) && INTEL_REVID(i915) == 0x0) + i915->dsm.usable_size = 0; + return 0; } -- cgit From bfa8342c27c67e86a7b7022df06848709386e00d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 12 Apr 2023 10:09:20 +0200 Subject: MAINTAINERS: add drm_bridge for drm bridge maintainers Otherwise core changes don't get noticed by the right people. I noticed this because a patch set from Jagan Teki seems to have fallen through the cracks. Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Cc: Jagan Teki Cc: Andrzej Hajda Cc: Neil Armstrong Cc: Robert Foss Cc: Laurent Pinchart Cc: Jonas Karlman Cc: Jernej Skrabec Reviewed-by: Laurent Pinchart Reviewed-by: Andrzej Hajda Acked-by: Neil Armstrong Reviewed-by: Jagan Teki [narmstrong: fixed ordering & Daniel's SoB] Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230412080921.10171-1-daniel.vetter@ffwll.ch --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 904500cbdcf0..1558eebdcdea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6841,6 +6841,7 @@ S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/bridge/ F: drivers/gpu/drm/bridge/ +F: drivers/gpu/drm/drm_bridge.c F: include/drm/drm_bridge.h DRM DRIVERS FOR EXYNOS -- cgit From 99cc528ebe923d04767e9979665a0824727376ba Mon Sep 17 00:00:00 2001 From: Maíra Canal Date: Mon, 16 Jan 2023 17:58:00 -0300 Subject: drm/vkms: Use drmm_crtc_init_with_planes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use drmm_crtc_init_with_planes() instead of drm_crtc_init_with_planes() to get rid of the explicit destroy hook in struct drm_crtc_funcs. Signed-off-by: Maíra Canal Reviewed-by: Javier Martinez Canillas Signed-off-by: Maíra Canal Link: https://patchwork.freedesktop.org/patch/msgid/20230116205800.1266227-1-mcanal@igalia.com --- drivers/gpu/drm/vkms/vkms_crtc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 57bbd32e9beb..515f6772b866 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -161,7 +161,6 @@ static void vkms_atomic_crtc_reset(struct drm_crtc *crtc) static const struct drm_crtc_funcs vkms_crtc_funcs = { .set_config = drm_atomic_helper_set_config, - .destroy = drm_crtc_cleanup, .page_flip = drm_atomic_helper_page_flip, .reset = vkms_atomic_crtc_reset, .atomic_duplicate_state = vkms_atomic_crtc_duplicate_state, @@ -282,8 +281,8 @@ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, struct vkms_output *vkms_out = drm_crtc_to_vkms_output(crtc); int ret; - ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor, - &vkms_crtc_funcs, NULL); + ret = drmm_crtc_init_with_planes(dev, crtc, primary, cursor, + &vkms_crtc_funcs, NULL); if (ret) { DRM_ERROR("Failed to init CRTC\n"); return ret; -- cgit From 17e05aeb3b987a17b2ee5185264bec5db1d0c746 Mon Sep 17 00:00:00 2001 From: Maíra Canal Date: Mon, 16 Jan 2023 17:58:01 -0300 Subject: drm/vkms: Use drmm_mode_config_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use drmm_mode_config_init() instead of drm_mode_config_init(), as it allows us to assure that the resource will be properly cleaned. Signed-off-by: Maíra Canal Reviewed-by: Javier Martinez Canillas Signed-off-by: Maíra Canal Link: https://patchwork.freedesktop.org/patch/msgid/20230116205800.1266227-2-mcanal@igalia.com --- drivers/gpu/drm/vkms/vkms_drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 6d3a2d57d992..e3c9c9571c8d 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -133,8 +133,12 @@ static const struct drm_mode_config_helper_funcs vkms_mode_config_helpers = { static int vkms_modeset_init(struct vkms_device *vkmsdev) { struct drm_device *dev = &vkmsdev->drm; + int ret; + + ret = drmm_mode_config_init(dev); + if (ret) + return ret; - drm_mode_config_init(dev); dev->mode_config.funcs = &vkms_mode_funcs; dev->mode_config.min_width = XRES_MIN; dev->mode_config.min_height = YRES_MIN; -- cgit From adfbae9ffe339eed08d54a4eb87c93f4b35f214b Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Thu, 13 Apr 2023 13:03:49 -0700 Subject: drm/i915/gt: Avoid out-of-bounds access when loading HuC When HuC is loaded by GSC, there is no header definition for the kernel to look at and firmware is just handed to GSC. However when reading the version, it should still check the size of the blob to guarantee it's not incurring into out-of-bounds array access. If firmware is smaller than expected, the following message is now printed: # echo boom > /lib/firmware/i915/dg2_huc_gsc.bin # dmesg | grep -i huc [drm] GT0: HuC firmware i915/dg2_huc_gsc.bin: invalid size: 5 < 184 [drm] *ERROR* GT0: HuC firmware i915/dg2_huc_gsc.bin: fetch failed -ENODATA ... Even without this change the size, header and signature are still checked by GSC when loading, so this only avoids the out-of-bounds array access. Fixes: a7b516bd981f ("drm/i915/huc: Add fetch support for gsc-loaded HuC binary") Cc: Daniele Ceraolo Spurio Cc: Alan Previn Signed-off-by: Lucas De Marchi Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20230413200349.3492571-1-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c index 264c952f777b..24765c30a0e1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c @@ -488,12 +488,25 @@ static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e) } } -static int check_gsc_manifest(const struct firmware *fw, +static int check_gsc_manifest(struct intel_gt *gt, + const struct firmware *fw, struct intel_uc_fw *uc_fw) { u32 *dw = (u32 *)fw->data; - u32 version_hi = dw[HUC_GSC_VERSION_HI_DW]; - u32 version_lo = dw[HUC_GSC_VERSION_LO_DW]; + u32 version_hi, version_lo; + size_t min_size; + + /* Check the size of the blob before examining buffer contents */ + min_size = sizeof(u32) * (HUC_GSC_VERSION_LO_DW + 1); + if (unlikely(fw->size < min_size)) { + gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n", + intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, + fw->size, min_size); + return -ENODATA; + } + + version_hi = dw[HUC_GSC_VERSION_HI_DW]; + version_lo = dw[HUC_GSC_VERSION_LO_DW]; uc_fw->file_selected.ver.major = FIELD_GET(HUC_GSC_MAJOR_VER_HI_MASK, version_hi); uc_fw->file_selected.ver.minor = FIELD_GET(HUC_GSC_MINOR_VER_HI_MASK, version_hi); @@ -664,7 +677,7 @@ static int check_fw_header(struct intel_gt *gt, return 0; if (uc_fw->loaded_via_gsc) - err = check_gsc_manifest(fw, uc_fw); + err = check_gsc_manifest(gt, fw, uc_fw); else err = check_ccs_header(gt, fw, uc_fw); if (err) -- cgit From f85f2ce57783913a23f21b9d3d03a27357c07c3a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 3 Apr 2023 23:01:28 -0300 Subject: dt-bindings: display: bridge: ldb: Add an i.MX6SX entry i.MX6SX has a single LVDS port and share a similar LDB_CTRL register layout with i.MX8MP and i.MX93. Signed-off-by: Fabio Estevam Reviewed-by: Krzysztof Kozlowski Reviewed-by: Marek Vasut Signed-off-by: Marek Vasut Link: https://patchwork.freedesktop.org/patch/msgid/20230404020129.509356-1-festevam@gmail.com --- Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml index 6e0e3ba9b49e..07388bf2b90d 100644 --- a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml +++ b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml @@ -17,6 +17,7 @@ description: | properties: compatible: enum: + - fsl,imx6sx-ldb - fsl,imx8mp-ldb - fsl,imx93-ldb @@ -64,7 +65,9 @@ allOf: properties: compatible: contains: - const: fsl,imx93-ldb + enum: + - fsl,imx6sx-ldb + - fsl,imx93-ldb then: properties: ports: -- cgit From ebb7619d3ac85d7aae0a5e8d7038d32211ca7dba Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 3 Apr 2023 23:01:29 -0300 Subject: drm/bridge: fsl-ldb: Add i.MX6SX support i.MX6SX has a single LVDS port and share a similar LDB_CTRL register layout with i.MX8MP and i.MX93. There is no LVDS CTRL register on the i.MX6SX, so only write to this register on the appropriate SoCs. Add support for the i.MX6SX LDB. Tested on a imx6sx-sdb board with a Hannstar HSD100PXN1 LVDS panel and also on a custom i.MX6SX-based board. Signed-off-by: Fabio Estevam Reviewed-by: Neil Armstrong Reviewed-by: Marek Vasut Signed-off-by: Marek Vasut Link: https://patchwork.freedesktop.org/patch/msgid/20230404020129.509356-2-festevam@gmail.com --- drivers/gpu/drm/bridge/fsl-ldb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c index 682623369498..b8e52156b07a 100644 --- a/drivers/gpu/drm/bridge/fsl-ldb.c +++ b/drivers/gpu/drm/bridge/fsl-ldb.c @@ -56,6 +56,7 @@ #define LVDS_CTRL_VBG_ADJ_MASK GENMASK(19, 17) enum fsl_ldb_devtype { + IMX6SX_LDB, IMX8MP_LDB, IMX93_LDB, }; @@ -64,9 +65,14 @@ struct fsl_ldb_devdata { u32 ldb_ctrl; u32 lvds_ctrl; bool lvds_en_bit; + bool single_ctrl_reg; }; static const struct fsl_ldb_devdata fsl_ldb_devdata[] = { + [IMX6SX_LDB] = { + .ldb_ctrl = 0x18, + .single_ctrl_reg = true, + }, [IMX8MP_LDB] = { .ldb_ctrl = 0x5c, .lvds_ctrl = 0x128, @@ -201,6 +207,9 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge, regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, reg); + if (fsl_ldb->devdata->single_ctrl_reg) + return; + /* Program LVDS_CTRL */ reg = LVDS_CTRL_CC_ADJ(2) | LVDS_CTRL_PRE_EMPH_EN | LVDS_CTRL_PRE_EMPH_ADJ(3) | LVDS_CTRL_VBG_EN; @@ -226,7 +235,8 @@ static void fsl_ldb_atomic_disable(struct drm_bridge *bridge, regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, LVDS_CTRL_LVDS_EN); else - regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0); + if (!fsl_ldb->devdata->single_ctrl_reg) + regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0); regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, 0); clk_disable_unprepare(fsl_ldb->clk); @@ -372,6 +382,8 @@ static void fsl_ldb_remove(struct platform_device *pdev) } static const struct of_device_id fsl_ldb_match[] = { + { .compatible = "fsl,imx6sx-ldb", + .data = &fsl_ldb_devdata[IMX6SX_LDB], }, { .compatible = "fsl,imx8mp-ldb", .data = &fsl_ldb_devdata[IMX8MP_LDB], }, { .compatible = "fsl,imx93-ldb", -- cgit From 8bfbdadce85c4c51689da10f39c805a7106d4567 Mon Sep 17 00:00:00 2001 From: Cong Liu Date: Sat, 15 Apr 2023 00:41:09 +0200 Subject: drm/i915: Fix memory leaks in i915 selftests This patch fixes memory leaks on error escapes in function fake_get_pages Fixes: c3bfba9a2225 ("drm/i915: Check for integer truncation on scatterlist creation") Signed-off-by: Cong Liu Reviewed-by: Andrzej Hajda Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20230414224109.1051922-1-andi.shyti@linux.intel.com --- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 5361ce70d3f2..154801f1c468 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -69,8 +69,10 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) rem = round_up(obj->base.size, BIT(31)) >> 31; /* restricted by sg_alloc_table */ - if (overflows_type(rem, unsigned int)) + if (overflows_type(rem, unsigned int)) { + kfree(pages); return -E2BIG; + } if (sg_alloc_table(pages, rem, GFP)) { kfree(pages); -- cgit From dae2f7b89a8436351a2982d0d96a8a56accca576 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 22 Mar 2023 12:06:55 +0300 Subject: drm/imx/lcdc: fix a NULL vs IS_ERR() bug in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The devm_drm_dev_alloc() function returns error pointers. It never returns NULL. Fix the check. Fixes: c87e859cdeb5 ("drm/imx/lcdc: Implement DRM driver for imx25") Signed-off-by: Dan Carpenter Reviewed-by: Uwe Kleine-König Signed-off-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/d0a1fc55-3ef6-444e-b3ef-fdc937d8d57a@kili.mountain --- drivers/gpu/drm/imx/lcdc/imx-lcdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c index 8e6d457917da..277ead6a459a 100644 --- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c @@ -400,8 +400,8 @@ static int imx_lcdc_probe(struct platform_device *pdev) lcdc = devm_drm_dev_alloc(dev, &imx_lcdc_drm_driver, struct imx_lcdc, drm); - if (!lcdc) - return -ENOMEM; + if (IS_ERR(lcdc)) + return PTR_ERR(lcdc); drm = &lcdc->drm; -- cgit From 80e993988b97fe794f3ec2be6db05fe30f9353c3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:01 +0200 Subject: drm/gma500: Use drm_aperture_remove_conflicting_pci_framebuffers This one nukes all framebuffers, which is a bit much. In reality gma500 is igpu and never shipped with anything discrete, so there should not be any difference. v2: Unfortunately the framebuffer sits outside of the pci bars for gma500, and so only using the pci helpers won't be enough. Otoh if we only use non-pci helper, then we don't get the vga handling, and subsequent refactoring to untangle these special cases won't work. It's not pretty, but the simplest fix (since gma500 really is the only quirky pci driver like this we have) is to just have both calls. v4: - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Patrik Jakobsson Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-2-tzimmermann@suse.de --- drivers/gpu/drm/gma500/psb_drv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 2ce96b1b9c74..f1e0eed8fea4 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -422,12 +422,17 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* * We cannot yet easily find the framebuffer's location in memory. So - * remove all framebuffers here. + * remove all framebuffers here. Note that we still want the pci special + * handling to kick out vgacon. * * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we * might be able to read the framebuffer range from the device. */ - ret = drm_aperture_remove_framebuffers(true, &driver); + ret = drm_aperture_remove_framebuffers(false, &driver); + if (ret) + return ret; + + ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); if (ret) return ret; -- cgit From db082219569e3392cd38c9e322151450c855eed4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:02 +0200 Subject: video/aperture: use generic code to figure out the vga default device Since vgaarb has been promoted to be a core piece of the pci subsystem we don't have to open code random guesses anymore, we actually know this in a platform agnostic way, and there's no need for an x86 specific hack. See also commit 1d38fe6ee6a8 ("PCI/VGA: Move vgaarb to drivers/pci") This should not result in any functional change, and the non-x86 multi-gpu pci systems are probably rare enough to not matter (I don't know of any tbh). But it's a nice cleanup, so let's do it. There's been a few questions on previous iterations on dri-devel and irc: - fb_is_primary_device() seems to be yet another implementation of this theme, and at least on x86 it checks for both vga_default_device OR rom shadowing. There shouldn't ever be a case where rom shadowing gives any additional hints about the boot vga device, but if there is then the default vga selection in vgaarb should probably be fixed. And not special-case checks replicated all over. - Thomas also brought up that on most !x86 systems fb_is_primary_device() returns 0, except on sparc/parisc. But these 2 special cases are about platform specific devices and not pci, so shouldn't have any interactions. - Furthermore fb_is_primary_device() is a bit a red herring since it's only used to select the right fbdev driver for fbcon, and not for the fw handover dance which the aperture helpers handle. At least for x86 we might want to look into unifying them, but that's a separate thing. v2: Extend commit message trying to summarize various discussions. v4: - make the test for the primary device easier to read (Javier) - fix commit message style (i.e., commit 1234 ("...")) - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-3-tzimmermann@suse.de --- drivers/video/aperture.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index b009468ffdff..c56553d86fe7 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -328,9 +328,8 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na resource_size_t base, size; int bar, ret; -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -#endif + if (pdev == vga_default_device()) + primary = true; for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) { if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) -- cgit From 62aeaeaa1b267c5149abee6b45967a5df3feed58 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:03 +0200 Subject: drm/aperture: Remove primary argument Only really pci devices have a business setting this - it's for figuring out whether the legacy vga stuff should be nuked too. And with the preceding two patches those are all using the pci version of this. Which means for all other callers primary == false and we can remove it now. v2: - Reorder to avoid compile fail (Thomas) - Include gma500, which retained it's called to the non-pci version. v4: - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Deepak Rawat Cc: Neil Armstrong Cc: Kevin Hilman Cc: Jerome Brunet Cc: Martin Blumenstingl Cc: Thierry Reding Cc: Jonathan Hunter Cc: Emma Anholt Cc: Helge Deller Cc: David Airlie Cc: Daniel Vetter Cc: linux-hyperv@vger.kernel.org Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-tegra@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Acked-by: Martin Blumenstingl Acked-by: Thierry Reding Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-4-tzimmermann@suse.de --- drivers/gpu/drm/arm/hdlcd_drv.c | 2 +- drivers/gpu/drm/armada/armada_drv.c | 2 +- drivers/gpu/drm/drm_aperture.c | 11 +++-------- drivers/gpu/drm/gma500/psb_drv.c | 2 +- drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 1 - drivers/gpu/drm/meson/meson_drv.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +- drivers/gpu/drm/stm/drv.c | 2 +- drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +- drivers/gpu/drm/tegra/drm.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- include/drm/drm_aperture.h | 7 +++---- 13 files changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 9020bf820bc8..12f5a2c7f03d 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -285,7 +285,7 @@ static int hdlcd_drm_bind(struct device *dev) */ if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) { hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); - drm_aperture_remove_framebuffers(false, &hdlcd_driver); + drm_aperture_remove_framebuffers(&hdlcd_driver); } drm_mode_config_reset(drm); diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 0643887800b4..c99ec7078301 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -95,7 +95,7 @@ static int armada_drm_bind(struct device *dev) } /* Remove early framebuffers */ - ret = drm_aperture_remove_framebuffers(false, &armada_drm_driver); + ret = drm_aperture_remove_framebuffers(&armada_drm_driver); if (ret) { dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n", __func__, ret); diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c index 3b8fdeeafd53..697cffbfd603 100644 --- a/drivers/gpu/drm/drm_aperture.c +++ b/drivers/gpu/drm/drm_aperture.c @@ -32,17 +32,13 @@ * * static int remove_conflicting_framebuffers(struct pci_dev *pdev) * { - * bool primary = false; * resource_size_t base, size; * int ret; * * base = pci_resource_start(pdev, 0); * size = pci_resource_len(pdev, 0); - * #ifdef CONFIG_X86 - * primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - * #endif * - * return drm_aperture_remove_conflicting_framebuffers(base, size, primary, + * return drm_aperture_remove_conflicting_framebuffers(base, size, * &example_driver); * } * @@ -161,7 +157,6 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); * drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range * @base: the aperture's base address in physical memory * @size: aperture size in bytes - * @primary: also kick vga16fb if present * @req_driver: requesting DRM driver * * This function removes graphics device drivers which use the memory range described by @@ -171,9 +166,9 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); * 0 on success, or a negative errno code otherwise */ int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, - bool primary, const struct drm_driver *req_driver) + const struct drm_driver *req_driver) { - return aperture_remove_conflicting_devices(base, size, primary, req_driver->name); + return aperture_remove_conflicting_devices(base, size, false, req_driver->name); } EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers); diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index f1e0eed8fea4..4bb06a89e48d 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -428,7 +428,7 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we * might be able to read the framebuffer range from the device. */ - ret = drm_aperture_remove_framebuffers(false, &driver); + ret = drm_aperture_remove_framebuffers(&driver); if (ret) return ret; diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index f830d62a5ce6..a7d2c92d6c6a 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -74,7 +74,6 @@ static int hyperv_setup_vram(struct hyperv_drm_device *hv, drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, screen_info.lfb_size, - false, &hyperv_driver); hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024; diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index bb72fda9106d..ca6d1e59e5d9 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -285,7 +285,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) * Remove early framebuffers (ie. simplefb). The framebuffer can be * located anywhere in RAM */ - ret = drm_aperture_remove_framebuffers(false, &meson_driver); + ret = drm_aperture_remove_framebuffers(&meson_driver); if (ret) goto free_drm; diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index d26aa52217ce..16652a5a7018 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -155,7 +155,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) } /* the fw fb could be anywhere in memory */ - ret = drm_aperture_remove_framebuffers(false, dev->driver); + ret = drm_aperture_remove_framebuffers(dev->driver); if (ret) goto fini; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 6e0788d14c10..d97f2edc646b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -140,7 +140,7 @@ static int rockchip_drm_bind(struct device *dev) int ret; /* Remove existing drivers that may own the framebuffer memory. */ - ret = drm_aperture_remove_framebuffers(false, &rockchip_drm_driver); + ret = drm_aperture_remove_framebuffers(&rockchip_drm_driver); if (ret) { DRM_DEV_ERROR(dev, "Failed to remove existing framebuffers - %d.\n", diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 422220df7d8c..cb4404b3ce62 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -185,7 +185,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev) DRM_DEBUG("%s\n", __func__); - ret = drm_aperture_remove_framebuffers(false, &drv_driver); + ret = drm_aperture_remove_framebuffers(&drv_driver); if (ret) return ret; diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index e49f78a6a8cf..daa7faf72a4b 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -98,7 +98,7 @@ static int sun4i_drv_bind(struct device *dev) goto unbind_all; /* Remove early framebuffers (ie. simplefb) */ - ret = drm_aperture_remove_framebuffers(false, &sun4i_drv_driver); + ret = drm_aperture_remove_framebuffers(&sun4i_drv_driver); if (ret) goto unbind_all; diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 6ca9f396e55b..d11d259f9399 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1252,7 +1252,7 @@ static int host1x_drm_probe(struct host1x_device *dev) drm_mode_config_reset(drm); - err = drm_aperture_remove_framebuffers(false, &tegra_drm_driver); + err = drm_aperture_remove_framebuffers(&tegra_drm_driver); if (err < 0) goto hub; diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index c8bf954042e0..823395c23cc3 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -350,7 +350,7 @@ static int vc4_drm_bind(struct device *dev) return -EPROBE_DEFER; } - ret = drm_aperture_remove_framebuffers(false, driver); + ret = drm_aperture_remove_framebuffers(driver); if (ret) return ret; diff --git a/include/drm/drm_aperture.h b/include/drm/drm_aperture.h index 7096703c3949..cbe33b49fd5d 100644 --- a/include/drm/drm_aperture.h +++ b/include/drm/drm_aperture.h @@ -13,14 +13,13 @@ int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t resource_size_t size); int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, - bool primary, const struct drm_driver *req_driver); + const struct drm_driver *req_driver); int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const struct drm_driver *req_driver); /** * drm_aperture_remove_framebuffers - remove all existing framebuffers - * @primary: also kick vga16fb if present * @req_driver: requesting DRM driver * * This function removes all graphics device drivers. Use this function on systems @@ -30,9 +29,9 @@ int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, * 0 on success, or a negative errno code otherwise */ static inline int -drm_aperture_remove_framebuffers(bool primary, const struct drm_driver *req_driver) +drm_aperture_remove_framebuffers(const struct drm_driver *req_driver) { - return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary, + return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, req_driver); } -- cgit From 7450cd235b45d43ee6f3c235f89e92623458175d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:04 +0200 Subject: video/aperture: Only kick vgacon when the pdev is decoding vga Otherwise it's a bit silly, and we might throw out the driver for the screen the user is actually looking at. I haven't found a bug report for this case yet, but we did get bug reports for the analog case where we're throwing out the efifb driver. v2: Flip the check around to make it clear it's a special case for kicking out the vgacon driver only (Thomas) v4: - fixes to commit message - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Link: https://bugzilla.kernel.org/show_bug.cgi?id=216303 Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-5-tzimmermann@suse.de --- drivers/video/aperture.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index c56553d86fe7..b85163e843f3 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -342,13 +342,15 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na return ret; } - /* - * WARNING: Apparently we must kick fbdev drivers before vgacon, - * otherwise the vga fbdev driver falls over. - */ - ret = vga_remove_vgacon(pdev); - if (ret) - return ret; + if (primary) { + /* + * WARNING: Apparently we must kick fbdev drivers before vgacon, + * otherwise the vga fbdev driver falls over. + */ + ret = vga_remove_vgacon(pdev); + if (ret) + return ret; + } return 0; -- cgit From f1d599d315fb7b7343cddaf365e671aaa8453aca Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:05 +0200 Subject: video/aperture: Move vga handling to pci function A few reasons for this: - It's really the only one where this matters. I tried looking around, and I didn't find any non-pci vga-compatible controllers for x86 (since that's the only platform where we had this until a few patches ago), where a driver participating in the aperture claim dance would interfere. - I also don't expect that any future bus anytime soon will not just look like pci towards the OS, that's been the case for like 25+ years by now for practically everything (even non non-x86). - Also it's a bit funny if we have one part of the vga removal in the pci function, and the other in the generic one. v2: Rebase. v4: - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-6-tzimmermann@suse.de --- drivers/video/aperture.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index b85163e843f3..b378cd1d44d0 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -298,14 +298,6 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si aperture_detach_devices(base, size); - /* - * If this is the primary adapter, there could be a VGA device - * that consumes the VGA framebuffer I/O range. Remove this device - * as well. - */ - if (primary) - aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); - return 0; } EXPORT_SYMBOL(aperture_remove_conflicting_devices); @@ -343,6 +335,13 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na } if (primary) { + /* + * If this is the primary adapter, there could be a VGA device + * that consumes the VGA framebuffer I/O range. Remove this + * device as well. + */ + aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); + /* * WARNING: Apparently we must kick fbdev drivers before vgacon, * otherwise the vga fbdev driver falls over. -- cgit From 5fbcc6708fe32ef80122cd2a59ddca9d18b24d6e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:06 +0200 Subject: video/aperture: Drop primary argument With the preceding patches it's become defunct. Also I'm about to add a different boolean argument, so it's better to keep the confusion down to the absolute minimum. v2: Since the hypervfb patch got droppped (it's only a pci device for gen1 vm, not for gen2) there is one leftover user in an actual driver left to touch. v4: - fixes to commit message - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Wei Liu Cc: Dexuan Cui Cc: linux-hyperv@vger.kernel.org Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-7-tzimmermann@suse.de --- drivers/gpu/drm/drm_aperture.c | 2 +- drivers/video/aperture.c | 7 +++---- drivers/video/fbdev/hyperv_fb.c | 2 +- include/linux/aperture.h | 9 ++++----- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c index 697cffbfd603..5729f3bb4398 100644 --- a/drivers/gpu/drm/drm_aperture.c +++ b/drivers/gpu/drm/drm_aperture.c @@ -168,7 +168,7 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, const struct drm_driver *req_driver) { - return aperture_remove_conflicting_devices(base, size, false, req_driver->name); + return aperture_remove_conflicting_devices(base, size, req_driver->name); } EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers); diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index b378cd1d44d0..a0945027e0df 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -43,7 +43,7 @@ * base = mem->start; * size = resource_size(mem); * - * ret = aperture_remove_conflicting_devices(base, size, false, "example"); + * ret = aperture_remove_conflicting_devices(base, size, "example"); * if (ret) * return ret; * @@ -274,7 +274,6 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) * aperture_remove_conflicting_devices - remove devices in the given range * @base: the aperture's base address in physical memory * @size: aperture size in bytes - * @primary: also kick vga16fb if present; only relevant for VGA devices * @name: a descriptive name of the requesting driver * * This function removes devices that own apertures within @base and @size. @@ -283,7 +282,7 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) * 0 on success, or a negative errno code otherwise */ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name) + const char *name) { /* * If a driver asked to unregister a platform device registered by @@ -329,7 +328,7 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na base = pci_resource_start(pdev, bar); size = pci_resource_len(pdev, bar); - ret = aperture_remove_conflicting_devices(base, size, primary, name); + ret = aperture_remove_conflicting_devices(base, size, name); if (ret) return ret; } diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index ec3f6cf05f8c..54f433e09ab8 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -1073,7 +1073,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) info->screen_size = dio_fb_size; getmem_done: - aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME); + aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME); if (gen2vm) { /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */ diff --git a/include/linux/aperture.h b/include/linux/aperture.h index 442f15a57cad..7248727753be 100644 --- a/include/linux/aperture.h +++ b/include/linux/aperture.h @@ -14,7 +14,7 @@ int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, resource_size_t size); int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name); + const char *name); int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name); #else @@ -26,7 +26,7 @@ static inline int devm_aperture_acquire_for_platform_device(struct platform_devi } static inline int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name) + const char *name) { return 0; } @@ -39,7 +39,6 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, /** * aperture_remove_all_conflicting_devices - remove all existing framebuffers - * @primary: also kick vga16fb if present; only relevant for VGA devices * @name: a descriptive name of the requesting driver * * This function removes all graphics device drivers. Use this function on systems @@ -48,9 +47,9 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, * Returns: * 0 on success, or a negative errno code otherwise */ -static inline int aperture_remove_all_conflicting_devices(bool primary, const char *name) +static inline int aperture_remove_all_conflicting_devices(const char *name) { - return aperture_remove_conflicting_devices(0, (resource_size_t)-1, primary, name); + return aperture_remove_conflicting_devices(0, (resource_size_t)-1, name); } #endif -- cgit From 5ae3716cfdcd286268133867f67d0803847acefc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:07 +0200 Subject: video/aperture: Only remove sysfb on the default vga pci device Instead of calling aperture_remove_conflicting_devices() to remove the conflicting devices, just call to aperture_detach_devices() to detach the device that matches the same PCI BAR / aperture range. Since the former is just a wrapper of the latter plus a sysfb_disable() call, and now that's done in this function but only for the primary devices. This fixes a regression introduced by commit ee7a69aa38d8 ("fbdev: Disable sysfb device registration when removing conflicting FBs"), where we remove the sysfb when loading a driver for an unrelated pci device, resulting in the user losing their efifb console or similar. Note that in practice this only is a problem with the nvidia blob, because that's the only gpu driver people might install which does not come with an fbdev driver of it's own. For everyone else the real gpu driver will restore a working console. Also note that in the referenced bug there's confusion that this same bug also happens on amdgpu. But that was just another amdgpu specific regression, which just happened to happen at roughly the same time and with the same user-observable symptoms. That bug is fixed now, see https://bugzilla.kernel.org/show_bug.cgi?id=216331#c15 Note that we should not have any such issues on non-pci multi-gpu issues, because I could only find two such cases: - SoC with some external panel over spi or similar. These panel drivers do not use drm_aperture_remove_conflicting_framebuffers(), so no problem. - vga+mga, which is a direct console driver and entirely bypasses all this. For the above reasons the cc: stable is just notionally, this patch will need a backport and that's up to nvidia if they care enough. v2: - Explain a bit better why other multi-gpu that aren't pci shouldn't have any issues with making all this fully pci specific. v3 - polish commit message (Javier) v4: - Fix commit message style (i.e., commit 1234 ("...")) - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Fixes: ee7a69aa38d8 ("fbdev: Disable sysfb device registration when removing conflicting FBs") Tested-by: Aaron Plattner Reviewed-by: Javier Martinez Canillas Link: https://bugzilla.kernel.org/show_bug.cgi?id=216303#c28 Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Aaron Plattner Cc: Javier Martinez Canillas Cc: Thomas Zimmermann Cc: Helge Deller Cc: Sam Ravnborg Cc: Alex Deucher Cc: # v5.19+ (if someone else does the backport) Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-8-tzimmermann@suse.de --- drivers/video/aperture.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index a0945027e0df..fa71f8257eed 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -322,15 +322,16 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na if (pdev == vga_default_device()) primary = true; + if (primary) + sysfb_disable(); + for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) { if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) continue; base = pci_resource_start(pdev, bar); size = pci_resource_len(pdev, bar); - ret = aperture_remove_conflicting_devices(base, size, name); - if (ret) - return ret; + aperture_detach_devices(base, size); } if (primary) { -- cgit From 5ca1479cd35d9003040e6ac829380debe89b802b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:08 +0200 Subject: fbdev: Simplify fb_is_primary_device for x86 vga_default_device really is supposed to cover all corners, at least for x86. Additionally checking for rom shadowing should be redundant, because the bios/fw only does that for the boot vga device. If this turns out to be wrong, then most likely that's a special case which should be added to the vgaarb code, not replicated all over. Patch motived by changes to the aperture helpers, which also have this open code in a bunch of places, and which are all removed in a clean-up series. This function here is just for selecting the default fbdev device for fbcon, but I figured for consistency it might be good to throw this patch in on top. Note that the shadow rom check predates vgaarb, which was only wired up in commit 88674088d10c ("x86: Use vga_default_device() when determining whether an fb is primary"). That patch doesn't explain why we still fall back to the shadow rom check. v4: - fix commit message style (i.e., commit 1234 ("...")) - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Daniel Vetter Cc: Helge Deller Cc: Daniel Vetter Cc: Javier Martinez Canillas Cc: Thomas Zimmermann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86@kernel.org Cc: "H. Peter Anvin" Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-9-tzimmermann@suse.de --- arch/x86/video/fbdev.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/fbdev.c index 9fd24846d094..5ec4eafbb981 100644 --- a/arch/x86/video/fbdev.c +++ b/arch/x86/video/fbdev.c @@ -14,26 +14,15 @@ int fb_is_primary_device(struct fb_info *info) { struct device *device = info->device; - struct pci_dev *default_device = vga_default_device(); struct pci_dev *pci_dev; - struct resource *res; if (!device || !dev_is_pci(device)) return 0; pci_dev = to_pci_dev(device); - if (default_device) { - if (pci_dev == default_device) - return 1; - return 0; - } - - res = pci_dev->resource + PCI_ROM_RESOURCE; - - if (res->flags & IORESOURCE_ROM_SHADOW) + if (pci_dev == vga_default_device()) return 1; - return 0; } EXPORT_SYMBOL(fb_is_primary_device); -- cgit From 116b1c5a364bcbdc40be64d4f3ec9dbc32e264dd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 6 Apr 2023 15:21:09 +0200 Subject: video/aperture: Provide a VGA helper for gma500 and internal use The hardware for gma500 is different from the rest, as it uses stolen framebuffer memory that is not available via PCI BAR. The regular PCI removal helper cannot detect the framebuffer, while the non-PCI helper misses possible conflicting VGA devices (i.e., a framebuffer or text console). Gma500 therefore calls both helpers to catch all cases. It's confusing as it implies that there's something about the PCI device that requires ownership management. The relationship between the PCI device and the VGA devices is non-obvious. At worst, readers might assume that calling two functions for clearing aperture ownership is a bug in the driver. Hence, move the PCI removal helper's code for VGA functionality into a separate function and call this function from gma500. Documents the purpose of each call to aperture helpers. The change contains comments and example code form the discussion at [1]. v5: * fix grammar in gma500 comment (Javier) Signed-off-by: Thomas Zimmermann Link: https://patchwork.kernel.org/project/dri-devel/patch/20230404201842.567344-1-daniel.vetter@ffwll.ch/ # 1 Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-10-tzimmermann@suse.de --- drivers/gpu/drm/gma500/psb_drv.c | 48 +++++++++++++++++++++++---------- drivers/video/aperture.c | 58 +++++++++++++++++++++++++++------------- include/linux/aperture.h | 7 +++++ 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 4bb06a89e48d..8b64f61ffaf9 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -7,6 +7,7 @@ * **************************************************************************/ +#include #include #include #include @@ -19,7 +20,6 @@ #include #include -#include #include #include #include @@ -414,25 +414,45 @@ out_err: return ret; } -static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +/* + * Hardware for gma500 is a hybrid device, which both acts as a PCI + * device (for legacy vga functionality) but also more like an + * integrated display on a SoC where the framebuffer simply + * resides in main memory and not in a special PCI bar (that + * internally redirects to a stolen range of main memory) like all + * other integrated PCI display devices implement it. + * + * To catch all cases we need to remove conflicting firmware devices + * for the stolen system memory and for the VGA functionality. As we + * currently cannot easily find the framebuffer's location in stolen + * memory, we remove all framebuffers here. + * + * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then + * we might be able to read the framebuffer range from the + * device. + */ +static int gma_remove_conflicting_framebuffers(struct pci_dev *pdev, + const struct drm_driver *req_driver) { - struct drm_psb_private *dev_priv; - struct drm_device *dev; + resource_size_t base = 0; + resource_size_t size = U32_MAX; /* 4 GiB HW limit */ + const char *name = req_driver->name; int ret; - /* - * We cannot yet easily find the framebuffer's location in memory. So - * remove all framebuffers here. Note that we still want the pci special - * handling to kick out vgacon. - * - * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we - * might be able to read the framebuffer range from the device. - */ - ret = drm_aperture_remove_framebuffers(&driver); + ret = aperture_remove_conflicting_devices(base, size, name); if (ret) return ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); + return __aperture_remove_legacy_vga_devices(pdev); +} + +static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct drm_psb_private *dev_priv; + struct drm_device *dev; + int ret; + + ret = gma_remove_conflicting_framebuffers(pdev, &driver); if (ret) return ret; diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index fa71f8257eed..561be8feca96 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -301,6 +301,37 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si } EXPORT_SYMBOL(aperture_remove_conflicting_devices); +/** + * __aperture_remove_legacy_vga_devices - remove legacy VGA devices of a PCI devices + * @pdev: PCI device + * + * This function removes VGA devices provided by @pdev, such as a VGA + * framebuffer or a console. This is useful if you have a VGA-compatible + * PCI graphics device with framebuffers in non-BAR locations. Drivers + * should acquire ownership of those memory areas and afterwards call + * this helper to release remaining VGA devices. + * + * If your hardware has its framebuffers accessible via PCI BARS, use + * aperture_remove_conflicting_pci_devices() instead. The function will + * release any VGA devices automatically. + * + * WARNING: Apparently we must remove graphics drivers before calling + * this helper. Otherwise the vga fbdev driver falls over if + * we have vgacon configured. + * + * Returns: + * 0 on success, or a negative errno code otherwise + */ +int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev) +{ + /* VGA framebuffer */ + aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); + + /* VGA textmode console */ + return vga_remove_vgacon(pdev); +} +EXPORT_SYMBOL(__aperture_remove_legacy_vga_devices); + /** * aperture_remove_conflicting_pci_devices - remove existing framebuffers for PCI devices * @pdev: PCI device @@ -317,7 +348,7 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na { bool primary = false; resource_size_t base, size; - int bar, ret; + int bar, ret = 0; if (pdev == vga_default_device()) primary = true; @@ -334,24 +365,15 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na aperture_detach_devices(base, size); } - if (primary) { - /* - * If this is the primary adapter, there could be a VGA device - * that consumes the VGA framebuffer I/O range. Remove this - * device as well. - */ - aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); - - /* - * WARNING: Apparently we must kick fbdev drivers before vgacon, - * otherwise the vga fbdev driver falls over. - */ - ret = vga_remove_vgacon(pdev); - if (ret) - return ret; - } + /* + * If this is the primary adapter, there could be a VGA device + * that consumes the VGA framebuffer I/O range. Remove this + * device as well. + */ + if (primary) + ret = __aperture_remove_legacy_vga_devices(pdev); - return 0; + return ret; } EXPORT_SYMBOL(aperture_remove_conflicting_pci_devices); diff --git a/include/linux/aperture.h b/include/linux/aperture.h index 7248727753be..1a9a88b11584 100644 --- a/include/linux/aperture.h +++ b/include/linux/aperture.h @@ -16,6 +16,8 @@ int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, const char *name); +int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev); + int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name); #else static inline int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, @@ -31,6 +33,11 @@ static inline int aperture_remove_conflicting_devices(resource_size_t base, reso return 0; } +static inline int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev) +{ + return 0; +} + static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name) { return 0; -- cgit From e28f6966ac8021d8b677fe3839361db8c9344206 Mon Sep 17 00:00:00 2001 From: Sui Jingfeng Date: Sun, 16 Apr 2023 22:38:49 +0800 Subject: dma-buf/dma-resv.c: fix a typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dma_resv_wait_timeout() function return a value greater than zero on success. Signed-off-by: Sui Jingfeng Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20230416143849.1142779-1-suijingfeng@loongson.cn --- drivers/dma-buf/dma-resv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index 2a594b754af1..b6f71eb00866 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -660,7 +660,7 @@ EXPORT_SYMBOL_GPL(dma_resv_get_singleton); * dma_resv_lock() already * RETURNS * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or - * greater than zer on success. + * greater than zero on success. */ long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage, bool intr, unsigned long timeout) -- cgit From b4b26ab24f8f9ad3aa9fbdfd211e51b051ddb91e Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 17 Apr 2023 16:39:03 +0200 Subject: dt-bindings: display: panel: nt36523: Add Lenovo J606F panel Some Lenovo J606F tablets come with a 2K (2000x1200) 60Hz 11" 5:3 video mode display. Document it and allow rotation while at it (Lenovo mounted it upside down!). Reviewed-by: Linus Walleij Reviewed-by: Krzysztof Kozlowski Signed-off-by: Konrad Dybcio Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230412-topic-lenovopanel-v3-1-bcf9ba4de46f@linaro.org --- .../bindings/display/panel/novatek,nt36523.yaml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml index 0039561ef04c..5f7e4c486094 100644 --- a/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml @@ -19,11 +19,16 @@ allOf: properties: compatible: - items: - - enum: - - xiaomi,elish-boe-nt36523 - - xiaomi,elish-csot-nt36523 - - const: novatek,nt36523 + oneOf: + - items: + - enum: + - xiaomi,elish-boe-nt36523 + - xiaomi,elish-csot-nt36523 + - const: novatek,nt36523 + - items: + - enum: + - lenovo,j606f-boe-nt36523w + - const: novatek,nt36523w reset-gpios: maxItems: 1 @@ -34,6 +39,7 @@ properties: reg: true ports: true + rotation: true backlight: true required: -- cgit From aecb583cb997935fb4f4a667a8013469528a8d53 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 17 Apr 2023 16:39:04 +0200 Subject: drm/panel: nt36523: Add DCS backlight support This chip supports controlling the backlight via DCS commands, on at least some panels. Add support for doing so. Note this may only concern the NT36523*W* variant. Nobody knows, really, there's no docs. Reviewed-by: Linus Walleij Reviewed-by: Jianhua Lu Signed-off-by: Konrad Dybcio Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230412-topic-lenovopanel-v3-2-bcf9ba4de46f@linaro.org --- drivers/gpu/drm/panel/panel-novatek-nt36523.c | 68 +++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index d30dbbfb67b1..b0466abae812 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -5,6 +5,7 @@ * Copyright (c) 2022, 2023 Jianhua Lu */ +#include #include #include #include @@ -53,6 +54,7 @@ struct panel_desc { int (*init_sequence)(struct panel_info *pinfo); bool is_dual_dsi; + bool has_dcs_backlight; }; static inline struct panel_info *to_panel_info(struct drm_panel *panel) @@ -679,6 +681,59 @@ static const struct drm_panel_funcs nt36523_panel_funcs = { .get_modes = nt36523_get_modes, }; +static int nt36523_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static int nt36523_bl_get_brightness(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return brightness; +} + +static const struct backlight_ops nt36523_bl_ops = { + .update_status = nt36523_bl_update_status, + .get_brightness = nt36523_bl_get_brightness, +}; + +static struct backlight_device *nt36523_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 512, + .max_brightness = 4095, + .scale = BACKLIGHT_SCALE_NON_LINEAR, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &nt36523_bl_ops, &props); +} + static int nt36523_probe(struct mipi_dsi_device *dsi) { struct device *dev = &dsi->dev; @@ -730,9 +785,16 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) mipi_dsi_set_drvdata(dsi, pinfo); drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&pinfo->panel); - if (ret) - return dev_err_probe(dev, ret, "failed to get backlight\n"); + if (pinfo->desc->has_dcs_backlight) { + pinfo->panel.backlight = nt36523_create_backlight(dsi); + if (IS_ERR(pinfo->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(pinfo->panel.backlight), + "Failed to create backlight\n"); + } else { + ret = drm_panel_of_backlight(&pinfo->panel); + if (ret) + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + } drm_panel_add(&pinfo->panel); -- cgit From 1eae88fa7b56b3b02d0e003a737fc31d71f3f486 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 17 Apr 2023 16:39:05 +0200 Subject: drm/panel: nt36523: Get orientation from OF Some bright vendors mount their display panels upside down. Add the required pieces to allow for accounting for that. Reviewed-by: Linus Walleij Reviewed-by: Jianhua Lu Signed-off-by: Konrad Dybcio Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230412-topic-lenovopanel-v3-3-bcf9ba4de46f@linaro.org --- drivers/gpu/drm/panel/panel-novatek-nt36523.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index b0466abae812..2c5712ac3037 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -31,6 +31,7 @@ struct panel_info { struct drm_panel panel; struct mipi_dsi_device *dsi[2]; const struct panel_desc *desc; + enum drm_panel_orientation orientation; struct gpio_desc *reset_gpio; struct backlight_device *backlight; @@ -674,11 +675,19 @@ static int nt36523_get_modes(struct drm_panel *panel, return pinfo->desc->num_modes; } +static enum drm_panel_orientation nt36523_get_orientation(struct drm_panel *panel) +{ + struct panel_info *pinfo = to_panel_info(panel); + + return pinfo->orientation; +} + static const struct drm_panel_funcs nt36523_panel_funcs = { .disable = nt36523_disable, .prepare = nt36523_prepare, .unprepare = nt36523_unprepare, .get_modes = nt36523_get_modes, + .get_orientation = nt36523_get_orientation, }; static int nt36523_bl_update_status(struct backlight_device *bl) @@ -785,6 +794,12 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) mipi_dsi_set_drvdata(dsi, pinfo); drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI); + ret = of_drm_get_panel_orientation(dev->of_node, &pinfo->orientation); + if (ret < 0) { + dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, ret); + return ret; + } + if (pinfo->desc->has_dcs_backlight) { pinfo->panel.backlight = nt36523_create_backlight(dsi); if (IS_ERR(pinfo->panel.backlight)) -- cgit From 4f048de28b90abefff2044f450e882576eb746e9 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 17 Apr 2023 16:39:06 +0200 Subject: drm/panel: nt36523: Add Lenovo J606F panel Some Lenovo J606F tablets come with a 2K (2000x1200) 60Hz 11" 5:3 video mode display. Add support for these panels. Reviewed-by: Linus Walleij Reviewed-by: Jianhua Lu Signed-off-by: Konrad Dybcio Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230412-topic-lenovopanel-v3-4-bcf9ba4de46f@linaro.org --- drivers/gpu/drm/panel/panel-novatek-nt36523.c | 486 ++++++++++++++++++++++++++ 1 file changed, 486 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index 2c5712ac3037..c3befa7f253d 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -13,6 +13,8 @@ #include #include +#include