[PATCH] drm/radeon: check the alloc_workqueue return value in radeon_crtc_init()

2023-11-29 Thread Yang Yingliang
From: Yang Yingliang 

check the alloc_workqueue return value in radeon_crtc_init()
to avoid null-ptr-deref.

Fixes: fa7f517cb26e ("drm/radeon: rework page flip handling v4")
Signed-off-by: Yang Yingliang 
---
 drivers/gpu/drm/radeon/radeon_display.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_display.c 
b/drivers/gpu/drm/radeon/radeon_display.c
index 901e75ec70ff..efd18c8d84c8 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -687,11 +687,16 @@ static void radeon_crtc_init(struct drm_device *dev, int 
index)
if (radeon_crtc == NULL)
return;
 
+   radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0);
+   if (!radeon_crtc->flip_queue) {
+   kfree(radeon_crtc);
+   return;
+   }
+
drm_crtc_init(dev, _crtc->base, _crtc_funcs);
 
drm_mode_crtc_set_gamma_size(_crtc->base, 256);
radeon_crtc->crtc_id = index;
-   radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0);
rdev->mode_info.crtcs[index] = radeon_crtc;
 
if (rdev->family >= CHIP_BONAIRE) {
-- 
2.25.1



[PATCH] drm/imagination: fix off by one in pvr_vm_mips_init() error handling

2023-11-29 Thread Dan Carpenter
If the call to vmap() fails the "page_nr" is one element beyond the end
of the mips_data->pt_dma_addr[] and mips_data->pt_pages[] arrays.

The way that this is traditionally written is that we clean up the
partial loop iteration before the goto and then we can say
while (--i >= 0).  At that point we know that all the elements thus
far are initialized so we don't need to have NULL checks.

Fixes: 927f3e0253c1 ("drm/imagination: Implement MIPS firmware processor and 
MMU support")
Signed-off-by: Dan Carpenter 
---
 drivers/gpu/drm/imagination/pvr_vm_mips.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/imagination/pvr_vm_mips.c 
b/drivers/gpu/drm/imagination/pvr_vm_mips.c
index 7268cf6e630b..2bc7181a4c3e 100644
--- a/drivers/gpu/drm/imagination/pvr_vm_mips.c
+++ b/drivers/gpu/drm/imagination/pvr_vm_mips.c
@@ -57,6 +57,7 @@ pvr_vm_mips_init(struct pvr_device *pvr_dev)
   PAGE_SIZE, 
DMA_TO_DEVICE);
if (dma_mapping_error(dev, mips_data->pt_dma_addr[page_nr])) {
err = -ENOMEM;
+   __free_page(mips_data->pt_pages[page_nr]);
goto err_free_pages;
}
}
@@ -79,13 +80,11 @@ pvr_vm_mips_init(struct pvr_device *pvr_dev)
return 0;
 
 err_free_pages:
-   for (; page_nr >= 0; page_nr--) {
-   if (mips_data->pt_dma_addr[page_nr])
-   dma_unmap_page(from_pvr_device(pvr_dev)->dev,
-  mips_data->pt_dma_addr[page_nr], 
PAGE_SIZE, DMA_TO_DEVICE);
+   while (--page_nr >= 0) {
+   dma_unmap_page(from_pvr_device(pvr_dev)->dev,
+  mips_data->pt_dma_addr[page_nr], PAGE_SIZE, 
DMA_TO_DEVICE);
 
-   if (mips_data->pt_pages[page_nr])
-   __free_page(mips_data->pt_pages[page_nr]);
+   __free_page(mips_data->pt_pages[page_nr]);
}
 
return err;
-- 
2.42.0



[bug report] drm/imagination: Implement firmware infrastructure and META FW support

2023-11-29 Thread Dan Carpenter
Hello Sarah Walker,

The patch cc1aeedb98ad: "drm/imagination: Implement firmware
infrastructure and META FW support" from Nov 22, 2023 (linux-next),
leads to the following Smatch static checker warning:

drivers/gpu/drm/imagination/pvr_ccb.c:277 
pvr_kccb_send_cmd_reserved_powered()
warn: odd binop '0x0 & 0xf'

drivers/gpu/drm/imagination/pvr_ccb.c
268 WRITE_ONCE(pvr_dev->kccb.rtn[old_write_offset],
269ROGUE_FWIF_KCCB_RTN_SLOT_NO_RESPONSE);
270 }
271 mb(); /* memory barrier */
272 WRITE_ONCE(ctrl->write_offset, new_write_offset);
273 pvr_dev->kccb.reserved_count--;
274 
275 /* Kick MTS */
276 pvr_fw_mts_schedule(pvr_dev,
--> 277 PVR_FWIF_DM_GP & 
~ROGUE_CR_MTS_SCHEDULE_DM_CLRMSK);
^^
PVR_FWIF_DM_GP is zero.

278 
279 out_unlock:
280 mutex_unlock(_ccb->lock);
281 }

regards,
dan carpenter


[PATCH 2/2] drm/imagination: Fix IS_ERR() vs NULL bug in pvr_request_firmware()

2023-11-29 Thread Dan Carpenter
The pvr_build_firmware_filename() function returns NULL on error.  It
doesn't return error pointers.

Fixes: f99f5f3ea7ef ("drm/imagination: Add GPU ID parsing and firmware loading")
Signed-off-by: Dan Carpenter 
---
 drivers/gpu/drm/imagination/pvr_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index e1dcc4e42087..5389aea7ff21 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -286,8 +286,8 @@ pvr_request_firmware(struct pvr_device *pvr_dev)
 
filename = pvr_build_firmware_filename(pvr_dev, "powervr/rogue",
   PVR_FW_VERSION_MAJOR);
-   if (IS_ERR(filename))
-   return PTR_ERR(filename);
+   if (!filename)
+   return -ENOMEM;
 
/*
 * This function takes a copy of , meaning we can free our
-- 
2.42.0



[PATCH 1/2] drm/imagination: Fix error codes in pvr_device_clk_init()

2023-11-29 Thread Dan Carpenter
There is a cut and paste error so this code returns the wrong variable.

Fixes: 1f88f017e649 ("drm/imagination: Get GPU resources")
Signed-off-by: Dan Carpenter 
---
 drivers/gpu/drm/imagination/pvr_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index 8499becf4fbb..e1dcc4e42087 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -105,12 +105,12 @@ static int pvr_device_clk_init(struct pvr_device *pvr_dev)
 
sys_clk = devm_clk_get_optional(drm_dev->dev, "sys");
if (IS_ERR(sys_clk))
-   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+   return dev_err_probe(drm_dev->dev, PTR_ERR(sys_clk),
 "failed to get sys clock\n");
 
mem_clk = devm_clk_get_optional(drm_dev->dev, "mem");
if (IS_ERR(mem_clk))
-   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+   return dev_err_probe(drm_dev->dev, PTR_ERR(mem_clk),
 "failed to get mem clock\n");
 
pvr_dev->core_clk = core_clk;
-- 
2.42.0



RE: [RFC PATCH 0/6] Supporting GMEM (generalized memory management) for external memory devices

2023-11-29 Thread zhuweixi
Add @Oak to the KFD discussion. I will reply separately elaborating your 
questions on GMEM's difference from HMM/MMU notifiers.

Christian, thanks for pointing me to that AMDKFD discussion. I have read the 
discussion around the AMDKFD skeleton patch and found the previous discussion 
in the following URLs:
https://lore.kernel.org/dri-devel/1405028848-5660-1-git-send-email-oded.gab...@amd.com/#r
https://lore.kernel.org/dri-devel/20140711154231.gb1...@gmail.com/

I believe AMDKFD's original patch was rejected mostly because of inserting 
vendor-specific stuff to the generic core MM.  Jérôme has clearly stated this 
issue in the second URL. If the code is vendor-specific then it has no place in 
core MM, period. 

But why does that vendor-specific solution relate to a generalized solution 
like GMEM? The initial AMDKFD patch doesn't work for Nvidia or Intel.

In fact I think the rejection of the initial AMDKFD patch supports GMEM's idea 
-- there could have been a simpler AMDKFD implementation if the core MM was 
extended by GMEM. Also, after 9 years, there are so many other companies 
building their accelerators over the past few years, especially now the 
GPT-family has made a much bigger success. Don't we want to advance Linux's 
core MM for more friendly and generalized support for the upcoming new vendors? 

Now answering Christian's design concerns:

1. "There are cases that do not want to share CPU address space"
Maybe, but I am not fully convinced. The current case we can find is when a NIC 
utilizes IOMMU for security. For this case, GMEM implemented a generalized VMA 
support and tested it with NICs using both Intel-IOMMU/Arm-SMMU. This cut 600 
LoC of IOVA management code from the IOMMU driver, but it is still not included 
in this RFC patch -- I cannot find other cases demanding this isolation. The 
isolation is also unnecessary -- the NIC can enable the IOMMU SVM feature to 
share the CPU address space. As of KVM, it is essentially a host process that 
utilizes two different MMUs within the same address space, so it fits GMEM's 
design... 

2. "This does not integrate well with the filesystem layer in Linux..."
To be honest, not using a logical page table for anonymous memory is why Linux 
THP fails compared with FreeBSD's superpage, but I am not going to elaborate it 
here. But yes, and I am looking for merging struct 
vm_object->logical_page_table with struct address_space->i_pages. This will 
make a natural support for devices oversubscribing both host DRAM and disks. As 
explained in my cover letter, struct vm_object borrows FreeBSD's VM design -- 
it provides a unified abstraction layer for anonymous, file-backed memory and 
etc. 

3. "Requirements to CPU address space management and device address space 
management are just massively different. For example huge and giant pages are a 
must have for modern devices..."
I think you are asking two questions. First, is VA space a problem? GMEM 
assumes that device VA space should be covered by CPU VA space (sorry i386), 
should we consider devices using more VA bits than the CPU (64-bit)? Second, 
yes, modern accelerators definitely demand large pages. From my experience, 
both Nvidia GPUs and Huawei Ascend NPUs suffer from performance issues using 
page sizes smaller than 2MB. However, GMEM does not stop a device to use a 
different page size. A device can choose a 64KB page size running on an X86 
host, and GMEM will still work -- whether the CPU page fault goes to 2MB-THP or 
4KB paths, GMEM looks up stuct vm_object to examine whether a 
virtual-to-physical mapping exist on the device page table. If the faulted VA 
is covered by a 64KB device mapping, a 4KB sub-page must at least be migrated 
and the 64KB device mapping must be invoked. The device can either keep the 
rest 15 4KB physical pages and create 15 "contiguous" (with a hole) 4KB 
mappings or simply wait for the next device page fault to migrate one 4KB page 
and install a 64KB mapping. The policy is left for device to choose, but the 
mechanisms are provided by GMEM. So, the current assumption of GMEM is just 
that your device page sizes must be multiples of CPU base page size.

4. "The argument that a shared memory management leads to less bugs has also 
absolutely not be proven true. Instead we literally spend month if not years 
hunting down bugs which resulted from interaction between CPU and devices."
This is another case supporting GMEM. Don't developers want to let GMEM handle 
the CPU-device interaction so that they can waive months of debugging cost?

PS, hmadvise() is based on the idea of Nvidia's cudaMemAdvise() which provides 
abundant and useful memory policies. HMM extended mbind() instead.

-Weixi

-Original Message-
From: Christian König  
Sent: Wednesday, November 29, 2023 11:22 PM
To: zhuweixi ; Dave Airlie 
Cc: linux...@kvack.org; linux-ker...@vger.kernel.org; 
a...@linux-foundation.org; weixi@openeuler.sh; mgor...@suse.de; 
jgli...@redhat.com; 

Re: [PATCH] drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg()

2023-11-29 Thread Christian König

Am 29.11.23 um 17:03 schrieb Alex Deucher:

On Wed, Nov 29, 2023 at 10:47 AM Christian König
 wrote:

Am 29.11.23 um 16:22 schrieb Nikita Zhandarovich:

While improbable, there may be a chance of hitting integer
overflow when the result of radeon_get_ib_value() gets shifted
left.

Avoid it by casting one of the operands to larger data type (u64).

Found by Linux Verification Center (linuxtesting.org) with static
analysis tool SVACE.

Well IIRC cb_color_bo_offset is just 32bits anyway, so this doesn't
change anything.

All of the GPU addresses in the structure are u64.  The registers are
32 bits which is why they are 256 byte aligned.  That said, I think
the MC on the chips supported by this code are only 32 bits so we
shouldn't see any addresses greater than 32 bits, but this seems like
good to do from a coding perspective.  Otherwise, we'll keep getting
this patch.


Just double checked it, in evergreen_cs_track the fields are just 
32bits, but in r600_cs_track they are 64bits.


No idea if we every used the full address space, but it's probably a 
good point to merge it just to silence the static checker warning.


Christian.



Alex


Alex


Regards,
Christian.


Fixes: 1729dd33d20b ("drm/radeon/kms: r600 CS parser fixes")
Signed-off-by: Nikita Zhandarovich 
---
   drivers/gpu/drm/radeon/r600_cs.c | 4 ++--
   1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 638f861af80f..6cf54a747749 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -1275,7 +1275,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, 
u32 reg, u32 idx)
   return -EINVAL;
   }
   tmp = (reg - CB_COLOR0_BASE) / 4;
- track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
+ track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, idx) 
<< 8;
   ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0x);
   track->cb_color_base_last[tmp] = ib[idx];
   track->cb_color_bo[tmp] = reloc->robj;
@@ -1302,7 +1302,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, 
u32 reg, u32 idx)
   "0x%04X\n", reg);
   return -EINVAL;
   }
- track->htile_offset = radeon_get_ib_value(p, idx) << 8;
+ track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8;
   ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0x);
   track->htile_bo = reloc->robj;
   track->db_dirty = true;




RE: [PATCH v5 3/5] mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file pages (v5)

2023-11-29 Thread Kasireddy, Vivek
Hi Christoph,

> 
> > +static struct page *alloc_file_page(struct file *file, pgoff_t idx)
> 
> alloc_file_pages seems like a weird name for something that assumes
> it is called either on a hugetlbfs or shmemfs file (without any
I see your concern. The word "file" does make it look like this API works
with all kinds of files although it is meant to specifically work with files 
that
belong to shmemfs or hugetlbfs. Since it is intended to work with memfds
in particular, I'll rename this helper alloc_memfd_page(). I think it also
makes sense to do s/file/memfd in this whole patch. Does this sound ok?

> asserts that this is true).  gup.c also seems like a very odd place
> for such a helper.
I only created this helper to cleanly separate lookup and creation and to
reduce the level of indentation in pin_user_pages_fd(). Anyway, would
mm/memfd.c be a more appropriate location?

> 
> > + * Attempt to pin pages associated with a file that belongs to either
> shmem
> > + * or hugetlb.
> 
> Why do we need a special case for hugetlb or shmemfs?
As mentioned above, this API is mainly intended for memfds and FWICS,
memfds are backed by files from either shmemfs or hugetlbfs.

> 
> > +   if (!file)
> > +   return -EINVAL;
> > +
> > +   if (!shmem_file(file) && !is_file_hugepages(file))
> > +   return -EINVAL;
> 
> Indentation is messed up here.
Ok, will fix it in next version.

> 
> > +   for (i = 0; i < nr_pages; i++) {
> > +   /*
> > +* In most cases, we should be able to find the page
> > +* in the page cache. If we cannot find it, we try to
> > +* allocate one and add it to the page cache.
> > +*/
> > +retry:
> > +   folio = __filemap_get_folio(file->f_mapping,
> > +   start + i,
> > +   FGP_ACCESSED, 0);
> 
> __filemap_get_folio is a very inefficient way to find a
> contiguous range of folios, I'd suggest to look into something that
> batches instead.
Ok, I will try to explore using filemap_get_folios_contig() or other
related APIs to make the lookup more efficient.

> 
> > +   page = IS_ERR(folio) ? NULL: >page;
> > +   if (!page) {
> > +   page = alloc_file_page(file, start + i);
> > +   if (IS_ERR(page)) {
> > +   ret = PTR_ERR(page);
> > +   if (ret == -EEXIST)
> > +   goto retry;
> > +   goto err;
> > +   }
> 
> This mix of folios and pages is odd.  Especially as hugetlbfs by
> definitions uses large folios.
Yeah, it does look odd but I ultimately need a list of pages to call
check_and_migrate_movable_pages() and also to populate a scatterlist.

Thanks,
Vivek



[PATCH] backlight: ili922x: add an error code check in ili922x_write

2023-11-29 Thread Su Hui
Clang static analyzer complains that value stored to 'ret' is never read.
Return the error code when spi_sync() failed.

Signed-off-by: Su Hui 
---
 drivers/video/backlight/ili922x.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/backlight/ili922x.c 
b/drivers/video/backlight/ili922x.c
index e7b6bd827986..47b872ac64a7 100644
--- a/drivers/video/backlight/ili922x.c
+++ b/drivers/video/backlight/ili922x.c
@@ -269,6 +269,10 @@ static int ili922x_write(struct spi_device *spi, u8 reg, 
u16 value)
spi_message_add_tail(_regindex, );
 
ret = spi_sync(spi, );
+   if (ret < 0) {
+   dev_err(>dev, "Error sending SPI message 0x%x", ret);
+   return ret;
+   }
 
spi_message_init();
tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_REG,
-- 
2.30.2



Re: [PATCH RFC v7 07/10] drm/atomic: Loosen FB atomic checks

2023-11-29 Thread Dmitry Baryshkov
On Sat, 28 Oct 2023 at 01:33, Jessica Zhang  wrote:
>
> Loosen the requirements for atomic and legacy commit so that, in cases
> where pixel_source != FB, the commit can still go through.
>
> This includes adding framebuffer NULL checks in other areas to account for
> FB being NULL when non-FB pixel sources are enabled.
>
> To disable a plane, the pixel_source must be NONE or the FB must be NULL
> if pixel_source == FB.
>
> Signed-off-by: Jessica Zhang 
> ---
>  drivers/gpu/drm/drm_atomic.c| 21 ++--
>  drivers/gpu/drm/drm_atomic_helper.c | 39 
> +
>  include/drm/drm_atomic_helper.h |  4 ++--
>  include/drm/drm_plane.h | 29 +++
>  4 files changed, 64 insertions(+), 29 deletions(-)

Reviewed-by: Dmitry Baryshkov 


-- 
With best wishes
Dmitry


Re: [PATCH RFC v7 02/10] drm: Introduce solid fill DRM plane property

2023-11-29 Thread Dmitry Baryshkov
On Sat, 28 Oct 2023 at 01:33, Jessica Zhang  wrote:
>
> Document and add support for solid_fill property to drm_plane. In
> addition, add support for setting and getting the values for solid_fill.
>
> To enable solid fill planes, userspace must assign a property blob to
> the "solid_fill" plane property containing the following information:
>
> struct drm_mode_solid_fill {
> u32 r, g, b, pad;
> };
>
> Acked-by: Harry Wentland 
> Acked-by: Sebastian Wick 
> Signed-off-by: Jessica Zhang 

Reviewed-by: Dmitry Baryshkov 

> ---
>  drivers/gpu/drm/drm_atomic_state_helper.c |  9 
>  drivers/gpu/drm/drm_atomic_uapi.c | 26 ++
>  drivers/gpu/drm/drm_blend.c   | 30 ++
>  include/drm/drm_blend.h   |  1 +
>  include/drm/drm_plane.h   | 36 
> +++
>  include/uapi/drm/drm_mode.h   | 24 +
>  6 files changed, 126 insertions(+)



-- 
With best wishes
Dmitry


Re: [PATCH v8 5/7] drm/msm/dp: incorporate pm_runtime framework into DP driver

2023-11-29 Thread Dmitry Baryshkov
On Wed, 29 Nov 2023 at 19:47, Kuogee Hsieh  wrote:
>
> Currently DP driver is executed independent of PM runtime framework.
> This leads msm eDP panel can not being detected by edp_panel driver
> during generic_edp_panel_probe() due to AUX DPCD read failed at
> edp panel driver. Incorporate PM runtime framework into DP driver so
> that host controller's power and clocks are enable/disable through
> PM runtime mechanism.  Once PM runtime framework is incorporated into
> DP driver, waking up device from power up path is not necessary. Hence
> remove it.
>
> After incorporating pm_runtime framework into eDP/DP driver,
> dp_pm_suspend() to handle power off both DP phy and controller during
> suspend and dp_pm_resume() to handle power on both DP phy and controller
> during resume are not necessary. Therefore both dp_pm_suspend() and
> dp_pm_resume() are dropped and replace with dp_pm_runtime_suspend() and
> dp_pm_runtime_resume() respectively.

There were comments for v7 of this patch that were not handled in this
revision. Please take care of them.

>
> Changes in v7:
> -- add comments to dp_pm_runtime_resume()
> -- add comments to dp_bridge_hpd_enable()
> -- delete dp->hpd_state = ST_DISCONNECTED from dp_bridge_hpd_notify()
>
> Changes in v6:
> -- delete dp_power_client_deinit(dp->power);
> -- remove if (!dp->dp_display.is_edp) condition checkout at plug_handle()
> -- remove if (!dp->dp_display.is_edp) condition checkout at unplug_handle()
> -- add IRQF_NO_AUTOEN to devm_request_irq()
> -- add enable_irq() and disable_irq() to pm_runtime_resume()/suspend()
> -- del dp->hpd_state = ST_DISCONNECTED from dp_bridge_hpd_disable()
>
> Changes in v5:
> -- remove pm_runtime_put_autosuspend feature, use pm_runtime_put_sync()
> -- squash add pm_runtime_force_suspend()/resume() patch into this patch
>
> Changes in v4:
> -- reworded commit text to explain why pm_framework is required for
>edp panel
> -- reworded commit text to explain autosuspend is choiced
> -- delete EV_POWER_PM_GET and PM_EV_POWER_PUT from changes #3
> -- delete dp_display_pm_get() and dp_display_pm_Put() from changes #3
> -- return value from pm_runtime_resume_and_get() directly
> -- check return value of devm_pm_runtime_enable()
> -- delete pm_runtime_xxx from dp_display_remove()
> -- drop dp_display_host_init() from EV_HPD_INIT_SETUP
> -- drop both dp_pm_prepare() and dp_pm_compete() from this change
> -- delete ST_SUSPENDED state
> -- rewording commit text to add more details regrading the purpose
>of this change
>
> Changes in v3:
> -- incorporate removing pm_runtime_xx() from dp_pwer.c to this patch
> -- use pm_runtime_resume_and_get() instead of pm_runtime_get()
> -- error checking pm_runtime_resume_and_get() return value
> -- add EV_POWER_PM_GET and PM_EV_POWER_PUT to handle HPD_GPIO case
> -- replace dp_pm_suspend() with pm_runtime_force_suspend()
> -- replace dp_pm_resume() with pm_runtime_force_resume()
>
> Signed-off-by: Kuogee Hsieh 
> Reviewed-by: Dmitry Baryshkov 
> ---
>  drivers/gpu/drm/msm/dp/dp_aux.c |   5 +
>  drivers/gpu/drm/msm/dp/dp_display.c | 181 
> ++--
>  drivers/gpu/drm/msm/dp/dp_power.c   |  16 
>  drivers/gpu/drm/msm/dp/dp_power.h   |  11 ---
>  4 files changed, 75 insertions(+), 138 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
> index 8e3b677..10b6eeb 100644
> --- a/drivers/gpu/drm/msm/dp/dp_aux.c
> +++ b/drivers/gpu/drm/msm/dp/dp_aux.c
> @@ -291,6 +291,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
> return -EINVAL;
> }
>
> +   ret = pm_runtime_resume_and_get(dp_aux->dev);
> +   if (ret)
> +   return  ret;
> +
> mutex_lock(>mutex);
> if (!aux->initted) {
> ret = -EIO;
> @@ -364,6 +368,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
>
>  exit:
> mutex_unlock(>mutex);
> +   pm_runtime_put_sync(dp_aux->dev);
>
> return ret;
>  }
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index a99a786..9520d83 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -49,7 +49,6 @@ enum {
> ST_CONNECTED,
> ST_DISCONNECT_PENDING,
> ST_DISPLAY_OFF,
> -   ST_SUSPENDED,
>  };
>
>  enum {
> @@ -309,10 +308,6 @@ static void dp_display_unbind(struct device *dev, struct 
> device *master,
> struct dp_display_private *dp = dev_get_dp_display_private(dev);
> struct msm_drm_private *priv = dev_get_drvdata(master);
>
> -   /* disable all HPD interrupts */
> -   if (dp->core_initialized)
> -   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, 
> false);
> -
> kthread_stop(dp->ev_tsk);
>
> of_dp_aux_depopulate_bus(dp->aux);
> @@ -542,6 +537,7 @@ static int dp_hpd_plug_handle(struct dp_display_private 
> *dp, u32 data)
>  {
> u32 state;
>  

Re: [PATCH v2] drm/msm/dpu: Capture dpu snapshot when frame_done_timer timeouts

2023-11-29 Thread Dmitry Baryshkov
On Wed, 29 Nov 2023 at 20:42, Paloma Arellano  wrote:
>
> Trigger a devcoredump to dump dpu registers and capture the drm atomic
> state when the frame_done_timer timeouts.
>
> Signed-off-by: Paloma Arellano 
> ---
>
> Changes since v1:
> - Optimized the format in which frame_done_timeout_cnt is incremented

Reviewed-by: Dmitry Baryshkov 

>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)


-- 
With best wishes
Dmitry


Re: [PATCH v1] drm/msm/dpu: improve DSC allocation

2023-11-29 Thread Dmitry Baryshkov
On Wed, 29 Nov 2023 at 22:31, Kuogee Hsieh  wrote:
>
> A DCE (Display Compression Engine) contains two DSC hard slice encoders.
> Each DCE start with even DSC encoder index followed by an odd DSC encoder
> index. Each encoder can work independently. But Only two DSC encoders from
> same DCE can be paired to work together to support merge mode. In addition,
> the DSC with even index have to mapping to even pingpong index and DSC with
> odd index have to mapping to odd pingpong index at its data path. This patch
> improve DSC allocation mechanism with consideration of above factors.

Is this applicable to old DSC 1.1 encoders?

>
> Signed-off-by: Kuogee Hsieh 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 94 
> +-
>  1 file changed, 82 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index f9215643..427d70d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -466,24 +466,94 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
>struct drm_encoder *enc,
>const struct msm_display_topology *top)
>  {
> -   int num_dsc = top->num_dsc;
> -   int i;
> +   int num_dsc = 0;
> +   int i, pp_idx;
> +   bool pair = false;
> +   int dsc_idx[DSC_MAX - DSC_0];
> +   uint32_t pp_to_enc_id[PINGPONG_MAX - PINGPONG_0];
> +   int pp_max = PINGPONG_MAX - PINGPONG_0;
> +
> +   if (!top->num_dsc || !top->num_intf)
> +   return 0;
> +
> +   /*
> +* Truth:
> +* 1) every layer mixer only connects to one pingpong
> +* 2) no pingpong split -- two layer mixers shared one pingpong
> +* 3) each DSC engine contains two dsc encoders
> +*-- index(0,1), index (2,3),... etc
> +* 4) dsc pair can only happens with same DSC engine except 4 dsc
> +*merge mode application (8k) which need two DSC engines
> +* 5) odd pingpong connect to odd dsc
> +* 6) even pingpong connect even dsc
> +*/
> +
> +   /* num_dsc should be either 1, 2 or 4 */
> +   if (top->num_dsc > top->num_intf)   /* merge mode */
> +   pair = true;
> +
> +   /* fill working copy with pingpong list */
> +   memcpy(pp_to_enc_id, global_state->pingpong_to_enc_id, 
> sizeof(pp_to_enc_id));
> +
> +   for (i = 0; i < ARRAY_SIZE(rm->dsc_blks); i++) {

&& num_dsc < top->num_dsc

> +   if (!rm->dsc_blks[i])   /* end of dsc list */
> +   break;

I'd say, it's `continue' instead, let's just skip the index.

>
> -   /* check if DSC required are allocated or not */
> -   for (i = 0; i < num_dsc; i++) {
> -   if (!rm->dsc_blks[i]) {
> -   DPU_ERROR("DSC %d does not exist\n", i);
> -   return -EIO;
> +   if (global_state->dsc_to_enc_id[i]) {   /* used */
> +   /* consective dsc index to be paired */
> +   if (pair && num_dsc) {  /* already start pairing, re 
> start */
> +   num_dsc = 0;
> +   /* fill working copy with pingpong list */
> +   memcpy(pp_to_enc_id, 
> global_state->pingpong_to_enc_id,
> +   
> sizeof(pp_to_enc_id));
> +   }
> +   continue;
> }
>
> -   if (global_state->dsc_to_enc_id[i]) {
> -   DPU_ERROR("DSC %d is already allocated\n", i);
> -   return -EIO;
> +   /* odd index can not become start of pairing */
> +   if (pair && (i & 0x01) && !num_dsc)
> +   continue;

After looking at all conditions, can we have two different helpers?
One which allocates a single DSC and another one which allocates a
pair. For the pair you can skip odd indices at all and just check if
DSC_i and DSC_i+1 are free.

> +
> +   /*
> +* find the pingpong index which had been reserved
> +* previously at layer mixer allocation
> +*/
> +   for (pp_idx = 0; pp_idx < pp_max; pp_idx++) {
> +   if (pp_to_enc_id[pp_idx] == enc->base.id)
> +   break;
> }
> +
> +   /*
> +* dsc even index must map to pingpong even index
> +* dsc odd index must map to pingpong odd index
> +*/
> +   if ((i & 0x01) != (pp_idx & 0x01))
> +   continue;
> +
> +   /*
> +* delete pp_idx so that it can not be found at next search
> +* in the case of pairing
> +*/
> +   pp_to_enc_id[pp_idx] = NULL;
> +
> + 

Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Luben Tuikov
On 2023-11-29 22:36, Luben Tuikov wrote:
> On 2023-11-29 15:49, Alex Deucher wrote:
>> On Wed, Nov 29, 2023 at 3:10 PM Alex Deucher  wrote:
>>>
>>> Actually I think I see the problem.  I'll try and send out a patch
>>> later today to test.
>>
>> Does the attached patch fix it?
> 
> Thanks for the patch, Alex.
> 
> Is it possible for AMD to also reproduce this issue and test this patch on a 
> Navi23 system?
> 
>> From 96e75b5218f7a124eafa53853681eef8fe567ab8 Mon Sep 17 00:00:00 2001
>> From: Alex Deucher 
>> Date: Wed, 29 Nov 2023 15:44:25 -0500
>> Subject: [PATCH] drm/amdgpu: fix buffer funcs setting order on suspend
>>
>> We need to make disable this after the last eviction
> 
> "make disable" --> "disable"
> 
>> call, but before we disable the SDMA IP.
>>
>> Fixes: b70438004a14 ("drm/amdgpu: move buffer funcs setting up a level")
>> Link: 
>> https://lists.freedesktop.org/archives/amd-gfx/2023-November/101197.html
> 
> Link: https://lore.kernel.org/r/87edgv4x3i@vps.thesusis.net
> 
> Let's link the start of the thread.
> 
> Regards,
> Luben
> 
>> Signed-off-by: Alex Deucher 
>> Cc: Phillip Susi 
>> Cc: Luben Tuikov 
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index b5edf40b5d03..78553e027db4 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -4531,8 +4531,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool 
>> fbcon)
>>  
>>  amdgpu_ras_suspend(adev);
>>  
>> -amdgpu_ttm_set_buffer_funcs_status(adev, false);
>> -
>>  amdgpu_device_ip_suspend_phase1(adev);
>>  
>>  if (!adev->in_s0ix)
>> @@ -4542,6 +4540,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool 
>> fbcon)
>>  if (r)
>>  return r;
>>  
>> +amdgpu_ttm_set_buffer_funcs_status(adev, false);
>> +

If you're moving this past phase 1, there's another instance in 
amdgpu_device_ip_suspend(),
which may need to be moved down.

Regards,
Luben

>>  amdgpu_fence_driver_hw_fini(adev);
>>  
>>  amdgpu_device_ip_suspend_phase2(adev);
> 
>>
>> Alex
>>
>>>
>>> Alex
>>>
>>> On Wed, Nov 29, 2023 at 1:52 PM Alex Deucher  wrote:

 On Wed, Nov 29, 2023 at 11:41 AM Luben Tuikov  wrote:
>
> On 2023-11-29 10:22, Alex Deucher wrote:
>> On Wed, Nov 29, 2023 at 8:50 AM Alex Deucher  
>> wrote:
>>>
>>> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  
>>> wrote:

 On 2023-11-28 17:13, Alex Deucher wrote:
> On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  
> wrote:
>>
>> Alex Deucher  writes:
>>
 In that case those are the already known problems with the 
 scheduler
 changes, aren't they?
>>>
>>> Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
>>> misunderstanding what the original report was actually testing.  If 
>>> it
>>> was 6.7, then try reverting:
>>> 56e449603f0ac580700621a356d35d5716a62ce5
>>> b70438004a14f4d0f9890b3297cd66248728546c
>>
>> At some point it was suggested that I file a gitlab issue, but I took
>> this to mean it was already known and being worked on.  -rc3 came out
>> today and still has the problem.  Is there a known issue I could 
>> track?
>>
>
> At this point, unless there are any objections, I think we should just
> revert the two patches
 Uhm, no.

 Why "the two" patches?

 This email, part of this thread,

 https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/

 clearly states that reverting *only* this commit,
 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable number 
 of run-queues
 *does not* mitigate the failed suspend. (Furthermore, this commit 
 doesn't really change
 anything operational, other than using an allocated array, instead of 
 a static one, in DRM,
 while the 2nd patch is solely contained within the amdgpu driver code.)

 Leaving us with only this change,
 b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
 to be at fault, as the kernel log attached in the linked email above 
 shows.

 The conclusion is that only b70438004a14f4 needs reverting.
>>>
>>> b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
>>> 56e449603f0ac5 breaks amdgpu.
>>
>> We can try and re-enable it in the next kernel.  I'm just not sure
>> we'll be able to fix this in time for 6.7 with the holidays and all
>> and I don't want to cause a lot of scheduler churn at the end of the
>> 6.7 cycle if we hold off and try and 

Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Luben Tuikov
On 2023-11-29 15:49, Alex Deucher wrote:
> On Wed, Nov 29, 2023 at 3:10 PM Alex Deucher  wrote:
>>
>> Actually I think I see the problem.  I'll try and send out a patch
>> later today to test.
> 
> Does the attached patch fix it?

Thanks for the patch, Alex.

Is it possible for AMD to also reproduce this issue and test this patch on a 
Navi23 system?

> From 96e75b5218f7a124eafa53853681eef8fe567ab8 Mon Sep 17 00:00:00 2001
> From: Alex Deucher 
> Date: Wed, 29 Nov 2023 15:44:25 -0500
> Subject: [PATCH] drm/amdgpu: fix buffer funcs setting order on suspend
> 
> We need to make disable this after the last eviction

"make disable" --> "disable"

> call, but before we disable the SDMA IP.
> 
> Fixes: b70438004a14 ("drm/amdgpu: move buffer funcs setting up a level")
> Link: https://lists.freedesktop.org/archives/amd-gfx/2023-November/101197.html

Link: https://lore.kernel.org/r/87edgv4x3i@vps.thesusis.net

Let's link the start of the thread.

Regards,
Luben

> Signed-off-by: Alex Deucher 
> Cc: Phillip Susi 
> Cc: Luben Tuikov 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index b5edf40b5d03..78553e027db4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -4531,8 +4531,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool 
> fbcon)
>  
>   amdgpu_ras_suspend(adev);
>  
> - amdgpu_ttm_set_buffer_funcs_status(adev, false);
> -
>   amdgpu_device_ip_suspend_phase1(adev);
>  
>   if (!adev->in_s0ix)
> @@ -4542,6 +4540,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool 
> fbcon)
>   if (r)
>   return r;
>  
> + amdgpu_ttm_set_buffer_funcs_status(adev, false);
> +
>   amdgpu_fence_driver_hw_fini(adev);
>  
>   amdgpu_device_ip_suspend_phase2(adev);

> 
> Alex
> 
>>
>> Alex
>>
>> On Wed, Nov 29, 2023 at 1:52 PM Alex Deucher  wrote:
>>>
>>> On Wed, Nov 29, 2023 at 11:41 AM Luben Tuikov  wrote:

 On 2023-11-29 10:22, Alex Deucher wrote:
> On Wed, Nov 29, 2023 at 8:50 AM Alex Deucher  
> wrote:
>>
>> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  
>> wrote:
>>>
>>> On 2023-11-28 17:13, Alex Deucher wrote:
 On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  
 wrote:
>
> Alex Deucher  writes:
>
>>> In that case those are the already known problems with the scheduler
>>> changes, aren't they?
>>
>> Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
>> misunderstanding what the original report was actually testing.  If 
>> it
>> was 6.7, then try reverting:
>> 56e449603f0ac580700621a356d35d5716a62ce5
>> b70438004a14f4d0f9890b3297cd66248728546c
>
> At some point it was suggested that I file a gitlab issue, but I took
> this to mean it was already known and being worked on.  -rc3 came out
> today and still has the problem.  Is there a known issue I could 
> track?
>

 At this point, unless there are any objections, I think we should just
 revert the two patches
>>> Uhm, no.
>>>
>>> Why "the two" patches?
>>>
>>> This email, part of this thread,
>>>
>>> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/
>>>
>>> clearly states that reverting *only* this commit,
>>> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable number 
>>> of run-queues
>>> *does not* mitigate the failed suspend. (Furthermore, this commit 
>>> doesn't really change
>>> anything operational, other than using an allocated array, instead of a 
>>> static one, in DRM,
>>> while the 2nd patch is solely contained within the amdgpu driver code.)
>>>
>>> Leaving us with only this change,
>>> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
>>> to be at fault, as the kernel log attached in the linked email above 
>>> shows.
>>>
>>> The conclusion is that only b70438004a14f4 needs reverting.
>>
>> b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
>> 56e449603f0ac5 breaks amdgpu.
>
> We can try and re-enable it in the next kernel.  I'm just not sure
> we'll be able to fix this in time for 6.7 with the holidays and all
> and I don't want to cause a lot of scheduler churn at the end of the
> 6.7 cycle if we hold off and try and fix it.  Reverting seems like the
> best short term solution.

 A lot of subsequent code has come in since commit 56e449603f0ac5, as it 
 opened
 the opportunity for a 1-to-1 relationship between an entity and a 
 scheduler.
 (Should've always been the case, from the outset. Not sure why it was 
 coded as
 a 

Re: [PATCH v2 11/12] drm/rockchip: vop2: Add debugfs support

2023-11-29 Thread Andy Yan

Hi Sascha:

On 11/29/23 20:59, Sascha Hauer wrote:

On Wed, Nov 29, 2023 at 07:01:37PM +0800, Andy Yan wrote:

Hi Sascha:



On 11/29/23 16:52, Sascha Hauer wrote:

On Mon, Nov 27, 2023 at 06:56:34PM +0800, Andy Yan wrote:

 Hi Sascha:

 thanks for you review.

 On 11/27/23 18:13, Sascha Hauer wrote:

   On Wed, Nov 22, 2023 at 08:56:01PM +0800, Andy Yan wrote:

   From: Andy Yan [1]

   /sys/kernel/debug/dri/vop2/summary:  dump vop display state
   /sys/kernel/debug/dri/vop2/regs: dump whole vop registers
   /sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
   activated modules

   Signed-off-by: Andy Yan [2]
   ---

   (no changes since v1)

drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 399 +++
1 file changed, 399 insertions(+)

   diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
   index 9eecbe1f71f9..4a2342209c15 100644
   --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
   +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
   @@ -27,6 +27,7 @@
#include 
#include 
#include 
   +#include 
#include 
#include 

   @@ -187,6 +188,7 @@ struct vop2 {
*/
   u32 registered_num_wins;

   +   struct resource *res;
   void __iomem *regs;
   struct regmap *map;

   @@ -228,6 +230,44 @@ struct vop2 {
#define vop2_output_if_is_lvds(x)  (x == ROCKCHIP_VOP2_EP_LVDS0 || x == 
ROCKCHIP_VOP2_EP_LVDS1)
#define vop2_output_if_is_dpi(x)   (x == ROCKCHIP_VOP2_EP_RGB0)

   +struct vop2_regs_dump {
   +   const char *name;
   +   u32 base;
   +   u32 en_reg;
   +   u32 en_val;
   +   u32 en_mask;
   +};
   +
   +/*
   + * bus-format types.
   + */
   +struct drm_bus_format_enum_list {
   +   int type;
   +   const char *name;
   +};
   +
   +static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
   +   { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
   +   { MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" },
   +   { MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" },
   +   { MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" },
   +   { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" },
   +   { MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" },
   +   { MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
   +   { MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
   +   { MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
   +   { MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
   +   { MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
   +   { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" },
   +   { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" },
   +   { MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" },
   +   { MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" },
   +   { MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" },
   +   { MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" },
   +   { MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" },
   +};
   +static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
   +
static const struct regmap_config vop2_regmap_config;

static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
   @@ -2487,6 +2527,363 @@ static const struct drm_crtc_helper_funcs 
vop2_crtc_helper_funcs = {
   .atomic_disable = vop2_crtc_atomic_disable,
};

   +static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct 
seq_file *s)
   +{
   +   struct drm_connector_list_iter conn_iter;
   +   struct drm_connector *connector;
   +
   +   drm_connector_list_iter_begin(crtc->dev, _iter);
   +   drm_for_each_connector_iter(connector, _iter) {
   +   if (crtc->state->connector_mask & 
drm_connector_mask(connector))
   +   seq_printf(s, "Connector: %s\n", 
connector->name);
   +
   +   }
   +   drm_connector_list_iter_end(_iter);
   +}
   +
   +static int vop2_plane_state_dump(struct seq_file *s, struct drm_plane 
*plane)
   +{
   +   struct vop2_win *win = to_vop2_win(plane);
   +   struct drm_plane_state *pstate = plane->state;
   +   struct drm_rect *src, *dst;
   +   struct drm_framebuffer *fb;
   +   struct drm_gem_object *obj;
   +   struct rockchip_gem_object *rk_obj;
   +   bool xmirror;
   +   bool ymirror;
   +   bool rotate_270;
   +   bool rotate_90;
   +   dma_addr_t fb_addr;
   +   int i;
   +
   +   seq_printf(s, "%s: %s\n", win->data->name, pstate->crtc ? "ACTIVE" : 
"DISABLED");
   +   if (!pstate || !pstate->fb)
   +   return 0;
   +
   +   fb = pstate->fb;
   +   src = >src;
   +   dst = >dst;
   +   xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
   +   ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
   +   rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
   +   rotate_90 = pstate->rotation & 

Re: [PATCH v3 10/11] drm/mediatek: Support CRC in VDOSYS0

2023-11-29 Thread 胡俊光


[PATCH] nouveau/tu102: flush all pdbs on vmm flush

2023-11-29 Thread Dave Airlie
From: Dave Airlie 

This is a hackaround a bug exposed with the GSP code, I'm not sure
what it happening exactly, but it appears some of our flushes don't
result in proper tlb invalidation for out BAR2 and we get a BAR2
fault from GSP and it all dies.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c
index e34bc6076401..8379e72d77ab 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c
@@ -31,7 +31,7 @@ tu102_vmm_flush(struct nvkm_vmm *vmm, int depth)
 
type |= 0x0001; /* PAGE_ALL */
if (atomic_read(>engref[NVKM_SUBDEV_BAR]))
-   type |= 0x0004; /* HUB_ONLY */
+   type |= 0x0006; /* HUB_ONLY | ALL PDB (hack) */
 
mutex_lock(>mmu->mutex);
 
-- 
2.42.0



Re: [PATCH 3/3] drm/amd/display: Support DRM_AMD_DC_FP on RISC-V

2023-11-29 Thread Nathan Chancellor
On Thu, Nov 23, 2023 at 02:23:01PM +, Conor Dooley wrote:
> On Tue, Nov 21, 2023 at 07:05:15PM -0800, Samuel Holland wrote:
> > RISC-V uses kernel_fpu_begin()/kernel_fpu_end() like several other
> > architectures. Enabling hardware FP requires overriding the ISA string
> > for the relevant compilation units.
> 
> Ah yes, bringing the joy of frame-larger-than warnings to RISC-V:
> ../drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c:58:13:
>  warning: stack frame size (2416) exceeds limit (2048) in 
> 'DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation'
>  [-Wframe-larger-than]

:(

> Nathan, have you given up on these being sorted out?

Does your configuration have KASAN (I don't think RISC-V supports
KCSAN)? It is possible that dml/dcn32 needs something similar to commit
6740ec97bcdb ("drm/amd/display: Increase frame warning limit with KASAN
or KCSAN in dml2")?

I am not really interested in playing whack-a-mole with these warnings
like I have done in the past for the reasons I outlined here:

https://lore.kernel.org/20231019205117.GA839902@dev-arch.thelio-3990X/

> Also, what on earth is that function name, it exceeds 80 characters
> before even considering anything else? Actually, I don't think I want
> to know.

Welcome to "gcc-parsable HW gospel, coming straight from HW engineers" :)

Cheers,
Nathan


Re: [PATCH v2 1/1] drm/i915/pxp: Add missing tag for Wa_14019159160

2023-11-29 Thread Teres Alexis, Alan Previn
On Wed, 2023-11-29 at 13:13 -0800, Teres Alexis, Alan Previn wrote:
> On Mon, 2023-11-27 at 15:24 -0500, Vivi, Rodrigo wrote:
> > On Wed, Nov 22, 2023 at 12:30:03PM -0800, Alan Previn wrote:
> alan:snip
> alan: thanks for reviewing and apologize for replying to this late.
> 
> > >   /*
> > > -  * On MTL and newer platforms, protected contexts require setting
> > > -  * the LRC run-alone bit or else the encryption will not happen.
> > > +  * Wa_14019159160 - Case 2: mtl
> > > +  * On some platforms, protected contexts require setting
> > > +  * the LRC run-alone bit or else the encryption/decryption will not 
> > > happen.
> > > +  * NOTE: Case 2 only applies to PXP use-case of said workaround.
> > >*/
> > 
> > hmm, interesting enough, on the wa description I read that it is incomplete 
> > for MTL/ARL
> > and something about a fuse bit. We should probably chase for some 
> > clarification in the
> > HSD?!
> alan: yes, i went through the HSD description with the architect and we both 
> had agreed that
> that from the KMD's perspective. At that time, the checking of the fuse from 
> KMD's
> could be optimized out for Case-2-PXP: if the fuses was set a certain way, 
> KMD can skip setting
> the bit in lrc because hw will enforce runalone in pxp mode irrespective of 
> what KMD does but
> if fuse was was not set that way KMD needed to set the runalone in lrc. So 
> for case2, its simpler
> to just turn it on always when the context is protected. However, that said, 
> i realized the
> wording of the HSDs have changed since the original patch was implemented so 
> i will reclarify
> offline and reply back. NOTE: i believe John Harrison is working on case-3 
> through a
> separate series.
alan: based on conversations with the architect, a different WA number, 
14019725520,
has the details of case-2 that explains the relationship the new fuse.
However, as before it can be optimized as explained above where PXP context
need to always set this bit to ensure encryption/decryption engages.




Re: [PATCH v6] Documentation/gpu: VM_BIND locking document

2023-11-29 Thread Bagas Sanjaya
On Wed, Nov 29, 2023 at 10:06:37AM +0100, Thomas Hellström wrote:
> diff --git a/Documentation/gpu/drm-vm-bind-locking.rst 
> b/Documentation/gpu/drm-vm-bind-locking.rst
> new file mode 100644
> index ..a345aa513d12
> --- /dev/null
> +++ b/Documentation/gpu/drm-vm-bind-locking.rst
> @@ -0,0 +1,582 @@
> +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +===
> +VM_BIND locking
> +===
> +
> +This document attempts to describe what's needed to get VM_BIND locking 
> right,
> +including the userptr mmu_notifier locking. It also discusses some
> +optimizations to get rid of the looping through of all userptr mappings and
> +external / shared object mappings that is needed in the simplest
> +implementation. In addition, there is a section describing the VM_BIND 
> locking
> +required for implementing recoverable pagefaults.
> +
> +The DRM GPUVM set of helpers
> +
> +
> +There is a set of helpers for drivers implementing VM_BIND, and this
> +set of helpers implements much, but not all of the locking described
> +in this document. In particular, it is currently lacking a userptr
> +implementation. This document does not intend to describe the DRM GPUVM
> +implementation in detail, but it is covered in :ref:`its own
> +documentation `. It is highly recommended for any driver
> +implementing VM_BIND to use the DRM GPUVM helpers and to extend it if
> +common functionality is missing.
> +
> +Nomenclature
> +
> +
> +* ``gpu_vm``: Abstraction of a virtual GPU address space with
> +  meta-data. Typically one per client (DRM file-private), or one per
> +  execution context.
> +* ``gpu_vma``: Abstraction of a GPU address range within a gpu_vm with
> +  associated meta-data. The backing storage of a gpu_vma can either be
> +  a GEM object or anonymous or page-cache pages mapped also into the CPU
> +  address space for the process.
> +* ``gpu_vm_bo``: Abstracts the association of a GEM object and
> +  a VM. The GEM object maintains a list of gpu_vm_bos, where each gpu_vm_bo
> +  maintains a list of gpu_vmas.
> +* ``userptr gpu_vma or just userptr``: A gpu_vma, whose backing store
> +  is anonymous or page-cache pages as described above.
> +* ``revalidating``: Revalidating a gpu_vma means making the latest version
> +  of the backing store resident and making sure the gpu_vma's
> +  page-table entries point to that backing store.
> +* ``dma_fence``: A struct dma_fence that is similar to a struct completion
> +  and which tracks GPU activity. When the GPU activity is finished,
> +  the dma_fence signals. Please refer to the ``DMA Fences`` section of
> +  the :doc:`dma-buf doc `.
> +* ``dma_resv``: A struct dma_resv (a.k.a reservation object) that is used
> +  to track GPU activity in the form of multiple dma_fences on a
> +  gpu_vm or a GEM object. The dma_resv contains an array / list
> +  of dma_fences and a lock that needs to be held when adding
> +  additional dma_fences to the dma_resv. The lock is of a type that
> +  allows deadlock-safe locking of multiple dma_resvs in arbitrary
> +  order. Please refer to the ``Reservation Objects`` section of the
> +  :doc:`dma-buf doc `.
> +* ``exec function``: An exec function is a function that revalidates all
> +  affected gpu_vmas, submits a GPU command batch and registers the
> +  dma_fence representing the GPU command's activity with all affected
> +  dma_resvs. For completeness, although not covered by this document,
> +  it's worth mentioning that an exec function may also be the
> +  revalidation worker that is used by some drivers in compute /
> +  long-running mode.
> +* ``local object``: A GEM object which is only mapped within a
> +  single VM. Local GEM objects share the gpu_vm's dma_resv.
> +* ``external object``: a.k.a shared object: A GEM object which may be shared
> +  by multiple gpu_vms and whose backing storage may be shared with
> +  other drivers.
> +
> +Locks and locking order
> +===
> +
> +One of the benefits of VM_BIND is that local GEM objects share the gpu_vm's
> +dma_resv object and hence the dma_resv lock. So, even with a huge
> +number of local GEM objects, only one lock is needed to make the exec
> +sequence atomic.
> +
> +The following locks and locking orders are used:
> +
> +* The ``gpu_vm->lock`` (optionally an rwsem). Protects the gpu_vm's
> +  data structure keeping track of gpu_vmas. It can also protect the
> +  gpu_vm's list of userptr gpu_vmas. With a CPU mm analogy this would
> +  correspond to the mmap_lock. An rwsem allows several readers to walk
> +  the VM tree concurrently, but the benefit of that concurrency most
> +  likely varies from driver to driver.
> +* The ``userptr_seqlock``. This lock is taken in read mode for each
> +  userptr gpu_vma on the gpu_vm's userptr list, and in write mode during mmu
> +  notifier invalidation. This is not a real seqlock but described in
> +  ``mm/mmu_notifier.c`` as a "Collision-retry 

[PATCH v7 0/2] Resolve suspend-resume racing with GuC destroy-context-worker

2023-11-29 Thread Alan Previn
This series is the result of debugging issues root caused to
races between the GuC's destroyed_worker_func being triggered
vs repeating suspend-resume cycles with concurrent delayed
fence signals for engine-freeing.

The reproduction steps require that an app is launched right
before the start of the suspend cycle where it creates a
new gem context and submits a tiny workload that would
complete in the middle of the suspend cycle. However this
app uses dma-buffer sharing or dma-fence with non-GPU
objects or signals that eventually triggers a FENCE_FREE
via__i915_sw_fence_notify that connects to engines_notify ->
free_engines_rcu -> intel_context_put ->
kref_put(>ref..) that queues the worker after the GuCs
CTB has been disabled (i.e. after i915-gem's suspend-late).

This sequence is a corner-case and required repeating this
app->suspend->resume cycle ~1500 times across 4 identical
systems to see it once. That said, based on above callstack,
it is clear that merely flushing the context destruction worker,
which is obviously missing and needed, isn't sufficient.

Because of that, this series adds additional patches besides
the obvious (Patch #1) flushing of the worker during the
suspend flows. It also includes (Patch #2) closing a race
between sending the context-deregistration H2G vs the CTB
getting disabled in the midst of it (by detecing the failure
and unrolling the guc-lrc-unpin flow) and adding an additional
rcu_barrier in the gem-suspend flow to purge outstanding
rcu defered tasks that may include context destruction.

This patch was tested and confirmed to be reliably working
after running ~1500 suspend resume cycles on 4 concurrent
machines.

Changes from prior revs:
   v6: - Dont hold the spinlock while calling deregister_context
 which can take a longer time. (Rodrigo)
   - Fix / improve of comments. (Rodrigo)
   - Release the ce->guc_state.lock before calling
 deregister_context and retake it if we fail. (John/Daniele).
   v5: - Remove Patch #3 which doesnt solve this exact bug
 but can be a separate patch(Tvrtko).
   v4: - In Patch #2, change the position of the calls into
 rcu_barrier based on latest testing data. (Alan/Anshuman).
   - In Patch #3, fix the timeout value selection for the
 final gt-pm idle-wait that was incorrectly using a 'ns'
 #define as a milisec timeout.
   v3: - In Patch #3, when deregister_context fails, instead
 of calling intel_gt_pm_put(that might sleep), call
 __intel_wakeref_put (without ASYNC flag) (Rodrigo/Anshuman).
   - In wait_for_suspend add an rcu_barrier before we
 proceed to wait for idle. (Anshuman)
   v2: - Patch #2 Restructure code in guc_lrc_desc_unpin so
 it's more readible to differentiate (1)direct guc-id
 cleanup ..vs (2) sending the H2G ctx-destroy action ..
 vs (3) the unrolling steps if the H2G fails.
   - Patch #2 Add a check to close the race sooner by checking
 for intel_guc_is_ready from destroyed_worker_func.
   - Patch #2 When guc_submission_send_busy_loop gets a
 failure from intel_guc_send_busy_loop, we need to undo
 i.e. decrement the outstanding_submission_g2h.
   - Patch #3 In wait_for_suspend, fix checking of return from
 intel_gt_pm_wait_timeout_for_idle to now use -ETIMEDOUT
 and add documentation for intel_wakeref_wait_for_idle.
 (Rodrigo).

Alan Previn (2):
  drm/i915/guc: Flush context destruction worker at suspend
  drm/i915/guc: Close deregister-context race against CT-loss

 drivers/gpu/drm/i915/gem/i915_gem_pm.c| 10 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 78 +--
 .../gpu/drm/i915/gt/uc/intel_guc_submission.h |  2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  2 +
 4 files changed, 87 insertions(+), 5 deletions(-)


base-commit: 436cb0ff9f20fadc99ec3b70c4d2ac6cb2e4410a
-- 
2.39.0



[PATCH v7 2/2] drm/i915/guc: Close deregister-context race against CT-loss

2023-11-29 Thread Alan Previn
If we are at the end of suspend or very early in resume
its possible an async fence signal (via rcu_call) is triggered
to free_engines which could lead us to the execution of
the context destruction worker (after a prior worker flush).

Thus, when suspending, insert rcu_barriers at the start
of i915_gem_suspend (part of driver's suspend prepare) and
again in i915_gem_suspend_late so that all such cases have
completed and context destruction list isn't missing anything.

In destroyed_worker_func, close the race against CT-loss
by checking that CT is enabled before calling into
deregister_destroyed_contexts.

Based on testing, guc_lrc_desc_unpin may still race and fail
as we traverse the GuC's context-destroy list because the
CT could be disabled right before calling GuC's CT send function.

We've witnessed this race condition once every ~6000-8000
suspend-resume cycles while ensuring workloads that render
something onscreen is continuously started just before
we suspend (and the workload is small enough to complete
and trigger the queued engine/context free-up either very
late in suspend or very early in resume).

In such a case, we need to unroll the entire process because
guc-lrc-unpin takes a gt wakeref which only gets released in
the G2H IRQ reply that never comes through in this corner
case. Without the unroll, the taken wakeref is leaked and will
cascade into a kernel hang later at the tail end of suspend in
this function:

   intel_wakeref_wait_for_idle(>wakeref)
   (called by) - intel_gt_pm_wait_for_idle
   (called by) - wait_for_suspend

Thus, do an unroll in guc_lrc_desc_unpin and deregister_destroyed_-
contexts if guc_lrc_desc_unpin fails due to CT send falure.
When unrolling, keep the context in the GuC's destroy-list so
it can get picked up on the next destroy worker invocation
(if suspend aborted) or get fully purged as part of a GuC
sanitization (end of suspend) or a reset flow.

Signed-off-by: Alan Previn 
Signed-off-by: Anshuman Gupta 
Tested-by: Mousumi Jana 
---
 drivers/gpu/drm/i915/gem/i915_gem_pm.c| 10 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 73 +--
 2 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 0d812f4d787d..3b27218aabe2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
@@ -28,6 +28,13 @@ void i915_gem_suspend(struct drm_i915_private *i915)
GEM_TRACE("%s\n", dev_name(i915->drm.dev));
 
intel_wakeref_auto(>runtime_pm.userfault_wakeref, 0);
+   /*
+* On rare occasions, we've observed the fence completion triggers
+* free_engines asynchronously via rcu_call. Ensure those are done.
+* This path is only called on suspend, so it's an acceptable cost.
+*/
+   rcu_barrier();
+
flush_workqueue(i915->wq);
 
/*
@@ -160,6 +167,9 @@ void i915_gem_suspend_late(struct drm_i915_private *i915)
 * machine in an unusable condition.
 */
 
+   /* Like i915_gem_suspend, flush tasks staged from fence triggers */
+   rcu_barrier();
+
for_each_gt(gt, i915, i)
intel_gt_suspend_late(gt);
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 6e3fb2fcce4f..a7228bebec39 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -236,6 +236,13 @@ set_context_destroyed(struct intel_context *ce)
ce->guc_state.sched_state |= SCHED_STATE_DESTROYED;
 }
 
+static inline void
+clr_context_destroyed(struct intel_context *ce)
+{
+   lockdep_assert_held(>guc_state.lock);
+   ce->guc_state.sched_state &= ~SCHED_STATE_DESTROYED;
+}
+
 static inline bool context_pending_disable(struct intel_context *ce)
 {
return ce->guc_state.sched_state & SCHED_STATE_PENDING_DISABLE;
@@ -613,6 +620,8 @@ static int guc_submission_send_busy_loop(struct intel_guc 
*guc,
 u32 g2h_len_dw,
 bool loop)
 {
+   int ret;
+
/*
 * We always loop when a send requires a reply (i.e. g2h_len_dw > 0),
 * so we don't handle the case where we don't get a reply because we
@@ -623,7 +632,11 @@ static int guc_submission_send_busy_loop(struct intel_guc 
*guc,
if (g2h_len_dw)
atomic_inc(>outstanding_submission_g2h);
 
-   return intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
+   ret = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
+   if (ret)
+   atomic_dec(>outstanding_submission_g2h);
+
+   return ret;
 }
 
 int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
@@ -3288,12 +3301,13 @@ static void guc_context_close(struct intel_context *ce)
spin_unlock_irqrestore(>guc_state.lock, flags);
 }
 
-static inline 

[PATCH v7 1/2] drm/i915/guc: Flush context destruction worker at suspend

2023-11-29 Thread Alan Previn
When suspending, flush the context-guc-id
deregistration worker at the final stages of
intel_gt_suspend_late when we finally call gt_sanitize
that eventually leads down to __uc_sanitize so that
the deregistration worker doesn't fire off later as
we reset the GuC microcontroller.

Signed-off-by: Alan Previn 
Reviewed-by: Rodrigo Vivi 
Tested-by: Mousumi Jana 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 5 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h | 2 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c | 2 ++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 04f8377fd7a3..6e3fb2fcce4f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1613,6 +1613,11 @@ static void guc_flush_submissions(struct intel_guc *guc)
spin_unlock_irqrestore(_engine->lock, flags);
 }
 
+void intel_guc_submission_flush_work(struct intel_guc *guc)
+{
+   flush_work(>submission_state.destroyed_worker);
+}
+
 static void guc_flush_destroyed_contexts(struct intel_guc *guc);
 
 void intel_guc_submission_reset_prepare(struct intel_guc *guc)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
index c57b29cdb1a6..b6df75622d3b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
@@ -38,6 +38,8 @@ int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
   bool interruptible,
   long timeout);
 
+void intel_guc_submission_flush_work(struct intel_guc *guc);
+
 static inline bool intel_guc_submission_is_supported(struct intel_guc *guc)
 {
return guc->submission_supported;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 3872d309ed31..b8b09b1bee3e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -690,6 +690,8 @@ void intel_uc_suspend(struct intel_uc *uc)
return;
}
 
+   intel_guc_submission_flush_work(guc);
+
with_intel_runtime_pm(_to_gt(uc)->i915->runtime_pm, wakeref) {
err = intel_guc_suspend(guc);
if (err)
-- 
2.39.0



Re: [PATCH] drm/nouveau: Removes unnecessary args check in nouveau_uvmm_sm_prepare

2023-11-29 Thread Danilo Krummrich

On 11/16/23 21:52, Yuran Pereira wrote:

Checking `args` after calling `op_map_prepare` is unnecessary since
if `op_map_prepare` was to be called with  NULL args, it would lead
to a NULL pointer dereference, thus never hitting that check.

Hence this check can be removed, and a note added to remind users of
this function to ensure that args != NULL when calling this function
for a map operation as it was suggested  by Danilo [1]

[1] https://lore.kernel.org/lkml/6a1ebcef-bade-45a0-9bd9-c05f0226e...@redhat.com

Suggested-by: Danilo Krummrich 
Signed-off-by: Yuran Pereira 


Applied to drm-misc-next.


---
  drivers/gpu/drm/nouveau/nouveau_uvmm.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c 
b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
index 5cf892c50f43..c8c3f1b1b604 100644
--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -604,6 +604,10 @@ op_unmap_prepare(struct drm_gpuva_op_unmap *u)
drm_gpuva_unmap(u);
  }
  
+/*

+ * Note: @args should not be NULL when calling for
+ * a map operation.
+ */
  static int
  nouveau_uvmm_sm_prepare(struct nouveau_uvmm *uvmm,
struct nouveau_uvma_prealloc *new,
@@ -624,7 +628,7 @@ nouveau_uvmm_sm_prepare(struct nouveau_uvmm *uvmm,
if (ret)
goto unwind;
  
-			if (args && vmm_get_range) {

+   if (vmm_get_range) {
ret = nouveau_uvmm_vmm_get(uvmm, vmm_get_start,
   vmm_get_range);
if (ret) {




Re: [PATCH] driver: gpu: Fix warning directly dereferencing a rcu pointer

2023-11-29 Thread Danilo Krummrich

Hi Abhinav,

Thanks for sending this follow-up patch.

On 11/26/23 15:57, Abhinav Singh wrote:

Fix a sparse warning with this message
"warning:dereference of noderef expression". In this context it means we
are dereferencing a __rcu tagged pointer directly.

We should not be directly dereferencing a rcu pointer. To get a normal
(non __rcu tagged pointer) from a __rcu tagged pointer we are using the
function unrcu_pointer(...). The non __rcu tagged pointer then can be
dereferenced just like a normal pointer.


Can you please add a brief explanation why unrcu_pointer() is fine here?



I tested with qemu with this command
qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel bzImage \
-append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
-drive file=bullseye.img,format=raw \
-net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
-net nic,model=e1000 \
-enable-kvm \
-nographic \
-pidfile vm.pid \
2>&1 | tee vm.log
with lockdep enabled.


How is that relevant for this patch?

- Danilo



Signed-off-by: Abhinav Singh 
---
  drivers/gpu/drm/nouveau/nv10_fence.c | 2 +-
  drivers/gpu/drm/nouveau/nv84_fence.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c 
b/drivers/gpu/drm/nouveau/nv10_fence.c
index c6a0db5b9e21..845b64c079ed 100644
--- a/drivers/gpu/drm/nouveau/nv10_fence.c
+++ b/drivers/gpu/drm/nouveau/nv10_fence.c
@@ -32,7 +32,7 @@
  int
  nv10_fence_emit(struct nouveau_fence *fence)
  {
-   struct nvif_push *push = fence->channel->chan.push;
+   struct nvif_push *push = unrcu_pointer(fence->channel)->chan.push;
int ret = PUSH_WAIT(push, 2);
if (ret == 0) {
PUSH_MTHD(push, NV06E, SET_REFERENCE, fence->base.seqno);
diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c 
b/drivers/gpu/drm/nouveau/nv84_fence.c
index 812b8c62eeba..d42e72e23dec 100644
--- a/drivers/gpu/drm/nouveau/nv84_fence.c
+++ b/drivers/gpu/drm/nouveau/nv84_fence.c
@@ -85,7 +85,7 @@ nv84_fence_chid(struct nouveau_channel *chan)
  static int
  nv84_fence_emit(struct nouveau_fence *fence)
  {
-   struct nouveau_channel *chan = fence->channel;
+   struct nouveau_channel *chan = unrcu_pointer(fence->channel);
struct nv84_fence_chan *fctx = chan->fence;
u64 addr = fctx->vma->addr + nv84_fence_chid(chan) * 16;
  




fbcon on one of multiple displays

2023-11-29 Thread Eric Nelson

Hi all,

Is there a way to configure a framebuffer console on a specific display 
on a machine with multiple displays?




RE: [RFC PATCH 0/6] Supporting GMEM (generalized memory management) for external memory devices

2023-11-29 Thread Zeng, Oak
Hi Weixi,

Even though Christian has listed reasons rejecting this proposal (yes they are 
very reasonable to me), I would open my mind and further explore the 
possibility here. Since the current GPU driver uses a hmm based implementation 
(AMD and NV has done this; At Intel we are catching up), I want to explore how 
much we can benefit from the proposed approach and how your approach can solve 
some pain points of our development. So basically what I am questioning here 
is: what is the advantage of your approach against hmm.

To implement a UVM (unified virtual address space b/t cpu and gpu device), with 
hmm, driver essentially need to implement below functions:

1. device page table update. Your approach requires the same because this is 
device specific codes

2. Some migration functions to migrate memory b/t system memory and GPU local 
memory. My understanding is, even though you generalized this a bit, such as 
modified cpu page fault path, provided "general" gm_dev_fault handler... but 
device driver still need to provide migration functions because migration 
functions have to be device specific (i.e., using device dma/copy engine for 
performance purpose). Right?

3. GPU physical memory management, this part is now in drm/buddy, shared by all 
drivers. I think with your approach, driver still need to provide callback 
functions to allocate/free physical pages. Right? Or do you let linux core mm 
buddy manage device memory directly?

4. madvise/hints/virtual address range management. This has been pain point for 
us. Right now device driver has to maintain certain virtual address range data 
structure to maintain hints and other virtual address range based memory 
attributes. Driver need to sync with linux vma. Driver need to explicitly deal 
with range split/merging... HMM doesn't provide support in this area. Your 
approach seems cleaner/simpler to me...


So in above, I have examined the some key factors of a gpu UVM memory manager. 
I think for #1 and #2, hmm has provide pretty good abstraction/tools for 
address space mirroring and migration helpers. For #3, since we have a common 
drm/buddy layer, I don't think it is a big problem for driver writer now.

I do see #4 is something you solved more beautifully, requires new system call 
though. 

Oak


> -Original Message-
> From: dri-devel  On Behalf Of
> Christian König
> Sent: Tuesday, November 28, 2023 8:09 AM
> To: Weixi Zhu ; linux...@kvack.org; linux-
> ker...@vger.kernel.org; a...@linux-foundation.org; Danilo Krummrich
> ; Dave Airlie ; Daniel Vetter
> 
> Cc: dri-devel@lists.freedesktop.org; leo...@nvidia.com; apop...@nvidia.com;
> amd-...@lists.freedesktop.org; mgor...@suse.de; z...@nvidia.com; Wang, Zhi
> A ; rcampb...@nvidia.com; j...@nvidia.com;
> weixi@openeuler.sh; jhubb...@nvidia.com; intel-...@lists.freedesktop.org;
> mhairgr...@nvidia.com; jgli...@redhat.com; Vivi, Rodrigo
> ; intel-gvt-...@lists.freedesktop.org;
> tvrtko.ursu...@linux.intel.com; felix.kuehl...@amd.com; xinhui@amd.com;
> alexander.deuc...@amd.com; ogab...@kernel.org
> Subject: Re: [RFC PATCH 0/6] Supporting GMEM (generalized memory
> management) for external memory devices
> 
> Adding a few missing important people to the explicit to list.
> 
> Am 28.11.23 um 13:50 schrieb Weixi Zhu:
> > The problem:
> >
> > Accelerator driver developers are forced to reinvent external MM subsystems
> > case by case, because Linux core MM only considers host memory resources.
> > These reinvented MM subsystems have similar orders of magnitude of LoC as
> > Linux MM (80K), e.g. Nvidia-UVM has 70K, AMD GPU has 14K and Huawei NPU
> has
> > 30K. Meanwhile, more and more vendors are implementing their own
> > accelerators, e.g. Microsoft's Maia 100. At the same time,
> > application-level developers suffer from poor programmability -- they must
> > consider parallel address spaces and be careful about the limited device
> > DRAM capacity. This can be alleviated if a malloc()-ed virtual address can
> > be shared by the accelerator, or the abundant host DRAM can further
> > transparently backup the device local memory.
> >
> > These external MM systems share similar mechanisms except for the
> > hardware-dependent part, so reinventing them is effectively introducing
> > redundant code (14K~70K for each case). Such developing/maintaining is not
> > cheap. Furthermore, to share a malloc()-ed virtual address, device drivers
> > need to deeply interact with Linux MM via low-level MM APIs, e.g. MMU
> > notifiers/HMM. This raises the bar for driver development, since developers
> > must understand how Linux MM works. Further, it creates code maintenance
> > problems -- any changes to Linux MM potentially require coordinated changes
> > to accelerator drivers using low-level MM APIs.
> >
> > Putting a cache-coherent bus between host and device will not make these
> > external MM subsystems disappear. For example, a throughput-oriented
> > accelerator will not tolerate 

[PATCH 1/2] drm/managed: Add drmm_release_action

2023-11-29 Thread Michał Winiarski
Similar to devres equivalent, it allows to call the "release" action
directly and remove the resource from the managed resources list.

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/drm_managed.c | 39 +++
 include/drm/drm_managed.h |  4 
 2 files changed, 43 insertions(+)

diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
index bcd111404b128..7646f67bda4e4 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -176,6 +176,45 @@ int __drmm_add_action_or_reset(struct drm_device *dev,
 }
 EXPORT_SYMBOL(__drmm_add_action_or_reset);
 
+/**
+ * drmm_release_action - release a managed action from a _device
+ * @dev: DRM device
+ * @action: function which would be called when @dev is released
+ * @data: opaque pointer, passed to @action
+ *
+ * This function calls the @action previously added by drmm_add_action()
+ * immediately.
+ * The @action is removed from the list of cleanup actions for @dev,
+ * which means that it won't be called in the final drm_dev_put().
+ */
+void drmm_release_action(struct drm_device *dev,
+drmres_release_t action,
+void *data)
+{
+   struct drmres *dr_match = NULL, *dr;
+   unsigned long flags;
+
+   spin_lock_irqsave(>managed.lock, flags);
+   list_for_each_entry_reverse(dr, >managed.resources, node.entry) {
+   if (dr->node.release == action) {
+   if (!data || (data && *(void **)dr->data == data)) {
+   dr_match = dr;
+   del_dr(dev, dr_match);
+   break;
+   }
+   }
+   }
+   spin_unlock_irqrestore(>managed.lock, flags);
+
+   if (WARN_ON(!dr_match))
+   return;
+
+   action(dev, data);
+
+   free_dr(dr_match);
+}
+EXPORT_SYMBOL(drmm_release_action);
+
 /**
  * drmm_kmalloc - _device managed kmalloc()
  * @dev: DRM device
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index ad08f834af408..f547b09ca0239 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -45,6 +45,10 @@ int __must_check __drmm_add_action_or_reset(struct 
drm_device *dev,
drmres_release_t action,
void *data, const char *name);
 
+void drmm_release_action(struct drm_device *dev,
+drmres_release_t action,
+void *data);
+
 void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
 
 /**
-- 
2.43.0



[PATCH 2/2] drm/tests: managed: Add a simple test for drmm_managed_release

2023-11-29 Thread Michał Winiarski
Add a simple test that checks whether the action is indeed called right
away and that it is not called on the final drm_dev_put().

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/tests/drm_managed_test.c | 65 ++--
 1 file changed, 50 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_managed_test.c 
b/drivers/gpu/drm/tests/drm_managed_test.c
index 1652dca11d30c..a645ea42aee56 100644
--- a/drivers/gpu/drm/tests/drm_managed_test.c
+++ b/drivers/gpu/drm/tests/drm_managed_test.c
@@ -12,6 +12,8 @@
 #define TEST_TIMEOUT_MS100
 
 struct managed_test_priv {
+   struct drm_device *drm;
+   struct device *dev;
bool action_done;
wait_queue_head_t action_wq;
 };
@@ -26,42 +28,75 @@ static void drm_action(struct drm_device *drm, void *ptr)
 
 static void drm_test_managed_run_action(struct kunit *test)
 {
-   struct managed_test_priv *priv;
-   struct drm_device *drm;
-   struct device *dev;
+   struct managed_test_priv *priv = test->priv;
int ret;
 
-   priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
-   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
-   init_waitqueue_head(>action_wq);
+   ret = drmm_add_action_or_reset(priv->drm, drm_action, priv);
+   KUNIT_EXPECT_EQ(test, ret, 0);
 
-   dev = drm_kunit_helper_alloc_device(test);
-   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+   ret = drm_dev_register(priv->drm, 0);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   drm_dev_unregister(priv->drm);
+   drm_kunit_helper_free_device(test, priv->dev);
 
-   drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, 
DRIVER_MODESET);
-   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
+   ret = wait_event_interruptible_timeout(priv->action_wq, 
priv->action_done,
+  
msecs_to_jiffies(TEST_TIMEOUT_MS));
+   KUNIT_EXPECT_GT(test, ret, 0);
+}
 
-   ret = drmm_add_action_or_reset(drm, drm_action, priv);
+static void drm_test_managed_release_action(struct kunit *test)
+{
+   struct managed_test_priv *priv = test->priv;
+   int ret;
+
+   ret = drmm_add_action_or_reset(priv->drm, drm_action, priv);
KUNIT_EXPECT_EQ(test, ret, 0);
 
-   ret = drm_dev_register(drm, 0);
+   ret = drm_dev_register(priv->drm, 0);
KUNIT_ASSERT_EQ(test, ret, 0);
 
-   drm_dev_unregister(drm);
-   drm_kunit_helper_free_device(test, dev);
+   drmm_release_action(priv->drm, drm_action, priv);
+   KUNIT_EXPECT_TRUE(test, priv->action_done);
+   priv->action_done = false;
+
+   drm_dev_unregister(priv->drm);
+   drm_kunit_helper_free_device(test, priv->dev);
 
ret = wait_event_interruptible_timeout(priv->action_wq, 
priv->action_done,
   
msecs_to_jiffies(TEST_TIMEOUT_MS));
-   KUNIT_EXPECT_GT(test, ret, 0);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static int drm_managed_test_init(struct kunit *test)
+{
+   struct managed_test_priv *priv;
+
+   priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+   init_waitqueue_head(>action_wq);
+
+   priv->dev = drm_kunit_helper_alloc_device(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
+
+   priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev, 
sizeof(*priv->drm),
+   0, DRIVER_MODESET);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
+
+   test->priv = priv;
+
+   return 0;
 }
 
 static struct kunit_case drm_managed_tests[] = {
KUNIT_CASE(drm_test_managed_run_action),
+   KUNIT_CASE(drm_test_managed_release_action),
{}
 };
 
 static struct kunit_suite drm_managed_test_suite = {
.name = "drm-test-managed",
+   .init = drm_managed_test_init,
.test_cases = drm_managed_tests
 };
 
-- 
2.43.0



[PATCH 0/2] drm/managed: Add drmm_release_action

2023-11-29 Thread Michał Winiarski
Upcoming Intel Xe driver will need to have a more fine-grained control
over DRM managed actions - namely, the ability to release a given
action, triggering it manually at a different point in time than the
final drm_dev_put().
This series adds a drmm_release_action function (which is similar to
devres devm_release_action) and a simple test that uses it.

Michał Winiarski (2):
  drm/managed: Add drmm_release_action
  drm/tests: managed: Add a simple test for drmm_managed_release

 drivers/gpu/drm/drm_managed.c| 39 ++
 drivers/gpu/drm/tests/drm_managed_test.c | 65 ++--
 include/drm/drm_managed.h|  4 ++
 3 files changed, 93 insertions(+), 15 deletions(-)

-- 
2.43.0



[PATCH drm-misc-next v2 2/2] drm/imagination: vm: make use of GPUVM's drm_exec helper

2023-11-29 Thread Danilo Krummrich
Make use of GPUVM's drm_exec helper functions preventing direct access
to GPUVM internal data structures, such as the external object list.

This is especially important to ensure following the locking rules
around the GPUVM external object list.

Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
Signed-off-by: Danilo Krummrich 
---
 drivers/gpu/drm/imagination/pvr_vm.c | 91 +++-
 1 file changed, 36 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/imagination/pvr_vm.c 
b/drivers/gpu/drm/imagination/pvr_vm.c
index e0d74d9a6190..c6ab1581d509 100644
--- a/drivers/gpu/drm/imagination/pvr_vm.c
+++ b/drivers/gpu/drm/imagination/pvr_vm.c
@@ -333,48 +333,6 @@ pvr_vm_bind_op_unmap_init(struct pvr_vm_bind_op *bind_op,
return err;
 }
 
-static int
-pvr_vm_bind_op_lock_resvs(struct drm_exec *exec, struct pvr_vm_bind_op 
*bind_op)
-{
-   drm_exec_until_all_locked(exec) {
-   struct drm_gem_object *r_obj = _op->vm_ctx->dummy_gem;
-   struct drm_gpuvm *gpuvm = _op->vm_ctx->gpuvm_mgr;
-   struct pvr_gem_object *pvr_obj = bind_op->pvr_obj;
-   struct drm_gpuvm_bo *gpuvm_bo;
-
-   /* Acquire lock on the vm_context's reserve object. */
-   int err = drm_exec_lock_obj(exec, r_obj);
-
-   drm_exec_retry_on_contention(exec);
-   if (err)
-   return err;
-
-   /* Acquire lock on all BOs in the context. */
-   list_for_each_entry(gpuvm_bo, >extobj.list,
-   list.entry.extobj) {
-   err = drm_exec_lock_obj(exec, gpuvm_bo->obj);
-
-   drm_exec_retry_on_contention(exec);
-   if (err)
-   return err;
-   }
-
-   /* Unmap operations don't have an object to lock. */
-   if (!pvr_obj)
-   break;
-
-   /* Acquire lock on the GEM being mapped. */
-   err = drm_exec_lock_obj(exec,
-   gem_from_pvr_gem(bind_op->pvr_obj));
-
-   drm_exec_retry_on_contention(exec);
-   if (err)
-   return err;
-   }
-
-   return 0;
-}
-
 /**
  * pvr_vm_gpuva_map() - Insert a mapping into a memory context.
  * @op: gpuva op containing the remap details.
@@ -731,6 +689,20 @@ void pvr_destroy_vm_contexts_for_file(struct pvr_file 
*pvr_file)
}
 }
 
+static int
+pvr_vm_lock_extra(struct drm_gpuvm_exec *vm_exec)
+{
+   struct pvr_vm_bind_op *bind_op = vm_exec->extra.priv;
+   struct pvr_gem_object *pvr_obj = bind_op->pvr_obj;
+
+   /* Unmap operations don't have an object to lock. */
+   if (!pvr_obj)
+   return 0;
+
+   /* Acquire lock on the GEM being mapped. */
+   return drm_exec_lock_obj(_exec->exec, gem_from_pvr_gem(pvr_obj));
+}
+
 /**
  * pvr_vm_map() - Map a section of physical memory into a section of
  * device-virtual memory.
@@ -758,7 +730,15 @@ pvr_vm_map(struct pvr_vm_context *vm_ctx, struct 
pvr_gem_object *pvr_obj,
   u64 pvr_obj_offset, u64 device_addr, u64 size)
 {
struct pvr_vm_bind_op bind_op = {0};
-   struct drm_exec exec;
+   struct drm_gpuvm_exec vm_exec = {
+   .vm = _ctx->gpuvm_mgr,
+   .flags = DRM_EXEC_INTERRUPTIBLE_WAIT |
+DRM_EXEC_IGNORE_DUPLICATES,
+   .extra = {
+   .fn = pvr_vm_lock_extra,
+   .priv = _op,
+   },
+   };
 
int err = pvr_vm_bind_op_map_init(_op, vm_ctx, pvr_obj,
  pvr_obj_offset, device_addr,
@@ -767,18 +747,15 @@ pvr_vm_map(struct pvr_vm_context *vm_ctx, struct 
pvr_gem_object *pvr_obj,
if (err)
return err;
 
-   drm_exec_init(,
- DRM_EXEC_INTERRUPTIBLE_WAIT | DRM_EXEC_IGNORE_DUPLICATES);
-
pvr_gem_object_get(pvr_obj);
 
-   err = pvr_vm_bind_op_lock_resvs(, _op);
+   err = drm_gpuvm_exec_lock(_exec);
if (err)
goto err_cleanup;
 
err = pvr_vm_bind_op_exec(_op);
 
-   drm_exec_fini();
+   drm_gpuvm_exec_unlock(_exec);
 
 err_cleanup:
pvr_vm_bind_op_fini(_op);
@@ -804,24 +781,28 @@ int
 pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
 {
struct pvr_vm_bind_op bind_op = {0};
-   struct drm_exec exec;
+   struct drm_gpuvm_exec vm_exec = {
+   .vm = _ctx->gpuvm_mgr,
+   .flags = DRM_EXEC_INTERRUPTIBLE_WAIT |
+DRM_EXEC_IGNORE_DUPLICATES,
+   .extra = {
+   .fn = pvr_vm_lock_extra,
+   .priv = _op,
+   },
+   };
 
int err = pvr_vm_bind_op_unmap_init(_op, vm_ctx, device_addr,
size);
-
if 

[PATCH drm-misc-next v2 1/2] drm/gpuvm: fall back to drm_exec_lock_obj()

2023-11-29 Thread Danilo Krummrich
Fall back to drm_exec_lock_obj() if num_fences is zero for the
drm_gpuvm_prepare_* function family.

Otherwise dma_resv_reserve_fences() would actually allocate slots even
though num_fences is zero.

Cc: Christian König 
Signed-off-by: Danilo Krummrich 
---
 drivers/gpu/drm/drm_gpuvm.c | 43 -
 include/drm/drm_gpuvm.h | 23 +++-
 2 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
index 54f5e8851de5..07a6676bc4f9 100644
--- a/drivers/gpu/drm/drm_gpuvm.c
+++ b/drivers/gpu/drm/drm_gpuvm.c
@@ -1085,6 +1085,37 @@ drm_gpuvm_put(struct drm_gpuvm *gpuvm)
 }
 EXPORT_SYMBOL_GPL(drm_gpuvm_put);
 
+static int
+exec_prepare_obj(struct drm_exec *exec, struct drm_gem_object *obj,
+unsigned int num_fences)
+{
+   return num_fences ? drm_exec_prepare_obj(exec, obj, num_fences) :
+   drm_exec_lock_obj(exec, obj);
+}
+
+/**
+ * drm_gpuvm_prepare_vm() - prepare the GPUVMs common dma-resv
+ * @gpuvm: the _gpuvm
+ * @exec: the _exec context
+ * @num_fences: the amount of _fences to reserve
+ *
+ * Calls drm_exec_prepare_obj() for the GPUVMs dummy _gem_object; if
+ * @num_fences is zero drm_exec_lock_obj() is called instead.
+ *
+ * Using this function directly, it is the drivers responsibility to call
+ * drm_exec_init() and drm_exec_fini() accordingly.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int
+drm_gpuvm_prepare_vm(struct drm_gpuvm *gpuvm,
+struct drm_exec *exec,
+unsigned int num_fences)
+{
+   return exec_prepare_obj(exec, gpuvm->r_obj, num_fences);
+}
+EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_vm);
+
 static int
 __drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
struct drm_exec *exec,
@@ -1095,7 +1126,7 @@ __drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
int ret = 0;
 
for_each_vm_bo_in_list(gpuvm, extobj, , vm_bo) {
-   ret = drm_exec_prepare_obj(exec, vm_bo->obj, num_fences);
+   ret = exec_prepare_obj(exec, vm_bo->obj, num_fences);
if (ret)
break;
}
@@ -1116,7 +1147,7 @@ drm_gpuvm_prepare_objects_locked(struct drm_gpuvm *gpuvm,
 
drm_gpuvm_resv_assert_held(gpuvm);
list_for_each_entry(vm_bo, >extobj.list, list.entry.extobj) {
-   ret = drm_exec_prepare_obj(exec, vm_bo->obj, num_fences);
+   ret = exec_prepare_obj(exec, vm_bo->obj, num_fences);
if (ret)
break;
 
@@ -1134,7 +1165,8 @@ drm_gpuvm_prepare_objects_locked(struct drm_gpuvm *gpuvm,
  * @num_fences: the amount of _fences to reserve
  *
  * Calls drm_exec_prepare_obj() for all _gem_objects the given
- * _gpuvm contains mappings of.
+ * _gpuvm contains mappings of; if @num_fences is zero drm_exec_lock_obj()
+ * is called instead.
  *
  * Using this function directly, it is the drivers responsibility to call
  * drm_exec_init() and drm_exec_fini() accordingly.
@@ -1171,7 +1203,8 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_objects);
  * @num_fences: the amount of _fences to reserve
  *
  * Calls drm_exec_prepare_obj() for all _gem_objects mapped between @addr
- * and @addr + @range.
+ * and @addr + @range; if @num_fences is zero drm_exec_lock_obj() is called
+ * instead.
  *
  * Returns: 0 on success, negative error code on failure.
  */
@@ -1186,7 +1219,7 @@ drm_gpuvm_prepare_range(struct drm_gpuvm *gpuvm, struct 
drm_exec *exec,
drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) {
struct drm_gem_object *obj = va->gem.obj;
 
-   ret = drm_exec_prepare_obj(exec, obj, num_fences);
+   ret = exec_prepare_obj(exec, obj, num_fences);
if (ret)
return ret;
}
diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
index f94fec9a8517..b3f82ec7fb17 100644
--- a/include/drm/drm_gpuvm.h
+++ b/include/drm/drm_gpuvm.h
@@ -544,26 +544,9 @@ struct drm_gpuvm_exec {
} extra;
 };
 
-/**
- * drm_gpuvm_prepare_vm() - prepare the GPUVMs common dma-resv
- * @gpuvm: the _gpuvm
- * @exec: the _exec context
- * @num_fences: the amount of _fences to reserve
- *
- * Calls drm_exec_prepare_obj() for the GPUVMs dummy _gem_object.
- *
- * Using this function directly, it is the drivers responsibility to call
- * drm_exec_init() and drm_exec_fini() accordingly.
- *
- * Returns: 0 on success, negative error code on failure.
- */
-static inline int
-drm_gpuvm_prepare_vm(struct drm_gpuvm *gpuvm,
-struct drm_exec *exec,
-unsigned int num_fences)
-{
-   return drm_exec_prepare_obj(exec, gpuvm->r_obj, num_fences);
-}
+int drm_gpuvm_prepare_vm(struct drm_gpuvm *gpuvm,
+struct drm_exec *exec,
+unsigned int num_fences);
 
 int drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,

[PATCH drm-misc-next v2 0/2] PowerVR VM fixes

2023-11-29 Thread Danilo Krummrich
Hi,

Some major GPUVM changes landed just before v8 of the PowerVR series. Since v8
went in rather quickly (review process was finished otherwise) I haven't had the
chance to review the subsequent code changes.

Hence, this series with a few fixes in this context. Plus a minor GPUVM patch to
make the drm_gpuvm_prepare_* helpers useful for PowerVR.

- Danilo

Changes in V2
=
- GPUVM: update function DOC comment to indicate the passing zero fences to
  drm_gpuvm_prepare_* functions results into drm_exec_lock_obj() calls rather
  than drm_exec_prepare_obj() calls.
- pvr/vm: use drm_gpuvm_exec wrappers
- drop 3 patches which were applied already

Danilo Krummrich (2):
  drm/gpuvm: fall back to drm_exec_lock_obj()
  drm/imagination: vm: make use of GPUVM's drm_exec helper

 drivers/gpu/drm/drm_gpuvm.c  | 43 +++--
 drivers/gpu/drm/imagination/pvr_vm.c | 91 +++-
 include/drm/drm_gpuvm.h  | 23 +--
 3 files changed, 77 insertions(+), 80 deletions(-)


base-commit: 83dc1029dcf50b5b849b26679a1b3f860b85d79c
-- 
2.43.0



[etnaviv-next v12 8/8] drm/etnaviv: Support binding multiple GPU cores with component

2023-11-29 Thread Sui Jingfeng
Because the JD9230P discrete GPU has two vivante 3D GPU (GC9200) cores,
the LingJiu GP102 discrete GPU has two separated GPU core (one is 3D and
another one is 2D). The etnaviv_create_platform_device() has been revised
to create a virtual platform device as the representation for the single
GPU core. All virtual gpu devices are bind to the real PCI master device
with the help of component.

Tested with LingJiu GP102 GPU:

 etnaviv :05:00.0: LingJiu GP102 has 2 GPU cores
 etnaviv :05:00.0: bound etnaviv-gpu,3d.0 (ops gpu_ops [etnaviv])
 etnaviv :05:00.0: bound etnaviv-gpu,2d.1 (ops gpu_ops [etnaviv])
 etnaviv-gpu etnaviv-gpu,3d.0: model: GC860, revision: 4601
 etnaviv-gpu etnaviv-gpu,2d.0: model: GC300, revision: 2000
 [drm] Initialized etnaviv 1.3.0 20151214 for :05:00.0 on minor 0

Tested with JEMO JD9230P GPU:

 etnaviv :05:00.0: JingJia Micro JD9230P has 2 GPU cores
 etnaviv :05:00.0: bound etnaviv-gpu,3d.0 (ops gpu_ops [etnaviv])
 etnaviv :05:00.0: bound etnaviv-gpu,3d.1 (ops gpu_ops [etnaviv])
 etnaviv-gpu etnaviv-gpu,3d.0: model: GC9200, revision: 6304
 etnaviv-gpu etnaviv-gpu,3d.1: model: GC9200, revision: 6304
 [drm] Initialized etnaviv 1.3.0 20151214 for :05:00.0 on minor 0

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/etnaviv_drv.c |  37 ++-
 drivers/gpu/drm/etnaviv/etnaviv_drv.h |   8 ++
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c |  53 --
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h |   3 +
 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c | 117 --
 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h |  19 
 6 files changed, 212 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 4a7a451237d5..3652b3017c94 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -571,6 +571,10 @@ int etnaviv_drm_bind(struct device *dev, bool component)
if (ret < 0)
goto out_free_priv;
 
+   ret = etnaviv_register_irq_handler(dev, priv);
+   if (ret)
+   goto out_unbind;
+
load_gpu(drm);
 
ret = drm_dev_register(drm, 0);
@@ -623,7 +627,7 @@ static void etnaviv_master_unbind(struct device *dev)
return etnaviv_drm_unbind(dev, true);
 }
 
-static const struct component_master_ops etnaviv_master_ops = {
+const struct component_master_ops etnaviv_master_ops = {
.bind = etnaviv_master_bind,
.unbind = etnaviv_master_unbind,
 };
@@ -701,16 +705,36 @@ static struct platform_driver etnaviv_platform_driver = {
},
 };
 
-static int etnaviv_create_platform_device(const char *name,
- struct platform_device **ppdev)
+int etnaviv_create_platform_device(struct device *parent,
+  const char *name, int id,
+  struct resource *pres,
+  void *data,
+  struct platform_device **ppdev)
 {
struct platform_device *pdev;
int ret;
 
-   pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE);
+   pdev = platform_device_alloc(name, id);
if (!pdev)
return -ENOMEM;
 
+   pdev->dev.parent = parent;
+
+   if (pres) {
+   ret = platform_device_add_resources(pdev, pres, 1);
+   if (ret) {
+   platform_device_put(pdev);
+   return ret;
+   }
+   }
+
+   if (data) {
+   void *pdata = kmalloc(sizeof(void *), GFP_KERNEL);
+
+   *(void **)pdata = data;
+   pdev->dev.platform_data = pdata;
+   }
+
ret = platform_device_add(pdev);
if (ret) {
platform_device_put(pdev);
@@ -763,7 +787,10 @@ static int __init etnaviv_init(void)
if (np) {
of_node_put(np);
 
-   ret = etnaviv_create_platform_device("etnaviv", _drm);
+   ret = etnaviv_create_platform_device(NULL, "etnaviv",
+PLATFORM_DEVID_NONE,
+NULL, NULL,
+_drm);
if (ret)
goto unregister_platform_driver;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index 6c9d934cbcbd..37e2e859856f 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -98,8 +99,15 @@ bool etnaviv_cmd_validate_one(struct etnaviv_gpu *gpu,
u32 *stream, unsigned int size,
struct drm_etnaviv_gem_submit_reloc *relocs, unsigned int reloc_size);
 
+int etnaviv_create_platform_device(struct device *parent,
+  const char 

[etnaviv-next v12 6/8] drm/etnaviv: Embed struct drm_device in struct etnaviv_drm_private

2023-11-29 Thread Sui Jingfeng
From: Sui Jingfeng 

The instance of struct drm_device and struct etnaviv_drm_private are
intended to be shared by all GPU cores. Embedding struct drm_device into
struct etnaviv_drm_private allow us to allocate storage for them togather.
And use container_of() to retrieve pointer for the containing structure.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/etnaviv_drv.c| 73 +---
 drivers/gpu/drm/etnaviv/etnaviv_drv.h|  8 ++-
 drivers/gpu/drm/etnaviv/etnaviv_gem.c|  6 +-
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |  2 +-
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c|  6 +-
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c|  4 +-
 6 files changed, 47 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 883352aded32..4a7a451237d5 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -45,14 +45,9 @@ static struct device_node 
*etnaviv_of_first_available_node(void)
return NULL;
 }
 
-static struct etnaviv_drm_private *etnaviv_alloc_private(struct device *dev)
+static int etnaviv_private_init(struct device *dev,
+   struct etnaviv_drm_private *priv)
 {
-   struct etnaviv_drm_private *priv;
-
-   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-   if (!priv)
-   return ERR_PTR(-ENOMEM);
-
xa_init_flags(>active_contexts, XA_FLAGS_ALLOC);
 
mutex_init(>gem_lock);
@@ -62,17 +57,16 @@ static struct etnaviv_drm_private 
*etnaviv_alloc_private(struct device *dev)
 
priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(dev);
if (IS_ERR(priv->cmdbuf_suballoc)) {
-   kfree(priv);
dev_err(dev, "Failed to create cmdbuf suballocator\n");
-   return ERR_PTR(-ENOMEM);
+   return -ENOMEM;
}
 
priv->cached_coherent = dev_is_dma_coherent(dev);
 
-   return priv;
+   return 0;
 }
 
-static void etnaviv_free_private(struct etnaviv_drm_private *priv)
+static void etnaviv_private_fini(struct etnaviv_drm_private *priv)
 {
if (!priv)
return;
@@ -80,13 +74,11 @@ static void etnaviv_free_private(struct etnaviv_drm_private 
*priv)
etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
 
xa_destroy(>active_contexts);
-
-   kfree(priv);
 }
 
 static void load_gpu(struct drm_device *dev)
 {
-   struct etnaviv_drm_private *priv = dev->dev_private;
+   struct etnaviv_drm_private *priv = to_etnaviv_priv(dev);
unsigned int i;
 
for (i = 0; i < ETNA_MAX_PIPES; i++) {
@@ -104,7 +96,7 @@ static void load_gpu(struct drm_device *dev)
 
 static int etnaviv_open(struct drm_device *dev, struct drm_file *file)
 {
-   struct etnaviv_drm_private *priv = dev->dev_private;
+   struct etnaviv_drm_private *priv = to_etnaviv_priv(dev);
struct etnaviv_file_private *ctx;
int ret, i;
 
@@ -147,7 +139,7 @@ static int etnaviv_open(struct drm_device *dev, struct 
drm_file *file)
 
 static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file)
 {
-   struct etnaviv_drm_private *priv = dev->dev_private;
+   struct etnaviv_drm_private *priv = to_etnaviv_priv(dev);
struct etnaviv_file_private *ctx = file->driver_priv;
unsigned int i;
 
@@ -172,7 +164,7 @@ static void etnaviv_postclose(struct drm_device *dev, 
struct drm_file *file)
 #ifdef CONFIG_DEBUG_FS
 static int etnaviv_gem_show(struct drm_device *dev, struct seq_file *m)
 {
-   struct etnaviv_drm_private *priv = dev->dev_private;
+   struct etnaviv_drm_private *priv = to_etnaviv_priv(dev);
 
etnaviv_gem_describe_objects(priv, m);
 
@@ -266,7 +258,7 @@ static int show_each_gpu(struct seq_file *m, void *arg)
 {
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
-   struct etnaviv_drm_private *priv = dev->dev_private;
+   struct etnaviv_drm_private *priv = to_etnaviv_priv(dev);
struct etnaviv_gpu *gpu;
int (*show)(struct etnaviv_gpu *gpu, struct seq_file *m) =
node->info_ent->data;
@@ -309,7 +301,7 @@ static void etnaviv_debugfs_init(struct drm_minor *minor)
 static int etnaviv_ioctl_get_param(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct etnaviv_drm_private *priv = dev->dev_private;
+   struct etnaviv_drm_private *priv = to_etnaviv_priv(dev);
struct drm_etnaviv_param *args = data;
struct etnaviv_gpu *gpu;
 
@@ -402,7 +394,7 @@ static int etnaviv_ioctl_wait_fence(struct drm_device *dev, 
void *data,
struct drm_file *file)
 {
struct drm_etnaviv_wait_fence *args = data;
-   struct etnaviv_drm_private *priv = dev->dev_private;
+   struct etnaviv_drm_private *priv = to_etnaviv_priv(dev);
struct drm_etnaviv_timespec *timeout 

[etnaviv-next v12 4/8] drm/etnaviv: Support for the vivante GPU core attached on PCI(e) device

2023-11-29 Thread Sui Jingfeng
From: Sui Jingfeng 

There is a Vivante GC1000 GPU (v5037) in Loongson LS2K1000 (0x0014:0x7a05)
and LS7A1000 (0x0014:0x7a15), the GPU in these chips is a PCI(e) device,
has only one core with both the 3D pipe and 2D pipe. This patch adds PCI
driver wrapper on the top of what drm/etnaviv already have, since this GPU
has only one GPU core, there no need to bind to anything for now. Hence,
the component framework get bypassed.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/Kconfig   |  8 +++
 drivers/gpu/drm/etnaviv/Makefile  |  2 +
 drivers/gpu/drm/etnaviv/etnaviv_drv.c | 10 ++-
 drivers/gpu/drm/etnaviv/etnaviv_drv.h |  3 +
 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c | 74 +++
 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h | 18 ++
 6 files changed, 113 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c
 create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h

diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig
index faa7fc68b009..38c251585ec1 100644
--- a/drivers/gpu/drm/etnaviv/Kconfig
+++ b/drivers/gpu/drm/etnaviv/Kconfig
@@ -15,6 +15,14 @@ config DRM_ETNAVIV
help
  DRM driver for Vivante GPUs.
 
+config DRM_ETNAVIV_PCI_DRIVER
+   bool "enable ETNAVIV PCI driver support"
+   depends on DRM_ETNAVIV
+   depends on PCI
+   help
+ Compile in support for Vivante GPUs attached via PCI(e).
+ Say Y if you have such hardwares.
+
 config DRM_ETNAVIV_THERMAL
bool "enable ETNAVIV thermal throttling"
depends on DRM_ETNAVIV
diff --git a/drivers/gpu/drm/etnaviv/Makefile b/drivers/gpu/drm/etnaviv/Makefile
index 46e5ffad69a6..6829e1ebf2db 100644
--- a/drivers/gpu/drm/etnaviv/Makefile
+++ b/drivers/gpu/drm/etnaviv/Makefile
@@ -16,4 +16,6 @@ etnaviv-y := \
etnaviv_perfmon.o \
etnaviv_sched.o
 
+etnaviv-$(CONFIG_DRM_ETNAVIV_PCI_DRIVER) += etnaviv_pci_drv.o
+
 obj-$(CONFIG_DRM_ETNAVIV)  += etnaviv.o
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 0b68c76d117e..8db86120b11d 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -23,6 +23,7 @@
 #include "etnaviv_gpu.h"
 #include "etnaviv_gem.h"
 #include "etnaviv_mmu.h"
+#include "etnaviv_pci_drv.h"
 #include "etnaviv_perfmon.h"
 
 static struct etnaviv_drm_private *etna_drm_priv_ptr;
@@ -547,7 +548,7 @@ static const struct drm_driver etnaviv_drm_driver = {
.minor  = 3,
 };
 
-static int etnaviv_drm_bind(struct device *dev, bool component)
+int etnaviv_drm_bind(struct device *dev, bool component)
 {
struct etnaviv_drm_private *priv;
struct drm_device *drm;
@@ -598,7 +599,7 @@ static int etnaviv_drm_bind(struct device *dev, bool 
component)
return ret;
 }
 
-static void etnaviv_drm_unbind(struct device *dev, bool component)
+void etnaviv_drm_unbind(struct device *dev, bool component)
 {
struct etnaviv_drm_private *priv = etna_drm_priv_ptr;
struct drm_device *drm = priv->drm;
@@ -758,6 +759,10 @@ static int __init etnaviv_init(void)
if (ret != 0)
goto unregister_gpu_driver;
 
+   ret = etnaviv_register_pci_driver();
+   if (ret != 0)
+   goto unregister_platform_driver;
+
/*
 * If the DT contains at least one available GPU device, instantiate
 * the DRM platform device.
@@ -786,6 +791,7 @@ static void __exit etnaviv_exit(void)
etnaviv_destroy_platform_device(_drm);
platform_driver_unregister(_platform_driver);
platform_driver_unregister(_gpu_driver);
+   etnaviv_unregister_pci_driver();
 }
 module_exit(etnaviv_exit);
 
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index e58f82e698de..9cd72948cfad 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -83,6 +83,9 @@ bool etnaviv_cmd_validate_one(struct etnaviv_gpu *gpu,
u32 *stream, unsigned int size,
struct drm_etnaviv_gem_submit_reloc *relocs, unsigned int reloc_size);
 
+int etnaviv_drm_bind(struct device *dev, bool component);
+void etnaviv_drm_unbind(struct device *dev, bool component);
+
 #ifdef CONFIG_DEBUG_FS
 void etnaviv_gem_describe_objects(struct etnaviv_drm_private *priv,
struct seq_file *m);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c
new file mode 100644
index ..37de661844d8
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+
+#include "etnaviv_drv.h"
+#include "etnaviv_gpu.h"
+#include "etnaviv_pci_drv.h"
+
+static int etnaviv_pci_probe(struct pci_dev *pdev,
+const struct pci_device_id *ent)
+{
+   struct device *dev = >dev;
+   void __iomem *mmio;
+   int ret;
+
+  

[etnaviv-next v12 2/8] drm/etnaviv: Add constructor and destructor for struct etnaviv_drm_private

2023-11-29 Thread Sui Jingfeng
From: Sui Jingfeng 

Noticed that there are a lot of members in the struct etnaviv_drm_private,
which are intended to be shared by all GPU cores. Introduces two helpers
for construction and destruction purpose for it. The benefit is that error
handling get simplified a lot.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/etnaviv_drv.c | 70 +--
 1 file changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index a9a1659840ec..41ef7a8b7839 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -41,6 +41,43 @@ static struct device_node 
*etnaviv_of_first_available_node(void)
return NULL;
 }
 
+static struct etnaviv_drm_private *etnaviv_alloc_private(struct device *dev)
+{
+   struct etnaviv_drm_private *priv;
+
+   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return ERR_PTR(-ENOMEM);
+
+   xa_init_flags(>active_contexts, XA_FLAGS_ALLOC);
+
+   mutex_init(>gem_lock);
+   INIT_LIST_HEAD(>gem_list);
+   priv->num_gpus = 0;
+   priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
+
+   priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(dev);
+   if (IS_ERR(priv->cmdbuf_suballoc)) {
+   kfree(priv);
+   dev_err(dev, "Failed to create cmdbuf suballocator\n");
+   return ERR_PTR(-ENOMEM);
+   }
+
+   return priv;
+}
+
+static void etnaviv_free_private(struct etnaviv_drm_private *priv)
+{
+   if (!priv)
+   return;
+
+   etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
+
+   xa_destroy(>active_contexts);
+
+   kfree(priv);
+}
+
 static void load_gpu(struct drm_device *dev)
 {
struct etnaviv_drm_private *priv = dev->dev_private;
@@ -521,35 +558,21 @@ static int etnaviv_bind(struct device *dev)
if (IS_ERR(drm))
return PTR_ERR(drm);
 
-   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-   if (!priv) {
-   dev_err(dev, "failed to allocate private data\n");
-   ret = -ENOMEM;
+   priv = etnaviv_alloc_private(dev);
+   if (IS_ERR(priv)) {
+   ret = PTR_ERR(priv);
goto out_put;
}
+
drm->dev_private = priv;
 
dma_set_max_seg_size(dev, SZ_2G);
 
-   xa_init_flags(>active_contexts, XA_FLAGS_ALLOC);
-
-   mutex_init(>gem_lock);
-   INIT_LIST_HEAD(>gem_list);
-   priv->num_gpus = 0;
-   priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
-
-   priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
-   if (IS_ERR(priv->cmdbuf_suballoc)) {
-   dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
-   ret = PTR_ERR(priv->cmdbuf_suballoc);
-   goto out_free_priv;
-   }
-
dev_set_drvdata(dev, drm);
 
ret = component_bind_all(dev, drm);
if (ret < 0)
-   goto out_destroy_suballoc;
+   goto out_free_priv;
 
load_gpu(drm);
 
@@ -561,10 +584,8 @@ static int etnaviv_bind(struct device *dev)
 
 out_unbind:
component_unbind_all(dev, drm);
-out_destroy_suballoc:
-   etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
 out_free_priv:
-   kfree(priv);
+   etnaviv_free_private(priv);
 out_put:
drm_dev_put(drm);
 
@@ -580,12 +601,9 @@ static void etnaviv_unbind(struct device *dev)
 
component_unbind_all(dev, drm);
 
-   etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
-
-   xa_destroy(>active_contexts);
+   etnaviv_free_private(priv);
 
drm->dev_private = NULL;
-   kfree(priv);
 
drm_dev_put(drm);
 }
-- 
2.34.1



[etnaviv-next v12 7/8] drm/etnaviv: Add support for the JingJia Macro and LingJiu PCI(e) GPUs

2023-11-29 Thread Sui Jingfeng
Tested on X86-64 with JM9100 GPU, the JM9100 discrete GPU has only one
vivante GPU found so far.

$ sudo dmesg | grep etnaviv

 etnaviv :0d:00.0: enabling device ( -> 0003)
 etnaviv :0d:00.0: Unbalanced pm_runtime_enable!
 etnaviv :0d:00.0: model: GC9200, revision: 6304
 [drm] Initialized etnaviv 1.3.0 20151214 for :0d:00.0 on minor 0

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c | 112 +-
 1 file changed, 109 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c
index 37de661844d8..b55ee6dd723e 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c
@@ -6,10 +6,109 @@
 #include "etnaviv_gpu.h"
 #include "etnaviv_pci_drv.h"
 
+enum etnaviv_pci_gpu_chip_id {
+   GC_CORE_UNKNOWN = 0,
+   JM9100 = 1,
+   JD9230P = 2,
+   LINGJIU_GP102 = 3,
+   GC1000_IN_LS7A1000 = 4,
+   GC1000_IN_LS2K1000 = 5,
+   GC_CORE_PCI_LAST,
+};
+
+struct etnaviv_pci_gpu_platform_data {
+   enum etnaviv_pci_gpu_chip_id chip_id;
+   u32 num_core;
+   u32 num_vram;
+   u32 vram_bars[2];
+   u32 mmio_bar;
+   struct {
+   u32 id;
+   u32 offset;
+   u32 size;
+   char name[20];
+   } cores[ETNA_MAX_PIPES];
+
+   bool has_dedicated_vram;
+   bool no_clk;
+   bool share_irq;
+   char name[24];
+};
+
+static const struct etnaviv_pci_gpu_platform_data
+gc_core_plaform_data[GC_CORE_PCI_LAST] = {
+   {
+   .chip_id = GC_CORE_UNKNOWN,
+   },
+   {
+   .chip_id = JM9100,
+   .num_core = 1,
+   .num_vram = 2,
+   .vram_bars = {0, 2},
+   .mmio_bar = 1,
+   .cores = {{0, 0x0090, 0x0001, "etnaviv-gpu,3d"},},
+   .has_dedicated_vram = true,
+   .no_clk = true,
+   .share_irq = true,
+   .name = "JingJia Micro JM9100",
+   },
+   {
+   .chip_id = JD9230P,
+   .num_core = 2,
+   .num_vram = 2,
+   .vram_bars = {0, 2},
+   .mmio_bar = 1,
+   .cores = {{0, 0x0090, 0x0001, "etnaviv-gpu,3d"},
+ {1, 0x0091, 0x0001, "etnaviv-gpu,3d"},},
+   .has_dedicated_vram = true,
+   .no_clk = true,
+   .share_irq = true,
+   .name = "JingJia Micro JD9230P",
+   },
+   {
+   .chip_id = LINGJIU_GP102,
+   .num_core = 2,
+   .num_vram = 1,
+   .vram_bars = {0,},
+   .mmio_bar = 2,
+   .cores = {{0, 0x0004, 0x0001, "etnaviv-gpu,3d"},
+ {0, 0x000C, 0x0001, "etnaviv-gpu,2d"},},
+   .has_dedicated_vram = true,
+   .no_clk = true,
+   .share_irq = true,
+   .name = "LingJiu GP102",
+   },
+   {
+   .chip_id = GC1000_IN_LS7A1000,
+   .num_core = 1,
+   .num_vram = 1,
+   .vram_bars = {2, 0},
+   .mmio_bar = 0,
+   .cores = {{0, 0, 0, "etnaviv-gpu,3d"}, {}, {}, {}},
+   .has_dedicated_vram = true,
+   .no_clk = true,
+   .share_irq = true,
+   .name = "GC1000 in LS7A1000",
+   },
+   {
+   .chip_id = GC1000_IN_LS2K1000,
+   .num_core = 1,
+   .num_vram = 0,
+   .mmio_bar = 0,
+   .cores = {{0, 0, 0, "etnaviv-gpu,3d"}, {}, {}, {}},
+   .has_dedicated_vram = false,
+   .no_clk = true,
+   .share_irq = true,
+   .name = "GC1000 in LS2K1000",
+   },
+};
+
 static int etnaviv_pci_probe(struct pci_dev *pdev,
 const struct pci_device_id *ent)
 {
+   enum etnaviv_pci_gpu_chip_id chip_id = ent->driver_data;
struct device *dev = >dev;
+   const struct etnaviv_pci_gpu_platform_data *pdata;
void __iomem *mmio;
int ret;
 
@@ -25,11 +124,15 @@ static int etnaviv_pci_probe(struct pci_dev *pdev,
if (ret)
return ret;
 
+   pdata = _core_plaform_data[chip_id];
+
/* PCI bar 0 contain the MMIO registers */
-   mmio = pcim_iomap(pdev, 0, 0);
+   mmio = pcim_iomap(pdev, pdata->mmio_bar, 0);
if (IS_ERR(mmio))
return PTR_ERR(mmio);
 
+   mmio += pdata->cores[0].offset;
+
ret = etnaviv_gpu_driver_create(dev, mmio, pdev->irq, false, false);
if (ret)
return ret;
@@ -49,8 +152,11 @@ static void etnaviv_pci_remove(struct pci_dev *pdev)
 }
 
 static const struct pci_device_id etnaviv_pci_id_lists[] = {
-   {PCI_VDEVICE(LOONGSON, 0x7a15)},
-   {PCI_VDEVICE(LOONGSON, 0x7a05)},
+   {0x0731, 0x9100, 

[etnaviv-next v12 5/8] drm/etnaviv: Add support for cached coherent caching mode

2023-11-29 Thread Sui Jingfeng
From: Sui Jingfeng 

Modern Loongson CPUs choose to define the peripheral devices as DMA
coherent by default, to be specific, the peripheral devices are capable
of snooping CPU's cache. This means that device drivers do not need to
manually maintain the coherency issue between a processor and an I/O
for the cached mappings. Because such hardware features are host platform
specific and vivante GPU IP has been integrated into different platform,
probe the features before using is necessary. Therefore, Do the probe with
the dev_is_dma_coherent() function and allow userspace to query.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/etnaviv_drv.c |  3 +++
 drivers/gpu/drm/etnaviv/etnaviv_drv.h |  9 +
 drivers/gpu/drm/etnaviv/etnaviv_gem.c | 16 ++--
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c |  4 
 include/uapi/drm/etnaviv_drm.h|  1 +
 5 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 8db86120b11d..883352aded32 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -66,6 +67,8 @@ static struct etnaviv_drm_private 
*etnaviv_alloc_private(struct device *dev)
return ERR_PTR(-ENOMEM);
}
 
+   priv->cached_coherent = dev_is_dma_coherent(dev);
+
return priv;
 }
 
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index 9cd72948cfad..acc2e77ad2db 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -46,6 +46,15 @@ struct etnaviv_drm_private {
struct xarray active_contexts;
u32 next_context_id;
 
+   /*
+* If true, the cached mapping is consistent for all CPU cores and
+* bus masters(refer to GPU cores here) in the system. It means that
+* both of the CPU and GPU will see the same data if the buffer being
+* access is cached. And this coherency is guaranteed by host platform
+* specific hardware, not maintained by software.
+*/
+   bool cached_coherent;
+
/* list of GEM objects: */
struct mutex gem_lock;
struct list_head gem_list;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index 71a6d2b1c80f..a72ca0a6883e 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -342,6 +342,7 @@ void *etnaviv_gem_vmap(struct drm_gem_object *obj)
 static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj)
 {
struct page **pages;
+   pgprot_t prot;
 
lockdep_assert_held(>lock);
 
@@ -349,8 +350,19 @@ static void *etnaviv_gem_vmap_impl(struct 
etnaviv_gem_object *obj)
if (IS_ERR(pages))
return NULL;
 
-   return vmap(pages, obj->base.size >> PAGE_SHIFT,
-   VM_MAP, pgprot_writecombine(PAGE_KERNEL));
+   switch (obj->flags) {
+   case ETNA_BO_CACHED:
+   prot = PAGE_KERNEL;
+   break;
+   case ETNA_BO_UNCACHED:
+   prot = pgprot_noncached(PAGE_KERNEL);
+   break;
+   case ETNA_BO_WC:
+   default:
+   prot = pgprot_writecombine(PAGE_KERNEL);
+   }
+
+   return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot);
 }
 
 static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 9db0fbfaf41a..c5a6d5809e2b 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -164,6 +164,10 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 
param, u64 *value)
*value = gpu->identity.eco_id;
break;
 
+   case ETNAVIV_PARAM_CACHED_COHERENT:
+   *value = priv->cached_coherent;
+   break;
+
default:
DBG("%s: invalid param: %u", dev_name(gpu->dev), param);
return -EINVAL;
diff --git a/include/uapi/drm/etnaviv_drm.h b/include/uapi/drm/etnaviv_drm.h
index af024d90453d..61eaa8cd0f5e 100644
--- a/include/uapi/drm/etnaviv_drm.h
+++ b/include/uapi/drm/etnaviv_drm.h
@@ -77,6 +77,7 @@ struct drm_etnaviv_timespec {
 #define ETNAVIV_PARAM_GPU_PRODUCT_ID0x1c
 #define ETNAVIV_PARAM_GPU_CUSTOMER_ID   0x1d
 #define ETNAVIV_PARAM_GPU_ECO_ID0x1e
+#define ETNAVIV_PARAM_CACHED_COHERENT   0x1f
 
 #define ETNA_MAX_PIPES 4
 
-- 
2.34.1



[etnaviv-next v12 3/8] drm/etnaviv: Allow bypass component framework

2023-11-29 Thread Sui Jingfeng
From: Sui Jingfeng 

The component helper is used to bind multiple GPU cores to a virtual
master platform device, but there are SoCs and/or chipsets that contain
only one GPU core. On such cases, component framework can be avoided.
The reason is that usperspace programs(such as X server and Mesa) will
search the PCIe device to open precedently. Creating a virtual master
device for PCI(e) GPUs is unnecessary and incurring troubles.

Add additional code paths to allow bypassing the component framework,
which pave the way for us to introduce the PCI device driver wrapper.
The goal is to share as much as possible between the PCI driver code path
and the platform driver code path. Platforms with a single GPU core could
also try non-component code path.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/etnaviv_drv.c | 48 +++-
 drivers/gpu/drm/etnaviv/etnaviv_drv.h |  1 +
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 83 +--
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h |  7 +++
 4 files changed, 96 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 41ef7a8b7839..0b68c76d117e 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -25,6 +25,8 @@
 #include "etnaviv_mmu.h"
 #include "etnaviv_perfmon.h"
 
+static struct etnaviv_drm_private *etna_drm_priv_ptr;
+
 /*
  * DRM operations:
  */
@@ -545,10 +547,7 @@ static const struct drm_driver etnaviv_drm_driver = {
.minor  = 3,
 };
 
-/*
- * Platform driver:
- */
-static int etnaviv_bind(struct device *dev)
+static int etnaviv_drm_bind(struct device *dev, bool component)
 {
struct etnaviv_drm_private *priv;
struct drm_device *drm;
@@ -564,13 +563,17 @@ static int etnaviv_bind(struct device *dev)
goto out_put;
}
 
+   priv->drm = drm;
drm->dev_private = priv;
+   etna_drm_priv_ptr = priv;
 
dma_set_max_seg_size(dev, SZ_2G);
 
-   dev_set_drvdata(dev, drm);
+   if (component)
+   ret = component_bind_all(dev, drm);
+   else
+   ret = etnaviv_gpu_bind(dev, NULL, drm);
 
-   ret = component_bind_all(dev, drm);
if (ret < 0)
goto out_free_priv;
 
@@ -583,7 +586,10 @@ static int etnaviv_bind(struct device *dev)
return 0;
 
 out_unbind:
-   component_unbind_all(dev, drm);
+   if (component)
+   component_unbind_all(dev, drm);
+   else
+   etnaviv_gpu_unbind(dev, NULL, drm);
 out_free_priv:
etnaviv_free_private(priv);
 out_put:
@@ -592,14 +598,17 @@ static int etnaviv_bind(struct device *dev)
return ret;
 }
 
-static void etnaviv_unbind(struct device *dev)
+static void etnaviv_drm_unbind(struct device *dev, bool component)
 {
-   struct drm_device *drm = dev_get_drvdata(dev);
-   struct etnaviv_drm_private *priv = drm->dev_private;
+   struct etnaviv_drm_private *priv = etna_drm_priv_ptr;
+   struct drm_device *drm = priv->drm;
 
drm_dev_unregister(drm);
 
-   component_unbind_all(dev, drm);
+   if (component)
+   component_unbind_all(dev, drm);
+   else
+   etnaviv_gpu_unbind(dev, NULL, drm);
 
etnaviv_free_private(priv);
 
@@ -608,9 +617,22 @@ static void etnaviv_unbind(struct device *dev)
drm_dev_put(drm);
 }
 
+/*
+ * Platform driver:
+ */
+static int etnaviv_master_bind(struct device *dev)
+{
+   return etnaviv_drm_bind(dev, true);
+}
+
+static void etnaviv_master_unbind(struct device *dev)
+{
+   return etnaviv_drm_unbind(dev, true);
+}
+
 static const struct component_master_ops etnaviv_master_ops = {
-   .bind = etnaviv_bind,
-   .unbind = etnaviv_unbind,
+   .bind = etnaviv_master_bind,
+   .unbind = etnaviv_master_unbind,
 };
 
 static int etnaviv_pdev_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index b3eb1662e90c..e58f82e698de 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -35,6 +35,7 @@ struct etnaviv_file_private {
 };
 
 struct etnaviv_drm_private {
+   struct drm_device *drm;
int num_gpus;
struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
gfp_t shm_gfp_mask;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 4d5819632597..9db0fbfaf41a 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1767,8 +1767,7 @@ static const struct thermal_cooling_device_ops 
cooling_ops = {
.set_cur_state = etnaviv_gpu_cooling_set_cur_state,
 };
 
-static int etnaviv_gpu_bind(struct device *dev, struct device *master,
-   void *data)
+int etnaviv_gpu_bind(struct device *dev, struct device *master, void *data)
 {
struct drm_device *drm = data;
struct 

[etnaviv-next v12 1/8] drm/etnaviv: Add a helper function to get clocks

2023-11-29 Thread Sui Jingfeng
From: Sui Jingfeng 

Because the current implement is DT-based, this is only works when the host
platform has the DT support. Typically, the PLL hardwares are provided by
the host platform, not the GPU core itself. So add a dedicated helper
function to get clocks, only call this function when DT is available.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 53 ---
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 3e35e7db5177..4d5819632597 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1597,6 +1597,35 @@ static irqreturn_t irq_handler(int irq, void *data)
return ret;
 }
 
+static int etnaviv_gpu_clk_get(struct etnaviv_gpu *gpu)
+{
+   struct device *dev = gpu->dev;
+
+   gpu->clk_reg = devm_clk_get_optional(dev, "reg");
+   DBG("clk_reg: %p", gpu->clk_reg);
+   if (IS_ERR(gpu->clk_reg))
+   return PTR_ERR(gpu->clk_reg);
+
+   gpu->clk_bus = devm_clk_get_optional(dev, "bus");
+   DBG("clk_bus: %p", gpu->clk_bus);
+   if (IS_ERR(gpu->clk_bus))
+   return PTR_ERR(gpu->clk_bus);
+
+   gpu->clk_core = devm_clk_get(dev, "core");
+   DBG("clk_core: %p", gpu->clk_core);
+   if (IS_ERR(gpu->clk_core))
+   return PTR_ERR(gpu->clk_core);
+   gpu->base_rate_core = clk_get_rate(gpu->clk_core);
+
+   gpu->clk_shader = devm_clk_get_optional(dev, "shader");
+   DBG("clk_shader: %p", gpu->clk_shader);
+   if (IS_ERR(gpu->clk_shader))
+   return PTR_ERR(gpu->clk_shader);
+   gpu->base_rate_shader = clk_get_rate(gpu->clk_shader);
+
+   return 0;
+}
+
 static int etnaviv_gpu_clk_enable(struct etnaviv_gpu *gpu)
 {
int ret;
@@ -1872,27 +1901,9 @@ static int etnaviv_gpu_platform_probe(struct 
platform_device *pdev)
}
 
/* Get Clocks: */
-   gpu->clk_reg = devm_clk_get_optional(>dev, "reg");
-   DBG("clk_reg: %p", gpu->clk_reg);
-   if (IS_ERR(gpu->clk_reg))
-   return PTR_ERR(gpu->clk_reg);
-
-   gpu->clk_bus = devm_clk_get_optional(>dev, "bus");
-   DBG("clk_bus: %p", gpu->clk_bus);
-   if (IS_ERR(gpu->clk_bus))
-   return PTR_ERR(gpu->clk_bus);
-
-   gpu->clk_core = devm_clk_get(>dev, "core");
-   DBG("clk_core: %p", gpu->clk_core);
-   if (IS_ERR(gpu->clk_core))
-   return PTR_ERR(gpu->clk_core);
-   gpu->base_rate_core = clk_get_rate(gpu->clk_core);
-
-   gpu->clk_shader = devm_clk_get_optional(>dev, "shader");
-   DBG("clk_shader: %p", gpu->clk_shader);
-   if (IS_ERR(gpu->clk_shader))
-   return PTR_ERR(gpu->clk_shader);
-   gpu->base_rate_shader = clk_get_rate(gpu->clk_shader);
+   err = etnaviv_gpu_clk_get(gpu);
+   if (err)
+   return err;
 
/* TODO: figure out max mapped size */
dev_set_drvdata(dev, gpu);
-- 
2.34.1



[etnaviv-next v12 0/8] drm/etnaviv: Add PCI(e) device driver wrapper and instances

2023-11-29 Thread Sui Jingfeng
This series is add PCI device driver wrapper, to support the Vivante GC1000
GPU in LS2K1000 and LS7A1000.

The whole serie have been tested on X86-64 and LoongArch platform, only the
kernel space driver are tested, basically normal and run stable!

v6:
* Fix build issue on system without CONFIG_PCI enabled
v7:
* Add a separate patch for the platform driver rearrangement (Bjorn)
* Switch to runtime check if the GPU is dma coherent or not (Lucas)
* Add ETNAVIV_PARAM_GPU_COHERENT to allow userspace to query (Lucas)
* Remove etnaviv_gpu.no_clk member (Lucas)
* Various Typos and coding style fixed (Bjorn)
v8:
* Fix typos and remove unnecessary header included (Bjorn).
* Add a dedicated function to create the virtual master platform
  device.
v9:
* Use PCI_VDEVICE() macro (Bjorn)
* Add trivial stubs for the PCI driver (Bjorn)
* Remove a redundant dev_err() usage (Bjorn)
* Clean up etnaviv_pdev_probe() with etnaviv_of_first_available_node()
v10:
* Add one more cleanup patch
* Resolve the conflict with a patch from Rob
* Make the dummy PCI stub inlined
* Print only if the platform is dma-coherrent
V11:
* Drop unnecessary changes (Lucas)
* Tweak according to other reviews of v10.

V12:
* Create a virtual platform device for the subcomponent GPU cores
* Bind all subordinate GPU cores to the real PCI master via component.

Sui Jingfeng (8):
  drm/etnaviv: Add a helper function to get clocks
  drm/etnaviv: Add constructor and destructor for struct
etnaviv_drm_private
  drm/etnaviv: Allow bypass component framework
  drm/etnaviv: Support for the vivante GPU core attached on PCI(e)
device
  drm/etnaviv: Add support for cached coherent caching mode
  drm/etnaviv: Embed struct drm_device in struct etnaviv_drm_private
  drm/etnaviv: Add support for the JingJia Macro and LingJiu PCI(e) GPUs
  drm/etnaviv: Support binding multiple GPU cores with component

 drivers/gpu/drm/etnaviv/Kconfig  |   8 +
 drivers/gpu/drm/etnaviv/Makefile |   2 +
 drivers/gpu/drm/etnaviv/etnaviv_drv.c| 189 -
 drivers/gpu/drm/etnaviv/etnaviv_drv.h|  27 ++
 drivers/gpu/drm/etnaviv/etnaviv_gem.c|  22 +-
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |   2 +-
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c| 187 +
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h|  10 +
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c|   4 +-
 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c| 279 +++
 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h|  37 +++
 include/uapi/drm/etnaviv_drm.h   |   1 +
 12 files changed, 639 insertions(+), 129 deletions(-)
 create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c
 create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h


base-commit: 5ce7ae0a6faece18d91ce807026197cface429db
-- 
2.34.1



Re: [PATCH v2 2/2] drm/i915/guc: Add a selftest for FAST_REQUEST errors

2023-11-29 Thread Daniele Ceraolo Spurio




On 11/13/2023 5:00 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

There is a mechanism for reporting errors from fire and forget H2G
messages. This is the only way to find out about almost any error in
the GuC backend submission path. So it would be useful to know that it
is working.

v2: Fix some dumb over-complications and a couple of typos - review
feedback from Daniele.

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   9 ++
  drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 115 ++
  3 files changed, 128 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2b6dfe62c8f2a..e22c12ce245ad 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -297,6 +297,10 @@ struct intel_guc {
 * @number_guc_id_stolen: The number of guc_ids that have been stolen
 */
int number_guc_id_stolen;
+   /**
+* @fast_response_selftest: Backdoor to CT handler for fast response 
selftest
+*/
+   u32 fast_response_selftest;
  #endif
  };
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c

index 89e314b3756bb..ed6ce73ef3b07 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1076,6 +1076,15 @@ static int ct_handle_response(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
found = true;
break;
}
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (!found && ct_to_guc(ct)->fast_response_selftest) {
+   CT_DEBUG(ct, "Assuming unsolicited response due to FAST_REQUEST 
selftest\n");
+   ct_to_guc(ct)->fast_response_selftest++;
+   found = true;
+   }
+#endif
+
if (!found) {
CT_ERROR(ct, "Unsolicited response message: len %u, data %#x (fence 
%u, last %u)\n",
 len, hxg[0], fence, ct->requests.last_fence);
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index bfb72143566f6..c900aac85adba 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -286,11 +286,126 @@ static int intel_guc_steal_guc_ids(void *arg)
return ret;
  }
  
+/*

+ * Send a context schedule H2G message with an invalid context id.
+ * This should generate a GUC_RESULT_INVALID_CONTEXT response.
+ */
+static int bad_h2g(struct intel_guc *guc)
+{
+   u32 action[] = {
+  INTEL_GUC_ACTION_SCHED_CONTEXT,
+  0x12345678,
+   };
+
+   return intel_guc_send_nb(guc, action, ARRAY_SIZE(action), 0);
+}
+
+/*
+ * Set a spinner running to make sure the system is alive and active,
+ * then send a bad but asynchronous H2G command and wait to see if an
+ * error response is returned. If no response is received or if the
+ * spinner dies then the test will fail.
+ */
+#define FAST_RESPONSE_TIMEOUT_MS   1000
+static int intel_guc_fast_request(void *arg)
+{
+   struct intel_gt *gt = arg;
+   struct intel_context *ce;
+   struct igt_spinner spin;
+   struct i915_request *rq;
+   intel_wakeref_t wakeref;
+   struct intel_engine_cs *engine = intel_selftest_find_any_engine(gt);
+   bool spinning = false;
+   int ret = 0;
+
+   if (!engine)
+   return 0;
+
+   wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+   ce = intel_context_create(engine);
+   if (IS_ERR(ce)) {
+   ret = PTR_ERR(ce);
+   gt_err(gt, "Failed to create spinner request: %pe\n", ce);
+   goto err_pm;
+   }
+
+   ret = igt_spinner_init(, engine->gt);
+   if (ret) {
+   gt_err(gt, "Failed to create spinner: %pe\n", ERR_PTR(ret));
+   goto err_pm;
+   }
+   spinning = true;
+
+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
+   intel_context_put(ce);
+   if (IS_ERR(rq)) {
+   ret = PTR_ERR(rq);
+   gt_err(gt, "Failed to create spinner request: %pe\n", rq);
+   goto err_spin;
+   }
+
+   ret = request_add_spin(rq, );
+   if (ret) {
+   gt_err(gt, "Failed to add Spinner request: %pe\n", 
ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   gt->uc.guc.fast_response_selftest = 1;
+
+   ret = bad_h2g(>uc.guc);
+   if (ret) {
+   gt_err(gt, "Failed to send H2G: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   ret = wait_for(gt->uc.guc.fast_response_selftest != 1 || 
i915_request_completed(rq),
+  FAST_RESPONSE_TIMEOUT_MS);
+   if (ret) {
+   gt_err(gt, "Request wait failed: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   if 

Re: [Linaro-mm-sig] Re: [PATCH] dma-buf: Correct the documentation of name and exp_name symbols

2023-11-29 Thread Alex Deucher
On Wed, Nov 22, 2023 at 1:58 PM Christian König
 wrote:
>
> Am 22.11.23 um 17:05 schrieb Ramesh Errabolu:
> > Fix the documentation of struct dma_buf members name and exp_name
> > as to how these members are to be used and accessed.
> >
> > Signed-off-by: Ramesh Errabolu 
>
> Reviewed-by: Christian König 

Please apply this to drm-misc.

Alex

>
> > ---
> >   include/linux/dma-buf.h | 11 +++
> >   1 file changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> > index 3f31baa3293f..8ff4add71f88 100644
> > --- a/include/linux/dma-buf.h
> > +++ b/include/linux/dma-buf.h
> > @@ -343,16 +343,19 @@ struct dma_buf {
> >   /**
> >* @exp_name:
> >*
> > -  * Name of the exporter; useful for debugging. See the
> > -  * DMA_BUF_SET_NAME IOCTL.
> > +  * Name of the exporter; useful for debugging. Must not be NULL
> >*/
> >   const char *exp_name;
> >
> >   /**
> >* @name:
> >*
> > -  * Userspace-provided name; useful for accounting and debugging,
> > -  * protected by dma_resv_lock() on @resv and @name_lock for read 
> > access.
> > +  * Userspace-provided name. Default value is NULL. If not NULL,
> > +  * length cannot be longer than DMA_BUF_NAME_LEN, including NIL
> > +  * char. Useful for accounting and debugging. Read/Write accesses
> > +  * are protected by @name_lock
> > +  *
> > +  * See the IOCTLs DMA_BUF_SET_NAME or DMA_BUF_SET_NAME_A/B
> >*/
> >   const char *name;
> >
>
> ___
> Linaro-mm-sig mailing list -- linaro-mm-...@lists.linaro.org
> To unsubscribe send an email to linaro-mm-sig-le...@lists.linaro.org


Re: [PATCH v2 1/1] drm/i915/pxp: Add missing tag for Wa_14019159160

2023-11-29 Thread Teres Alexis, Alan Previn
On Mon, 2023-11-27 at 15:24 -0500, Vivi, Rodrigo wrote:
> On Wed, Nov 22, 2023 at 12:30:03PM -0800, Alan Previn wrote:
alan:snip
alan: thanks for reviewing and apologize for replying to this late.

> > /*
> > -* On MTL and newer platforms, protected contexts require setting
> > -* the LRC run-alone bit or else the encryption will not happen.
> > +* Wa_14019159160 - Case 2: mtl
> > +* On some platforms, protected contexts require setting
> > +* the LRC run-alone bit or else the encryption/decryption will not 
> > happen.
> > +* NOTE: Case 2 only applies to PXP use-case of said workaround.
> >  */
> 
> hmm, interesting enough, on the wa description I read that it is incomplete 
> for MTL/ARL
> and something about a fuse bit. We should probably chase for some 
> clarification in the
> HSD?!
alan: yes, i went through the HSD description with the architect and we both 
had agreed that
that from the KMD's perspective. At that time, the checking of the fuse from 
KMD's
could be optimized out for Case-2-PXP: if the fuses was set a certain way, KMD 
can skip setting
the bit in lrc because hw will enforce runalone in pxp mode irrespective of 
what KMD does but
if fuse was was not set that way KMD needed to set the runalone in lrc. So for 
case2, its simpler
to just turn it on always when the context is protected. However, that said, i 
realized the
wording of the HSDs have changed since the original patch was implemented so i 
will reclarify
offline and reply back. NOTE: i believe John Harrison is working on case-3 
through a
separate series.

> 
> > -   if (GRAPHICS_VER_FULL(ce->engine->i915) >= IP_VER(12, 70) &&
> > -   (ce->engine->class == COMPUTE_CLASS || ce->engine->class == 
> > RENDER_CLASS)) {
> > +   if (IS_METEORLAKE(ce->engine->i915) && (ce->engine->class == 
> > COMPUTE_CLASS ||
> > +   ce->engine->class == 
> > RENDER_CLASS)) {
> 
> This check now excludes the ARL with the same IP, no?!
alan: yeah - re-reved this part just now.
> 
> > rcu_read_lock();
> > gem_ctx = rcu_dereference(ce->gem_context);
> > if (gem_ctx)
> > 
> > base-commit: 5429d55de723544dfc0630cf39d96392052b27a1
> > -- 
> > 2.39.0
> > 



Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Alex Deucher
On Wed, Nov 29, 2023 at 3:10 PM Alex Deucher  wrote:
>
> Actually I think I see the problem.  I'll try and send out a patch
> later today to test.

Does the attached patch fix it?

Alex

>
> Alex
>
> On Wed, Nov 29, 2023 at 1:52 PM Alex Deucher  wrote:
> >
> > On Wed, Nov 29, 2023 at 11:41 AM Luben Tuikov  wrote:
> > >
> > > On 2023-11-29 10:22, Alex Deucher wrote:
> > > > On Wed, Nov 29, 2023 at 8:50 AM Alex Deucher  
> > > > wrote:
> > > >>
> > > >> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  
> > > >> wrote:
> > > >>>
> > > >>> On 2023-11-28 17:13, Alex Deucher wrote:
> > >  On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  
> > >  wrote:
> > > >
> > > > Alex Deucher  writes:
> > > >
> > > >>> In that case those are the already known problems with the 
> > > >>> scheduler
> > > >>> changes, aren't they?
> > > >>
> > > >> Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
> > > >> misunderstanding what the original report was actually testing.  
> > > >> If it
> > > >> was 6.7, then try reverting:
> > > >> 56e449603f0ac580700621a356d35d5716a62ce5
> > > >> b70438004a14f4d0f9890b3297cd66248728546c
> > > >
> > > > At some point it was suggested that I file a gitlab issue, but I 
> > > > took
> > > > this to mean it was already known and being worked on.  -rc3 came 
> > > > out
> > > > today and still has the problem.  Is there a known issue I could 
> > > > track?
> > > >
> > > 
> > >  At this point, unless there are any objections, I think we should 
> > >  just
> > >  revert the two patches
> > > >>> Uhm, no.
> > > >>>
> > > >>> Why "the two" patches?
> > > >>>
> > > >>> This email, part of this thread,
> > > >>>
> > > >>> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/
> > > >>>
> > > >>> clearly states that reverting *only* this commit,
> > > >>> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable 
> > > >>> number of run-queues
> > > >>> *does not* mitigate the failed suspend. (Furthermore, this commit 
> > > >>> doesn't really change
> > > >>> anything operational, other than using an allocated array, instead of 
> > > >>> a static one, in DRM,
> > > >>> while the 2nd patch is solely contained within the amdgpu driver 
> > > >>> code.)
> > > >>>
> > > >>> Leaving us with only this change,
> > > >>> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
> > > >>> to be at fault, as the kernel log attached in the linked email above 
> > > >>> shows.
> > > >>>
> > > >>> The conclusion is that only b70438004a14f4 needs reverting.
> > > >>
> > > >> b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
> > > >> 56e449603f0ac5 breaks amdgpu.
> > > >
> > > > We can try and re-enable it in the next kernel.  I'm just not sure
> > > > we'll be able to fix this in time for 6.7 with the holidays and all
> > > > and I don't want to cause a lot of scheduler churn at the end of the
> > > > 6.7 cycle if we hold off and try and fix it.  Reverting seems like the
> > > > best short term solution.
> > >
> > > A lot of subsequent code has come in since commit 56e449603f0ac5, as it 
> > > opened
> > > the opportunity for a 1-to-1 relationship between an entity and a 
> > > scheduler.
> > > (Should've always been the case, from the outset. Not sure why it was 
> > > coded as
> > > a fixed-size array.)
> > >
> > > Given that commit 56e449603f0ac5 has nothing to do with amdgpu, and the 
> > > problem
> > > is wholly contained in amdgpu, and no other driver has this problem, 
> > > there is
> > > no reason to have to "churn", i.e. go back and forth in DRM, only to 
> > > cover up
> > > an init bug in amdgpu. See the response I just sent in @this thread:
> > > https://lore.kernel.org/r/05007cb0-871e-4dc7-af58-1351f4ba4...@gmail.com
> > >
> > > And it's not like this issue is unknown. I first posted about it on 
> > > 2023-10-16.
> > >
> > > Ideally, amdgpu would just fix their init code.
> >
> > You can't make changes to core code that break other drivers.
> > Arguably 56e449603f0ac5 should not have gone in in the first place if
> > it broke amdgpu.  b70438004a14f4 was the code to fix amdgpu's init
> > code, but as a side effect it seems to have broken suspend for some
> > users.
> >
> > Alex
From 96e75b5218f7a124eafa53853681eef8fe567ab8 Mon Sep 17 00:00:00 2001
From: Alex Deucher 
Date: Wed, 29 Nov 2023 15:44:25 -0500
Subject: [PATCH] drm/amdgpu: fix buffer funcs setting order on suspend

We need to make disable this after the last eviction
call, but before we disable the SDMA IP.

Fixes: b70438004a14 ("drm/amdgpu: move buffer funcs setting up a level")
Link: https://lists.freedesktop.org/archives/amd-gfx/2023-November/101197.html
Signed-off-by: Alex Deucher 
Cc: Phillip Susi 
Cc: Luben Tuikov 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 

[PATCH v1] drm/msm/dpu: improve DSC allocation

2023-11-29 Thread Kuogee Hsieh
A DCE (Display Compression Engine) contains two DSC hard slice encoders.
Each DCE start with even DSC encoder index followed by an odd DSC encoder
index. Each encoder can work independently. But Only two DSC encoders from
same DCE can be paired to work together to support merge mode. In addition,
the DSC with even index have to mapping to even pingpong index and DSC with
odd index have to mapping to odd pingpong index at its data path. This patch
improve DSC allocation mechanism with consideration of above factors.

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 94 +-
 1 file changed, 82 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index f9215643..427d70d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -466,24 +466,94 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
   struct drm_encoder *enc,
   const struct msm_display_topology *top)
 {
-   int num_dsc = top->num_dsc;
-   int i;
+   int num_dsc = 0;
+   int i, pp_idx;
+   bool pair = false;
+   int dsc_idx[DSC_MAX - DSC_0];
+   uint32_t pp_to_enc_id[PINGPONG_MAX - PINGPONG_0];
+   int pp_max = PINGPONG_MAX - PINGPONG_0;
+
+   if (!top->num_dsc || !top->num_intf)
+   return 0;
+
+   /*
+* Truth:
+* 1) every layer mixer only connects to one pingpong
+* 2) no pingpong split -- two layer mixers shared one pingpong
+* 3) each DSC engine contains two dsc encoders
+*-- index(0,1), index (2,3),... etc
+* 4) dsc pair can only happens with same DSC engine except 4 dsc
+*merge mode application (8k) which need two DSC engines
+* 5) odd pingpong connect to odd dsc
+* 6) even pingpong connect even dsc
+*/
+
+   /* num_dsc should be either 1, 2 or 4 */
+   if (top->num_dsc > top->num_intf)   /* merge mode */
+   pair = true;
+
+   /* fill working copy with pingpong list */
+   memcpy(pp_to_enc_id, global_state->pingpong_to_enc_id, 
sizeof(pp_to_enc_id));
+
+   for (i = 0; i < ARRAY_SIZE(rm->dsc_blks); i++) {
+   if (!rm->dsc_blks[i])   /* end of dsc list */
+   break;
 
-   /* check if DSC required are allocated or not */
-   for (i = 0; i < num_dsc; i++) {
-   if (!rm->dsc_blks[i]) {
-   DPU_ERROR("DSC %d does not exist\n", i);
-   return -EIO;
+   if (global_state->dsc_to_enc_id[i]) {   /* used */
+   /* consective dsc index to be paired */
+   if (pair && num_dsc) {  /* already start pairing, re 
start */
+   num_dsc = 0;
+   /* fill working copy with pingpong list */
+   memcpy(pp_to_enc_id, 
global_state->pingpong_to_enc_id,
+   
sizeof(pp_to_enc_id));
+   }
+   continue;
}
 
-   if (global_state->dsc_to_enc_id[i]) {
-   DPU_ERROR("DSC %d is already allocated\n", i);
-   return -EIO;
+   /* odd index can not become start of pairing */
+   if (pair && (i & 0x01) && !num_dsc)
+   continue;
+
+   /*
+* find the pingpong index which had been reserved
+* previously at layer mixer allocation
+*/
+   for (pp_idx = 0; pp_idx < pp_max; pp_idx++) {
+   if (pp_to_enc_id[pp_idx] == enc->base.id)
+   break;
}
+
+   /*
+* dsc even index must map to pingpong even index
+* dsc odd index must map to pingpong odd index
+*/
+   if ((i & 0x01) != (pp_idx & 0x01))
+   continue;
+
+   /*
+* delete pp_idx so that it can not be found at next search
+* in the case of pairing
+*/
+   pp_to_enc_id[pp_idx] = NULL;
+
+   dsc_idx[num_dsc++] = i;
+   if (num_dsc >= top->num_dsc)
+   break;
}
 
-   for (i = 0; i < num_dsc; i++)
-   global_state->dsc_to_enc_id[i] = enc->base.id;
+   if (num_dsc < top->num_dsc) {
+   DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n",
+   num_dsc, top->num_dsc );
+   return -ENAVAIL;
+   }
+
+   /* reserve dsc */
+   for (i = 0; i < top->num_dsc; i++) {
+   int j;
+
+   j = dsc_idx[i];
+   global_state->dsc_to_enc_id[j] = 

Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Phillip Susi
Luben Tuikov  writes:

> I remember that the problem was really that amdgpu called 
> drm_sched_entity_init(),
> in amdgpu_ttm_set_buffer_funcs_status() without actually having initialized 
> the scheduler
> used therein. For instance, the code before commit b70438004a14f4, looked 
> like this:
>



>   sched = >sched; <-- LT: No 
> one has initialized this scheduler
>   r = drm_sched_entity_init(>mman.entity, <-- Oopses, 
> now that sched->sched_rq is not



> Before commit 56e449603f0ac5, amdgpu was getting away with this, because the 
> sched->sched_rq
> was a static array.
>
> Ideally, amdgpu code would be fixed.

This sounds like an initilization problem that resulted in an OOPS at
boot time, but I don't remember seeing that.  I just get a failure on
system suspend.


Re: [RFC] drm: enable W=1 warnings by default across the subsystem

2023-11-29 Thread Hamza Mahfooz

Cc: Nathan Chancellor 

On 11/29/23 13:12, Jani Nikula wrote:

At least the i915 and amd drivers enable a bunch more compiler warnings
than the kernel defaults.

Extend the W=1 warnings to the entire drm subsystem by default. Use the
copy-pasted warnings from scripts/Makefile.extrawarn with
s/KBUILD_CFLAGS/subdir-ccflags-y/ to make it easier to compare and keep
up with them in the future.

This is similar to the approach currently used in i915.

Some of the -Wextra warnings do need to be disabled, just like in
Makefile.extrawarn, but take care to not disable them for W=2 or W=3
builds, depending on the warning.


I think this should go in after drm-misc-next has a clean build (for
COMPILE_TEST builds) with this patch applied. Otherwise, it will break a
lot of build configs.



Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
Cc: Alex Deucher 
Cc: Christian König 
Cc: Pan, Xinhui 
Cc: Karol Herbst 
Cc: Lyude Paul 
Cc: Danilo Krummrich 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
Cc: Marijn Suijten 
Signed-off-by: Jani Nikula 

---

With my admittedly limited and very much x86 focused kernel config, I
get some -Wunused-but-set-variable and -Wformat-truncation= warnings,
but nothing we can't handle.

We could fix them up front, or disable the extra warnings on a per
driver basis with a FIXME comment in their respective Makefiles.

With the experience from i915, I think this would significantly reduce
the constant loop of warnings added by people not using W=1 and
subsequently fixed by people using W=1.

Note: I've Cc'd the maintainers of drm, drm misc and some of the biggest
drivers.
---
  drivers/gpu/drm/Makefile | 27 +++
  1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index b4cb0835620a..6939e4ea13d5 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -5,6 +5,33 @@
  
  CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG)	+= -DDYNAMIC_DEBUG_MODULE
  
+# Unconditionally enable W=1 warnings locally

+# --- begin copy-paste W=1 warnings from scripts/Makefile.extrawarn
+subdir-ccflags-y += -Wextra -Wunused -Wno-unused-parameter
+subdir-ccflags-y += -Wmissing-declarations
+subdir-ccflags-y += $(call cc-option, -Wrestrict)
+subdir-ccflags-y += -Wmissing-format-attribute
+subdir-ccflags-y += -Wmissing-prototypes
+subdir-ccflags-y += -Wold-style-definition
+subdir-ccflags-y += -Wmissing-include-dirs
+subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable)
+subdir-ccflags-y += $(call cc-option, -Wunused-const-variable)
+subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned)
+subdir-ccflags-y += $(call cc-option, -Wformat-overflow)
+subdir-ccflags-y += $(call cc-option, -Wformat-truncation)
+subdir-ccflags-y += $(call cc-option, -Wstringop-overflow)
+subdir-ccflags-y += $(call cc-option, -Wstringop-truncation)
+# The following turn off the warnings enabled by -Wextra
+ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),)
+subdir-ccflags-y += -Wno-missing-field-initializers
+subdir-ccflags-y += -Wno-type-limits
+subdir-ccflags-y += -Wno-shift-negative-value
+endif
+ifeq ($(findstring 3, $(KBUILD_EXTRA_WARN)),)
+subdir-ccflags-y += -Wno-sign-compare
+endif
+# --- end copy-paste
+
  drm-y := \
drm_aperture.o \
drm_atomic.o \

--
Hamza



Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Alex Deucher
Actually I think I see the problem.  I'll try and send out a patch
later today to test.

Alex

On Wed, Nov 29, 2023 at 1:52 PM Alex Deucher  wrote:
>
> On Wed, Nov 29, 2023 at 11:41 AM Luben Tuikov  wrote:
> >
> > On 2023-11-29 10:22, Alex Deucher wrote:
> > > On Wed, Nov 29, 2023 at 8:50 AM Alex Deucher  
> > > wrote:
> > >>
> > >> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  
> > >> wrote:
> > >>>
> > >>> On 2023-11-28 17:13, Alex Deucher wrote:
> >  On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  
> >  wrote:
> > >
> > > Alex Deucher  writes:
> > >
> > >>> In that case those are the already known problems with the scheduler
> > >>> changes, aren't they?
> > >>
> > >> Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
> > >> misunderstanding what the original report was actually testing.  If 
> > >> it
> > >> was 6.7, then try reverting:
> > >> 56e449603f0ac580700621a356d35d5716a62ce5
> > >> b70438004a14f4d0f9890b3297cd66248728546c
> > >
> > > At some point it was suggested that I file a gitlab issue, but I took
> > > this to mean it was already known and being worked on.  -rc3 came out
> > > today and still has the problem.  Is there a known issue I could 
> > > track?
> > >
> > 
> >  At this point, unless there are any objections, I think we should just
> >  revert the two patches
> > >>> Uhm, no.
> > >>>
> > >>> Why "the two" patches?
> > >>>
> > >>> This email, part of this thread,
> > >>>
> > >>> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/
> > >>>
> > >>> clearly states that reverting *only* this commit,
> > >>> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable number 
> > >>> of run-queues
> > >>> *does not* mitigate the failed suspend. (Furthermore, this commit 
> > >>> doesn't really change
> > >>> anything operational, other than using an allocated array, instead of a 
> > >>> static one, in DRM,
> > >>> while the 2nd patch is solely contained within the amdgpu driver code.)
> > >>>
> > >>> Leaving us with only this change,
> > >>> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
> > >>> to be at fault, as the kernel log attached in the linked email above 
> > >>> shows.
> > >>>
> > >>> The conclusion is that only b70438004a14f4 needs reverting.
> > >>
> > >> b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
> > >> 56e449603f0ac5 breaks amdgpu.
> > >
> > > We can try and re-enable it in the next kernel.  I'm just not sure
> > > we'll be able to fix this in time for 6.7 with the holidays and all
> > > and I don't want to cause a lot of scheduler churn at the end of the
> > > 6.7 cycle if we hold off and try and fix it.  Reverting seems like the
> > > best short term solution.
> >
> > A lot of subsequent code has come in since commit 56e449603f0ac5, as it 
> > opened
> > the opportunity for a 1-to-1 relationship between an entity and a scheduler.
> > (Should've always been the case, from the outset. Not sure why it was coded 
> > as
> > a fixed-size array.)
> >
> > Given that commit 56e449603f0ac5 has nothing to do with amdgpu, and the 
> > problem
> > is wholly contained in amdgpu, and no other driver has this problem, there 
> > is
> > no reason to have to "churn", i.e. go back and forth in DRM, only to cover 
> > up
> > an init bug in amdgpu. See the response I just sent in @this thread:
> > https://lore.kernel.org/r/05007cb0-871e-4dc7-af58-1351f4ba4...@gmail.com
> >
> > And it's not like this issue is unknown. I first posted about it on 
> > 2023-10-16.
> >
> > Ideally, amdgpu would just fix their init code.
>
> You can't make changes to core code that break other drivers.
> Arguably 56e449603f0ac5 should not have gone in in the first place if
> it broke amdgpu.  b70438004a14f4 was the code to fix amdgpu's init
> code, but as a side effect it seems to have broken suspend for some
> users.
>
> Alex


[PULL] drm-misc-fixes

2023-11-29 Thread Maarten Lankhorst

Hi Dave, Daniel,

This pull request is a bit confusing, as it first adds the panel fixes 
and a driver/core change, then immediately revert it.


Cheers,
~Maarten

drm-misc-fixes-2023-11-29:
Fixes for v6.7-rc4:
- Revert panel fixes as they require exporting device_is_dependent.
- Do not double add fences in dma_resv_add_fence.
- Fix GPUVM license identifier.
- Assorted nouveau fixes.
- Fix error check for nt36523.
The following changes since commit ab93edb2f94c3c0d5965be3815782472adbe3f52:

  nouveau/gsp: allocate enough space for all channel ids. (2023-11-21 
22:28:01 +0100)


are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-11-29

for you to fetch changes up to fb18fe0fdf22a2f4512a8b644bb5ea1473829cda:

  drm/panel: nt36523: fix return value check in nt36523_probe() 
(2023-11-29 16:54:23 +0100)



Fixes for v6.7-rc4:
- Revert panel fixes as they require exporting device_is_dependent.
- Do not double add fences in dma_resv_add_fence.
- Fix GPUVM license identifier.
- Assorted nouveau fixes.
- Fix error check for nt36523.


Christian König (1):
  dma-buf: fix check in dma_resv_add_fence

Dan Carpenter (1):
  nouveau/gsp/r535: remove a stray unlock in r535_gsp_rpc_send()

Dave Airlie (1):
  nouveau: find the smallest page allocation to cover a buffer alloc.

Gustavo A. R. Silva (1):
  nouveau/gsp: replace zero-length array with flex-array member and 
use __counted_by


Linus Walleij (3):
  Revert "drm/bridge: panel: Check device dependency before 
managing device link"

  Revert "driver core: Export device_is_dependent() to modules"
  Revert "drm/bridge: panel: Add a device link between drm device 
and panel device"


Liu Ying (2):
  drm/bridge: panel: Check device dependency before managing device 
link

  driver core: Export device_is_dependent() to modules

Thomas Hellström (1):
  drm/gpuvm: Fix deprecated license identifier

Yang Yingliang (1):
  drm/panel: nt36523: fix return value check in nt36523_probe()

xiazhengqiao (1):
  drm/panel: starry-2081101qfh032011-53g: Fine tune the panel power 
sequence


 drivers/dma-buf/dma-resv.c  |  2 +-
 drivers/gpu/drm/bridge/panel.c  | 17 
-

 drivers/gpu/drm/drm_gpuvm.c |  2 +-
 .../nvrm/535.113.01/nvidia/generated/g_os_nvoc.h|  2 +-
 drivers/gpu/drm/nouveau/nouveau_bo.c|  5 +++--
 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c  |  6 ++
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c  |  1 +
 drivers/gpu/drm/panel/panel-novatek-nt36523.c   |  4 ++--
 include/drm/drm_gpuvm.h |  2 +-
 include/linux/dma-fence.h   | 15 
+++

 10 files changed, 27 insertions(+), 29 deletions(-)


Re: [PATCH v6] Documentation/gpu: VM_BIND locking document

2023-11-29 Thread Thomas Hellström



On 11/29/23 20:20, John Hubbard wrote:

On 11/29/23 01:06, Thomas Hellström wrote:

Add the first version of the VM_BIND locking document which is
intended to be part of the xe driver upstreaming agreement.

The document describes and discuss the locking used during exec-
functions, evicton and for userptr gpu-vmas. Intention is to be using 
the

same nomenclature as the drm-vm-bind-async.rst.



Hi Thomas,

As requested, for the pin_user_pages() aspects (the MMU notifier
registration case), please feel free to add:

Acked-by: John Hubbard 

Hi, John,

Thanks!
/Thomas




Re: [PATCH 08/10] iommu/tegra: Use tegra_dev_iommu_get_stream_id() in the remaining places

2023-11-29 Thread Jason Gunthorpe
On Wed, Nov 29, 2023 at 05:23:13PM +0100, Thierry Reding wrote:
> > diff --git a/drivers/memory/tegra/tegra186.c 
> > b/drivers/memory/tegra/tegra186.c
> > index 533f85a4b2bdb7..3e4fbe94dd666e 100644
> > --- a/drivers/memory/tegra/tegra186.c
> > +++ b/drivers/memory/tegra/tegra186.c
> > @@ -111,21 +111,21 @@ static void tegra186_mc_client_sid_override(struct 
> > tegra_mc *mc,
> >  static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device 
> > *dev)
> >  {
> >  #if IS_ENABLED(CONFIG_IOMMU_API)
> > -   struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > struct of_phandle_args args;
> > unsigned int i, index = 0;
> > +   u32 sid;
> >  
> > +   WARN_ON(!tegra_dev_iommu_get_stream_id(dev, ));
> 
> I know the code previously didn't check for any errors, but we may want
> to do so now. If tegra_dev_iommu_get_stream_id() ever fails we may end
> up writing some undefined value into the override register.

My assumption was it never fails otherwise this probably already
doesn't work?

> I'm also unsure if WARN_ON() is appropriate here. I vaguely recall that
> ->probe_device() was called for all devices on the bus and not all of
> them may have been associated with the IOMMU. Not all of them may in
> fact access memory in the first place.

So you are thinkin that of_parse_phandle_with_args() is a NOP
sometimes so it will tolerate the failure?

Seems like the best thing to do is just continue to ignore it then?

> Perhaps I'm misremembering and the IOMMU core now takes care of only
> calling this when fwspec is indeed valid?

Can't advise, I have no idea what tegra_mc_ops is for :)

Jason



Re: [Intel-gfx] [PATCH v5] drm/i915/pxp: Add drm_dbgs for critical PXP events.

2023-11-29 Thread Teres Alexis, Alan Previn
On Fri, 2023-11-24 at 08:30 +, Tvrtko Ursulin wrote:
> On 22/11/2023 19:15, Alan Previn wrote:
alan:snip
alan: thanks for reviewing.
> > if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
> > -   pxp->session_events |= PXP_TERMINATION_COMPLETE;
> > +   pxp->session_events |= PXP_TERMINATION_COMPLETE | 
> > PXP_EVENT_TYPE_IRQ;
> 
> This looked to be doing more than adding debug logs, but then no one is 
> actually consuming this new flag?!
alan: see below hunk, inside pxp_session_work the drm_dbg that was prints
the "events" that came from above. we need this debug message to uniquely
recognize that contexts pxp keys would get invalidated in response to
a KCR IRQ (as opposed to other known flows that are being reported by other
means like banning hanging contexts, or as part of suspend etc).
NOTE: pxp->session_events does get set in at lease one other path
outside the IRQ (which triggers teardown but not coming from KCR-hw)
This flag is solely for the debug message. Hope this works.

> 
> Regards,
> 
> Tvrtko
> 
> >   
> > if (pxp->session_events)
> > queue_work(system_unbound_wq, >session_work);
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
> > b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > index 0a3e66b0265e..091c86e03d1a 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > @@ -137,8 +137,10 @@ void intel_pxp_terminate(struct intel_pxp *pxp, bool 
> > post_invalidation_needs_res
> >   static void pxp_terminate_complete(struct intel_pxp *pxp)
> >   {
> > /* Re-create the arb session after teardown handle complete */
> > -   if (fetch_and_zero(>hw_state_invalidated))
> > +   if (fetch_and_zero(>hw_state_invalidated)) {
> > +   drm_dbg(>ctrl_gt->i915->drm, "PXP: creating arb_session 
> > after invalidation");
> > pxp_create_arb_session(pxp);
> > +   }
> >   
> > complete_all(>termination);
> >   }
> > @@ -157,6 +159,8 @@ static void pxp_session_work(struct work_struct *work)
> > if (!events)
> > return;
> >   
> > +   drm_dbg(>i915->drm, "PXP: processing event-flags 0x%08x", events);
> > +
> > if (events & PXP_INVAL_REQUIRED)
> > intel_pxp_invalidate(pxp);
> >   
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h 
> > b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > index 7e11fa8034b2..07864b584cf4 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > @@ -124,6 +124,7 @@ struct intel_pxp {
> >   #define PXP_TERMINATION_REQUEST  BIT(0)
> >   #define PXP_TERMINATION_COMPLETE BIT(1)
> >   #define PXP_INVAL_REQUIRED   BIT(2)
> > +#define PXP_EVENT_TYPE_IRQ   BIT(3)
> >   };
> >   
> >   #endif /* __INTEL_PXP_TYPES_H__ */
> > 
> > base-commit: 5429d55de723544dfc0630cf39d96392052b27a1



Re: [PATCH v6] Documentation/gpu: VM_BIND locking document

2023-11-29 Thread John Hubbard

On 11/29/23 01:06, Thomas Hellström wrote:

Add the first version of the VM_BIND locking document which is
intended to be part of the xe driver upstreaming agreement.

The document describes and discuss the locking used during exec-
functions, evicton and for userptr gpu-vmas. Intention is to be using the
same nomenclature as the drm-vm-bind-async.rst.



Hi Thomas,

As requested, for the pin_user_pages() aspects (the MMU notifier
registration case), please feel free to add:

Acked-by: John Hubbard 
v2:
- s/gvm/gpu_vm/g (Rodrigo Vivi)
- Clarify the userptr seqlock with a pointer to mm/mmu_notifier.c
   (Rodrigo Vivi)
- Adjust commit message accordingly.
- Add SPDX license header.

v3:
- Large update to align with the drm_gpuvm manager locking
- Add "Efficient userptr gpu_vma exec function iteration" section
- Add "Locking at bind- and unbind time" section.

v4:
- Fix tabs vs space errors by untabifying (Rodrigo Vivi)
- Minor style fixes and typos (Rodrigo Vivi)
- Clarify situations where stale GPU mappings are occurring and how
   access through these mappings are blocked. (Rodrigo Vivi)
- Insert into the toctree in implementation_guidelines.rst

v5:
- Add a section about recoverable page-faults.
- Use local references to other documentation where possible
   (Bagas Sanjaya)
- General documentation fixes and typos (Danilo Krummrich and
   Boris Brezillon)
- Improve the documentation around locks that need to be grabbed from the
   dm-fence critical section (Boris Brezillon)
- Add more references to the DRM GPUVM helpers (Danilo Krummrich and
   Boriz Brezillon)
- Update the rfc/xe.rst document.

v6:
- Rework wording to improve readability (Boris Brezillon, Rodrigo Vivi,
   Bagas Sanjaya)
- Various minor fixes across the document (Boris Brezillon)

Cc: Rodrigo Vivi 
Signed-off-by: Thomas Hellström 
Reviewed-by: Boris Brezillon 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Danilo Krummrich 
---
  Documentation/core-api/pin_user_pages.rst |   2 +
  Documentation/gpu/drm-mm.rst  |   4 +
  Documentation/gpu/drm-vm-bind-locking.rst | 582 ++
  .../gpu/implementation_guidelines.rst |   1 +
  Documentation/gpu/rfc/xe.rst  |   5 +
  5 files changed, 594 insertions(+)
  create mode 100644 Documentation/gpu/drm-vm-bind-locking.rst

diff --git a/Documentation/core-api/pin_user_pages.rst 
b/Documentation/core-api/pin_user_pages.rst
index d3c1f6d8c0e0..6b5f7e6e7155 100644
--- a/Documentation/core-api/pin_user_pages.rst
+++ b/Documentation/core-api/pin_user_pages.rst
@@ -153,6 +153,8 @@ NOTE: Some pages, such as DAX pages, cannot be pinned with 
longterm pins. That's
  because DAX pages do not have a separate page cache, and so "pinning" implies
  locking down file system blocks, which is not (yet) supported in that way.
  
+.. _mmu-notifier-registration-case:

+
  CASE 3: MMU notifier registration, with or without page faulting hardware
  -
  Device drivers can pin pages via get_user_pages*(), and register for mmu
diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index acc5901ac840..d55751cad67c 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -466,6 +466,8 @@ DRM MM Range Allocator Function References
  .. kernel-doc:: drivers/gpu/drm/drm_mm.c
 :export:
  
+.. _drm_gpuvm:

+
  DRM GPUVM
  =
  
@@ -481,6 +483,8 @@ Split and Merge

  .. kernel-doc:: drivers/gpu/drm/drm_gpuvm.c
 :doc: Split and Merge
  
+.. _drm_gpuvm_locking:

+
  Locking
  ---
  
diff --git a/Documentation/gpu/drm-vm-bind-locking.rst b/Documentation/gpu/drm-vm-bind-locking.rst

new file mode 100644
index ..a345aa513d12
--- /dev/null
+++ b/Documentation/gpu/drm-vm-bind-locking.rst
@@ -0,0 +1,582 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+===
+VM_BIND locking
+===
+
+This document attempts to describe what's needed to get VM_BIND locking right,
+including the userptr mmu_notifier locking. It also discusses some
+optimizations to get rid of the looping through of all userptr mappings and
+external / shared object mappings that is needed in the simplest
+implementation. In addition, there is a section describing the VM_BIND locking
+required for implementing recoverable pagefaults.
+
+The DRM GPUVM set of helpers
+
+
+There is a set of helpers for drivers implementing VM_BIND, and this
+set of helpers implements much, but not all of the locking described
+in this document. In particular, it is currently lacking a userptr
+implementation. This document does not intend to describe the DRM GPUVM
+implementation in detail, but it is covered in :ref:`its own
+documentation `. It is highly recommended for any driver
+implementing VM_BIND to use the DRM GPUVM helpers and to extend it if
+common functionality is missing.
+
+Nomenclature
+
+
+* ``gpu_vm``: Abstraction of a 

Re: [PATCH v6 2/2] drm/i915/guc: Close deregister-context race against CT-loss

2023-11-29 Thread Teres Alexis, Alan Previn
On Mon, 2023-11-27 at 16:51 -0500, Vivi, Rodrigo wrote:

alan: Firstly, thanks for taking the time to review this, knowing you have a 
lot on your plate right now.
> 
alan:snip
> > @@ -3301,19 +3315,38 @@ static inline void guc_lrc_desc_unpin(struct 
> > intel_context *ce)
> > /* Seal race with Reset */
> > spin_lock_irqsave(>guc_state.lock, flags);
> > disabled = submission_disabled(guc);
> > -   if (likely(!disabled)) {
> > -   __intel_gt_pm_get(gt);
> > -   set_context_destroyed(ce);
> > -   clr_context_registered(ce);
> > -   }
> > -   spin_unlock_irqrestore(>guc_state.lock, flags);
> 
> you are now holding this spin lock for too long...
alan: my intention was to ensure that an async H2G request to change this
gucid-context state wouldnt come in while we are in the middle of attempting
to send the context-destruction H2G and later realize it needed to be
unrolled (corner case race we are solving here as discovered on
customer platform). But after discussing with Daniele and John, they
agreed that we should move the unlock back to before the deregister and then
take the lock again inside of the unrolling code (if deregister_context 
fails).
alan:snip
> 
> > -   deregister_context(ce, ce->guc_id.id);
> > +   /* GuC is active, lets destroy this context,
> 
> for multi-line comments you need to start with '/*' only
> and start the real comment below, like:
alan:my bad. will fix.
> *
>  * GuC is active, ...
> > +* but at this point we can still be racing with
> > +* suspend, so we undo everything if the H2G fails
> > +*/
> > +
> > +   /* Change context state to destroyed and get gt-pm */
> > +   __intel_gt_pm_get(gt);
> > +   set_context_destroyed(ce);
> > +   clr_context_registered(ce);
> > +
> > +   ret = deregister_context(ce, ce->guc_id.id);
> > +   if (ret) {
> > +   /* Undo the state change and put gt-pm if that failed */
> > +   set_context_registered(ce);
> > +   clr_context_destroyed(ce);
> > +   /*
> > +* Dont use might_sleep / ASYNC verion of put because
> > +* CT loss in deregister_context could mean an ongoing
> > +* reset or suspend flow. Immediately put before the unlock
> > +*/
> > +   __intel_wakeref_put(>wakeref, 0);
> 
> interesting enough you use the '__' version to bypass the might_sleep(),
> but also sending 0 as argument what might lead you in the mutex_lock inside
> the spin lock area, what is not allowed.
alan: so one thing to note, the motivation for an alternative unlock was only
driven by the fact we were holding that spinlock. However, as per the review
comment and response on the spin lock above, if we move the pm-put
outside the spin lock, we can call the intel_wakeref_put_async (which will not
actually trigger a delayed task becase this function (guc_lrc_desc_unpin) starts
with GEM_BUG_ON(!intel_gt_pm_is_awake(gt)); which means it would only decrement
the ref count.
alan:snip
> > +   spin_lock_irqsave(>submission_state.lock, flags);
> > +   list_add_tail(>destroyed_link,
> > + 
> > >submission_state.destroyed_contexts);
> > +   spin_unlock_irqrestore(>submission_state.lock, 
> > flags);
> > +   /* Bail now since the list might never be emptied if 
> > h2gs fail */
> 
> For this GuC interaction part I'd like to get an ack from John Harrison 
> please.
alan:okay - will do. I might alternatively tap on Daniele since he knows the 
guc just as well.
> 
alan:snip

> > @@ -3392,6 +3440,17 @@ static void destroyed_worker_func(struct work_struct 
> > *w)
> > struct intel_gt *gt = guc_to_gt(guc);
> > int tmp;
> >  
> > +   /*
> > +* In rare cases we can get here via async context-free fence-signals 
> > that
> > +* come very late in suspend flow or very early in resume flows. In 
> > these
> > +* cases, GuC won't be ready but just skipping it here is fine as these
> > +* pending-destroy-contexts get destroyed totally at GuC reset time at 
> > the
> > +* end of suspend.. OR.. this worker can be picked up later on the next
> > +* context destruction trigger after resume-completes
> > +*/
> > +   if (!intel_guc_is_ready(guc))
> > +   return;
> 
> is this racy?
alan: this is to reduce raciness. This worker function eventually calls
deregister_destroyed_context which calls the guc_lrc_desc_unpin that does
all the work we discussed above (taking locks, taking refs, sending h2g,
potentially unrolling). So this check an optimization to skip that without
going through the locking. So yes its a bit racy but its trying to reduce
raciness. NOTE1: Without this line of code, in theory everything would still
work fine, with the driver potentially experiencing more unroll cases
in those thousands of cycles. NOTE2: This check using intel_guc_is_ready
is done in many places in the driver knowing that it doesnt take any locks.
Of 

[PATCH v4 1/1] drm/i915/pxp: Add missing tag for Wa_14019159160

2023-11-29 Thread Alan Previn
Add missing tag for "Wa_14019159160 - Case 2" (for existing
PXP code that ensures run alone mode bit is set to allow
PxP-decryption.

 v4: - Include IP_VER 12.71. (Matt Roper)
 v3: - Check targeted platforms using IP_VAL. (John Harrison)
 v2: - Fix WA id number (John Harrison).
 - Improve comments and code to be specific
   for the targeted platforms (John Harrison)

Signed-off-by: Alan Previn 
---
 drivers/gpu/drm/i915/gt/intel_lrc.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 7c367ba8d9dc..d92e39bbb13d 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -863,10 +863,12 @@ static bool ctx_needs_runalone(const struct intel_context 
*ce)
bool ctx_is_protected = false;
 
/*
-* On MTL and newer platforms, protected contexts require setting
-* the LRC run-alone bit or else the encryption will not happen.
+* Wa_14019159160 - Case 2.
+* On some platforms, protected contexts require setting
+* the LRC run-alone bit or else the encryption/decryption will not 
happen.
+* NOTE: Case 2 only applies to PXP use-case of said workaround.
 */
-   if (GRAPHICS_VER_FULL(ce->engine->i915) >= IP_VER(12, 70) &&
+   if (IS_GFX_GT_IP_RANGE(ce->engine->gt, IP_VER(12, 70), IP_VER(12, 71)) 
&&
(ce->engine->class == COMPUTE_CLASS || ce->engine->class == 
RENDER_CLASS)) {
rcu_read_lock();
gem_ctx = rcu_dereference(ce->gem_context);

base-commit: 436cb0ff9f20fadc99ec3b70c4d2ac6cb2e4410a
-- 
2.39.0



Re: [PATCH 10/10] ACPI: IORT: Allow COMPILE_TEST of IORT

2023-11-29 Thread Jason Gunthorpe
On Wed, Nov 29, 2023 at 01:55:04PM +0100, Lorenzo Pieralisi wrote:

> I don't think it should be done this way. Is the goal compile testing
> IORT code ? 

Yes

> If so, why are we forcing it through the SMMU (only because
> it can be compile tested while eg SMMUv3 driver can't ?) menu entry ?

Because something needs to select it, and SMMU is one of the places
that are implicitly using it.

It isn't (and shouldn't be) a user selectable kconfig. Currently the
only thing that selects it is the ARM64 master kconfig.

> This looks a bit artificial (and it is unclear from the Kconfig
> file why only that driver selects IORT, it looks like eg the SMMUv3
> does not have the same dependency - there is also the SMMUv3 perf
> driver to consider).

SMMUv3 doesn't COMPILE_TEST so it picks up the dependency transitivity
through ARM64. I'm not sure why IORT was put as a global ARM64 kconfig
dependency and not put in the places that directly need it.

"perf driver" ? There is a bunch of GIC stuff that uses this too but I
don't know if it compile tests.

> Maybe we can move IORT code into drivers/acpi and add a silent config
> option there with a dependency on ARM64 || COMPILE_TEST.

That seems pretty weird to me, this is the right way to approach it,
IMHO. Making an entire directory condition is pretty incompatible with
COMPILE_TEST as a philosophy.

> Don't know but at least it is clearer. As for the benefits of compile
> testing IORT code - yes the previous patch is a warning to fix but
> I am not so sure about the actual benefits.

IMHO COMPILE_TEST is an inherently good thing. It makes development
easier for everyone because you have a less fractured code base to
work with.

Jason


Re: [PATCH 06/10] iommu: Replace iommu_device_lock with iommu_probe_device_lock

2023-11-29 Thread Jason Gunthorpe
On Wed, Nov 29, 2023 at 05:58:08PM +, Robin Murphy wrote:
> On 29/11/2023 12:48 am, Jason Gunthorpe wrote:
> > The iommu_device_lock protects the iommu_device_list which is only read by
> > iommu_ops_from_fwnode().
> > 
> > This is now always called under the iommu_probe_device_lock, so we don't
> > need to double lock the linked list. Use the iommu_probe_device_lock on
> > the write side too.
> 
> Please no, iommu_probe_device_lock() is a hack and we need to remove the
> *reason* it exists at all.

Yes, I agree that goal is good

However, it is doing a lot of things, removing it is not so easy.

One thing it is quietly doing is keeping the ops and iommu_device
pointers alive during the entire probe process against(deeply broken,
but whatever) concurrent iommu driver removal.

It is also protecting access to dev->iommu_group during the group
formation process.

So, it is a little more complex. My specific interest was to make it
not a spinlock.

> And IMO just because iommu_present() is
> deprecated doesn't justify making it look utterly nonsensical - in no way
> does that have any relationship with probe_device, much less need to
> serialise against it!

The naming is poor now, I agree, but it is not nonsensical since it
still holds the correct lock for the data it is accessing.

Thanks,
Jason


Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Alex Deucher
On Wed, Nov 29, 2023 at 11:41 AM Luben Tuikov  wrote:
>
> On 2023-11-29 10:22, Alex Deucher wrote:
> > On Wed, Nov 29, 2023 at 8:50 AM Alex Deucher  wrote:
> >>
> >> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  wrote:
> >>>
> >>> On 2023-11-28 17:13, Alex Deucher wrote:
>  On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  wrote:
> >
> > Alex Deucher  writes:
> >
> >>> In that case those are the already known problems with the scheduler
> >>> changes, aren't they?
> >>
> >> Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
> >> misunderstanding what the original report was actually testing.  If it
> >> was 6.7, then try reverting:
> >> 56e449603f0ac580700621a356d35d5716a62ce5
> >> b70438004a14f4d0f9890b3297cd66248728546c
> >
> > At some point it was suggested that I file a gitlab issue, but I took
> > this to mean it was already known and being worked on.  -rc3 came out
> > today and still has the problem.  Is there a known issue I could track?
> >
> 
>  At this point, unless there are any objections, I think we should just
>  revert the two patches
> >>> Uhm, no.
> >>>
> >>> Why "the two" patches?
> >>>
> >>> This email, part of this thread,
> >>>
> >>> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/
> >>>
> >>> clearly states that reverting *only* this commit,
> >>> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable number of 
> >>> run-queues
> >>> *does not* mitigate the failed suspend. (Furthermore, this commit doesn't 
> >>> really change
> >>> anything operational, other than using an allocated array, instead of a 
> >>> static one, in DRM,
> >>> while the 2nd patch is solely contained within the amdgpu driver code.)
> >>>
> >>> Leaving us with only this change,
> >>> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
> >>> to be at fault, as the kernel log attached in the linked email above 
> >>> shows.
> >>>
> >>> The conclusion is that only b70438004a14f4 needs reverting.
> >>
> >> b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
> >> 56e449603f0ac5 breaks amdgpu.
> >
> > We can try and re-enable it in the next kernel.  I'm just not sure
> > we'll be able to fix this in time for 6.7 with the holidays and all
> > and I don't want to cause a lot of scheduler churn at the end of the
> > 6.7 cycle if we hold off and try and fix it.  Reverting seems like the
> > best short term solution.
>
> A lot of subsequent code has come in since commit 56e449603f0ac5, as it opened
> the opportunity for a 1-to-1 relationship between an entity and a scheduler.
> (Should've always been the case, from the outset. Not sure why it was coded as
> a fixed-size array.)
>
> Given that commit 56e449603f0ac5 has nothing to do with amdgpu, and the 
> problem
> is wholly contained in amdgpu, and no other driver has this problem, there is
> no reason to have to "churn", i.e. go back and forth in DRM, only to cover up
> an init bug in amdgpu. See the response I just sent in @this thread:
> https://lore.kernel.org/r/05007cb0-871e-4dc7-af58-1351f4ba4...@gmail.com
>
> And it's not like this issue is unknown. I first posted about it on 
> 2023-10-16.
>
> Ideally, amdgpu would just fix their init code.

You can't make changes to core code that break other drivers.
Arguably 56e449603f0ac5 should not have gone in in the first place if
it broke amdgpu.  b70438004a14f4 was the code to fix amdgpu's init
code, but as a side effect it seems to have broken suspend for some
users.

Alex


Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Alex Deucher
On Wed, Nov 29, 2023 at 11:21 AM Luben Tuikov  wrote:
>
> On 2023-11-29 08:50, Alex Deucher wrote:
> > On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  wrote:
> >>
> >> On 2023-11-28 17:13, Alex Deucher wrote:
> >>> On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  wrote:
> 
>  Alex Deucher  writes:
> 
> >> In that case those are the already known problems with the scheduler
> >> changes, aren't they?
> >
> > Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
> > misunderstanding what the original report was actually testing.  If it
> > was 6.7, then try reverting:
> > 56e449603f0ac580700621a356d35d5716a62ce5
> > b70438004a14f4d0f9890b3297cd66248728546c
> 
>  At some point it was suggested that I file a gitlab issue, but I took
>  this to mean it was already known and being worked on.  -rc3 came out
>  today and still has the problem.  Is there a known issue I could track?
> 
> >>>
> >>> At this point, unless there are any objections, I think we should just
> >>> revert the two patches
> >> Uhm, no.
> >>
> >> Why "the two" patches?
> >>
> >> This email, part of this thread,
> >>
> >> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/
> >>
> >> clearly states that reverting *only* this commit,
> >> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable number of 
> >> run-queues
> >> *does not* mitigate the failed suspend. (Furthermore, this commit doesn't 
> >> really change
> >> anything operational, other than using an allocated array, instead of a 
> >> static one, in DRM,
> >> while the 2nd patch is solely contained within the amdgpu driver code.)
> >>
> >> Leaving us with only this change,
> >> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
> >> to be at fault, as the kernel log attached in the linked email above shows.
> >>
> >> The conclusion is that only b70438004a14f4 needs reverting.
> >
> > b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
> > 56e449603f0ac5 breaks amdgpu.
>
> It doesn't "break" it, amdgpu just needs to be fixed.
>
> I know we put in a Fixes tag in
> b70438004a14f4 "drm/amdgpu: move buffer funcs setting up a level"
> pointing to 56e449603f0ac5 "drm/sched: Convert the GPU scheduler to variable 
> number of run-queues",
> but given the testing Phillip has done, the culprit is wholly contained in
> the amdgpu driver code.
>
> No other driver has this problem since commit 56e449603f0ac5.
>
> The Fixes tag in b70438004a14f4 "drm/amdgpu: move buffer funcs setting up a 
> level" should've ideally
> pointed to an amdgpu-driver code commit only (perhaps an old-old commit), and 
> I was a bit uncomfortable
> putting in a Fixes tag which pointed to drm code, but we did it so that the 
> amdgpu commit follows
> the changes in DRM. In retrospect, the Fixes tag should've pointed to and 
> amdgpu-driver commit when
> that the amdgpu code was originally written.
>
> I remember that the problem was really that amdgpu called 
> drm_sched_entity_init(),
> in amdgpu_ttm_set_buffer_funcs_status() without actually having initialized 
> the scheduler
> used therein. For instance, the code before commit b70438004a14f4, looked 
> like this:
>
> void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool 
> enable)
> {
> struct ttm_resource_manager *man = ttm_manager_type(>mman.bdev, 
> TTM_PL_VRAM);
> uint64_t size;
> int r;
>
> if (!adev->mman.initialized || amdgpu_in_reset(adev) ||
> adev->mman.buffer_funcs_enabled == enable)
> return;
>
> if (enable) {
> struct amdgpu_ring *ring;
> struct drm_gpu_scheduler *sched;
>
> ring = adev->mman.buffer_funcs_ring;
> sched = >sched; <-- LT: No 
> one has initialized this scheduler
> r = drm_sched_entity_init(>mman.entity, <-- Oopses, 
> now that sched->sched_rq is not a static array
>   DRM_SCHED_PRIORITY_KERNEL, ,
>   1, NULL);
> if (r) {
> DRM_ERROR("Failed setting up TTM BO move entity 
> (%d)\n",
>   r);
> return;
> }
>
>
> Before commit 56e449603f0ac5, amdgpu was getting away with this, because the 
> sched->sched_rq
> was a static array.
>
> Ideally, amdgpu code would be fixed.

b70438004a14f4 was the amdgpu fix for this, but it appears to break
suspend for some users.  I'm not confident we can fix it in time for
6.7 final.

Alex


[PATCH v2] drm/msm/dpu: Capture dpu snapshot when frame_done_timer timeouts

2023-11-29 Thread Paloma Arellano
Trigger a devcoredump to dump dpu registers and capture the drm atomic
state when the frame_done_timer timeouts.

Signed-off-by: Paloma Arellano 
---

Changes since v1:
- Optimized the format in which frame_done_timeout_cnt is incremented

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 1cf7ff6caff4e..ae3309ebb8f8a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -191,6 +191,7 @@ struct dpu_encoder_virt {
void *crtc_frame_event_cb_data;
 
atomic_t frame_done_timeout_ms;
+   atomic_t frame_done_timeout_cnt;
struct timer_list frame_done_timer;
 
struct msm_display_info disp_info;
@@ -1204,6 +1205,8 @@ static void dpu_encoder_virt_atomic_enable(struct 
drm_encoder *drm_enc,
 
dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc);
 
+   atomic_set(_enc->frame_done_timeout_cnt, 0);
+
if (disp_info->intf_type == INTF_DP)
dpu_enc->wide_bus_en = 
msm_dp_wide_bus_available(priv->dp[index]);
else if (disp_info->intf_type == INTF_DSI)
@@ -2115,11 +2118,12 @@ static int _dpu_encoder_status_show(struct seq_file *s, 
void *data)
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-   seq_printf(s, "intf:%d  wb:%d  vsync:%8d underrun:%8d",
+   seq_printf(s, "intf:%d  wb:%d  vsync:%8d underrun:%8d
frame_done_cnt:%d",
phys->hw_intf ? phys->hw_intf->idx - INTF_0 : 
-1,
phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1,
atomic_read(>vsync_cnt),
-   atomic_read(>underrun_cnt));
+   atomic_read(>underrun_cnt),
+   atomic_read(_enc->frame_done_timeout_cnt));
 
seq_printf(s, "mode: %s\n", 
dpu_encoder_helper_get_intf_type(phys->intf_mode));
}
@@ -2341,6 +2345,9 @@ static void dpu_encoder_frame_done_timeout(struct 
timer_list *t)
 
DPU_ERROR_ENC(dpu_enc, "frame done timeout\n");
 
+   if (atomic_inc_return(_enc->frame_done_timeout_cnt) == 1)
+   msm_disp_snapshot_state(drm_enc->dev);
+
event = DPU_ENCODER_FRAME_EVENT_ERROR;
trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event);
dpu_enc->crtc_frame_event_cb(dpu_enc->crtc_frame_event_cb_data, event);
@@ -2392,6 +2399,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device 
*dev,
goto fail;
 
atomic_set(_enc->frame_done_timeout_ms, 0);
+   atomic_set(_enc->frame_done_timeout_cnt, 0);
timer_setup(_enc->frame_done_timer,
dpu_encoder_frame_done_timeout, 0);
 
-- 
2.39.2



[RFC] drm: enable W=1 warnings by default across the subsystem

2023-11-29 Thread Jani Nikula
At least the i915 and amd drivers enable a bunch more compiler warnings
than the kernel defaults.

Extend the W=1 warnings to the entire drm subsystem by default. Use the
copy-pasted warnings from scripts/Makefile.extrawarn with
s/KBUILD_CFLAGS/subdir-ccflags-y/ to make it easier to compare and keep
up with them in the future.

This is similar to the approach currently used in i915.

Some of the -Wextra warnings do need to be disabled, just like in
Makefile.extrawarn, but take care to not disable them for W=2 or W=3
builds, depending on the warning.

Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
Cc: Alex Deucher 
Cc: Christian König 
Cc: Pan, Xinhui 
Cc: Karol Herbst 
Cc: Lyude Paul 
Cc: Danilo Krummrich 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
Cc: Marijn Suijten 
Signed-off-by: Jani Nikula 

---

With my admittedly limited and very much x86 focused kernel config, I
get some -Wunused-but-set-variable and -Wformat-truncation= warnings,
but nothing we can't handle.

We could fix them up front, or disable the extra warnings on a per
driver basis with a FIXME comment in their respective Makefiles.

With the experience from i915, I think this would significantly reduce
the constant loop of warnings added by people not using W=1 and
subsequently fixed by people using W=1.

Note: I've Cc'd the maintainers of drm, drm misc and some of the biggest
drivers.
---
 drivers/gpu/drm/Makefile | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index b4cb0835620a..6939e4ea13d5 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -5,6 +5,33 @@
 
 CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
 
+# Unconditionally enable W=1 warnings locally
+# --- begin copy-paste W=1 warnings from scripts/Makefile.extrawarn
+subdir-ccflags-y += -Wextra -Wunused -Wno-unused-parameter
+subdir-ccflags-y += -Wmissing-declarations
+subdir-ccflags-y += $(call cc-option, -Wrestrict)
+subdir-ccflags-y += -Wmissing-format-attribute
+subdir-ccflags-y += -Wmissing-prototypes
+subdir-ccflags-y += -Wold-style-definition
+subdir-ccflags-y += -Wmissing-include-dirs
+subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable)
+subdir-ccflags-y += $(call cc-option, -Wunused-const-variable)
+subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned)
+subdir-ccflags-y += $(call cc-option, -Wformat-overflow)
+subdir-ccflags-y += $(call cc-option, -Wformat-truncation)
+subdir-ccflags-y += $(call cc-option, -Wstringop-overflow)
+subdir-ccflags-y += $(call cc-option, -Wstringop-truncation)
+# The following turn off the warnings enabled by -Wextra
+ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),)
+subdir-ccflags-y += -Wno-missing-field-initializers
+subdir-ccflags-y += -Wno-type-limits
+subdir-ccflags-y += -Wno-shift-negative-value
+endif
+ifeq ($(findstring 3, $(KBUILD_EXTRA_WARN)),)
+subdir-ccflags-y += -Wno-sign-compare
+endif
+# --- end copy-paste
+
 drm-y := \
drm_aperture.o \
drm_atomic.o \
-- 
2.39.2



Re: [PATCH 06/10] iommu: Replace iommu_device_lock with iommu_probe_device_lock

2023-11-29 Thread Robin Murphy

On 29/11/2023 12:48 am, Jason Gunthorpe wrote:

The iommu_device_lock protects the iommu_device_list which is only read by
iommu_ops_from_fwnode().

This is now always called under the iommu_probe_device_lock, so we don't
need to double lock the linked list. Use the iommu_probe_device_lock on
the write side too.


Please no, iommu_probe_device_lock() is a hack and we need to remove the 
*reason* it exists at all. And IMO just because iommu_present() is 
deprecated doesn't justify making it look utterly nonsensical - in no 
way does that have any relationship with probe_device, much less need to 
serialise against it!


Thanks,
Robin.


Signed-off-by: Jason Gunthorpe 
---
  drivers/iommu/iommu.c | 30 +-
  1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 08f29a1dfcd5f8..9557c2ec08d915 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -146,7 +146,6 @@ struct iommu_group_attribute iommu_group_attr_##_name = 
\
container_of(_kobj, struct iommu_group, kobj)
  
  static LIST_HEAD(iommu_device_list);

-static DEFINE_SPINLOCK(iommu_device_lock);
  
  static const struct bus_type * const iommu_buses[] = {

_bus_type,
@@ -262,9 +261,9 @@ int iommu_device_register(struct iommu_device *iommu,
if (hwdev)
iommu->fwnode = dev_fwnode(hwdev);
  
-	spin_lock(_device_lock);

+   mutex_lock(_probe_device_lock);
list_add_tail(>list, _device_list);
-   spin_unlock(_device_lock);
+   mutex_unlock(_probe_device_lock);
  
  	for (int i = 0; i < ARRAY_SIZE(iommu_buses) && !err; i++)

err = bus_iommu_probe(iommu_buses[i]);
@@ -279,9 +278,9 @@ void iommu_device_unregister(struct iommu_device *iommu)
for (int i = 0; i < ARRAY_SIZE(iommu_buses); i++)
bus_for_each_dev(iommu_buses[i], NULL, iommu, 
remove_iommu_group);
  
-	spin_lock(_device_lock);

+   mutex_lock(_probe_device_lock);
list_del(>list);
-   spin_unlock(_device_lock);
+   mutex_unlock(_probe_device_lock);
  
  	/* Pairs with the alloc in generic_single_device_group() */

iommu_group_put(iommu->singleton_group);
@@ -316,9 +315,9 @@ int iommu_device_register_bus(struct iommu_device *iommu,
if (err)
return err;
  
-	spin_lock(_device_lock);

+   mutex_lock(_probe_device_lock);
list_add_tail(>list, _device_list);
-   spin_unlock(_device_lock);
+   mutex_unlock(_probe_device_lock);
  
  	err = bus_iommu_probe(bus);

if (err) {
@@ -2033,9 +2032,9 @@ bool iommu_present(const struct bus_type *bus)
  
  	for (int i = 0; i < ARRAY_SIZE(iommu_buses); i++) {

if (iommu_buses[i] == bus) {
-   spin_lock(_device_lock);
+   mutex_lock(_probe_device_lock);
ret = !list_empty(_device_list);
-   spin_unlock(_device_lock);
+   mutex_unlock(_probe_device_lock);
}
}
return ret;
@@ -2980,17 +2979,14 @@ EXPORT_SYMBOL_GPL(iommu_default_passthrough);
  
  const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)

  {
-   const struct iommu_ops *ops = NULL;
struct iommu_device *iommu;
  
-	spin_lock(_device_lock);

+   lockdep_assert_held(_probe_device_lock);
+
list_for_each_entry(iommu, _device_list, list)
-   if (iommu->fwnode == fwnode) {
-   ops = iommu->ops;
-   break;
-   }
-   spin_unlock(_device_lock);
-   return ops;
+   if (iommu->fwnode == fwnode)
+   return iommu->ops;
+   return NULL;
  }
  
  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,


Re: [Intel-gfx] [PATCH v3 1/1] drm/i915/pxp: Add missing tag for Wa_14019159160

2023-11-29 Thread Teres Alexis, Alan Previn
On Tue, 2023-11-28 at 10:03 -0800, Roper, Matthew D wrote:
> On Mon, Nov 27, 2023 at 12:11:50PM -0800, Alan Previn wrote:
> > Add missing tag for "Wa_14019159160 - Case 2" (for existing
> > PXP code that ensures run alone mode bit is set to allow
> > PxP-decryption.
alan:snip.
alan: thanks for reviewing.
> > -   if (GRAPHICS_VER_FULL(ce->engine->i915) >= IP_VER(12, 70) &&
> > +   if (GRAPHICS_VER_FULL(ce->engine->i915) == IP_VER(12, 70) &&
> 
> The workaround database lists this as being needed on both 12.70 and
> 12.71.  Should this be a
> 
> IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))
alan: sure - will do this.
> 
> check instead?
> 
> The workaround is also listed in the database as applying to DG2; is
> this "case 2" subset of the workaround not relevant to that platform?
alan: i dont believe so - not the pxp case 2.



[PATCH v8 4/7] drm/msm/dp: move parser->parse() and dp_power_client_init() to probe

2023-11-29 Thread Kuogee Hsieh
Original both parser->parse() and dp_power_client_init() are done at
dp_display_bind() since eDP population is done at binding time.
In the preparation of having eDP population done at probe() time,
move both function from dp_display_bind() to dp_display_probe().

Changes in v6:
-- move dp_power_client_deinit() to remove()

Changes in v5:
-- explain why parser->parse() and dp_power_client_init() are moved to
   probe time
-- tear down sub modules if failed

Changes in v4:
-- split this patch out of "incorporate pm_runtime framework into DP
   driver" patch

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index c2e3247..a99a786 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -275,11 +275,6 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
dp->dp_display.drm_dev = drm;
priv->dp[dp->id] = >dp_display;
 
-   rc = dp->parser->parse(dp->parser);
-   if (rc) {
-   DRM_ERROR("device tree parsing failed\n");
-   goto end;
-   }
 
 
dp->drm_dev = drm;
@@ -290,11 +285,6 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
goto end;
}
 
-   rc = dp_power_client_init(dp->power);
-   if (rc) {
-   DRM_ERROR("Power client create failed\n");
-   goto end;
-   }
 
rc = dp_register_audio_driver(dev, dp->audio);
if (rc) {
@@ -327,7 +317,6 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
 
of_dp_aux_depopulate_bus(dp->aux);
 
-   dp_power_client_deinit(dp->power);
dp_unregister_audio_driver(dev, dp->audio);
dp_aux_unregister(dp->aux);
dp->drm_dev = NULL;
@@ -1241,6 +1230,18 @@ static int dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
+   rc = dp->parser->parse(dp->parser);
+   if (rc) {
+   DRM_ERROR("device tree parsing failed\n");
+   goto err;
+   }
+
+   rc = dp_power_client_init(dp->power);
+   if (rc) {
+   DRM_ERROR("Power client create failed\n");
+   goto err;
+   }
+
/* setup event q */
mutex_init(>event_mutex);
init_waitqueue_head(>event_q);
@@ -1275,6 +1276,7 @@ static void dp_display_remove(struct platform_device 
*pdev)
struct dp_display_private *dp = dev_get_dp_display_private(>dev);
 
component_del(>dev, _display_comp_ops);
+   dp_power_client_deinit(dp->power);
dp_display_deinit_sub_modules(dp);
 
platform_set_drvdata(pdev, NULL);
-- 
2.7.4



[PATCH v8 6/7] drm/msm/dp: delete EV_HPD_INIT_SETUP

2023-11-29 Thread Kuogee Hsieh
EV_HPD_INIT_SETUP flag is used to trigger the initialization of external
DP host controller. Since external DP host controller initialization had
been incorporated into pm_runtime_resume(), this flag became obsolete.
msm_dp_irq_postinstall() which triggers EV_HPD_INIT_SETUP event is
obsoleted accordingly.

Changes in v4:
-- reworded commit text
-- drop EV_HPD_INIT_SETUP
-- drop msm_dp_irq_postinstall()

Changes in v3:
-- drop EV_HPD_INIT_SETUP and msm_dp_irq_postinstall()

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  4 
 drivers/gpu/drm/msm/dp/dp_display.c | 16 
 drivers/gpu/drm/msm/msm_drv.h   |  5 -
 3 files changed, 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index fe7267b..5d5a045 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -856,7 +856,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms)
 {
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
-   int i;
 
if (!dpu_kms || !dpu_kms->dev)
return -EINVAL;
@@ -865,9 +864,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms)
if (!priv)
return -EINVAL;
 
-   for (i = 0; i < ARRAY_SIZE(priv->dp); i++)
-   msm_dp_irq_postinstall(priv->dp[i]);
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 9520d83..6693582 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -54,7 +54,6 @@ enum {
 enum {
EV_NO_EVENT,
/* hpd events */
-   EV_HPD_INIT_SETUP,
EV_HPD_PLUG_INT,
EV_IRQ_HPD_INT,
EV_HPD_UNPLUG_INT,
@@ -1079,8 +1078,6 @@ static int hpd_event_thread(void *data)
spin_unlock_irqrestore(_priv->event_lock, flag);
 
switch (todo->event_id) {
-   case EV_HPD_INIT_SETUP:
-   break;
case EV_HPD_PLUG_INT:
dp_hpd_plug_handle(dp_priv, todo->data);
break;
@@ -1360,19 +1357,6 @@ void __exit msm_dp_unregister(void)
platform_driver_unregister(_display_driver);
 }
 
-void msm_dp_irq_postinstall(struct msm_dp *dp_display)
-{
-   struct dp_display_private *dp;
-
-   if (!dp_display)
-   return;
-
-   dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-   if (!dp_display->is_edp)
-   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
-}
-
 bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
 {
struct dp_display_private *dp;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index cd5bf65..e79b93b 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -386,7 +386,6 @@ int __init msm_dp_register(void);
 void __exit msm_dp_unregister(void);
 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 struct drm_encoder *encoder);
-void msm_dp_irq_postinstall(struct msm_dp *dp_display);
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp 
*dp_display);
 
 void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor);
@@ -407,10 +406,6 @@ static inline int msm_dp_modeset_init(struct msm_dp 
*dp_display,
return -EINVAL;
 }
 
-static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
-{
-}
-
 static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct 
msm_dp *dp_display)
 {
 }
-- 
2.7.4



[PATCH v8 7/7] drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe()

2023-11-29 Thread Kuogee Hsieh
Currently eDP population is done at msm_dp_modeset_init() which happen
at binding time. Move eDP population to be done at display probe time
so that probe deferral cases can be handled effectively.
wait_for_hpd_asserted callback is added during drm_dp_aux_init()
to ensure eDP's HPD is up before proceeding eDP population.

Changes in v5:
-- inline dp_display_auxbus_population() and delete it

Changes in v4:
-- delete duplicate initialize code to dp_aux before drm_dp_aux_register()
-- delete of_get_child_by_name(dev->of_node, "aux-bus") and inline the
   function
-- not initialize rc = 0

Changes in v3:
-- add done_probing callback into devm_of_dp_aux_populate_bus()

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_aux.c | 34 -
 drivers/gpu/drm/msm/dp/dp_display.c | 59 +++--
 2 files changed, 51 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 10b6eeb..03f4951 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -479,7 +479,6 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux)
 
 int dp_aux_register(struct drm_dp_aux *dp_aux)
 {
-   struct dp_aux_private *aux;
int ret;
 
if (!dp_aux) {
@@ -487,12 +486,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux)
return -EINVAL;
}
 
-   aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
-
-   aux->dp_aux.name = "dpu_dp_aux";
-   aux->dp_aux.dev = aux->dev;
-   aux->dp_aux.transfer = dp_aux_transfer;
-   ret = drm_dp_aux_register(>dp_aux);
+   ret = drm_dp_aux_register(dp_aux);
if (ret) {
DRM_ERROR("%s: failed to register drm aux: %d\n", __func__,
ret);
@@ -507,6 +501,21 @@ void dp_aux_unregister(struct drm_dp_aux *dp_aux)
drm_dp_aux_unregister(dp_aux);
 }
 
+static int dp_wait_hpd_asserted(struct drm_dp_aux *dp_aux,
+unsigned long wait_us)
+{
+   int ret;
+   struct dp_aux_private *aux;
+
+   aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+
+   pm_runtime_get_sync(aux->dev);
+   ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog);
+   pm_runtime_put_sync(aux->dev);
+
+   return ret;
+}
+
 struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog,
  bool is_edp)
 {
@@ -530,6 +539,17 @@ struct drm_dp_aux *dp_aux_get(struct device *dev, struct 
dp_catalog *catalog,
aux->catalog = catalog;
aux->retry_cnt = 0;
 
+   /*
+* Use the drm_dp_aux_init() to use the aux adapter
+* before registering AUX with the DRM device so that
+* msm eDP panel can be detected by generic_dep_panel_probe().
+*/
+   aux->dp_aux.name = "dpu_dp_aux";
+   aux->dp_aux.dev = dev;
+   aux->dp_aux.transfer = dp_aux_transfer;
+   aux->dp_aux.wait_hpd_asserted = dp_wait_hpd_asserted;
+   drm_dp_aux_init(>dp_aux);
+
return >dp_aux;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 6693582..cfbc610 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1199,6 +1199,17 @@ static const struct msm_dp_desc 
*dp_display_get_desc(struct platform_device *pde
return NULL;
 }
 
+static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
+{
+   int rc;
+
+   rc = component_add(aux->dev, _display_comp_ops);
+   if (rc)
+   DRM_ERROR("eDP component add failed, rc=%d\n", rc);
+
+   return rc;
+}
+
 static int dp_display_probe(struct platform_device *pdev)
 {
int rc = 0;
@@ -1264,10 +1275,18 @@ static int dp_display_probe(struct platform_device 
*pdev)
if (rc)
goto err;
 
-   rc = component_add(>dev, _display_comp_ops);
-   if (rc) {
-   DRM_ERROR("component add failed, rc=%d\n", rc);
-   goto err;
+   if (dp->dp_display.is_edp) {
+   rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe);
+   if (rc) {
+   DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc);
+   goto err;
+   }
+   } else {
+   rc = component_add(>dev, _display_comp_ops);
+   if (rc) {
+   DRM_ERROR("component add failed, rc=%d\n", rc);
+   goto err;
+   }
}
 
return rc;
@@ -1283,7 +1302,6 @@ static void dp_display_remove(struct platform_device 
*pdev)
 
component_del(>dev, _display_comp_ops);
dp_display_deinit_sub_modules(dp);
-
platform_set_drvdata(pdev, NULL);
 }
 
@@ -1389,29 +1407,8 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
 {
int rc;
struct dp_display_private *dp_priv;
-   struct 

[PATCH v8 1/7] drm/msm/dp: tie dp_display_irq_handler() with dp driver

2023-11-29 Thread Kuogee Hsieh
Currently the dp_display_request_irq() is executed at
msm_dp_modeset_init() which ties irq registering to the DPU device's
life cycle, while depending on resources that are released as the DP
device is torn down. Move register DP driver irq handler to
dp_display_probe() to have dp_display_irq_handler() IRQ tied with DP
device. In addition, use platform_get_irq() to retrieve irq number
from platform device directly.

Changes in v5:
-- reworded commit text as review comments at change #4
-- tear down component if failed at dp_display_request_irq()

Changes in v4:
-- delete dp->irq check at dp_display_request_irq()

Changes in v3:
-- move calling dp_display_irq_handler() to probe

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 32 +---
 drivers/gpu/drm/msm/dp/dp_display.h |  1 -
 2 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index e329e03..2110862 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1184,26 +1184,18 @@ static irqreturn_t dp_display_irq_handler(int irq, void 
*dev_id)
return ret;
 }
 
-int dp_display_request_irq(struct msm_dp *dp_display)
+static int dp_display_request_irq(struct dp_display_private *dp)
 {
int rc = 0;
-   struct dp_display_private *dp;
-
-   if (!dp_display) {
-   DRM_ERROR("invalid input\n");
-   return -EINVAL;
-   }
-
-   dp = container_of(dp_display, struct dp_display_private, dp_display);
+   struct platform_device *pdev = dp->dp_display.pdev;
 
-   dp->irq = irq_of_parse_and_map(dp->dp_display.pdev->dev.of_node, 0);
+   dp->irq = platform_get_irq(pdev, 0);
if (!dp->irq) {
DRM_ERROR("failed to get irq\n");
return -EINVAL;
}
 
-   rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
-   dp_display_irq_handler,
+   rc = devm_request_irq(>dev, dp->irq, dp_display_irq_handler,
IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
if (rc < 0) {
DRM_ERROR("failed to request IRQ%u: %d\n",
@@ -1278,13 +1270,21 @@ static int dp_display_probe(struct platform_device 
*pdev)
 
platform_set_drvdata(pdev, >dp_display);
 
+   rc = dp_display_request_irq(dp);
+   if (rc)
+   goto err;
+
rc = component_add(>dev, _display_comp_ops);
if (rc) {
DRM_ERROR("component add failed, rc=%d\n", rc);
-   dp_display_deinit_sub_modules(dp);
+   goto err;
}
 
return rc;
+
+err:
+   dp_display_deinit_sub_modules(dp);
+   return rc;
 }
 
 static void dp_display_remove(struct platform_device *pdev)
@@ -1537,12 +1537,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, 
struct drm_device *dev,
 
dp_priv = container_of(dp_display, struct dp_display_private, 
dp_display);
 
-   ret = dp_display_request_irq(dp_display);
-   if (ret) {
-   DRM_ERROR("request_irq failed, ret=%d\n", ret);
-   return ret;
-   }
-
ret = dp_display_get_next_bridge(dp_display);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
b/drivers/gpu/drm/msm/dp/dp_display.h
index f66cdbc..15dbd2f 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -36,7 +36,6 @@ struct msm_dp {
 int dp_display_set_plugged_cb(struct msm_dp *dp_display,
hdmi_codec_plugged_cb fn, struct device *codec_dev);
 int dp_display_get_modes(struct msm_dp *dp_display);
-int dp_display_request_irq(struct msm_dp *dp_display);
 bool dp_display_check_video_test(struct msm_dp *dp_display);
 int dp_display_get_test_bpp(struct msm_dp *dp_display);
 void dp_display_signal_audio_start(struct msm_dp *dp_display);
-- 
2.7.4



[PATCH v8 5/7] drm/msm/dp: incorporate pm_runtime framework into DP driver

2023-11-29 Thread Kuogee Hsieh
Currently DP driver is executed independent of PM runtime framework.
This leads msm eDP panel can not being detected by edp_panel driver
during generic_edp_panel_probe() due to AUX DPCD read failed at
edp panel driver. Incorporate PM runtime framework into DP driver so
that host controller's power and clocks are enable/disable through
PM runtime mechanism.  Once PM runtime framework is incorporated into
DP driver, waking up device from power up path is not necessary. Hence
remove it.

After incorporating pm_runtime framework into eDP/DP driver,
dp_pm_suspend() to handle power off both DP phy and controller during
suspend and dp_pm_resume() to handle power on both DP phy and controller
during resume are not necessary. Therefore both dp_pm_suspend() and
dp_pm_resume() are dropped and replace with dp_pm_runtime_suspend() and
dp_pm_runtime_resume() respectively.

Changes in v7:
-- add comments to dp_pm_runtime_resume()
-- add comments to dp_bridge_hpd_enable()
-- delete dp->hpd_state = ST_DISCONNECTED from dp_bridge_hpd_notify()

Changes in v6:
-- delete dp_power_client_deinit(dp->power);
-- remove if (!dp->dp_display.is_edp) condition checkout at plug_handle()
-- remove if (!dp->dp_display.is_edp) condition checkout at unplug_handle()
-- add IRQF_NO_AUTOEN to devm_request_irq()
-- add enable_irq() and disable_irq() to pm_runtime_resume()/suspend()
-- del dp->hpd_state = ST_DISCONNECTED from dp_bridge_hpd_disable()

Changes in v5:
-- remove pm_runtime_put_autosuspend feature, use pm_runtime_put_sync()
-- squash add pm_runtime_force_suspend()/resume() patch into this patch

Changes in v4:
-- reworded commit text to explain why pm_framework is required for
   edp panel
-- reworded commit text to explain autosuspend is choiced
-- delete EV_POWER_PM_GET and PM_EV_POWER_PUT from changes #3
-- delete dp_display_pm_get() and dp_display_pm_Put() from changes #3
-- return value from pm_runtime_resume_and_get() directly
-- check return value of devm_pm_runtime_enable()
-- delete pm_runtime_xxx from dp_display_remove()
-- drop dp_display_host_init() from EV_HPD_INIT_SETUP
-- drop both dp_pm_prepare() and dp_pm_compete() from this change
-- delete ST_SUSPENDED state
-- rewording commit text to add more details regrading the purpose
   of this change

Changes in v3:
-- incorporate removing pm_runtime_xx() from dp_pwer.c to this patch
-- use pm_runtime_resume_and_get() instead of pm_runtime_get()
-- error checking pm_runtime_resume_and_get() return value
-- add EV_POWER_PM_GET and PM_EV_POWER_PUT to handle HPD_GPIO case
-- replace dp_pm_suspend() with pm_runtime_force_suspend()
-- replace dp_pm_resume() with pm_runtime_force_resume()

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_aux.c |   5 +
 drivers/gpu/drm/msm/dp/dp_display.c | 181 ++--
 drivers/gpu/drm/msm/dp/dp_power.c   |  16 
 drivers/gpu/drm/msm/dp/dp_power.h   |  11 ---
 4 files changed, 75 insertions(+), 138 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 8e3b677..10b6eeb 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -291,6 +291,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
return -EINVAL;
}
 
+   ret = pm_runtime_resume_and_get(dp_aux->dev);
+   if (ret)
+   return  ret;
+
mutex_lock(>mutex);
if (!aux->initted) {
ret = -EIO;
@@ -364,6 +368,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
 
 exit:
mutex_unlock(>mutex);
+   pm_runtime_put_sync(dp_aux->dev);
 
return ret;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index a99a786..9520d83 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -49,7 +49,6 @@ enum {
ST_CONNECTED,
ST_DISCONNECT_PENDING,
ST_DISPLAY_OFF,
-   ST_SUSPENDED,
 };
 
 enum {
@@ -309,10 +308,6 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
struct dp_display_private *dp = dev_get_dp_display_private(dev);
struct msm_drm_private *priv = dev_get_drvdata(master);
 
-   /* disable all HPD interrupts */
-   if (dp->core_initialized)
-   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, 
false);
-
kthread_stop(dp->ev_tsk);
 
of_dp_aux_depopulate_bus(dp->aux);
@@ -542,6 +537,7 @@ static int dp_hpd_plug_handle(struct dp_display_private 
*dp, u32 data)
 {
u32 state;
int ret;
+   struct platform_device *pdev = dp->dp_display.pdev;
 
mutex_lock(>event_mutex);
 
@@ -549,7 +545,7 @@ static int dp_hpd_plug_handle(struct dp_display_private 
*dp, u32 data)
drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
dp->dp_display.connector_type, state);
 
-   if (state == ST_DISPLAY_OFF || state == 

[PATCH v8 3/7] drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes

2023-11-29 Thread Kuogee Hsieh
Currently DP driver use drm_helper_hpd_irq_event(), bypassing drm bridge
framework, to report HPD status changes to user space frame work.
Replace it with drm_bridge_hpd_notify() since DP driver is part of drm
bridge.

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 20 ++--
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 56f8d91..c2e3247 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -340,26 +340,10 @@ static const struct component_ops dp_display_comp_ops = {
.unbind = dp_display_unbind,
 };
 
-static void dp_display_send_hpd_event(struct msm_dp *dp_display)
-{
-   struct dp_display_private *dp;
-   struct drm_connector *connector;
-
-   dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-   connector = dp->dp_display.connector;
-   drm_helper_hpd_irq_event(connector->dev);
-}
-
 static int dp_display_send_hpd_notification(struct dp_display_private *dp,
bool hpd)
 {
-   if ((hpd && dp->dp_display.link_ready) ||
-   (!hpd && !dp->dp_display.link_ready)) {
-   drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
-   (hpd ? "on" : "off"));
-   return 0;
-   }
+   struct drm_bridge *bridge = dp->dp_display.bridge;
 
/* reset video pattern flag on disconnect */
if (!hpd) {
@@ -373,7 +357,7 @@ static int dp_display_send_hpd_notification(struct 
dp_display_private *dp,
 
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
dp->dp_display.connector_type, hpd);
-   dp_display_send_hpd_event(>dp_display);
+   drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready);
 
return 0;
 }
-- 
2.7.4



[PATCH v8 0/7] incorporate pm runtime framework and eDP clean up

2023-11-29 Thread Kuogee Hsieh
The purpose of this patch series is to incorporate pm runtime framework
into MSM eDP/DP driver so that eDP panel can be detected by DRM eDP panel
driver during system probe time. During incorporating procedure, original
customized pm realted fucntions, such as dp_pm_prepare(), dp_pm_suspend(),
dp_pm_resume() and dp_pm_prepare(), are removed and replaced with functions
provided by pm runtiem framework such as pm_runtime_force_suspend() and
pm_runtime_force_resume(). In addition, both eDP aux-bus and irq handler
are bound at system probe time too.

Please be noted that v8 patches is rebase on top of latest msm-next branch

Kuogee Hsieh (7):
  drm/msm/dp: tie dp_display_irq_handler() with dp driver
  drm/msm/dp: rename is_connected with link_ready
  drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes
  drm/msm/dp: move parser->parse() and dp_power_client_init() to probe
  drm/msm/dp: incorporate pm_runtime framework into DP driver
  drm/msm/dp: delete EV_HPD_INIT_SETUP
  drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe()

 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |   4 -
 drivers/gpu/drm/msm/dp/dp_aux.c |  39 +++-
 drivers/gpu/drm/msm/dp/dp_display.c | 337 
 drivers/gpu/drm/msm/dp/dp_display.h |   3 +-
 drivers/gpu/drm/msm/dp/dp_drm.c |  14 +-
 drivers/gpu/drm/msm/dp/dp_power.c   |  16 --
 drivers/gpu/drm/msm/dp/dp_power.h   |  11 --
 drivers/gpu/drm/msm/msm_drv.h   |   5 -
 8 files changed, 164 insertions(+), 265 deletions(-)

-- 
2.7.4



[PATCH v8 2/7] drm/msm/dp: rename is_connected with link_ready

2023-11-29 Thread Kuogee Hsieh
The is_connected flag is set to true after DP mainlink successfully
finishes link training to enter into ST_MAINLINK_READY state rather
than being set after the DP dongle is connected. Rename the
is_connected flag with link_ready flag to match the state of DP
driver's state machine.

Changes in v5:
-- reworded commit text according to review comments from change #4

Changes in v4:
-- reworded commit text

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 19 +--
 drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
 drivers/gpu/drm/msm/dp/dp_drm.c | 14 +++---
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 2110862..56f8d91 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -351,12 +351,11 @@ static void dp_display_send_hpd_event(struct msm_dp 
*dp_display)
drm_helper_hpd_irq_event(connector->dev);
 }
 
-
 static int dp_display_send_hpd_notification(struct dp_display_private *dp,
bool hpd)
 {
-   if ((hpd && dp->dp_display.is_connected) ||
-   (!hpd && !dp->dp_display.is_connected)) {
+   if ((hpd && dp->dp_display.link_ready) ||
+   (!hpd && !dp->dp_display.link_ready)) {
drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
(hpd ? "on" : "off"));
return 0;
@@ -370,7 +369,7 @@ static int dp_display_send_hpd_notification(struct 
dp_display_private *dp,
 dp->panel->dpcd, 
dp->panel->downstream_ports);
}
 
-   dp->dp_display.is_connected = hpd;
+   dp->dp_display.link_ready = hpd;
 
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
dp->dp_display.connector_type, hpd);
@@ -913,7 +912,7 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display,
 
dp_display->plugged_cb = fn;
dp_display->codec_dev = codec_dev;
-   plugged = dp_display->is_connected;
+   plugged = dp_display->link_ready;
dp_display_handle_plugged_change(dp_display, plugged);
 
return 0;
@@ -1344,16 +1343,16 @@ static int dp_pm_resume(struct device *dev)
 * also only signal audio when disconnected
 */
if (dp->link->sink_count) {
-   dp->dp_display.is_connected = true;
+   dp->dp_display.link_ready = true;
} else {
-   dp->dp_display.is_connected = false;
+   dp->dp_display.link_ready = false;
dp_display_handle_plugged_change(dp_display, false);
}
 
drm_dbg_dp(dp->drm_dev,
"After, type=%d sink=%d conn=%d core_init=%d phy_init=%d 
power=%d\n",
dp->dp_display.connector_type, dp->link->sink_count,
-   dp->dp_display.is_connected, dp->core_initialized,
+   dp->dp_display.link_ready, dp->core_initialized,
dp->phy_initialized, dp_display->power_on);
 
mutex_unlock(>event_mutex);
@@ -1741,8 +1740,8 @@ void dp_bridge_hpd_notify(struct drm_bridge *bridge,
return;
}
 
-   if (!dp_display->is_connected && status == connector_status_connected)
+   if (!dp_display->link_ready && status == connector_status_connected)
dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
-   else if (dp_display->is_connected && status == 
connector_status_disconnected)
+   else if (dp_display->link_ready && status == 
connector_status_disconnected)
dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
b/drivers/gpu/drm/msm/dp/dp_display.h
index 15dbd2f..46780af 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -17,7 +17,7 @@ struct msm_dp {
struct drm_bridge *bridge;
struct drm_connector *connector;
struct drm_bridge *next_bridge;
-   bool is_connected;
+   bool link_ready;
bool audio_enabled;
bool power_on;
unsigned int connector_type;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 40e7344..f18cb6f 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -24,10 +24,10 @@ static enum drm_connector_status dp_bridge_detect(struct 
drm_bridge *bridge)
 
dp = to_dp_bridge(bridge)->dp_display;
 
-   drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
-   (dp->is_connected) ? "true" : "false");
+   drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
+   (dp->link_ready) ? "true" : "false");
 
-   return (dp->is_connected) ? connector_status_connected :
+   return (dp->link_ready) ? connector_status_connected :
connector_status_disconnected;
 }
 
@@ -40,8 +40,8 @@ static 

Re: 回复: [PATCH v2] drm/i915: correct the input parameter on _intel_dsb_commit()

2023-11-29 Thread Jani Nikula
On Wed, 29 Nov 2023, 何敏红  wrote:
> Friendly ping. I think this patch was forgotten.

Pushed, thanks for the patch.

>
> 
>
> 主 题:[PATCH v2] drm/i915: correct the input parameter on _intel_dsb_commit() 
> 日 期:2023-11-14 10:43 
> 发件人:何敏红 
> 收件人:何敏红;
>
> Current, the dewake_scanline variable is defined as unsigned int,
> an unsigned int variable that is always greater than or equal to 0.
> when _intel_dsb_commit function is called by intel_dsb_commit function,
> the dewake_scanline variable may have an int value.
> So the dewake_scanline variable is necessary to defined as an int.
>
> Fixes: f83b94d23770 ("drm/i915/dsb: Use DEwake to combat PkgC latency")
> Reported-by: kernel test robot 
> Closes: 
> https://lore.kernel.org/oe-kbuild-all/202310052201.anvbpgpr-...@intel.com/
> Cc: Ville Syrjälä 
> Cc: Uma Shankar 
>
> Signed-off-by: heminhong 
> ---
> drivers/gpu/drm/i915/display/intel_dsb.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c 
> b/drivers/gpu/drm/i915/display/intel_dsb.c
> index 78b6fe24dcd8..7fd6280c54a7 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.c
> @@ -340,7 +340,7 @@ static int intel_dsb_dewake_scanline(const struct 
> intel_crtc_state *crtc_state)
> }
>
> static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
> - unsigned int dewake_scanline)
> + int dewake_scanline)
> {
> struct intel_crtc *crtc = dsb->crtc;
> struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);

-- 
Jani Nikula, Intel


Re: [PATCH] drm/msm/dpu: Capture dpu snapshot when frame_done_timer timeouts

2023-11-29 Thread Paloma Arellano



On 11/28/2023 12:24 PM, Dmitry Baryshkov wrote:

On Tue, 28 Nov 2023 at 19:43, Paloma Arellano  wrote:


On 11/27/2023 5:48 PM, Dmitry Baryshkov wrote:

On Tue, 28 Nov 2023 at 03:12, Paloma Arellano  wrote:

Trigger a devcoredump to dump dpu registers and capture the drm atomic
state when the frame_done_timer timeouts.

Signed-off-by: Paloma Arellano 
---
   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 13 +++--
   1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 1cf7ff6caff4..5cf7594feb5a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -191,6 +191,7 @@ struct dpu_encoder_virt {
  void *crtc_frame_event_cb_data;

  atomic_t frame_done_timeout_ms;
+   atomic_t frame_done_timeout_cnt;
  struct timer_list frame_done_timer;

  struct msm_display_info disp_info;
@@ -1204,6 +1205,8 @@ static void dpu_encoder_virt_atomic_enable(struct 
drm_encoder *drm_enc,

  dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc);

+   atomic_set(_enc->frame_done_timeout_cnt, 0);
+
  if (disp_info->intf_type == INTF_DP)
  dpu_enc->wide_bus_en = 
msm_dp_wide_bus_available(priv->dp[index]);
  else if (disp_info->intf_type == INTF_DSI)
@@ -2115,11 +2118,12 @@ static int _dpu_encoder_status_show(struct seq_file *s, 
void *data)
  for (i = 0; i < dpu_enc->num_phys_encs; i++) {
  struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];

-   seq_printf(s, "intf:%d  wb:%d  vsync:%8d underrun:%8d",
+   seq_printf(s, "intf:%d  wb:%d  vsync:%8d underrun:%8d
frame_done_cnt:%d",
  phys->hw_intf ? phys->hw_intf->idx - INTF_0 : 
-1,
  phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1,
  atomic_read(>vsync_cnt),
-   atomic_read(>underrun_cnt));
+   atomic_read(>underrun_cnt),
+   atomic_read(_enc->frame_done_timeout_cnt));

  seq_printf(s, "mode: %s\n", 
dpu_encoder_helper_get_intf_type(phys->intf_mode));
  }
@@ -2341,6 +2345,10 @@ static void dpu_encoder_frame_done_timeout(struct 
timer_list *t)

  DPU_ERROR_ENC(dpu_enc, "frame done timeout\n");

+   atomic_inc(_enc->frame_done_timeout_cnt);
+   if (atomic_read(_enc->frame_done_timeout_cnt) == 1)
+   msm_disp_snapshot_state(drm_enc->dev);

atomic_inc_and_test(), please

Hi Dmitry,

We only want to create a snapshot for the first instance in which the
timer timeouts. atomic_int_and_test() increments the value and then
returns whether it has a value of zero or not. FWIW I think I should
change it to 'atomic_add_return(1, _enc->frame_done_timeout_cnt)' so
that we can check only when this value equals one.

Works for me too.

I suggested atomic_inc_test() because then we can let devcoredump take
care of duplicate events.


Ack

-Paloma




Thank you,

Paloma


+
  event = DPU_ENCODER_FRAME_EVENT_ERROR;
  trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event);
  dpu_enc->crtc_frame_event_cb(dpu_enc->crtc_frame_event_cb_data, 
event);
@@ -2392,6 +2400,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device 
*dev,
  goto fail;

  atomic_set(_enc->frame_done_timeout_ms, 0);
+   atomic_set(_enc->frame_done_timeout_cnt, 0);
  timer_setup(_enc->frame_done_timer,
  dpu_encoder_frame_done_timeout, 0);

--
2.41.0






Re: [PATCH v2 0/3] drm/panfrost: Fix poweroff and sync IRQs for suspend

2023-11-29 Thread Marek Szyprowski


On 28.11.2023 13:45, AngeloGioacchino Del Regno wrote:
> This series contains a fast fix for the basic GPU poweroff functionality
> and goes further by implementing interrupt masking and synchronization
> before suspend.
>
> For more information, please look at the conversation at [1], which
> explains the regression seen with the poweroff commit and the initial
> approaches taken to solve that.

Just to let You know, as there is still some discussion about 
beautifying the final code, I've tested this version on my test hardware 
and everything works fine again! Thanks!

Tested-by: Marek Szyprowski 


> Cheers!
>
> [1]: 
> https://lore.kernel.org/all/20231123095320.41433-1-angelogioacchino.delre...@collabora.com/
>
> AngeloGioacchino Del Regno (3):
>drm/panfrost: Ignore core_mask for poweroff and disable PWRTRANS irq
>drm/panfrost: Add gpu_irq, mmu_irq to struct panfrost_device
>drm/panfrost: Synchronize and disable interrupts before powering off
>
>   drivers/gpu/drm/panfrost/panfrost_device.c |  4 +++
>   drivers/gpu/drm/panfrost/panfrost_device.h |  9 +++
>   drivers/gpu/drm/panfrost/panfrost_gpu.c| 29 +++---
>   drivers/gpu/drm/panfrost/panfrost_gpu.h|  1 +
>   drivers/gpu/drm/panfrost/panfrost_job.c| 18 +++---
>   drivers/gpu/drm/panfrost/panfrost_job.h|  1 +
>   drivers/gpu/drm/panfrost/panfrost_mmu.c| 27 ++--
>   drivers/gpu/drm/panfrost/panfrost_mmu.h|  1 +
>   8 files changed, 70 insertions(+), 20 deletions(-)
>
Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



Re: [PATCH v1 1/1] drm/i915/display: Don't use "proxy" headers

2023-11-29 Thread Jani Nikula
On Wed, 29 Nov 2023, Andy Shevchenko  wrote:
> The driver uses math.h and not util_macros.h.
>
> Signed-off-by: Andy Shevchenko 

Reviewed-by: Jani Nikula 

> ---
>  drivers/gpu/drm/i915/display/intel_snps_phy.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c 
> b/drivers/gpu/drm/i915/display/intel_snps_phy.c
> index ce5a73a4cc89..bc61e736f9b3 100644
> --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
> +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
> @@ -3,7 +3,7 @@
>   * Copyright © 2019 Intel Corporation
>   */
>  
> -#include 
> +#include 
>  
>  #include "i915_reg.h"
>  #include "intel_ddi.h"

-- 
Jani Nikula, Intel


Re: [PATCH v2] drm/i915: correct the input parameter on _intel_dsb_commit()

2023-11-29 Thread Jani Nikula
On Tue, 14 Nov 2023, heminhong  wrote:
> Current, the dewake_scanline variable is defined as unsigned int,
> an unsigned int variable that is always greater than or equal to 0.
> when _intel_dsb_commit function is called by intel_dsb_commit function,
> the dewake_scanline variable may have an int value.
> So the dewake_scanline variable is necessary to defined as an int.
>
> Fixes: f83b94d23770 ("drm/i915/dsb: Use DEwake to combat PkgC latency")
> Reported-by: kernel test robot 
> Closes: 
> https://lore.kernel.org/oe-kbuild-all/202310052201.anvbpgpr-...@intel.com/
> Cc: Ville Syrjälä 
> Cc: Uma Shankar 
>
> Signed-off-by: heminhong 

Pushed to drm-intel-next, thanks for the patch.

BR,
Jani.


> ---
>  drivers/gpu/drm/i915/display/intel_dsb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c 
> b/drivers/gpu/drm/i915/display/intel_dsb.c
> index 78b6fe24dcd8..7fd6280c54a7 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.c
> @@ -340,7 +340,7 @@ static int intel_dsb_dewake_scanline(const struct 
> intel_crtc_state *crtc_state)
>  }
>  
>  static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
> -   unsigned int dewake_scanline)
> +   int dewake_scanline)
>  {
>   struct intel_crtc *crtc = dsb->crtc;
>   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);

-- 
Jani Nikula, Intel


Re: [PATCH v2] backlight: mp3309c: fix uninitialized local variable

2023-11-29 Thread Daniel Thompson
On Wed, Nov 29, 2023 at 05:45:14PM +0100, Flavio Suligoi wrote:
> In the function "pm3309c_parse_dt_node", when the dimming analog control
> mode (by I2C messages) is enabled, the local variable "prop_levels" is
> tested without any initialization, as indicated by the following smatch
> warning:
>
> drivers/video/backlight/mp3309c.c:279 pm3309c_parse_dt_node() error: 
> uninitialized symbol 'prop_levels'.
>
> To avoid any problem in case of undefined behavior, we need to initialize
> it to "NULL".
>
> Reported-by: Dan Carpenter 
> Closes: 
> https://lore.kernel.org/dri-devel/af0a1870-693b-442f-9b11-0503cfcd944a@moroto.mountain/
> Fixes: 2e914516a58c ("backlight: mp3309c: Add support for MPS MP3309C")
> Signed-off-by: Flavio Suligoi 

Reviewed-by: Daniel Thompson 


Daniel.


[PATCH v2] backlight: mp3309c: fix uninitialized local variable

2023-11-29 Thread Flavio Suligoi
In the function "pm3309c_parse_dt_node", when the dimming analog control
mode (by I2C messages) is enabled, the local variable "prop_levels" is
tested without any initialization, as indicated by the following smatch
warning:

drivers/video/backlight/mp3309c.c:279 pm3309c_parse_dt_node() error: 
uninitialized symbol 'prop_levels'.

To avoid any problem in case of undefined behavior, we need to initialize
it to "NULL".

Reported-by: Dan Carpenter 
Closes: 
https://lore.kernel.org/dri-devel/af0a1870-693b-442f-9b11-0503cfcd944a@moroto.mountain/
Fixes: 2e914516a58c ("backlight: mp3309c: Add support for MPS MP3309C")
Signed-off-by: Flavio Suligoi 
---

v2:
 - remove redundant initialization of "prop_pwms" variable
 - remove "thanks to Dan Carpenter for the report"
 - add "Reported-by: Dan Carpenter " tag
 - add "Closes:" tag

 drivers/video/backlight/mp3309c.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/video/backlight/mp3309c.c 
b/drivers/video/backlight/mp3309c.c
index 3fe4469ef43f..34d71259fac1 100644
--- a/drivers/video/backlight/mp3309c.c
+++ b/drivers/video/backlight/mp3309c.c
@@ -203,7 +203,8 @@ static int pm3309c_parse_dt_node(struct mp3309c_chip *chip,
 struct mp3309c_platform_data *pdata)
 {
struct device_node *node = chip->dev->of_node;
-   struct property *prop_pwms, *prop_levels;
+   struct property *prop_pwms;
+   struct property *prop_levels = NULL;
int length = 0;
int ret, i;
unsigned int num_levels, tmp_value;
-- 
2.34.1



Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Luben Tuikov
On 2023-11-29 10:22, Alex Deucher wrote:
> On Wed, Nov 29, 2023 at 8:50 AM Alex Deucher  wrote:
>>
>> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  wrote:
>>>
>>> On 2023-11-28 17:13, Alex Deucher wrote:
 On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  wrote:
>
> Alex Deucher  writes:
>
>>> In that case those are the already known problems with the scheduler
>>> changes, aren't they?
>>
>> Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
>> misunderstanding what the original report was actually testing.  If it
>> was 6.7, then try reverting:
>> 56e449603f0ac580700621a356d35d5716a62ce5
>> b70438004a14f4d0f9890b3297cd66248728546c
>
> At some point it was suggested that I file a gitlab issue, but I took
> this to mean it was already known and being worked on.  -rc3 came out
> today and still has the problem.  Is there a known issue I could track?
>

 At this point, unless there are any objections, I think we should just
 revert the two patches
>>> Uhm, no.
>>>
>>> Why "the two" patches?
>>>
>>> This email, part of this thread,
>>>
>>> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/
>>>
>>> clearly states that reverting *only* this commit,
>>> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable number of 
>>> run-queues
>>> *does not* mitigate the failed suspend. (Furthermore, this commit doesn't 
>>> really change
>>> anything operational, other than using an allocated array, instead of a 
>>> static one, in DRM,
>>> while the 2nd patch is solely contained within the amdgpu driver code.)
>>>
>>> Leaving us with only this change,
>>> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
>>> to be at fault, as the kernel log attached in the linked email above shows.
>>>
>>> The conclusion is that only b70438004a14f4 needs reverting.
>>
>> b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
>> 56e449603f0ac5 breaks amdgpu.
> 
> We can try and re-enable it in the next kernel.  I'm just not sure
> we'll be able to fix this in time for 6.7 with the holidays and all
> and I don't want to cause a lot of scheduler churn at the end of the
> 6.7 cycle if we hold off and try and fix it.  Reverting seems like the
> best short term solution.

A lot of subsequent code has come in since commit 56e449603f0ac5, as it opened
the opportunity for a 1-to-1 relationship between an entity and a scheduler.
(Should've always been the case, from the outset. Not sure why it was coded as
a fixed-size array.)

Given that commit 56e449603f0ac5 has nothing to do with amdgpu, and the problem
is wholly contained in amdgpu, and no other driver has this problem, there is
no reason to have to "churn", i.e. go back and forth in DRM, only to cover up
an init bug in amdgpu. See the response I just sent in @this thread:
https://lore.kernel.org/r/05007cb0-871e-4dc7-af58-1351f4ba4...@gmail.com

And it's not like this issue is unknown. I first posted about it on 2023-10-16. 

Ideally, amdgpu would just fix their init code.
-- 
Regards,
Luben


OpenPGP_0x4C15479431A334AF.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH 2/2] drm/tiny: Add driver for the sharp LS027B7DH01 Memory LCD

2023-11-29 Thread Paul Kocialkowski
m_rect rect;
> +
> + if (!pipe->crtc.state->active)
> + return;
> +
> + if (drm_atomic_helper_damage_merged(old_state, state, ))
> + sharp_ls027b7dh01_fb_damaged(state->fb, );
> +}
> +
> +static void sharp_ls027b7dh01_pipe_disable(struct drm_simple_display_pipe 
> *pipe)
> +{
> + struct sharp_ls027b7dh01 *priv;
> +
> + priv = drm_to_priv(pipe->crtc.dev);
> + gpiod_set_value(priv->enable_gpio, 0);
> +}
> +
> +static int sharp_ls027b7dh01_clear_display(struct sharp_ls027b7dh01 *priv)
> +{
> + u8 clear_buf[2] = { CMD_CLEAR, 0 };
> +
> + return spi_write(priv->spi, clear_buf, sizeof(clear_buf));
> +}
> +
> +static int sharp_ls027b7dh01_pwm_enable(struct sharp_ls027b7dh01 *priv)
> +{
> + struct device *dev = >spi->dev;
> + struct pwm_state pwmstate;
> +
> + priv->extcomin_pwm = devm_pwm_get(dev, NULL);

You should almost certainly do that just once in probe, not every time you want
to enable the pwm. This might increase some internal refcount which won't be
balanced.

> + if (IS_ERR(priv->extcomin_pwm)) {
> + dev_err(dev, "Could not get EXTCOMIN pwm\n");
> + return PTR_ERR(priv->extcomin_pwm);
> + }
> +
> + pwm_init_state(priv->extcomin_pwm, );
> + pwm_set_relative_duty_cycle(, 50, 100);
> + pwm_apply_state(priv->extcomin_pwm, );
> +
> + pwm_enable(priv->extcomin_pwm);
> +
> + return 0;
> +}
> +
> +static void sharp_ls027b7dh01_pipe_enable(struct drm_simple_display_pipe 
> *pipe,
> +   struct drm_crtc_state *crtc_state,
> +   struct drm_plane_state *plane_state)
> +{
> + struct sharp_ls027b7dh01 *priv;
> + int ret, drm_idx;
> +
> + priv = drm_to_priv(pipe->crtc.dev);
> +
> + if (!drm_dev_enter(pipe->crtc.dev, _idx))
> + return;
> +
> + gpiod_set_value(priv->enable_gpio, 1);
> +

Does the panel documentation specify some delay between setting the enable GPIO
and communicating with it? It's rarely instantaneous.

> + ret = sharp_ls027b7dh01_clear_display(priv);
> + if (ret)
> + goto exit;
> +
> + sharp_ls027b7dh01_pwm_enable(priv);
> +
> +exit:
> + drm_dev_exit(drm_idx);
> +}
> +
> +static const struct drm_simple_display_pipe_funcs 
> sharp_ls027b7dh01_pipe_funcs = {
> + .enable = sharp_ls027b7dh01_pipe_enable,
> + .disable = sharp_ls027b7dh01_pipe_disable,
> + .update = sharp_ls027b7dh01_pipe_update,
> +};
> +
> +static int sharp_ls027b7dh01_connector_get_modes(struct drm_connector 
> *connector)
> +{
> + struct sharp_ls027b7dh01 *priv = drm_to_priv(connector->dev);
> +
> + return drm_connector_helper_get_modes_fixed(connector, 
> priv->display_mode);
> +}
> +
> +static const struct drm_connector_helper_funcs 
> sharp_ls027b7dh01_connector_hfuncs = {
> + .get_modes = sharp_ls027b7dh01_connector_get_modes,
> +};
> +
> +static const struct drm_connector_funcs sharp_ls027b7dh01_connector_funcs = {
> + .reset = drm_atomic_helper_connector_reset,
> + .fill_modes = drm_helper_probe_single_connector_modes,
> + .destroy = drm_connector_cleanup,
> + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static const struct drm_mode_config_funcs 
> sharp_ls027b7dh01_mode_config_funcs = {
> + .fb_create = drm_gem_fb_create_with_dirty,
> + .atomic_check = drm_atomic_helper_check,
> + .atomic_commit = drm_atomic_helper_commit,
> +};
> +
> +static const uint32_t sharp_ls027b7dh01_formats[] = {
> + DRM_FORMAT_XRGB,
> +};
> +
> +static const struct drm_display_mode sharp_ls027b7dh01_mode = {
> + DRM_SIMPLE_MODE(400, 240, 59, 35),
> +};
> +
> +DEFINE_DRM_GEM_DMA_FOPS(sharp_ls027b7dh01_fops);
> +
> +static const struct drm_driver sharp_ls027b7dh01_drm_driver = {
> + .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> + .fops   = _ls027b7dh01_fops,
> + DRM_GEM_DMA_DRIVER_OPS_VMAP,
> + .name   = "sharp_ls027b7dh01",
> + .desc   = "Sharp ls027b7dh01 Memory LCD",
> + .date   = "20231129",
> + .major  = 1,
> + .minor  = 0,
> +};
> +
> +static int sharp_ls027b7dh01_probe(struct spi_device *spi)
> +{
> + struct device *dev = >dev;
> + struct sharp_ls027b7dh01 *priv;
> + struct drm_device

Re: [PATCH 08/10] iommu/tegra: Use tegra_dev_iommu_get_stream_id() in the remaining places

2023-11-29 Thread Thierry Reding
On Tue, Nov 28, 2023 at 08:48:04PM -0400, Jason Gunthorpe wrote:
> This API was defined to formalize the access to internal iommu details on
> some Tegra SOCs, but a few callers got missed. Add them.
> 
> The helper already masks by 0x so remove this code from the callers.
> 
> Suggested-by: Thierry Reding 
> Signed-off-by: Jason Gunthorpe 
> ---
>  drivers/dma/tegra186-gpc-dma.c  |  8 +++-
>  drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c |  7 ++-
>  drivers/memory/tegra/tegra186.c | 12 ++--
>  3 files changed, 11 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c
> index fa4d4142a68a21..88547a23825b18 100644
> --- a/drivers/dma/tegra186-gpc-dma.c
> +++ b/drivers/dma/tegra186-gpc-dma.c
> @@ -1348,8 +1348,8 @@ static int tegra_dma_program_sid(struct 
> tegra_dma_channel *tdc, int stream_id)
>  static int tegra_dma_probe(struct platform_device *pdev)
>  {
>   const struct tegra_dma_chip_data *cdata = NULL;
> - struct iommu_fwspec *iommu_spec;
> - unsigned int stream_id, i;
> + unsigned int i;
> + u32 stream_id;
>   struct tegra_dma *tdma;
>   int ret;
>  
> @@ -1378,12 +1378,10 @@ static int tegra_dma_probe(struct platform_device 
> *pdev)
>  
>   tdma->dma_dev.dev = >dev;
>  
> - iommu_spec = dev_iommu_fwspec_get(>dev);
> - if (!iommu_spec) {
> + if (!tegra_dev_iommu_get_stream_id(>dev, _id)) {
>   dev_err(>dev, "Missing iommu stream-id\n");
>   return -EINVAL;
>   }
> - stream_id = iommu_spec->ids[0] & 0x;
>  
>   ret = device_property_read_u32(>dev, "dma-channel-mask",
>  >chan_mask);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c
> index e7e8fdf3adab7a..b40fd1dbb21617 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c
> @@ -28,16 +28,13 @@ static void
>  gp10b_ltc_init(struct nvkm_ltc *ltc)
>  {
>   struct nvkm_device *device = ltc->subdev.device;
> - struct iommu_fwspec *spec;
> + u32 sid;
>  
>   nvkm_wr32(device, 0x17e27c, ltc->ltc_nr);
>   nvkm_wr32(device, 0x17e000, ltc->ltc_nr);
>   nvkm_wr32(device, 0x100800, ltc->ltc_nr);
>  
> - spec = dev_iommu_fwspec_get(device->dev);
> - if (spec) {
> - u32 sid = spec->ids[0] & 0x;
> -
> + if (tegra_dev_iommu_get_stream_id(device->dev, )) {
>   /* stream ID */
>   nvkm_wr32(device, 0x16, sid << 2);

We could probably also remove the comment now since the function and
variable names make it obvious what's being written here.

>   }
> diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
> index 533f85a4b2bdb7..3e4fbe94dd666e 100644
> --- a/drivers/memory/tegra/tegra186.c
> +++ b/drivers/memory/tegra/tegra186.c
> @@ -111,21 +111,21 @@ static void tegra186_mc_client_sid_override(struct 
> tegra_mc *mc,
>  static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev)
>  {
>  #if IS_ENABLED(CONFIG_IOMMU_API)
> - struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>   struct of_phandle_args args;
>   unsigned int i, index = 0;
> + u32 sid;
>  
> + WARN_ON(!tegra_dev_iommu_get_stream_id(dev, ));

I know the code previously didn't check for any errors, but we may want
to do so now. If tegra_dev_iommu_get_stream_id() ever fails we may end
up writing some undefined value into the override register.

I'm also unsure if WARN_ON() is appropriate here. I vaguely recall that
->probe_device() was called for all devices on the bus and not all of
them may have been associated with the IOMMU. Not all of them may in
fact access memory in the first place.

Perhaps I'm misremembering and the IOMMU core now takes care of only
calling this when fwspec is indeed valid?

Thierry


signature.asc
Description: PGP signature


Re: [PATCH 2/2] drm/tiny: Add driver for the sharp LS027B7DH01 Memory LCD

2023-11-29 Thread Thomas Zimmermann
t struct drm_simple_display_pipe_funcs sharp_ls027b7dh01_pipe_funcs 
= {
+   .enable = sharp_ls027b7dh01_pipe_enable,
+   .disable = sharp_ls027b7dh01_pipe_disable,
+   .update = sharp_ls027b7dh01_pipe_update,
+};
+
+static int sharp_ls027b7dh01_connector_get_modes(struct drm_connector 
*connector)
+{
+   struct sharp_ls027b7dh01 *priv = drm_to_priv(connector->dev);
+
+   return drm_connector_helper_get_modes_fixed(connector, 
priv->display_mode);
+}
+
+static const struct drm_connector_helper_funcs 
sharp_ls027b7dh01_connector_hfuncs = {
+   .get_modes = sharp_ls027b7dh01_connector_get_modes,
+};
+
+static const struct drm_connector_funcs sharp_ls027b7dh01_connector_funcs = {
+   .reset = drm_atomic_helper_connector_reset,
+   .fill_modes = drm_helper_probe_single_connector_modes,
+   .destroy = drm_connector_cleanup,
+   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_mode_config_funcs sharp_ls027b7dh01_mode_config_funcs 
= {
+   .fb_create = drm_gem_fb_create_with_dirty,
+   .atomic_check = drm_atomic_helper_check,
+   .atomic_commit = drm_atomic_helper_commit,
+};
+
+static const uint32_t sharp_ls027b7dh01_formats[] = {
+   DRM_FORMAT_XRGB,
+};
+
+static const struct drm_display_mode sharp_ls027b7dh01_mode = {
+   DRM_SIMPLE_MODE(400, 240, 59, 35),
+};
+
+DEFINE_DRM_GEM_DMA_FOPS(sharp_ls027b7dh01_fops);
+
+static const struct drm_driver sharp_ls027b7dh01_drm_driver = {
+   .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+   .fops   = _ls027b7dh01_fops,
+   DRM_GEM_DMA_DRIVER_OPS_VMAP,
+   .name   = "sharp_ls027b7dh01",
+   .desc   = "Sharp ls027b7dh01 Memory LCD",
+   .date   = "20231129",
+   .major  = 1,
+   .minor  = 0,
+};
+
+static int sharp_ls027b7dh01_probe(struct spi_device *spi)
+{
+   struct device *dev = >dev;
+   struct sharp_ls027b7dh01 *priv;
+   struct drm_device *drm;
+   unsigned int write_buf_size;
+   int ret;
+
+   if (!dev->coherent_dma_mask) {
+   ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
+   if (ret)
+   return dev_err_probe(dev, ret, "Failed to set dma 
mask\n");
+   }
+
+   priv = devm_drm_dev_alloc(dev, _ls027b7dh01_drm_driver,
+ struct sharp_ls027b7dh01, drm);
+   if (IS_ERR(priv))
+   return PTR_ERR(priv);
+
+   spi_set_drvdata(spi, priv);
+   priv->spi = spi;
+
+   priv->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
+   if (IS_ERR(priv->enable_gpio))
+   return dev_err_probe(dev, PTR_ERR(priv->enable_gpio),
+"Failed to get GPIO 'enable'\n");
+
+   drm = >drm;
+   ret = drmm_mode_config_init(drm);
+   if (ret)
+   return ret;
+
+   drm->mode_config.funcs = _ls027b7dh01_mode_config_funcs;
+   priv->display_mode = _ls027b7dh01_mode;
+
+   /*
+* write_buf_size:
+*
+* hdisplay * vdisplay / 8 => 1 bit per Pixel.
+* 2 * vdisplay => line number byte + trailer dummy byte for every line.
+* 2 => write command byte + final trailer dummy byte.
+*/
+   write_buf_size = priv->display_mode->hdisplay * 
priv->display_mode->vdisplay / 8
++ 2 * priv->display_mode->vdisplay + 2;
+
+   priv->write_buf = devm_kzalloc(dev, write_buf_size, GFP_KERNEL);
+   if (!priv->write_buf)
+   return -ENOMEM;
+
+   drm->mode_config.min_width = priv->display_mode->hdisplay;
+   drm->mode_config.max_width = priv->display_mode->hdisplay;
+   drm->mode_config.min_height = priv->display_mode->vdisplay;
+   drm->mode_config.max_height = priv->display_mode->vdisplay;
+
+   ret = drm_connector_init(drm, >connector,
+_ls027b7dh01_connector_funcs,
+DRM_MODE_CONNECTOR_SPI);
+   if (ret)
+   return ret;
+
+   drm_connector_helper_add(>connector,
+_ls027b7dh01_connector_hfuncs);
+
+   ret = drm_simple_display_pipe_init(drm, >pipe,
+  _ls027b7dh01_pipe_funcs,
+  sharp_ls027b7dh01_formats,
+  
ARRAY_SIZE(sharp_ls027b7dh01_formats),
+  NULL, >connector);
+   if (ret)
+   return ret;
+
+   drm_plane_enable_fb_damage_clips(>pipe.plane);
+   drm_mode_config_reset(drm

Re: Radeon regression in 6.6 kernel

2023-11-29 Thread Luben Tuikov
On 2023-11-29 08:50, Alex Deucher wrote:
> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov  wrote:
>>
>> On 2023-11-28 17:13, Alex Deucher wrote:
>>> On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi  wrote:

 Alex Deucher  writes:

>> In that case those are the already known problems with the scheduler
>> changes, aren't they?
>
> Yes.  Those changes went into 6.7 though, not 6.6 AFAIK.  Maybe I'm
> misunderstanding what the original report was actually testing.  If it
> was 6.7, then try reverting:
> 56e449603f0ac580700621a356d35d5716a62ce5
> b70438004a14f4d0f9890b3297cd66248728546c

 At some point it was suggested that I file a gitlab issue, but I took
 this to mean it was already known and being worked on.  -rc3 came out
 today and still has the problem.  Is there a known issue I could track?

>>>
>>> At this point, unless there are any objections, I think we should just
>>> revert the two patches
>> Uhm, no.
>>
>> Why "the two" patches?
>>
>> This email, part of this thread,
>>
>> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/
>>
>> clearly states that reverting *only* this commit,
>> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable number of 
>> run-queues
>> *does not* mitigate the failed suspend. (Furthermore, this commit doesn't 
>> really change
>> anything operational, other than using an allocated array, instead of a 
>> static one, in DRM,
>> while the 2nd patch is solely contained within the amdgpu driver code.)
>>
>> Leaving us with only this change,
>> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level
>> to be at fault, as the kernel log attached in the linked email above shows.
>>
>> The conclusion is that only b70438004a14f4 needs reverting.
> 
> b70438004a14f4 was a fix for 56e449603f0ac5.  Without b70438004a14f4,
> 56e449603f0ac5 breaks amdgpu.

It doesn't "break" it, amdgpu just needs to be fixed.

I know we put in a Fixes tag in 
b70438004a14f4 "drm/amdgpu: move buffer funcs setting up a level"
pointing to 56e449603f0ac5 "drm/sched: Convert the GPU scheduler to variable 
number of run-queues",
but given the testing Phillip has done, the culprit is wholly contained in
the amdgpu driver code.

No other driver has this problem since commit 56e449603f0ac5.

The Fixes tag in b70438004a14f4 "drm/amdgpu: move buffer funcs setting up a 
level" should've ideally
pointed to an amdgpu-driver code commit only (perhaps an old-old commit), and I 
was a bit uncomfortable
putting in a Fixes tag which pointed to drm code, but we did it so that the 
amdgpu commit follows
the changes in DRM. In retrospect, the Fixes tag should've pointed to and 
amdgpu-driver commit when
that the amdgpu code was originally written.

I remember that the problem was really that amdgpu called 
drm_sched_entity_init(),
in amdgpu_ttm_set_buffer_funcs_status() without actually having initialized the 
scheduler
used therein. For instance, the code before commit b70438004a14f4, looked like 
this:

void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
{
struct ttm_resource_manager *man = ttm_manager_type(>mman.bdev, 
TTM_PL_VRAM);
uint64_t size;
int r;

if (!adev->mman.initialized || amdgpu_in_reset(adev) ||
adev->mman.buffer_funcs_enabled == enable)
return;

if (enable) {
struct amdgpu_ring *ring;
struct drm_gpu_scheduler *sched;

ring = adev->mman.buffer_funcs_ring;
sched = >sched; <-- LT: No 
one has initialized this scheduler
r = drm_sched_entity_init(>mman.entity, <-- Oopses, 
now that sched->sched_rq is not a static array
  DRM_SCHED_PRIORITY_KERNEL, ,
  1, NULL);
if (r) {
DRM_ERROR("Failed setting up TTM BO move entity (%d)\n",
  r);
return;
}


Before commit 56e449603f0ac5, amdgpu was getting away with this, because the 
sched->sched_rq
was a static array.

Ideally, amdgpu code would be fixed.
-- 
Regards,
Luben


OpenPGP_0x4C15479431A334AF.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH] drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg()

2023-11-29 Thread Alex Deucher
On Wed, Nov 29, 2023 at 10:47 AM Christian König
 wrote:
>
> Am 29.11.23 um 16:22 schrieb Nikita Zhandarovich:
> > While improbable, there may be a chance of hitting integer
> > overflow when the result of radeon_get_ib_value() gets shifted
> > left.
> >
> > Avoid it by casting one of the operands to larger data type (u64).
> >
> > Found by Linux Verification Center (linuxtesting.org) with static
> > analysis tool SVACE.
>
> Well IIRC cb_color_bo_offset is just 32bits anyway, so this doesn't
> change anything.

All of the GPU addresses in the structure are u64.  The registers are
32 bits which is why they are 256 byte aligned.  That said, I think
the MC on the chips supported by this code are only 32 bits so we
shouldn't see any addresses greater than 32 bits, but this seems like
good to do from a coding perspective.  Otherwise, we'll keep getting
this patch.

Alex


Alex

>
> Regards,
> Christian.
>
> >
> > Fixes: 1729dd33d20b ("drm/radeon/kms: r600 CS parser fixes")
> > Signed-off-by: Nikita Zhandarovich 
> > ---
> >   drivers/gpu/drm/radeon/r600_cs.c | 4 ++--
> >   1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/radeon/r600_cs.c 
> > b/drivers/gpu/drm/radeon/r600_cs.c
> > index 638f861af80f..6cf54a747749 100644
> > --- a/drivers/gpu/drm/radeon/r600_cs.c
> > +++ b/drivers/gpu/drm/radeon/r600_cs.c
> > @@ -1275,7 +1275,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser 
> > *p, u32 reg, u32 idx)
> >   return -EINVAL;
> >   }
> >   tmp = (reg - CB_COLOR0_BASE) / 4;
> > - track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) 
> > << 8;
> > + track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, 
> > idx) << 8;
> >   ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0x);
> >   track->cb_color_base_last[tmp] = ib[idx];
> >   track->cb_color_bo[tmp] = reloc->robj;
> > @@ -1302,7 +1302,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser 
> > *p, u32 reg, u32 idx)
> >   "0x%04X\n", reg);
> >   return -EINVAL;
> >   }
> > - track->htile_offset = radeon_get_ib_value(p, idx) << 8;
> > + track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8;
> >   ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0x);
> >   track->htile_bo = reloc->robj;
> >   track->db_dirty = true;
>


[PATCH 1/4] fbdev/efifb: Replace references to global screen_info by local pointer

2023-11-29 Thread Thomas Zimmermann
Get the global screen_info's address once and access the data via
this pointer. Limits the use of global state.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/efifb.c | 113 ++--
 1 file changed, 58 insertions(+), 55 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index f9b4ddd592ce4..6cbb65bbe1110 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -147,10 +147,9 @@ static bool efifb_bgrt_sanity_check(struct screen_info 
*si, u32 bmp_width)
 }
 #endif
 
-static void efifb_show_boot_graphics(struct fb_info *info)
+static void efifb_show_boot_graphics(struct fb_info *info, struct screen_info 
*si)
 {
u32 bmp_width, bmp_height, bmp_pitch, dst_x, y, src_y;
-   struct screen_info *si = _info;
struct bmp_file_header *file_header;
struct bmp_dib_header *dib_header;
void *bgrt_image = NULL;
@@ -282,7 +281,7 @@ static const struct fb_ops efifb_ops = {
.fb_setcolreg   = efifb_setcolreg,
 };
 
-static int efifb_setup(char *options)
+static int efifb_setup(struct screen_info *si, char *options)
 {
char *this_opt;
 
@@ -290,16 +289,16 @@ static int efifb_setup(char *options)
while ((this_opt = strsep(, ",")) != NULL) {
if (!*this_opt) continue;
 
-   efifb_setup_from_dmi(_info, this_opt);
+   efifb_setup_from_dmi(si, this_opt);
 
if (!strncmp(this_opt, "base:", 5))
-   screen_info.lfb_base = 
simple_strtoul(this_opt+5, NULL, 0);
+   si->lfb_base = simple_strtoul(this_opt+5, NULL, 
0);
else if (!strncmp(this_opt, "stride:", 7))
-   screen_info.lfb_linelength = 
simple_strtoul(this_opt+7, NULL, 0) * 4;
+   si->lfb_linelength = simple_strtoul(this_opt+7, 
NULL, 0) * 4;
else if (!strncmp(this_opt, "height:", 7))
-   screen_info.lfb_height = 
simple_strtoul(this_opt+7, NULL, 0);
+   si->lfb_height = simple_strtoul(this_opt+7, 
NULL, 0);
else if (!strncmp(this_opt, "width:", 6))
-   screen_info.lfb_width = 
simple_strtoul(this_opt+6, NULL, 0);
+   si->lfb_width = simple_strtoul(this_opt+6, 
NULL, 0);
else if (!strcmp(this_opt, "nowc"))
mem_flags &= ~EFI_MEMORY_WC;
else if (!strcmp(this_opt, "nobgrt"))
@@ -310,15 +309,15 @@ static int efifb_setup(char *options)
return 0;
 }
 
-static inline bool fb_base_is_valid(void)
+static inline bool fb_base_is_valid(struct screen_info *si)
 {
-   if (screen_info.lfb_base)
+   if (si->lfb_base)
return true;
 
-   if (!(screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE))
+   if (!(si->capabilities & VIDEO_CAPABILITY_64BIT_BASE))
return false;
 
-   if (screen_info.ext_lfb_base)
+   if (si->ext_lfb_base)
return true;
 
return false;
@@ -329,7 +328,10 @@ static ssize_t name##_show(struct device *dev, 
\
   struct device_attribute *attr,   \
   char *buf)   \
 {  \
-   return sprintf(buf, fmt "\n", (screen_info.lfb_##name));\
+   struct screen_info *si = dev_get_platdata(dev); \
+   if (!si)\
+   return -ENODEV; \
+   return sprintf(buf, fmt "\n", (si->lfb_##name));\
 }  \
 static DEVICE_ATTR_RO(name)
 
@@ -356,6 +358,7 @@ static u64 bar_offset;
 
 static int efifb_probe(struct platform_device *dev)
 {
+   struct screen_info *si = _info;
struct fb_info *info;
struct efifb_par *par;
int err, orientation;
@@ -365,48 +368,48 @@ static int efifb_probe(struct platform_device *dev)
char *option = NULL;
efi_memory_desc_t md;
 
-   if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
+   if (si->orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
return -ENODEV;
 
if (fb_get_options("efifb", ))
return -ENODEV;
-   efifb_setup(option);
+   efifb_setup(si, option);
 
/* We don't get linelength from UGA Draw Protocol, only from
 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
 * passed in from the user, we really can't use the framebuffer.
 */
-   if (!screen_info.lfb_linelength)
+   if 

[PATCH 2/4] fbdev/efifb: Use screen_info pointer from device

2023-11-29 Thread Thomas Zimmermann
Use the screen_info instance from the device instead of dereferencing
the global screen_info state. Decouples the driver from per-architecture
code. Duplicated the screen_info data, so that efifb can modify it at
will.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/efifb.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index 6cbb65bbe1110..d0ce357ff2684 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -358,7 +358,7 @@ static u64 bar_offset;
 
 static int efifb_probe(struct platform_device *dev)
 {
-   struct screen_info *si = _info;
+   struct screen_info *si;
struct fb_info *info;
struct efifb_par *par;
int err, orientation;
@@ -368,6 +368,13 @@ static int efifb_probe(struct platform_device *dev)
char *option = NULL;
efi_memory_desc_t md;
 
+   si = dev_get_platdata(>dev);
+   if (!si)
+   return -ENODEV;
+   si = devm_kmemdup(>dev, si, sizeof(*si), GFP_KERNEL);
+   if (!si)
+   return -ENOMEM;
+
if (si->orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
return -ENODEV;
 
-- 
2.43.0



[PATCH 3/4] fbdev/vesafb: Replace references to global screen_info by local pointer

2023-11-29 Thread Thomas Zimmermann
Get the global screen_info's address once and access the data via
this pointer. Limits the use of global state.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/vesafb.c | 66 +++-
 1 file changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c
index c0edceea0a793..ea89accbec385 100644
--- a/drivers/video/fbdev/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
@@ -243,6 +243,7 @@ static int vesafb_setup(char *options)
 
 static int vesafb_probe(struct platform_device *dev)
 {
+   struct screen_info *si = _info;
struct fb_info *info;
struct vesafb_par *par;
int i, err;
@@ -255,17 +256,17 @@ static int vesafb_probe(struct platform_device *dev)
fb_get_options("vesafb", );
vesafb_setup(option);
 
-   if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
+   if (si->orig_video_isVGA != VIDEO_TYPE_VLFB)
return -ENODEV;
 
-   vga_compat = (screen_info.capabilities & 2) ? 0 : 1;
-   vesafb_fix.smem_start = screen_info.lfb_base;
-   vesafb_defined.bits_per_pixel = screen_info.lfb_depth;
+   vga_compat = (si->capabilities & 2) ? 0 : 1;
+   vesafb_fix.smem_start = si->lfb_base;
+   vesafb_defined.bits_per_pixel = si->lfb_depth;
if (15 == vesafb_defined.bits_per_pixel)
vesafb_defined.bits_per_pixel = 16;
-   vesafb_defined.xres = screen_info.lfb_width;
-   vesafb_defined.yres = screen_info.lfb_height;
-   vesafb_fix.line_length = screen_info.lfb_linelength;
+   vesafb_defined.xres = si->lfb_width;
+   vesafb_defined.yres = si->lfb_height;
+   vesafb_fix.line_length = si->lfb_linelength;
vesafb_fix.visual   = (vesafb_defined.bits_per_pixel == 8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
 
@@ -277,7 +278,7 @@ static int vesafb_probe(struct platform_device *dev)
/*   size_total -- all video memory we have. Used for mtrr
 * entries, resource allocation and bounds
 * checking. */
-   size_total = screen_info.lfb_size * 65536;
+   size_total = si->lfb_size * 65536;
if (vram_total)
size_total = vram_total * 1024 * 1024;
if (size_total < size_vmode)
@@ -297,7 +298,7 @@ static int vesafb_probe(struct platform_device *dev)
vesafb_fix.smem_len = size_remap;
 
 #ifndef __i386__
-   screen_info.vesapm_seg = 0;
+   si->vesapm_seg = 0;
 #endif
 
if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
@@ -317,23 +318,26 @@ static int vesafb_probe(struct platform_device *dev)
par = info->par;
info->pseudo_palette = par->pseudo_palette;
 
-   par->base = screen_info.lfb_base;
+   par->base = si->lfb_base;
par->size = size_total;
 
printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
-  vesafb_defined.xres, vesafb_defined.yres, 
vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
+  vesafb_defined.xres, vesafb_defined.yres, 
vesafb_defined.bits_per_pixel,
+  vesafb_fix.line_length, si->pages);
 
-   if (screen_info.vesapm_seg) {
+   if (si->vesapm_seg) {
printk(KERN_INFO "vesafb: protected mode interface info at 
%04x:%04x\n",
-  screen_info.vesapm_seg,screen_info.vesapm_off);
+  si->vesapm_seg, si->vesapm_off);
}
 
-   if (screen_info.vesapm_seg < 0xc000)
+   if (si->vesapm_seg < 0xc000)
ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
 
if (ypan || pmi_setpal) {
+   unsigned long pmi_phys;
unsigned short *pmi_base;
-   pmi_base  = (unsigned short*)phys_to_virt(((unsigned 
long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
+   pmi_phys  = ((unsigned long)si->vesapm_seg << 4) + 
si->vesapm_off;
+   pmi_base  = (unsigned short *)phys_to_virt(pmi_phys);
pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
pmi_pal   = (void*)((char*)pmi_base + pmi_base[2]);
printk(KERN_INFO "vesafb: pmi: set display start = %p, set 
palette = %p\n",pmi_start,pmi_pal);
@@ -377,14 +381,14 @@ static int vesafb_probe(struct platform_device *dev)
vesafb_defined.left_margin  = (vesafb_defined.xres / 8) & 0xf8;
vesafb_defined.hsync_len= (vesafb_defined.xres / 8) & 0xf8;
 
-   vesafb_defined.red.offset= screen_info.red_pos;
-   vesafb_defined.red.length= screen_info.red_size;
-   vesafb_defined.green.offset  = screen_info.green_pos;
-   vesafb_defined.green.length  = screen_info.green_size;
-   vesafb_defined.blue.offset   = screen_info.blue_pos;
-   vesafb_defined.blue.length   = screen_info.blue_size;
-   vesafb_defined.transp.offset = screen_info.rsvd_pos;
- 

Re: [PATCH] drm/panel: nt36523: fix return value check in nt36523_probe()

2023-11-29 Thread Neil Armstrong
Hi,

On Wed, 29 Nov 2023 17:07:15 +0800, Yang Yingliang wrote:
> mipi_dsi_device_register_full() never returns NULL pointer, it
> will return ERR_PTR() when it fails, so replace the check with
> IS_ERR().
> 
> 

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git 
(drm-misc-fixes)

[1/1] drm/panel: nt36523: fix return value check in nt36523_probe()
  
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=fb18fe0fdf22a2f4512a8b644bb5ea1473829cda

-- 
Neil



[PATCH 4/4] fbdev/vesafb: Use screen_info pointer from device

2023-11-29 Thread Thomas Zimmermann
Use the screen_info instance from the device instead of dereferencing
the global screen_info state. Decouples the driver from per-architecture
code. Duplicated the screen_info data, so that vesafb can modify it at
will.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/vesafb.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c
index ea89accbec385..8912b16db75a1 100644
--- a/drivers/video/fbdev/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
@@ -243,7 +243,7 @@ static int vesafb_setup(char *options)
 
 static int vesafb_probe(struct platform_device *dev)
 {
-   struct screen_info *si = _info;
+   struct screen_info *si;
struct fb_info *info;
struct vesafb_par *par;
int i, err;
@@ -252,6 +252,13 @@ static int vesafb_probe(struct platform_device *dev)
unsigned int size_total;
char *option = NULL;
 
+   si = dev_get_platdata(>dev);
+   if (!si)
+   return -ENODEV;
+   si = devm_kmemdup(>dev, si, sizeof(*si), GFP_KERNEL);
+   if (!si)
+   return -ENOMEM;
+
/* ignore error return of fb_get_options */
fb_get_options("vesafb", );
vesafb_setup(option);
-- 
2.43.0



[PATCH 0/4] fbdev: Remove global screen_info in efifb/vesafb

2023-11-29 Thread Thomas Zimmermann
Replace the global instance of screen_info with the per-device instance
that is set by the sysfb code. The use of the global screen_info should
be limited and ideally be pushed into per-architecture code.

Thomas Zimmermann (4):
  fbdev/efifb: Replace references to global screen_info by local pointer
  fbdev/efifb: Use screen_info pointer from device
  fbdev/vesafb: Replace references to global screen_info by local
pointer
  fbdev/vesafb: Use screen_info pointer from device

 drivers/video/fbdev/efifb.c  | 120 +++
 drivers/video/fbdev/vesafb.c |  73 -
 2 files changed, 107 insertions(+), 86 deletions(-)

-- 
2.43.0



Re: [PATCH] drm/panel: nt36523: fix return value check in nt36523_probe()

2023-11-29 Thread neil . armstrong

On 29/11/2023 10:07, Yang Yingliang wrote:

From: Yang Yingliang 

mipi_dsi_device_register_full() never returns NULL pointer, it
will return ERR_PTR() when it fails, so replace the check with
IS_ERR().

Fixes: 0993234a0045 ("drm/panel: Add driver for Novatek NT36523")
Signed-off-by: Yang Yingliang 
---
  drivers/gpu/drm/panel/panel-novatek-nt36523.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36523.c
index 9b9a7eb1bc60..a189ce236328 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c
@@ -1254,9 +1254,9 @@ static int nt36523_probe(struct mipi_dsi_device *dsi)
return dev_err_probe(dev, -EPROBE_DEFER, "cannot get 
secondary DSI host\n");
  
  		pinfo->dsi[1] = mipi_dsi_device_register_full(dsi1_host, info);

-   if (!pinfo->dsi[1]) {
+   if (IS_ERR(pinfo->dsi[1])) {
dev_err(dev, "cannot get secondary DSI device\n");
-   return -ENODEV;
+   return PTR_ERR(pinfo->dsi[1]);
}
}
  


Reviewed-by: Neil Armstrong 


Re: [PATCH v2 RESEND] drm/panel: starry-2081101qfh032011-53g: Fine tune the panel power sequence

2023-11-29 Thread Neil Armstrong
Hi,

On Wed, 29 Nov 2023 16:41:15 +0800, xiazhengqiao wrote:
> For the "starry, 2081101qfh032011-53g" panel, it is stipulated in the
> panel spec that MIPI needs to keep the LP11 state before the
> lcm_reset pin is pulled high.
> 
> 

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git 
(drm-misc-fixes)

[1/1] drm/panel: starry-2081101qfh032011-53g: Fine tune the panel power sequence
  
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=fc1ccc16271a0526518f19f460fed63d575a8a42

-- 
Neil



Re: [PATCH v18 04/26] drm/shmem-helper: Refactor locked/unlocked functions

2023-11-29 Thread Boris Brezillon
On Wed, 29 Nov 2023 16:15:27 +0100
Maxime Ripard  wrote:

> > Now, let's assume we drop the _locked() suffix on
> > drm_gem_shmem_v[un]map(), but keep it on other helpers that need both
> > variants. This results in an inconsistent naming scheme inside the
> > same source file, which I find utterly confusing.
> >
> > Note that the initial reason I asked Dmitry if he could add the
> > _locked suffix to drm_gem_shmem_vmap() is because I started using
> > drm_gem_shmem_vmap() in powervr, before realizing this version wasn't
> > taking the lock, and I should have used drm_gem_vmap_unlocked()
> > instead, so this is not something I'm making up.  
> 
> Sorry if I gave you the impression I thought that you're making that up,
> I'm not.
> 
> Thanks for the explanation btw, I think I get what you're saying now:
> 
>  - drm_gem_shmem_vmap() is never taking the locks because the core
>expects to take them before calling them.
> 
>  - drm_gem_shmem_vunmap() is never taking the locks because the core
>expects to take them before calling them.

Correct.

> 
>  - Some other code path can still call those helpers in drivers, and the
>locking isn't handled by the core anymore.

They can, if they want to v[un]map a BO and they already acquired the
GEM resv lock. But I'm not sure anyone needs to do that yet. The main
reason for exposing these helpers is if one driver needs to overload the
default gem_shmem_funcs.

> 
>  - We now have _vmap/vunmap_unlocked functions to take those locks for
>those code paths

We don't have drm_gem_shmem_vmap/vunmap_unlocked(), we have
drm_gem_shmem_vmap/vunmap_locked(), which can be called directly, but
are mainly used to populate the drm_gem_object_funcs vtable. If drivers
want to v[un]map in a path where the resv lock is not held, they should
call drm_gem_vmap/vunmap_unlocked() (which are renamed
drm_gem_vmap/vunmap() in patch 1 of this series). Mind the **drm_gem_**
vs **drm_gem_shmem_** difference in the helper names. drm_gem_ helpers
are provided by drm_gem.c and call drm_gem_object_funcs callback, which
are supposed to be populated with drm_gem_shmem helpers.

> 
>  - And the variant names are now confusing, making people use the
>lockless version in situations where they should have use the locked
>one.

That's what happened to me, at least.

> 
> Is that a correct summary?

Almost ;-).

> 
> If so, then I agree that we need to change the name.

Cool.

> 
> We discussed it some more on IRC, and we agree that the "default"
> function should handle the locking properly and that's what the most
> common case should use.

Agree if by 'default' you mean the lock is always acquired by the
helper, not 'let's decide based on what users do most of the time with
this specific helper', because otherwise we'd be back to a situation
where the name doesn't clearly encode the function behavior.

> 
> So that means than drm_gem_shmem_vmap/vunmap() should take the lock
> itself, and drm_gem_shmem_vmap/vunmap_nolock/unlocked never does.

Not sure we have a need for drm_gem_shmem_vmap/vunmap(), but if we ever
add such helpers, they would acquire the resv lock, indeed.

Just to be clear, _nolock == _locked in the current semantics :-).
_nolock means 'don't take the lock', and _locked means 'lock is already
held'.

> 
> I think I'd prefer the nolock variant over unlocked still.

Okay, that means s/_locked/_nolock/ in drm_gem_shmem_helpers.{c,h}, I
guess.

> 
> And I also think we can improve the documentation and add lockdep calls

Lockdep asserts are already there, I think.

> to make sure that the difference between variants is clear in the doc,
> and if someone still get confused we can catch it.
> 
> Does that sound like a plan?

Assuming I understood it correctly, yes. Can you just confirm my
understanding is correct though?

Regards,

Boris



Re: [PATCH] drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg()

2023-11-29 Thread Christian König

Am 29.11.23 um 16:22 schrieb Nikita Zhandarovich:

While improbable, there may be a chance of hitting integer
overflow when the result of radeon_get_ib_value() gets shifted
left.

Avoid it by casting one of the operands to larger data type (u64).

Found by Linux Verification Center (linuxtesting.org) with static
analysis tool SVACE.


Well IIRC cb_color_bo_offset is just 32bits anyway, so this doesn't 
change anything.


Regards,
Christian.



Fixes: 1729dd33d20b ("drm/radeon/kms: r600 CS parser fixes")
Signed-off-by: Nikita Zhandarovich 
---
  drivers/gpu/drm/radeon/r600_cs.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 638f861af80f..6cf54a747749 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -1275,7 +1275,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, 
u32 reg, u32 idx)
return -EINVAL;
}
tmp = (reg - CB_COLOR0_BASE) / 4;
-   track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 
8;
+   track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, idx) 
<< 8;
ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0x);
track->cb_color_base_last[tmp] = ib[idx];
track->cb_color_bo[tmp] = reloc->robj;
@@ -1302,7 +1302,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, 
u32 reg, u32 idx)
"0x%04X\n", reg);
return -EINVAL;
}
-   track->htile_offset = radeon_get_ib_value(p, idx) << 8;
+   track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8;
ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0x);
track->htile_bo = reloc->robj;
track->db_dirty = true;




[PATCH 5/5] drm/imagination: Removed unused function to_pvr_vm_gpuva()

2023-11-29 Thread Donald Robson
Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202311242159.hh8mwiam-...@intel.com/
Fixes: 3c96dd170efe ("drm/imagination: Add GEM and VM related code")
Signed-off-by: Donald Robson 
---
 drivers/gpu/drm/imagination/pvr_vm.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/imagination/pvr_vm.c 
b/drivers/gpu/drm/imagination/pvr_vm.c
index 89eb6ee1bbcf..375a03707f4e 100644
--- a/drivers/gpu/drm/imagination/pvr_vm.c
+++ b/drivers/gpu/drm/imagination/pvr_vm.c
@@ -108,12 +108,6 @@ struct pvr_vm_gpuva {
struct drm_gpuva base;
 };
 
-static __always_inline
-struct pvr_vm_gpuva *to_pvr_vm_gpuva(struct drm_gpuva *gpuva)
-{
-   return container_of(gpuva, struct pvr_vm_gpuva, base);
-}
-
 enum pvr_vm_bind_type {
PVR_VM_BIND_TYPE_MAP,
PVR_VM_BIND_TYPE_UNMAP,
-- 
2.25.1



[PATCH 4/5] drm/imagination: pvr_gpuvm_free() now static

2023-11-29 Thread Donald Robson
Reported-by: Arnd Bergmann 
Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202311242159.hh8mwiam-...@intel.com/
Fixes: 3c96dd170efe ("drm/imagination: Add GEM and VM related code")
Signed-off-by: Donald Robson 
---
 drivers/gpu/drm/imagination/pvr_vm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/imagination/pvr_vm.c 
b/drivers/gpu/drm/imagination/pvr_vm.c
index 04f7d0cf4188..89eb6ee1bbcf 100644
--- a/drivers/gpu/drm/imagination/pvr_vm.c
+++ b/drivers/gpu/drm/imagination/pvr_vm.c
@@ -528,7 +528,7 @@ pvr_device_addr_and_size_are_valid(u64 device_addr, u64 
size)
   (device_addr + size <= PVR_PAGE_TABLE_ADDR_SPACE_SIZE);
 }
 
-void pvr_gpuvm_free(struct drm_gpuvm *gpuvm)
+static void pvr_gpuvm_free(struct drm_gpuvm *gpuvm)
 {
 
 }
-- 
2.25.1



  1   2   3   >