Re: [PATCH v2 44/63] mac80211: Use memset_after() to clear tx status

2021-08-18 Thread Johannes Berg
On Tue, 2021-08-17 at 23:05 -0700, Kees Cook wrote:
> 
> @@ -275,12 +275,11 @@ static void carl9170_tx_release(struct kref *ref)
>   if (WARN_ON_ONCE(!ar))
>   return;
>  
> 
> 
> 
> - BUILD_BUG_ON(
> - offsetof(struct ieee80211_tx_info, status.ack_signal) != 20);
> -
> - memset(&txinfo->status.ack_signal, 0,
> -sizeof(struct ieee80211_tx_info) -
> -offsetof(struct ieee80211_tx_info, status.ack_signal));
> + /*
> +  * Should this call ieee80211_tx_info_clear_status() instead of clearing
> +  * manually? txinfo->status.rates do not seem to be used here.
> +  */

Since you insist, I went digging :)

It should not, carl9170_tx_fill_rateinfo() has filled the rate
information before we get to this point.

johannes



Re: [RFC PATCH 2/5] drm/mediatek: dpi: Add dpintf support

2021-08-18 Thread Markus Schneider-Pargmann
Hi,

On Tue, Aug 17, 2021 at 05:50:44PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > dpintf is the displayport interface hardware unit. This unit is similar
> > to dpi and can reuse most of the code.
> > 
> > This patch adds support for mt8195-dpintf to this dpi driver. Main
> > differences are:
> >  - Some features/functional components are not available for dpintf
> >which are now excluded from code execution once is_dpintf is set
> >  - dpintf can and needs to choose between different clockdividers based
> >on the clockspeed. This is done by choosing a different clock parent.
> >  - There are two additional clocks that need to be managed. These are
> >only set for dpintf and will be set to NULL if not supplied. The
> >clk_* calls handle these as normal clocks then.
> >  - Some register contents differ slightly between the two components. To
> >work around this I added register bits/masks with a DPINTF_ prefix
> >and use them where different.
> > 
> > Based on a separate driver for dpintf created by
> > Jason-JH.Lin .
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c  | 282 
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
> >  2 files changed, 247 insertions(+), 47 deletions(-)
> > 
> 
> [snip]
> 
> >  
> > +static void mtk_dpi_set_pixel_clk_parent(struct mtk_dpi *dpi,
> > +unsigned int factor)
> > +{
> > +   struct clk *new_parent;
> > +
> > +   switch (factor) {
> > +   case 16:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D16].clk;
> > +   break;
> > +   case 8:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D8].clk;
> > +   break;
> > +   case 4:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D4].clk;
> > +   break;
> > +   case 2:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D2].clk;
> > +   break;
> > +   default:
> > +   new_parent = NULL;
> > +   }
> > +   if (new_parent)
> > +   clk_set_parent(dpi->pixel_clk, new_parent);
> 
> I prefer that dpi->pixel_clk provide set_rate() interface, and let clock
> driver to control the parent of dpi->pixel_clk.

Good point, will do that, thanks.

Best,
Markus

> 
> Regards,
> CK
> 
> > +}
> > +
> >  static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> > struct drm_display_mode *mode)
> >  {
> > @@ -465,6 +568,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> > drm_display_mode_to_videomode(mode, &vm);
> > pll_rate = vm.pixelclock * factor;
> >  
> > +   mtk_dpi_set_pixel_clk_parent(dpi, factor);
> > +
> > dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
> > pll_rate, vm.pixelclock);
> >  
> 
> 


Re: [RFC PATCH 1/5] dt-bindings: mediatek,dpi: Add mt8195 dpintf

2021-08-18 Thread Markus Schneider-Pargmann
Hi,

On Wed, Aug 18, 2021 at 12:45:46PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > DP_INTF is similar to the actual dpi. They differ in some points
> > regarding registers and what needs to be set but the function blocks
> > itself are similar in design.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  .../display/mediatek/mediatek,dpi.yaml| 48 ---
> >  1 file changed, 42 insertions(+), 6 deletions(-)
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml 
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > index dd2896a40ff0..de4bdacd83ac 100644
> > --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > @@ -4,7 +4,7 @@
> >  $id: 
> > https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnDFMa1qYg$
> >  
> >  $schema: 
> > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnAjuBCxsg$
> >  
> > 
> > -title: mediatek DPI Controller Device Tree Bindings
> > +title: mediatek DPI/DP_INTF Controller Device Tree Bindings
> >  
> >  maintainers:
> >- CK Hu 
> > @@ -13,7 +13,8 @@ maintainers:
> >  description: |
> >The Mediatek DPI function block is a sink of the display subsystem and
> >provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
> > -  output bus.
> > +  output bus. The Mediatek DP_INTF is a similar function block that is
> > +  connected to the (embedded) display port function block.
> >  
> >  properties:
> >compatible:
> > @@ -23,6 +24,7 @@ properties:
> >- mediatek,mt8173-dpi
> >- mediatek,mt8183-dpi
> >- mediatek,mt8192-dpi
> > +  - mediatek,mt8195-dpintf
> 
> I've reviewed the modification in driver, it seems that dpintf is almost
> the same as dpi. Why use the name "dpintf"? I could accept this name
> only it's defined by hardware data sheet.

Yes the data sheet makes a distinction between DPI and DP_INTF. mt8195
has a DPI unit as well. DP_INTF has a slightly different feature set and
also uses slightly different register bits.

Best,
Markus

> 
> Regards,
> CK
> 
> >  
> >reg:
> >  maxItems: 1
> > @@ -37,10 +39,11 @@ properties:
> >- description: DPI PLL
> >  
> >clock-names:
> > -items:
> > -  - const: pixel
> > -  - const: engine
> > -  - const: pll
> > +description:
> > +  For dpi clocks pixel, engine and pll are required. For dpintf pixel, 
> > pll,
> > +  pll_d2, pll_d4, pll_d8, pll_d16, hf_fmm, hf_fdp are required.
> > +minItems: 3
> > +maxItems: 8
> >  
> >pinctrl-0: true
> >pinctrl-1: true
> > @@ -64,6 +67,39 @@ required:
> >- clock-names
> >- port
> >  
> > +allOf:
> > +  - if:
> > +  properties:
> > +compatible:
> > +  contains:
> > +enum:
> > +  - mediatek,mt8195-dpintf
> > +then:
> > +  properties:
> > +clocks:
> > +  minItems: 8
> > +  maxItems: 8
> > +clock-names:
> > +  items:
> > +- const: pixel
> > +- const: pll
> > +- const: pll_d2
> > +- const: pll_d4
> > +- const: pll_d8
> > +- const: pll_d16
> > +- const: hf_fmm
> > +- const: hf_fdp
> > +else:
> > +  properties:
> > +clocks:
> > +  minItems: 3
> > +  maxItems: 3
> > +clock-names:
> > +  items:
> > +- const: pixel
> > +- const: engine
> > +- const: pll
> > +
> >  additionalProperties: false
> >  
> >  examples:
> 


[PATCH v3 0/9] drm, kernel: update locking for DRM

2021-08-18 Thread Desmond Cheong Zhi Xi
Hi,

The patches in this series are largely fixes and prepwork leading up to
the final patch which plugs races with modesetting rights. Most of the
fixes don't have bug reports, so comments would be very appreciated.

The biggest change from the previous version is that we convert
drm_device.master_mutex into master_rwsem, instead of introducing
master_rwsem as a third lock.

Overall, this series makes the following changes:

- Patch 1: Move master_lookup_lock into struct drm_device (enables us to
use it to protect attributes accessed by different drm_files)

- Patch 2: Add a missing master_lookup_lock in drm_master_release

- Patch 3: Fix a potential race in drm_is_current_master_locked

- Patch 4: Fix potential null ptr dereferences in drm_{auth, ioctl}

- Patch 5: Move magic_map,unique{_len} out from master_mutex's
protection into master_lookup_lock's protection (allows us to avoid
read_lock -> write_lock deadlocks)

- Patch 6: Convert master_mutex into rwsem (avoids creating a new lock)

- Patch 7: Update global mutex locking in the ioctl handler (avoids
deadlock when grabbing read lock on master_rwsem in drm_ioctl_kernel)

- Patch 8: Export task_work_add (enables us to write drm_master_flush)

- Patch 9: Plug races with drm modesetting rights

v2 -> v3:
- Unexport drm_master_flush, as suggested by Daniel Vetter.
- Merge master_mutex and master_rwsem, as suggested by Daniel Vetter.
- Export task_work_add, reported by kernel test robot.
- Make master_flush static, reported by kernel test robot.
- Move master_lookup_lock into struct drm_device.
- Add a missing lock on master_lookup_lock in drm_master_release.
- Fix a potential race in drm_is_current_master_locked.
- Fix potential null ptr dereferences in drm_{auth, ioctl}.
- Protect magic_map,unique{_len} with  master_lookup_lock.
- Convert master_mutex into a rwsem.
- Update global mutex locking in the ioctl handler.

v1 -> v2 (suggested by Daniel Vetter):
- Address an additional race when drm_open runs.
- Switch from SRCU to rwsem to synchronise readers and writers.
- Implement drm_master_flush with task_work so that flushes can be
queued to run before returning to userspace without creating a new
DRM_MASTER_FLUSH ioctl flag.

Best wishes,
Desmond

Desmond Cheong Zhi Xi (9):
  drm: move master_lookup_lock into drm_device
  drm: hold master_lookup_lock when releasing a drm_file's master
  drm: check for null master in drm_is_current_master_locked
  drm: fix potential null ptr dereferences in drm_{auth,ioctl}
  drm: protect magic_map,unique{_len} with master_lookup_lock
  drm: convert drm_device.master_mutex into a rwsem
  drm: update global mutex lock in the ioctl handler
  kernel: export task_work_add
  drm: avoid races with modesetting rights

 drivers/gpu/drm/drm_auth.c | 108 -
 drivers/gpu/drm/drm_debugfs.c  |   4 +-
 drivers/gpu/drm/drm_drv.c  |   4 +-
 drivers/gpu/drm/drm_file.c |   1 -
 drivers/gpu/drm/drm_internal.h |   1 +
 drivers/gpu/drm/drm_ioctl.c|  39 +++-
 drivers/gpu/drm/drm_lease.c|   1 +
 include/drm/drm_auth.h |   6 +-
 include/drm/drm_device.h   |  27 +++--
 include/drm/drm_file.h |  20 +++---
 kernel/task_work.c |   1 +
 11 files changed, 145 insertions(+), 67 deletions(-)

-- 
2.25.1



[PATCH v3 1/9] drm: move master_lookup_lock into drm_device

2021-08-18 Thread Desmond Cheong Zhi Xi
The master_lookup_lock spinlock can be useful as an inner lock for
other attributes that are currently protected by
drm_device.master_mutex.

However, since the spinlock belongs to struct drm_file, its use case
is limited to serializing accesses by a single drm_file. Moving this
lock into struct drm_device allows us to use it for structures that
are accessed by multiple drm_files, such as drm_master.magic_map.

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_auth.c | 18 +-
 drivers/gpu/drm/drm_drv.c  |  1 +
 drivers/gpu/drm/drm_file.c |  1 -
 include/drm/drm_device.h   |  3 +++
 include/drm/drm_file.h | 10 --
 5 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 60a6b21474b1..8efb58aa7d95 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -63,7 +63,7 @@
 
 static bool drm_is_current_master_locked(struct drm_file *fpriv)
 {
-   lockdep_assert_once(lockdep_is_held(&fpriv->master_lookup_lock) ||
+   
lockdep_assert_once(lockdep_is_held(&fpriv->minor->dev->master_lookup_lock) ||
lockdep_is_held(&fpriv->minor->dev->master_mutex));
 
return fpriv->is_master && drm_lease_owner(fpriv->master) == 
fpriv->minor->dev->master;
@@ -83,9 +83,9 @@ bool drm_is_current_master(struct drm_file *fpriv)
 {
bool ret;
 
-   spin_lock(&fpriv->master_lookup_lock);
+   spin_lock(&fpriv->minor->dev->master_lookup_lock);
ret = drm_is_current_master_locked(fpriv);
-   spin_unlock(&fpriv->master_lookup_lock);
+   spin_unlock(&fpriv->minor->dev->master_lookup_lock);
 
return ret;
 }
@@ -174,9 +174,9 @@ static int drm_new_set_master(struct drm_device *dev, 
struct drm_file *fpriv)
new_master = drm_master_create(dev);
if (!new_master)
return -ENOMEM;
-   spin_lock(&fpriv->master_lookup_lock);
+   spin_lock(&dev->master_lookup_lock);
fpriv->master = new_master;
-   spin_unlock(&fpriv->master_lookup_lock);
+   spin_unlock(&dev->master_lookup_lock);
 
fpriv->is_master = 1;
fpriv->authenticated = 1;
@@ -338,9 +338,9 @@ int drm_master_open(struct drm_file *file_priv)
if (!dev->master) {
ret = drm_new_set_master(dev, file_priv);
} else {
-   spin_lock(&file_priv->master_lookup_lock);
+   spin_lock(&dev->master_lookup_lock);
file_priv->master = drm_master_get(dev->master);
-   spin_unlock(&file_priv->master_lookup_lock);
+   spin_unlock(&dev->master_lookup_lock);
}
mutex_unlock(&dev->master_mutex);
 
@@ -405,13 +405,13 @@ struct drm_master *drm_file_get_master(struct drm_file 
*file_priv)
 {
struct drm_master *master = NULL;
 
-   spin_lock(&file_priv->master_lookup_lock);
+   spin_lock(&file_priv->minor->dev->master_lookup_lock);
if (!file_priv->master)
goto unlock;
master = drm_master_get(file_priv->master);
 
 unlock:
-   spin_unlock(&file_priv->master_lookup_lock);
+   spin_unlock(&file_priv->minor->dev->master_lookup_lock);
return master;
 }
 EXPORT_SYMBOL(drm_file_get_master);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 7a5097467ba5..218c16f11c80 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -612,6 +612,7 @@ static int drm_dev_init(struct drm_device *dev,
mutex_init(&dev->filelist_mutex);
mutex_init(&dev->clientlist_mutex);
mutex_init(&dev->master_mutex);
+   spin_lock_init(&dev->master_lookup_lock);
 
ret = drmm_add_action(dev, drm_dev_init_release, NULL);
if (ret)
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index ed25168619fc..b8679bbaea69 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -176,7 +176,6 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
init_waitqueue_head(&file->event_wait);
file->event_space = 4096; /* set aside 4k for event buffer */
 
-   spin_lock_init(&file->master_lookup_lock);
mutex_init(&file->event_read_lock);
 
if (drm_core_check_feature(dev, DRIVER_GEM))
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 604b1d1b2d72..506eb2784819 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -152,6 +152,9 @@ struct drm_device {
 */
struct mutex master_mutex;
 
+   /** @master_lookup_lock: Serializes &drm_file.master. */
+   spinlock_t master_lookup_lock;
+
/**
 * @open_count:
 *
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index a3acb7ac3550..0536e9612a46 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -227,15 +227,16 @@ struct drm_file {
 * @master:
 *
 * Master this node is currently associated with. Protected by s

[PATCH v3 2/9] drm: hold master_lookup_lock when releasing a drm_file's master

2021-08-18 Thread Desmond Cheong Zhi Xi
When drm_file.master changes value, the corresponding
drm_device.master_lookup_lock should be held.

In drm_master_release, a call to drm_master_put sets the
file_priv->master to NULL, so we protect this section with
drm_device.master_lookup_lock.

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_auth.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 8efb58aa7d95..8c0e0dba1611 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -373,8 +373,11 @@ void drm_master_release(struct drm_file *file_priv)
}
 
/* drop the master reference held by the file priv */
-   if (file_priv->master)
+   if (file_priv->master) {
+   spin_lock(&dev->master_lookup_lock);
drm_master_put(&file_priv->master);
+   spin_unlock(&dev->master_lookup_lock);
+   }
mutex_unlock(&dev->master_mutex);
 }
 
-- 
2.25.1



[PATCH v3 4/9] drm: fix potential null ptr dereferences in drm_{auth, ioctl}

2021-08-18 Thread Desmond Cheong Zhi Xi
There are three areas where we dereference struct drm_master without
checking if the pointer is non-NULL.

1. drm_getmagic is called from the ioctl_handler. Since
DRM_IOCTL_GET_MAGIC has no ioctl flags, drm_getmagic is run without
any check that drm_file.master has been set.

2. Similarly, drm_getunique is called from the ioctl_handler, but
DRM_IOCTL_GET_UNIQUE has no ioctl flags. So there is no guarantee that
drm_file.master has been set.

3. drm_master_release can also be called without having a
drm_file.master set. Here is one error path:
  drm_open():
drm_open_helper():
  drm_master_open():
drm_new_set_master(); <--- returns -ENOMEM,
   drm_file.master not set
  drm_file_free():
drm_master_release(); <--- NULL ptr dereference
   (file_priv->master->magic_map)

Fix these by checking if the master pointers are NULL before use.

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_auth.c  | 16 ++--
 drivers/gpu/drm/drm_ioctl.c |  5 +
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index f9267b21556e..b7230604496b 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -95,11 +95,18 @@ EXPORT_SYMBOL(drm_is_current_master);
 int drm_getmagic(struct drm_device *dev, void *data, struct drm_file 
*file_priv)
 {
struct drm_auth *auth = data;
+   struct drm_master *master;
int ret = 0;
 
mutex_lock(&dev->master_mutex);
+   master = file_priv->master;
+   if (!master) {
+   mutex_unlock(&dev->master_mutex);
+   return -EINVAL;
+   }
+
if (!file_priv->magic) {
-   ret = idr_alloc(&file_priv->master->magic_map, file_priv,
+   ret = idr_alloc(&master->magic_map, file_priv,
1, 0, GFP_KERNEL);
if (ret >= 0)
file_priv->magic = ret;
@@ -355,8 +362,12 @@ void drm_master_release(struct drm_file *file_priv)
 
mutex_lock(&dev->master_mutex);
master = file_priv->master;
+
+   if (!master)
+   goto unlock;
+
if (file_priv->magic)
-   idr_remove(&file_priv->master->magic_map, file_priv->magic);
+   idr_remove(&master->magic_map, file_priv->magic);
 
if (!drm_is_current_master_locked(file_priv))
goto out;
@@ -379,6 +390,7 @@ void drm_master_release(struct drm_file *file_priv)
drm_master_put(&file_priv->master);
spin_unlock(&dev->master_lookup_lock);
}
+unlock:
mutex_unlock(&dev->master_mutex);
 }
 
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 26f3a9ede8fe..4d029d3061d9 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -121,6 +121,11 @@ int drm_getunique(struct drm_device *dev, void *data,
 
mutex_lock(&dev->master_mutex);
master = file_priv->master;
+   if (!master) {
+   mutex_unlock(&dev->master_mutex);
+   return -EINVAL;
+   }
+
if (u->unique_len >= master->unique_len) {
if (copy_to_user(u->unique, master->unique, 
master->unique_len)) {
mutex_unlock(&dev->master_mutex);
-- 
2.25.1



[PATCH v3 3/9] drm: check for null master in drm_is_current_master_locked

2021-08-18 Thread Desmond Cheong Zhi Xi
There is a window after calling drm_master_release, and before a file
is freed, where drm_file can have is_master set to true, but both the
drm_file and drm_device have no master.

This could result in wrongly approving permissions in
drm_is_current_master_locked. Add a check that fpriv->master is
non-NULl to guard against this scenario.

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_auth.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 8c0e0dba1611..f9267b21556e 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -66,7 +66,8 @@ static bool drm_is_current_master_locked(struct drm_file 
*fpriv)

lockdep_assert_once(lockdep_is_held(&fpriv->minor->dev->master_lookup_lock) ||
lockdep_is_held(&fpriv->minor->dev->master_mutex));
 
-   return fpriv->is_master && drm_lease_owner(fpriv->master) == 
fpriv->minor->dev->master;
+   return (fpriv->is_master && fpriv->master &&
+   drm_lease_owner(fpriv->master) == fpriv->minor->dev->master);
 }
 
 /**
-- 
2.25.1



[PATCH v3 5/9] drm: protect magic_map, unique{_len} with master_lookup_lock

2021-08-18 Thread Desmond Cheong Zhi Xi
Currently, drm_device.master_mutex is used to serialize writes to the
drm_master.magic_map idr and to protect drm_master.unique{_len}.

In preparation for converting drm_device.master_mutex into an outer
rwsem that might be read locked before entering some of these
functions, we can instead serialize access to drm_master.magic_map and
drm_master.unique{_len} using drm_device.master_lookup_lock which is
an inner lock.

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_auth.c  | 12 +++-
 drivers/gpu/drm/drm_ioctl.c | 10 ++
 include/drm/drm_auth.h  |  6 +++---
 include/drm/drm_device.h|  7 ++-
 4 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index b7230604496b..0acb444fbbac 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -98,10 +98,10 @@ int drm_getmagic(struct drm_device *dev, void *data, struct 
drm_file *file_priv)
struct drm_master *master;
int ret = 0;
 
-   mutex_lock(&dev->master_mutex);
+   spin_lock(&dev->master_lookup_lock);
master = file_priv->master;
if (!master) {
-   mutex_unlock(&dev->master_mutex);
+   spin_unlock(&dev->master_lookup_lock);
return -EINVAL;
}
 
@@ -112,7 +112,7 @@ int drm_getmagic(struct drm_device *dev, void *data, struct 
drm_file *file_priv)
file_priv->magic = ret;
}
auth->magic = file_priv->magic;
-   mutex_unlock(&dev->master_mutex);
+   spin_unlock(&dev->master_lookup_lock);
 
DRM_DEBUG("%u\n", auth->magic);
 
@@ -127,13 +127,13 @@ int drm_authmagic(struct drm_device *dev, void *data,
 
DRM_DEBUG("%u\n", auth->magic);
 
-   mutex_lock(&dev->master_mutex);
+   spin_lock(&dev->master_lookup_lock);
file = idr_find(&file_priv->master->magic_map, auth->magic);
if (file) {
file->authenticated = 1;
idr_replace(&file_priv->master->magic_map, NULL, auth->magic);
}
-   mutex_unlock(&dev->master_mutex);
+   spin_unlock(&dev->master_lookup_lock);
 
return file ? 0 : -EINVAL;
 }
@@ -366,8 +366,10 @@ void drm_master_release(struct drm_file *file_priv)
if (!master)
goto unlock;
 
+   spin_lock(&dev->master_lookup_lock);
if (file_priv->magic)
idr_remove(&master->magic_map, file_priv->magic);
+   spin_unlock(&dev->master_lookup_lock);
 
if (!drm_is_current_master_locked(file_priv))
goto out;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 4d029d3061d9..e5c3845b6e62 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -119,21 +119,21 @@ int drm_getunique(struct drm_device *dev, void *data,
struct drm_unique *u = data;
struct drm_master *master;
 
-   mutex_lock(&dev->master_mutex);
+   spin_lock(&dev->master_lookup_lock);
master = file_priv->master;
if (!master) {
-   mutex_unlock(&dev->master_mutex);
+   spin_unlock(&dev->master_lookup_lock);
return -EINVAL;
}
 
if (u->unique_len >= master->unique_len) {
if (copy_to_user(u->unique, master->unique, 
master->unique_len)) {
-   mutex_unlock(&dev->master_mutex);
+   spin_unlock(&dev->master_lookup_lock);
return -EFAULT;
}
}
u->unique_len = master->unique_len;
-   mutex_unlock(&dev->master_mutex);
+   spin_unlock(&dev->master_lookup_lock);
 
return 0;
 }
@@ -405,7 +405,9 @@ static int drm_setversion(struct drm_device *dev, void 
*data, struct drm_file *f
 * Version 1.1 includes tying of DRM to specific device
 * Version 1.4 has proper PCI domain support
 */
+   spin_lock(&dev->master_lookup_lock);
retcode = drm_set_busid(dev, file_priv);
+   spin_unlock(&dev->master_lookup_lock);
if (retcode)
goto done;
}
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index ba248ca8866f..f5be73153798 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -67,17 +67,17 @@ struct drm_master {
struct drm_device *dev;
/**
 * @unique: Unique identifier: e.g. busid. Protected by
-* &drm_device.master_mutex.
+* &drm_device.master_lookup_lock.
 */
char *unique;
/**
 * @unique_len: Length of unique field. Protected by
-* &drm_device.master_mutex.
+* &drm_device.master_lookup_lock.
 */
int unique_len;
/**
 * @magic_map: Map of used authentication tokens. Protected by
-* &drm_device.master_mutex.

[PATCH v3 6/9] drm: convert drm_device.master_mutex into a rwsem

2021-08-18 Thread Desmond Cheong Zhi Xi
drm_device.master_mutex currently protects the following:
- drm_device.master
- drm_file.master
- drm_file.was_master
- drm_file.is_master

These attributes determine modesetting permissions for drm devices,
and there is a clear separation between functions that read or change
the permissions. Hence, convert master_mutex into a rwsem to enable
concurrent readers.

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_auth.c| 27 ++-
 drivers/gpu/drm/drm_debugfs.c |  4 ++--
 drivers/gpu/drm/drm_drv.c |  3 +--
 drivers/gpu/drm/drm_ioctl.c   |  4 ++--
 include/drm/drm_device.h  | 11 +++
 include/drm/drm_file.h| 12 ++--
 6 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 0acb444fbbac..b65681ff42fc 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -64,7 +64,7 @@
 static bool drm_is_current_master_locked(struct drm_file *fpriv)
 {

lockdep_assert_once(lockdep_is_held(&fpriv->minor->dev->master_lookup_lock) ||
-   lockdep_is_held(&fpriv->minor->dev->master_mutex));
+   lockdep_is_held(&fpriv->minor->dev->master_rwsem));
 
return (fpriv->is_master && fpriv->master &&
drm_lease_owner(fpriv->master) == fpriv->minor->dev->master);
@@ -175,7 +175,7 @@ static int drm_new_set_master(struct drm_device *dev, 
struct drm_file *fpriv)
struct drm_master *old_master;
struct drm_master *new_master;
 
-   lockdep_assert_held_once(&dev->master_mutex);
+   lockdep_assert_held_once(&dev->master_rwsem);
 
WARN_ON(fpriv->is_master);
old_master = fpriv->master;
@@ -257,7 +257,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 {
int ret;
 
-   mutex_lock(&dev->master_mutex);
+   down_write(&dev->master_rwsem);
 
ret = drm_master_check_perm(dev, file_priv);
if (ret)
@@ -289,7 +289,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 
drm_set_master(dev, file_priv, false);
 out_unlock:
-   mutex_unlock(&dev->master_mutex);
+   up_write(&dev->master_rwsem);
return ret;
 }
 
@@ -306,7 +306,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 {
int ret;
 
-   mutex_lock(&dev->master_mutex);
+   down_write(&dev->master_rwsem);
 
ret = drm_master_check_perm(dev, file_priv);
if (ret)
@@ -329,8 +329,9 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
}
 
drm_drop_master(dev, file_priv);
+
 out_unlock:
-   mutex_unlock(&dev->master_mutex);
+   up_write(&dev->master_rwsem);
return ret;
 }
 
@@ -342,7 +343,7 @@ int drm_master_open(struct drm_file *file_priv)
/* if there is no current master make this fd it, but do not create
 * any master object for render clients
 */
-   mutex_lock(&dev->master_mutex);
+   down_write(&dev->master_rwsem);
if (!dev->master) {
ret = drm_new_set_master(dev, file_priv);
} else {
@@ -350,7 +351,7 @@ int drm_master_open(struct drm_file *file_priv)
file_priv->master = drm_master_get(dev->master);
spin_unlock(&dev->master_lookup_lock);
}
-   mutex_unlock(&dev->master_mutex);
+   up_write(&dev->master_rwsem);
 
return ret;
 }
@@ -360,7 +361,7 @@ void drm_master_release(struct drm_file *file_priv)
struct drm_device *dev = file_priv->minor->dev;
struct drm_master *master;
 
-   mutex_lock(&dev->master_mutex);
+   down_write(&dev->master_rwsem);
master = file_priv->master;
 
if (!master)
@@ -393,7 +394,7 @@ void drm_master_release(struct drm_file *file_priv)
spin_unlock(&dev->master_lookup_lock);
}
 unlock:
-   mutex_unlock(&dev->master_mutex);
+   up_write(&dev->master_rwsem);
 }
 
 /**
@@ -468,9 +469,9 @@ EXPORT_SYMBOL(drm_master_put);
 /* Used by drm_client and drm_fb_helper */
 bool drm_master_internal_acquire(struct drm_device *dev)
 {
-   mutex_lock(&dev->master_mutex);
+   down_read(&dev->master_rwsem);
if (dev->master) {
-   mutex_unlock(&dev->master_mutex);
+   up_read(&dev->master_rwsem);
return false;
}
 
@@ -481,6 +482,6 @@ EXPORT_SYMBOL(drm_master_internal_acquire);
 /* Used by drm_client and drm_fb_helper */
 void drm_master_internal_release(struct drm_device *dev)
 {
-   mutex_unlock(&dev->master_mutex);
+   up_read(&dev->master_rwsem);
 }
 EXPORT_SYMBOL(drm_master_internal_release);
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b0a826489488..b34c9c263188 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -55,7 +55,7 @@ static int drm_name_info(struct seq_file *m, void *data)
struct drm_device *dev = minor->dev;
s

[PATCH v3 7/9] drm: update global mutex lock in the ioctl handler

2021-08-18 Thread Desmond Cheong Zhi Xi
In a future patch, a read lock on drm_device.master_rwsem is
held in the ioctl handler before the check for ioctl
permissions. However, this produces the following lockdep splat:

==
WARNING: possible circular locking dependency detected
5.14.0-rc6-CI-Patchwork_20831+ #1 Tainted: G U
--
kms_lease/1752 is trying to acquire lock:
827bad88 (drm_global_mutex){+.+.}-{3:3}, at: drm_open+0x64/0x280

but task is already holding lock:
88812e350108 (&dev->master_rwsem){}-{3:3}, at:
drm_ioctl_kernel+0xfb/0x1a0

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #2 (&dev->master_rwsem){}-{3:3}:
   lock_acquire+0xd3/0x310
   down_read+0x3b/0x140
   drm_master_internal_acquire+0x1d/0x60
   drm_client_modeset_commit+0x10/0x40
   __drm_fb_helper_restore_fbdev_mode_unlocked+0x88/0xb0
   drm_fb_helper_set_par+0x34/0x40
   intel_fbdev_set_par+0x11/0x40 [i915]
   fbcon_init+0x270/0x4f0
   visual_init+0xc6/0x130
   do_bind_con_driver+0x1de/0x2c0
   do_take_over_console+0x10e/0x180
   do_fbcon_takeover+0x53/0xb0
   register_framebuffer+0x22d/0x310
   __drm_fb_helper_initial_config_and_unlock+0x36c/0x540
   intel_fbdev_initial_config+0xf/0x20 [i915]
   async_run_entry_fn+0x28/0x130
   process_one_work+0x26d/0x5c0
   worker_thread+0x37/0x390
   kthread+0x13b/0x170
   ret_from_fork+0x1f/0x30

-> #1 (&helper->lock){+.+.}-{3:3}:
   lock_acquire+0xd3/0x310
   __mutex_lock+0xa8/0x930
   __drm_fb_helper_restore_fbdev_mode_unlocked+0x44/0xb0
   intel_fbdev_restore_mode+0x2b/0x50 [i915]
   drm_lastclose+0x27/0x50
   drm_release_noglobal+0x42/0x60
   __fput+0x9e/0x250
   task_work_run+0x6b/0xb0
   exit_to_user_mode_prepare+0x1c5/0x1d0
   syscall_exit_to_user_mode+0x19/0x50
   do_syscall_64+0x46/0xb0
   entry_SYSCALL_64_after_hwframe+0x44/0xae

-> #0 (drm_global_mutex){+.+.}-{3:3}:
   validate_chain+0xb39/0x1e70
   __lock_acquire+0x5a1/0xb70
   lock_acquire+0xd3/0x310
   __mutex_lock+0xa8/0x930
   drm_open+0x64/0x280
   drm_stub_open+0x9f/0x100
   chrdev_open+0x9f/0x1d0
   do_dentry_open+0x14a/0x3a0
   dentry_open+0x53/0x70
   drm_mode_create_lease_ioctl+0x3cb/0x970
   drm_ioctl_kernel+0xc9/0x1a0
   drm_ioctl+0x201/0x3d0
   __x64_sys_ioctl+0x6a/0xa0
   do_syscall_64+0x37/0xb0
   entry_SYSCALL_64_after_hwframe+0x44/0xae

other info that might help us debug this:
Chain exists of:
  drm_global_mutex --> &helper->lock --> &dev->master_rwsem
 Possible unsafe locking scenario:
   CPU0CPU1
   
  lock(&dev->master_rwsem);
   lock(&helper->lock);
   lock(&dev->master_rwsem);
  lock(drm_global_mutex);

 *** DEADLOCK ***

The lock hierarchy inversion happens because we grab the
drm_global_mutex while already holding on to master_rwsem. To avoid
this, we do some prep work to grab the drm_global_mutex before
checking for ioctl permissions.

At the same time, we update the check for the global mutex to use the
drm_dev_needs_global_mutex helper function.

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_ioctl.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 880fc565d599..2cb57378a787 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -779,19 +779,19 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t 
*func, void *kdata,
if (drm_dev_is_unplugged(dev))
return -ENODEV;
 
+   /* Enforce sane locking for modern driver ioctls. */
+   if (unlikely(drm_dev_needs_global_mutex(dev)) && !(flags & 
DRM_UNLOCKED))
+   mutex_lock(&drm_global_mutex);
+
retcode = drm_ioctl_permit(flags, file_priv);
if (unlikely(retcode))
-   return retcode;
+   goto out;
 
-   /* Enforce sane locking for modern driver ioctls. */
-   if (likely(!drm_core_check_feature(dev, DRIVER_LEGACY)) ||
-   (flags & DRM_UNLOCKED))
-   retcode = func(dev, kdata, file_priv);
-   else {
-   mutex_lock(&drm_global_mutex);
-   retcode = func(dev, kdata, file_priv);
+   retcode = func(dev, kdata, file_priv);
+
+out:
+   if (unlikely(drm_dev_needs_global_mutex(dev)) && !(flags & 
DRM_UNLOCKED))
mutex_unlock(&drm_global_mutex);
-   }
return retcode;
 }
 EXPORT_SYMBOL(drm_ioctl_kernel);
-- 
2.25.1



[PATCH v3 8/9] kernel: export task_work_add

2021-08-18 Thread Desmond Cheong Zhi Xi
The task_work_add function is needed to prevent userspace races with
DRM modesetting rights.

Some DRM ioctls can change modesetting permissions while other
concurrent users are performing modesetting. To prevent races with
userspace, such functions should flush readers of old permissions
before returning to user mode. As the function that changes
permissions might itself be a reader of the old permissions, we intend
to schedule this flush using task_work_add.

However, when DRM is compiled as a loadable kernel module without
exporting task_work_add, we get the following compilation error:

ERROR: modpost: "task_work_add" [drivers/gpu/drm/drm.ko] undefined!

Reported-by: kernel test robot 
Signed-off-by: Desmond Cheong Zhi Xi 
---
 kernel/task_work.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/task_work.c b/kernel/task_work.c
index 1698fbe6f0e1..9404af2b 100644
--- a/kernel/task_work.c
+++ b/kernel/task_work.c
@@ -60,6 +60,7 @@ int task_work_add(struct task_struct *task, struct 
callback_head *work,
 
return 0;
 }
+EXPORT_SYMBOL(task_work_add);
 
 /**
  * task_work_cancel_match - cancel a pending work added by task_work_add()
-- 
2.25.1



[PATCH v3 9/9] drm: avoid races with modesetting rights

2021-08-18 Thread Desmond Cheong Zhi Xi
In drm_client_modeset.c and drm_fb_helper.c,
drm_master_internal_{acquire,release} are used to avoid races with DRM
userspace. These functions hold onto drm_device.master_rwsem while
committing, and bail if there's already a master.

However, there are other places where modesetting rights can race. A
time-of-check-to-time-of-use error can occur if an ioctl that changes
the modeset has its rights revoked after it validates its permissions,
but before it completes.

There are four places where modesetting permissions can change:

- DROP_MASTER ioctl removes rights for a master and its leases

- REVOKE_LEASE ioctl revokes rights for a specific lease

- SET_MASTER ioctl sets the device master if the master role hasn't
been acquired yet

- drm_open which can create a new master for a device if one does not
currently exist

These races can be avoided using drm_device.master_rwsem: users that
perform modesetting should hold a read lock on the new
drm_device.master_rwsem, and users that change these permissions
should either hold a write lock, or should flush readers before
returning to userspace.

Reported-by: Daniel Vetter 
Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_auth.c | 29 +
 drivers/gpu/drm/drm_internal.h |  1 +
 drivers/gpu/drm/drm_ioctl.c|  8 ++--
 drivers/gpu/drm/drm_lease.c|  1 +
 include/drm/drm_device.h   | 10 +-
 5 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index b65681ff42fc..84d00275ff8a 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -29,6 +29,7 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
@@ -127,6 +128,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
 
DRM_DEBUG("%u\n", auth->magic);
 
+   lockdep_assert_held_once(&dev->master_rwsem);
spin_lock(&dev->master_lookup_lock);
file = idr_find(&file_priv->master->magic_map, auth->magic);
if (file) {
@@ -485,3 +487,30 @@ void drm_master_internal_release(struct drm_device *dev)
up_read(&dev->master_rwsem);
 }
 EXPORT_SYMBOL(drm_master_internal_release);
+
+/* After flushing, all readers that might have seen old master/lease
+ * permissions are guaranteed to have completed.
+ */
+static void master_flush(struct callback_head *cb)
+{
+   struct drm_device *dev = container_of(cb, struct drm_device,
+ master_flush_work);
+
+   down_write(&dev->master_rwsem);
+   up_write(&dev->master_rwsem);
+}
+
+/* Queues up work to flush all readers of master/lease permissions. This work
+ * is run before this task returns to user mode. Calling this function when a
+ * task changes modesetting rights ensures that other processes that perform
+ * modesetting do not race with userspace.
+ */
+void drm_master_flush(struct drm_device *dev)
+{
+   init_task_work(&dev->master_flush_work, master_flush);
+   task_work_add(current, &dev->master_flush_work, TWA_RESUME);
+   /* If task_work_add fails, then the task is exiting. In this case, it
+* doesn't matter if master_flush is run, so we don't need an
+* alternative mechanism for flushing.
+*/
+}
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 17f3548c8ed2..b1cd39338756 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -144,6 +144,7 @@ int drm_master_open(struct drm_file *file_priv);
 void drm_master_release(struct drm_file *file_priv);
 bool drm_master_internal_acquire(struct drm_device *dev);
 void drm_master_internal_release(struct drm_device *dev);
+void drm_master_flush(struct drm_device *dev);
 
 /* drm_sysfs.c */
 extern struct class *drm_class;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 2cb57378a787..7f523e1c5650 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -390,7 +390,7 @@ static int drm_setversion(struct drm_device *dev, void 
*data, struct drm_file *f
struct drm_set_version *sv = data;
int if_version, retcode = 0;
 
-   down_read(&dev->master_rwsem);
+   lockdep_assert_held_once(&dev->master_rwsem);
if (sv->drm_di_major != -1) {
if (sv->drm_di_major != DRM_IF_MAJOR ||
sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
@@ -427,7 +427,6 @@ static int drm_setversion(struct drm_device *dev, void 
*data, struct drm_file *f
sv->drm_di_minor = DRM_IF_MINOR;
sv->drm_dd_major = dev->driver->major;
sv->drm_dd_minor = dev->driver->minor;
-   up_read(&dev->master_rwsem);
 
return retcode;
 }
@@ -783,6 +782,9 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, 
void *kdata,
if (unlikely(drm_dev_needs_global_mutex(dev)) && !(flags & 
DRM_UNLOCKED))
mutex_lock(&drm_global_mutex);
 
+   if (unlikely(flags & DRM_MASTER))
+

Re: [PATCH] drm/vc4: hdmi: make vc4_hdmi_codec_pdata static

2021-08-18 Thread Maxime Ripard
On Fri, Jul 30, 2021 at 06:26:34PM +0800, Jiapeng Chong wrote:
> This symbol is not used outside of vc4_hdmi.c, so marks it static.
> 
> Fix the following sparse warning:
> 
> drivers/gpu/drm/vc4/vc4_hdmi.c:1479:25: warning: symbol
> 'vc4_hdmi_codec_pdata' was not declared. Should it be static?
> 
> Reported-by: Abaci Robot 
> Signed-off-by: Jiapeng Chong 

Applied, thanks

Maxime


signature.asc
Description: PGP signature


Re: [RFC] Make use of non-dynamic dmabuf in RDMA

2021-08-18 Thread Christian König

Am 18.08.21 um 09:43 schrieb Gal Pressman:

Hey all,

Currently, the RDMA subsystem can only work with dynamic dmabuf
attachments, which requires the RDMA device to support on-demand-paging
(ODP) which is not common on most devices (only supported by mlx5).

While the dynamic requirement makes sense for certain GPUs, some devices
(such as habanalabs) have device memory that is always "pinned" and do
not need/use the move_notify operation.

The motivation of this RFC is to use habanalabs as the dmabuf exporter,
and EFA as the importer to allow for peer2peer access through libibverbs.

This draft patch changes the dmabuf driver to differentiate between
static/dynamic attachments by looking at the move_notify op instead of
the importer_ops struct, and allowing the peer2peer flag to be enabled
in case of a static exporter.


Well NAK to the general approach, this can be solved much easier.

If you can't support dynamic moves while using the buffer then just pin 
all buffers during import/export.


This avoids the move notification and the framework/exporter can still 
correctly account for pinned buffers.


But please note that at least amdgpu never uses P2P support for pinned 
buffers since we want to avoid that unmoveable buffers clutter video 
memory and create conflicts with V4L and scanout.


If you don't have such concerns in habanalabs then you can implement the 
pinning there while keeping P2P still enabled.


Regards,
Christian.



Thanks

Signed-off-by: Gal Pressman 
---
  drivers/dma-buf/dma-buf.c | 5 +++--
  drivers/infiniband/core/umem_dmabuf.c | 2 +-
  include/linux/dma-buf.h   | 2 +-
  3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 511fe0d217a0..e3faad8f492c 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -727,7 +727,8 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct 
device *dev,
if (WARN_ON(!dmabuf || !dev))
return ERR_PTR(-EINVAL);
  
-	if (WARN_ON(importer_ops && !importer_ops->move_notify))

+   if (WARN_ON(importer_ops && !importer_ops->move_notify &&
+   dma_buf_is_dynamic(attach->dmabuf)))
return ERR_PTR(-EINVAL);
  
  	attach = kzalloc(sizeof(*attach), GFP_KERNEL);

@@ -1048,7 +1049,7 @@ void dma_buf_move_notify(struct dma_buf *dmabuf)
dma_resv_assert_held(dmabuf->resv);
  
  	list_for_each_entry(attach, &dmabuf->attachments, node)

-   if (attach->importer_ops)
+   if (attach->importer_ops && attach->importer_ops->move_notify)
attach->importer_ops->move_notify(attach);
  }
  EXPORT_SYMBOL_GPL(dma_buf_move_notify);
diff --git a/drivers/infiniband/core/umem_dmabuf.c 
b/drivers/infiniband/core/umem_dmabuf.c
index c6e875619fac..c502ae828bd3 100644
--- a/drivers/infiniband/core/umem_dmabuf.c
+++ b/drivers/infiniband/core/umem_dmabuf.c
@@ -118,7 +118,7 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device 
*device,
if (check_add_overflow(offset, (unsigned long)size, &end))
return ret;
  
-	if (unlikely(!ops || !ops->move_notify))

+   if (unlikely(!ops))
return ret;
  
  	dmabuf = dma_buf_get(fd);

diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index efdc56b9d95f..4b2e99012cb1 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -473,7 +473,7 @@ static inline bool dma_buf_is_dynamic(struct dma_buf 
*dmabuf)
  static inline bool
  dma_buf_attachment_is_dynamic(struct dma_buf_attachment *attach)
  {
-   return !!attach->importer_ops;
+   return !!attach->importer_ops->move_notify;
  }
  
  struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,




Re: [PATCH v2 44/63] mac80211: Use memset_after() to clear tx status

2021-08-18 Thread Johannes Berg
On Wed, 2021-08-18 at 09:08 +0200, Johannes Berg wrote:
> On Tue, 2021-08-17 at 23:05 -0700, Kees Cook wrote:
> > 
> > @@ -275,12 +275,11 @@ static void carl9170_tx_release(struct kref *ref)
> >     if (WARN_ON_ONCE(!ar))
> >     return;
> >  
> > 
> > 
> > 
> > -   BUILD_BUG_ON(
> > -   offsetof(struct ieee80211_tx_info, status.ack_signal) != 20);
> > -
> > -   memset(&txinfo->status.ack_signal, 0,
> > -  sizeof(struct ieee80211_tx_info) -
> > -  offsetof(struct ieee80211_tx_info, status.ack_signal));
> > +   /*
> > +* Should this call ieee80211_tx_info_clear_status() instead of clearing
> > +* manually? txinfo->status.rates do not seem to be used here.
> > +*/
> 
> Since you insist, I went digging :)
> 
> It should not, carl9170_tx_fill_rateinfo() has filled the rate
> information before we get to this point.

Otherwise, looks fine, FWIW.

Are you going to apply all of these together somewhere? I (we) can't,
since memset_after() doesn't exist yet.

johannes



Re: [PATCH v3 1/3] dt-bindings: Add YAML bindings for NVDEC

2021-08-18 Thread Mikko Perttunen

On 8/18/21 12:20 AM, Rob Herring wrote:

On Wed, Aug 11, 2021 at 01:50:28PM +0300, Mikko Perttunen wrote:

Add YAML device tree bindings for NVDEC, now in a more appropriate
place compared to the old textual Host1x bindings.

Signed-off-by: Mikko Perttunen 
---
v3:
* Drop host1x bindings
* Change read2 to read-1 in interconnect names
v2:
* Fix issues pointed out in v1
* Add T194 nvidia,instance property
---
  .../gpu/host1x/nvidia,tegra210-nvdec.yaml | 109 ++
  MAINTAINERS   |   1 +
  2 files changed, 110 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml

diff --git 
a/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml 
b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
new file mode 100644
index ..571849625da8
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/gpu/host1x/nvidia,tegra210-nvdec.yaml#";
+$schema: "http://devicetree.org/meta-schemas/core.yaml#";
+
+title: Device tree binding for NVIDIA Tegra NVDEC
+
+description: |
+  NVDEC is the hardware video decoder present on NVIDIA Tegra210
+  and newer chips. It is located on the Host1x bus and typically
+  programmed through Host1x channels.
+
+maintainers:
+  - Thierry Reding 
+  - Mikko Perttunen 
+
+properties:
+  $nodename:
+pattern: "^nvdec@[0-9a-f]*$"
+
+  compatible:
+enum:
+  - nvidia,tegra210-nvdec
+  - nvidia,tegra186-nvdec
+  - nvidia,tegra194-nvdec
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: nvdec
+
+  resets:
+maxItems: 1
+
+  reset-names:
+items:
+  - const: nvdec
+
+  power-domains:
+maxItems: 1
+
+  iommus:
+maxItems: 1
+
+  interconnects:
+items:
+  - description: DMA read memory client
+  - description: DMA read 2 memory client
+  - description: DMA write memory client
+
+  interconnect-names:
+items:
+  - const: dma-mem
+  - const: read-1
+  - const: write
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - power-domains
+
+if:
+  properties:
+compatible:
+  contains:
+const: nvidia,tegra194-host1x


host1x? This will never be true as the schema is only applied to nodes
with the nvdec compatible.


Argh, it's a typo indeed. Should be nvidia,tegra194-nvdec.




+then:
+  properties:
+nvidia,instance:
+  items:
+- description: 0 for NVDEC0, or 1 for NVDEC1


What's this for? We generally don't do indices in DT.


When programming the hardware through Host1x, we need to know the "class 
ID" of the hardware, specific to each instance. So we need to know which 
instance it is. Technically of course we could derive this from the MMIO 
address but that seems more confusing.





+
+additionalProperties: true


This should be false or 'unevaluatedProperties: false'


I tried that but it resulted in validation failures; please see the 
discussion in v2.


Thanks,
Mikko



Rob



Re: [PATCH v8 01/34] opp: Add dev_pm_opp_sync() helper

2021-08-18 Thread Ulf Hansson
On Wed, 18 Aug 2021 at 08:27, Viresh Kumar  wrote:
>
> On 18-08-21, 09:22, Dmitry Osipenko wrote:
> > 18.08.2021 08:58, Viresh Kumar пишет:
> > > What about calling dev_pm_opp_set_rate(dev, clk_get_rate(dev)) here
> > > instead ? That will work, right ? The advantage is it works without
> > > any special routine to do so.
> >
> > It will work, but a dedicated helper is nicer.
> >
> > > I also wonder looking at your gr3d.c changes, you set a set-opp
> > > helper, but the driver doesn't call set_opp_rate at all. Who calls it
> > > ?
> >
> > dev_pm_opp_sync() calls it from _set_opp().
>
> Okay, please use dev_pm_opp_set_rate() instead then. New helper just
> adds to the confusion and isn't doing anything special apart from
> doing clk_get_rate() for you.
>
> > > And if it is all about just syncing the genpd core, then can the genpd
> > > core do something like what clk framework does? i.e. allow a new
> > > optional genpd callback, get_performance_state() (just like
> > > set_performance_state()), which can be called initially by the core to
> > > get the performance to something other than zero. opp-set-rate is
> > > there to set the performance state and enable the stuff as well.
> > > That's why it looks incorrect in your case, where the function was
> > > only required to be called once, and you are ending up calling it on
> > > each resume. Limiting that with another local variable is bad as well.
> >
> > We discussed variant with get_performance_state() previously and Ulf
> > didn't like it either since it still requires to touch 'internals' of GENPD.
>
> Hmm, I wonder if that would be a problem since only genpd core is
> going to call that routine anyway.

Me and Dmitry discussed adding a new genpd callback for this. I agreed
that it seems like a reasonable thing to add, if he insists.

The intent was to invoke the new callback from __genpd_dev_pm_attach()
when the device has been attached to its genpd. This allows the
callback, to invoke clk_get_rate() and then dev_pm_opp_set_rate(), to
update the vote according to the current state of the HW.

I am not sure if/why that approach seemed insufficient?

Another option to solve the problem, I think, is simply to patch
drivers to let them call dev_pm_opp_set_rate() during ->probe(), this
should synchronize the HW state too.

Dmitry, can you please elaborate on this?

Kind regards
Uffe


Re: [PATCH v8 11/34] gpu: host1x: Add runtime PM and OPP support

2021-08-18 Thread Ulf Hansson
On Tue, 17 Aug 2021 at 16:03, Thierry Reding  wrote:
>
> On Tue, Aug 17, 2021 at 02:04:38PM +0200, Ulf Hansson wrote:
> > On Tue, 17 Aug 2021 at 03:30, Dmitry Osipenko  wrote:
> > >
> > > Add runtime PM and OPP support to the Host1x driver. It's required for
> > > enabling system-wide DVFS and supporting dynamic power management using
> > > a generic power domain. For the starter we will keep host1x always-on
> > > because dynamic power management require a major refactoring of the driver
> > > code since lot's of code paths will need the RPM handling and we're going
> > > to remove some of these paths in the future. Host1x doesn't consume much
> > > power so it is good enough, we at least need to resume Host1x in order
> > > to initialize the power state.
> > >
> > > Tested-by: Peter Geis  # Ouya T30
> > > Tested-by: Paul Fertser  # PAZ00 T20
> > > Tested-by: Nicolas Chauvet  # PAZ00 T20 and TK1 T124
> > > Tested-by: Matt Merhar  # Ouya T30
> > > Signed-off-by: Dmitry Osipenko 
> > > ---
> >
> > [...]
> >
> > > +
> > >  static int host1x_probe(struct platform_device *pdev)
> > >  {
> > > struct host1x *host;
> > > @@ -394,6 +423,10 @@ static int host1x_probe(struct platform_device *pdev)
> > > /* set common host1x device data */
> > > platform_set_drvdata(pdev, host);
> > >
> > > +   err = devm_tegra_core_dev_init_opp_table_simple(&pdev->dev);
> > > +   if (err)
> > > +   return err;
> > > +
> > > host->regs = devm_ioremap_resource(&pdev->dev, regs);
> > > if (IS_ERR(host->regs))
> > > return PTR_ERR(host->regs);
> > > @@ -423,12 +456,9 @@ static int host1x_probe(struct platform_device *pdev)
> > > return err;
> > > }
> > >
> > > -   host->rst = devm_reset_control_get(&pdev->dev, "host1x");
> > > -   if (IS_ERR(host->rst)) {
> > > -   err = PTR_ERR(host->rst);
> > > -   dev_err(&pdev->dev, "failed to get reset: %d\n", err);
> > > +   err = host1x_get_resets(host);
> > > +   if (err)
> > > return err;
> > > -   }
> > >
> > > err = host1x_iommu_init(host);
> > > if (err < 0) {
> > > @@ -443,22 +473,10 @@ static int host1x_probe(struct platform_device 
> > > *pdev)
> > > goto iommu_exit;
> > > }
> > >
> > > -   err = clk_prepare_enable(host->clk);
> > > -   if (err < 0) {
> > > -   dev_err(&pdev->dev, "failed to enable clock\n");
> > > -   goto free_channels;
> > > -   }
> > > -
> > > -   err = reset_control_deassert(host->rst);
> > > -   if (err < 0) {
> > > -   dev_err(&pdev->dev, "failed to deassert reset: %d\n", 
> > > err);
> > > -   goto unprepare_disable;
> > > -   }
> > > -
> >
> > Removing the clk_prepare_enable() and reset_control_deassert() from
> > host1x_probe(), might not be a good idea. See more about why, below.
> >
> > > err = host1x_syncpt_init(host);
> > > if (err) {
> > > dev_err(&pdev->dev, "failed to initialize syncpts\n");
> > > -   goto reset_assert;
> > > +   goto free_channels;
> > > }
> > >
> > > err = host1x_intr_init(host, syncpt_irq);
> > > @@ -467,10 +485,14 @@ static int host1x_probe(struct platform_device 
> > > *pdev)
> > > goto deinit_syncpt;
> > > }
> > >
> > > -   host1x_debug_init(host);
> > > +   pm_runtime_enable(&pdev->dev);
> > >
> > > -   if (host->info->has_hypervisor)
> > > -   host1x_setup_sid_table(host);
> > > +   /* the driver's code isn't ready yet for the dynamic RPM */
> > > +   err = pm_runtime_resume_and_get(&pdev->dev);
> >
> > If the driver is being built with the CONFIG_PM Kconfig option being
> > unset, pm_runtime_resume_and_get() will return 0 to indicate success -
> > and without calling the ->runtime_resume() callback.
> > In other words, the clock will remain gated and the reset will not be
> > deasserted, likely causing the driver to be malfunctioning.
> >
> > If the driver isn't ever being built with CONFIG_PM unset, feel free
> > to ignore my above comments.
> >
> > Otherwise, if it needs to work both with and without CONFIG_PM being
> > set, you may use the following pattern in host1x_probe() to deploy
> > runtime PM support:
> >
> > "Enable the needed resources to probe the device"
> > pm_runtime_get_noresume()
> > pm_runtime_set_active()
> > pm_runtime_enable()
> >
> > "Before successfully completing probe"
> > pm_runtime_put()
>
> We made a conscious decision a few years ago to have ARCH_TEGRA select
> PM on both 32-bit and 64-bit ARM, specifically to avoid the need to do
> this dance (though there are still a few drivers left that do this, I
> think).
>
> So I think this should be unnecessary. Unless perhaps if the sysfs PM
> controls have any influence on this. As far as I know, as long as the
> PM kconfig option is enabled, the sysfs control onl

Re: [RFC] Make use of non-dynamic dmabuf in RDMA

2021-08-18 Thread Gal Pressman
On 18/08/2021 11:00, Christian König wrote:
> Am 18.08.21 um 09:43 schrieb Gal Pressman:
>> Hey all,
>>
>> Currently, the RDMA subsystem can only work with dynamic dmabuf
>> attachments, which requires the RDMA device to support on-demand-paging
>> (ODP) which is not common on most devices (only supported by mlx5).
>>
>> While the dynamic requirement makes sense for certain GPUs, some devices
>> (such as habanalabs) have device memory that is always "pinned" and do
>> not need/use the move_notify operation.
>>
>> The motivation of this RFC is to use habanalabs as the dmabuf exporter,
>> and EFA as the importer to allow for peer2peer access through libibverbs.
>>
>> This draft patch changes the dmabuf driver to differentiate between
>> static/dynamic attachments by looking at the move_notify op instead of
>> the importer_ops struct, and allowing the peer2peer flag to be enabled
>> in case of a static exporter.
> 
> Well NAK to the general approach, this can be solved much easier.
> 
> If you can't support dynamic moves while using the buffer then just pin all
> buffers during import/export.
> 
> This avoids the move notification and the framework/exporter can still 
> correctly
> account for pinned buffers.
> 
> But please note that at least amdgpu never uses P2P support for pinned buffers
> since we want to avoid that unmoveable buffers clutter video memory and create
> conflicts with V4L and scanout.
> 
> If you don't have such concerns in habanalabs then you can implement the 
> pinning
> there while keeping P2P still enabled.
Thanks Christian!

Are you suggesting to pass an empty move_notify callback instead of passing 
NULL?
Also, doesn't the pin operation move the memory from the device to host memory?


Re: [PATCH v2 44/63] mac80211: Use memset_after() to clear tx status

2021-08-18 Thread Kees Cook
On Wed, Aug 18, 2021 at 10:06:51AM +0200, Johannes Berg wrote:
> On Wed, 2021-08-18 at 09:08 +0200, Johannes Berg wrote:
> > On Tue, 2021-08-17 at 23:05 -0700, Kees Cook wrote:
> > > 
> > > @@ -275,12 +275,11 @@ static void carl9170_tx_release(struct kref *ref)
> > >   if (WARN_ON_ONCE(!ar))
> > >   return;
> > >  
> > > 
> > > 
> > > 
> > > - BUILD_BUG_ON(
> > > - offsetof(struct ieee80211_tx_info, status.ack_signal) != 20);
> > > -
> > > - memset(&txinfo->status.ack_signal, 0,
> > > -sizeof(struct ieee80211_tx_info) -
> > > -offsetof(struct ieee80211_tx_info, status.ack_signal));
> > > + /*
> > > +  * Should this call ieee80211_tx_info_clear_status() instead of clearing
> > > +  * manually? txinfo->status.rates do not seem to be used here.
> > > +  */
> > 
> > Since you insist, I went digging :)
> > 
> > It should not, carl9170_tx_fill_rateinfo() has filled the rate
> > information before we get to this point.

Ah-ha! Thanks for checking. I'll update the comment to explain the
rationale here.

> Otherwise, looks fine, FWIW.

Thanks!

> Are you going to apply all of these together somewhere? I (we) can't,
> since memset_after() doesn't exist yet.

Right, given the dependencies, I am expecting to just carry the whole
series, since the vast majority of it has no binary changes, etc. I'm
hoping to get it into -next soon, but we're uncomfortably close to the
merge window. :P

-- 
Kees Cook


Re: [PATCH v8 01/34] opp: Add dev_pm_opp_sync() helper

2021-08-18 Thread Viresh Kumar
On 18-08-21, 10:29, Ulf Hansson wrote:
> Me and Dmitry discussed adding a new genpd callback for this. I agreed
> that it seems like a reasonable thing to add, if he insists.
> 
> The intent was to invoke the new callback from __genpd_dev_pm_attach()
> when the device has been attached to its genpd. This allows the
> callback, to invoke clk_get_rate() and then dev_pm_opp_set_rate(), to
> update the vote according to the current state of the HW.

I wouldn't call dev_pm_opp_set_rate() from there, since it means
configure and enable (both) for different resources, clk, regulator,
genpd, etc..

What we need here is just configure. So something like this then:

- genpd->get_performance_state()
  -> dev_pm_opp_get_current_opp() //New API
  -> dev_pm_genpd_set_performance_state(dev, current_opp->pstate);

This can be done just once from probe() then.

> I am not sure if/why that approach seemed insufficient?
> 
> Another option to solve the problem, I think, is simply to patch
> drivers to let them call dev_pm_opp_set_rate() during ->probe(), this
> should synchronize the HW state too.

Dmitry already mentioned that this will make the device start
consuming power, and he doesn't want that, else we need an explicit
disble call as well.

-- 
viresh


[PATCH v3 10/15] soc: mediatek: mmsys: Add reset controller support for MT8195 vdosys1

2021-08-18 Thread Nancy . Lin
Among other features the mmsys driver should implement a reset
controller to be able to reset different bits from their space.

For MT8195 vdosys1, many async modules need to reset after
the display pipe stops and restart.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mt8195-mmsys.h |  1 +
 drivers/soc/mediatek/mtk-mmsys.c| 76 +
 drivers/soc/mediatek/mtk-mmsys.h|  1 +
 3 files changed, 78 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h 
b/drivers/soc/mediatek/mt8195-mmsys.h
index 0b079cba443f..0b08ac0cf2bf 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -123,6 +123,7 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN  0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER   (0 << 0)
 
+#define MT8195_VDO1_SW0_RST_B   0x1d0
 #define MT8195_VDO1_MERGE0_ASYNC_CFG_WD0xe30
 #define MT8195_VDO1_MERGE1_ASYNC_CFG_WD0xe40
 #define MT8195_VDO1_MERGE2_ASYNC_CFG_WD0xe50
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index e2bcd701ceb0..5e6c116e589a 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -4,10 +4,12 @@
  * Author: James Liao 
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "mtk-mmsys.h"
@@ -16,6 +18,8 @@
 #include "mt8365-mmsys.h"
 #include "mt8195-mmsys.h"
 
+#define MMSYS_SW_RESET_PER_REG 32
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
.clk_driver = "clk-mt2701-mm",
.routes = mmsys_default_routing_table,
@@ -72,12 +76,15 @@ static const struct mtk_mmsys_driver_data 
mt8195_vdosys1_driver_data = {
.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
.config = mmsys_mt8195_config_table,
.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
+   .sw_reset_start = MT8195_VDO1_SW0_RST_B,
 };
 
 struct mtk_mmsys {
void __iomem *regs;
const struct mtk_mmsys_driver_data *data;
struct cmdq_client_reg cmdq_base;
+   spinlock_t lock; /* protects mmsys_sw_rst_b reg */
+   struct reset_controller_dev rcdev;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -158,6 +165,63 @@ void mtk_mmsys_ddp_config(struct device *dev, enum 
mtk_mmsys_config_type config,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
+static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned 
long id,
+ bool assert)
+{
+   struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
+   unsigned long flags;
+   u32 reg;
+   int i;
+   u32 offset;
+
+   offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32);
+   id = id % MMSYS_SW_RESET_PER_REG;
+
+   spin_lock_irqsave(&mmsys->lock, flags);
+
+   reg = readl_relaxed(mmsys->regs + mmsys->data->sw_reset_start + offset);
+
+   if (assert)
+   reg &= ~BIT(id);
+   else
+   reg |= BIT(id);
+
+   writel_relaxed(reg, mmsys->regs + mmsys->data->sw_reset_start + offset);
+
+   spin_unlock_irqrestore(&mmsys->lock, flags);
+
+   return 0;
+}
+
+static int mtk_mmsys_reset_assert(struct reset_controller_dev *rcdev, unsigned 
long id)
+{
+   return mtk_mmsys_reset_update(rcdev, id, true);
+}
+
+static int mtk_mmsys_reset_deassert(struct reset_controller_dev *rcdev, 
unsigned long id)
+{
+   return mtk_mmsys_reset_update(rcdev, id, false);
+}
+
+static int mtk_mmsys_reset(struct reset_controller_dev *rcdev, unsigned long 
id)
+{
+   int ret;
+
+   ret = mtk_mmsys_reset_assert(rcdev, id);
+   if (ret)
+   return ret;
+
+   usleep_range(1000, 1100);
+
+   return mtk_mmsys_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops mtk_mmsys_reset_ops = {
+   .assert = mtk_mmsys_reset_assert,
+   .deassert = mtk_mmsys_reset_deassert,
+   .reset = mtk_mmsys_reset,
+};
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
struct device *dev = &pdev->dev;
@@ -185,6 +249,18 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
dev_dbg(dev, "No mediatek,gce-client-reg!\n");
 #endif
 
+   spin_lock_init(&mmsys->lock);
+
+   mmsys->rcdev.owner = THIS_MODULE;
+   mmsys->rcdev.nr_resets = 64;
+   mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
+   mmsys->rcdev.of_node = pdev->dev.of_node;
+   ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
+   if (ret) {
+   dev_err(&pdev->dev, "Couldn't register mmsys reset controller: 
%d\n", ret);
+   return ret;
+   }
+
platform_set_drvdata(pdev, mmsys);
 
clks = platform_device_register_data(&pdev->dev, 
mmsys->data->clk_driver,
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 825857d8d7f4..d84f5cb78f8c 100644
--- a/drivers/soc/mediatek/mtk-mmsy

[PATCH v3 03/15] dt-bindings: mediatek: add ethdr definition for mt8195

2021-08-18 Thread Nancy . Lin
Add vdosys1 ETHDR definition.

Signed-off-by: Nancy.Lin 
---
 .../display/mediatek/mediatek,ethdr.yaml  | 144 ++
 1 file changed, 144 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
new file mode 100644
index ..64d5349cdf8f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
@@ -0,0 +1,144 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek ethdr Device Tree Bindings
+
+maintainers:
+  - CK Hu 
+  - Nancy.Lin 
+
+description: |
+  ETHDR is designed for HDR video and graphics conversion in the external 
display path.
+  It handles multiple HDR input types and performs tone mapping, color 
space/color
+  format conversion, and then combine different layers, output the required 
HDR or
+  SDR signal to the subsequent display path. This engine is composed of two 
video
+  frontends, two graphic frontends, one video backend and a mixer.
+
+properties:
+  compatible:
+items:
+  - const: mediatek,mt8195-disp-ethdr
+  reg:
+maxItems: 7
+  reg-names:
+items:
+  - const: mixer
+  - const: vdo_fe0
+  - const: vdo_fe1
+  - const: gfx_fe0
+  - const: gfx_fe1
+  - const: vdo_be
+  - const: adl_ds
+  interrupts:
+minItems: 1
+  iommus:
+description: The compatible property is DMA function blocks.
+  Should point to the respective IOMMU block with master port as argument,
+  see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for
+  details.
+minItems: 1
+maxItems: 2
+  clocks:
+items:
+  - description: mixer clock
+  - description: video frontend 0 clock
+  - description: video frontend 1 clock
+  - description: graphic frontend 0 clock
+  - description: graphic frontend 1 clock
+  - description: video backend clock
+  - description: autodownload and menuload clock
+  - description: video frontend 0 async clock
+  - description: video frontend 1 async clock
+  - description: graphic frontend 0 async clock
+  - description: graphic frontend 1 async clock
+  - description: video backend async clock
+  - description: ethdr top clock
+  clock-names:
+items:
+  - const: mixer
+  - const: vdo_fe0
+  - const: vdo_fe1
+  - const: gfx_fe0
+  - const: gfx_fe1
+  - const: vdo_be
+  - const: adl_ds
+  - const: vdo_fe0_async
+  - const: vdo_fe1_async
+  - const: gfx_fe0_async
+  - const: gfx_fe1_async
+  - const: vdo_be_async
+  - const: ethdr_top
+  power-domains:
+maxItems: 1
+  resets:
+maxItems: 5
+  mediatek,gce-client-reg:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+description: The register of display function block to be set by gce.
+  There are 4 arguments in this property, gce node, subsys id, offset and
+  register size. The subsys id is defined in the gce header of each chips
+  include/include/dt-bindings/gce/-gce.h, mapping to the register of
+  display function block.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+
+disp_ethdr@1c114000 {
+compatible = "mediatek,mt8195-disp-ethdr";
+reg = <0 0x1c114000 0 0x1000>,
+  <0 0x1c115000 0 0x1000>,
+  <0 0x1c117000 0 0x1000>,
+  <0 0x1c119000 0 0x1000>,
+  <0 0x1c11A000 0 0x1000>,
+  <0 0x1c11B000 0 0x1000>,
+  <0 0x1c11C000 0 0x1000>;
+reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+"vdo_be", "adl_ds";
+mediatek,gce-client-reg = <&gce1 SUBSYS_1c11 0x4000 0x1000>,
+  <&gce1 SUBSYS_1c11 0x5000 0x1000>,
+  <&gce1 SUBSYS_1c11 0x7000 0x1000>,
+  <&gce1 SUBSYS_1c11 0x9000 0x1000>,
+  <&gce1 SUBSYS_1c11 0xA000 0x1000>,
+  <&gce1 SUBSYS_1c11 0xB000 0x1000>,
+  <&gce1 SUBSYS_1c11 0xC000 0x1000>;
+clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+ <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+ <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+ <&vdosys1 CLK_VDO1_26M_SLOW>,
+   

[PATCH v3 01/15] dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195

2021-08-18 Thread Nancy . Lin
Add vdosys1 RDMA definition.

Signed-off-by: Nancy.Lin 
---
 .../display/mediatek/mediatek,mdp-rdma.yaml   | 77 +++
 1 file changed, 77 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
new file mode 100644
index ..3610093848e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mdp-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display MDP RDMA
+
+maintainers:
+  - CK Hu 
+
+description: |
+  The mediatek display MDP RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for 
details.
+
+properties:
+  compatible:
+oneOf:
+  - items:
+  - const: mediatek,mt8195-vdo1-rdma
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  power-domains:
+description: A phandle and PM domain specifier as defined by bindings of
+  the power controller specified by phandle. See
+  Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+items:
+  - description: RDMA Clock
+
+  iommus:
+description:
+  This property should point to the respective IOMMU block with master 
port as argument,
+  see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for 
details.
+
+  mediatek,gce-client-reg:
+description:
+  The register of display function block to be set by gce. There are 4 
arguments,
+  such as gce node, subsys id, offset and register size. The subsys id 
that is
+  mapping to the register of display function blocks is defined in the gce 
header
+  include/include/dt-bindings/gce/-gce.h of each chips.
+$ref: /schemas/types.yaml#/definitions/phandle-array
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+vdo1_rdma0: vdo1_rdma@1c104000 {
+compatible = "mediatek,mt8195-vdo1-rdma";
+reg = <0 0x1c104000 0 0x1000>;
+interrupts = ;
+clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+mediatek,gce-client-reg = <&gce1 SUBSYS_1c10 0x4000 0x1000>;
+};
+
-- 
2.18.0



[PATCH v3 07/15] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1

2021-08-18 Thread Nancy . Lin
Add mt8195 vdosys1 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mt8195-mmsys.h| 136 +
 drivers/soc/mediatek/mtk-mmsys.c   |  10 ++
 include/linux/soc/mediatek/mtk-mmsys.h |   2 +
 3 files changed, 148 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h 
b/drivers/soc/mediatek/mt8195-mmsys.h
index 39a2b125494d..3c2b1d43dcc4 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -59,6 +59,70 @@
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0 (2 << 16)
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE (3 << 16)
 
+#define MT8195_VDO1_VPP_MERGE0_P0_SEL_IN   0xf04
+#define MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0 (1 << 0)
+
+#define MT8195_VDO1_VPP_MERGE0_P1_SEL_IN   0xf08
+#define MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1 (1 << 0)
+
+#define MT8195_VDO1_DISP_DPI1_SEL_IN   0xf10
+#define MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT   (0 << 0)
+
+#define MT8195_VDO1_DISP_DP_INTF0_SEL_IN   0xf14
+#define MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT   (0 << 0)
+
+#define MT8195_VDO1_MERGE4_SOUT_SEL0xf18
+#define MT8195_MERGE4_SOUT_TO_DPI1_SEL (2 << 0)
+#define MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL (3 << 0)
+
+#define MT8195_VDO1_MIXER_IN1_SEL_IN   0xf24
+#define MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT (1 << 0)
+
+#define MT8195_VDO1_MIXER_IN2_SEL_IN   0xf28
+#define MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT (1 << 0)
+
+#define MT8195_VDO1_MIXER_IN3_SEL_IN   0xf2c
+#define MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT (1 << 0)
+
+#define MT8195_VDO1_MIXER_IN4_SEL_IN   0xf30
+#define MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT (1 << 0)
+
+#define MT8195_VDO1_MIXER_OUT_SOUT_SEL 0xf34
+#define MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL  (1 << 0)
+
+#define MT8195_VDO1_VPP_MERGE1_P0_SEL_IN   0xf3c
+#define MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2 (1 << 0)
+
+#define MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL  0xf40
+#define MT8195_SOUT_TO_MIXER_IN1_SEL   (1 << 0)
+
+#define MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL  0xf44
+#define MT8195_SOUT_TO_MIXER_IN2_SEL   (1 << 0)
+
+#define MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL  0xf48
+#define MT8195_SOUT_TO_MIXER_IN3_SEL   (1 << 0)
+
+#define MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL  0xf4c
+#define MT8195_SOUT_TO_MIXER_IN4_SEL   (1 << 0)
+
+#define MT8195_VDO1_MERGE4_ASYNC_SEL_IN0xf50
+#define MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT (1 << 0)
+
+#define MT8195_VDO1_MIXER_IN1_SOUT_SEL 0xf58
+#define MT8195_MIXER_IN1_SOUT_TO_DISP_MIXER(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN2_SOUT_SEL 0xf5c
+#define MT8195_MIXER_IN2_SOUT_TO_DISP_MIXER(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN3_SOUT_SEL 0xf60
+#define MT8195_MIXER_IN3_SOUT_TO_DISP_MIXER(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN4_SOUT_SEL 0xf64
+#define MT8195_MIXER_IN4_SOUT_TO_DISP_MIXER(0 << 0)
+
+#define MT8195_VDO1_MIXER_SOUT_SEL_IN  0xf68
+#define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER   (0 << 0)
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
{
DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -108,6 +172,78 @@ static const struct mtk_mmsys_routes 
mmsys_mt8195_routing_table[] = {
DDP_COMPONENT_MERGE0 , DDP_COMPONENT_DP_INTF0,
MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_VPP_MERGE0_P0_SEL_IN, GENMASK(0, 0),
+   MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_VPP_MERGE0_P1_SEL_IN, GENMASK(0, 0),
+   MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_VPP_MERGE1_P0_SEL_IN, GENMASK(0, 0),
+   MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL, GENMASK(1, 0),
+ 

[PATCH v3 14/15] drm/mediatek: add ETHDR support for MT8195

2021-08-18 Thread Nancy . Lin
ETHDR is a part of ovl_adaptor.
ETHDR is designed for HDR video and graphics conversion in the external
display path. It handles multiple HDR input types and performs tone
mapping, color space/color format conversion, and then combine
different layers, output the required HDR or SDR signal to the
subsequent display path.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/Makefile   |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  16 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   1 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c| 440 
 5 files changed, 462 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index f04ac86c9593..c42d0623e629 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -14,7 +14,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
  mtk_dsi.o \
  mtk_dpi.o \
  mtk_mdp_rdma.o \
- mtk_disp_ovl_adaptor.o
+ mtk_disp_ovl_adaptor.o \
+ mtk_ethdr.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 7129ba061ecb..964d0ad2b81d 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -98,6 +98,22 @@ void mtk_rdma_enable_vblank(struct device *dev,
void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_ethdr_clk_enable(struct device *dev);
+void mtk_ethdr_clk_disable(struct device *dev);
+void mtk_ethdr_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
+   struct mtk_plane_state *state,
+   struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_enable_vblank(struct device *dev,
+void (*vblank_cb)(void *),
+void *vblank_cb_data);
+void mtk_ethdr_disable_vblank(struct device *dev);
+void mtk_ethdr_start(struct device *dev);
+void mtk_ethdr_stop(struct device *dev);
+unsigned int mtk_ethdr_layer_nr(struct device *dev);
+
 void mtk_mdp_rdma_start(void __iomem *base,
struct cmdq_pkt *cmdq_pkt,
struct cmdq_client_reg *cmdq_base);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 9aebf73144c6..6a18c12fe04e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -452,6 +452,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
  .data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8183-disp-ovl-2l",
  .data = (void *)MTK_DISP_OVL_2L },
+   { .compatible = "mediatek,mt8195-disp-ethdr",
+ .data = (void *)MTK_DISP_OVL_ADAPTOR },
{ .compatible = "mediatek,mt2701-disp-pwm",
  .data = (void *)MTK_DISP_BLS },
{ .compatible = "mediatek,mt8173-disp-pwm",
@@ -674,6 +676,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
&mtk_dpi_driver,
&mtk_drm_platform_driver,
&mtk_dsi_driver,
+   &mtk_ethdr_driver,
 };
 
 static int __init mtk_drm_init(void)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 0fa417219a69..7b09fe6db067 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -54,5 +54,6 @@ extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
+extern struct platform_driver mtk_ethdr_driver;
 
 #endif /* MTK_DRM_DRV_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c 
b/drivers/gpu/drm/mediatek/mtk_ethdr.c
new file mode 100644
index ..05035b6015d8
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_ovl_adaptor.h"
+
+#define MIX_INTEN  0x4
+   #define MIX_FME_CPL_INTEN   BIT(1)
+#define MIX_INTSTA 0x8
+#define MIX_EN 0xc
+#define MIX_RST0x14
+#define MIX_ROI_SIZE   0x18
+#define MIX_DATAPATH_CON   0x1c
+   #define OUTPUT_NO_RND   BIT(3)
+   #define SOURCE_RGB_SEL  BIT(7)
+   #define BACKGROUND_RELAY  

[PATCH v3 11/15] soc: mediatek: add mtk-mutex support for mt8195 vdosys1

2021-08-18 Thread Nancy . Lin
Add mtk-mutex support for mt8195 vdosys1.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements,
so change it to support multi-bit control.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mtk-mutex.c | 270 ++-
 1 file changed, 162 insertions(+), 108 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index c177156ee2fa..588e378d1855 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -29,101 +29,130 @@
 
 #define INT_MUTEX  BIT(1)
 
-#define MT8167_MUTEX_MOD_DISP_PWM  1
-#define MT8167_MUTEX_MOD_DISP_OVL0 6
-#define MT8167_MUTEX_MOD_DISP_OVL1 7
-#define MT8167_MUTEX_MOD_DISP_RDMA08
-#define MT8167_MUTEX_MOD_DISP_RDMA19
-#define MT8167_MUTEX_MOD_DISP_WDMA010
-#define MT8167_MUTEX_MOD_DISP_CCORR11
-#define MT8167_MUTEX_MOD_DISP_COLOR12
-#define MT8167_MUTEX_MOD_DISP_AAL  13
-#define MT8167_MUTEX_MOD_DISP_GAMMA14
-#define MT8167_MUTEX_MOD_DISP_DITHER   15
-#define MT8167_MUTEX_MOD_DISP_UFOE 16
-
-#define MT8183_MUTEX_MOD_DISP_RDMA00
-#define MT8183_MUTEX_MOD_DISP_RDMA11
-#define MT8183_MUTEX_MOD_DISP_OVL0 9
-#define MT8183_MUTEX_MOD_DISP_OVL0_2L  10
-#define MT8183_MUTEX_MOD_DISP_OVL1_2L  11
-#define MT8183_MUTEX_MOD_DISP_WDMA012
-#define MT8183_MUTEX_MOD_DISP_COLOR0   13
-#define MT8183_MUTEX_MOD_DISP_CCORR0   14
-#define MT8183_MUTEX_MOD_DISP_AAL0 15
-#define MT8183_MUTEX_MOD_DISP_GAMMA0   16
-#define MT8183_MUTEX_MOD_DISP_DITHER0  17
-
-#define MT8173_MUTEX_MOD_DISP_OVL0 11
-#define MT8173_MUTEX_MOD_DISP_OVL1 12
-#define MT8173_MUTEX_MOD_DISP_RDMA013
-#define MT8173_MUTEX_MOD_DISP_RDMA114
-#define MT8173_MUTEX_MOD_DISP_RDMA215
-#define MT8173_MUTEX_MOD_DISP_WDMA016
-#define MT8173_MUTEX_MOD_DISP_WDMA117
-#define MT8173_MUTEX_MOD_DISP_COLOR0   18
-#define MT8173_MUTEX_MOD_DISP_COLOR1   19
-#define MT8173_MUTEX_MOD_DISP_AAL  20
-#define MT8173_MUTEX_MOD_DISP_GAMMA21
-#define MT8173_MUTEX_MOD_DISP_UFOE 22
-#define MT8173_MUTEX_MOD_DISP_PWM0 23
-#define MT8173_MUTEX_MOD_DISP_PWM1 24
-#define MT8173_MUTEX_MOD_DISP_OD   25
-
-#define MT8195_MUTEX_MOD_DISP_OVL0 0
-#define MT8195_MUTEX_MOD_DISP_WDMA01
-#define MT8195_MUTEX_MOD_DISP_RDMA02
-#define MT8195_MUTEX_MOD_DISP_COLOR0   3
-#define MT8195_MUTEX_MOD_DISP_CCORR0   4
-#define MT8195_MUTEX_MOD_DISP_AAL0 5
-#define MT8195_MUTEX_MOD_DISP_GAMMA0   6
-#define MT8195_MUTEX_MOD_DISP_DITHER0  7
-#define MT8195_MUTEX_MOD_DISP_DSI0 8
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0  9
-#define MT8195_MUTEX_MOD_DISP_OVL1 10
-#define MT8195_MUTEX_MOD_DISP_WDMA111
-#define MT8195_MUTEX_MOD_DISP_RDMA112
-#define MT8195_MUTEX_MOD_DISP_COLOR1   13
-#define MT8195_MUTEX_MOD_DISP_CCORR1   14
-#define MT8195_MUTEX_MOD_DISP_AAL1 15
-#define MT8195_MUTEX_MOD_DISP_GAMMA1   16
-#define MT8195_MUTEX_MOD_DISP_DITHER1  17
-#define MT8195_MUTEX_MOD_DISP_DSI1 18
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1  19
-#define MT8195_MUTEX_MOD_DISP_VPP_MERGE20
-#define MT8195_MUTEX_MOD_DISP_DP_INTF0 21
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0   22
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1   23
-#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2   24
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3   25
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4   26
-#define MT8195_MUTEX_MOD_DISP_PWM0 27
-#define MT8195_MUTEX_MOD_DISP_PWM1 28
-
-#define MT2712_MUTEX_MOD_DISP_PWM2 10
-#define MT2712_MUTEX_MOD_DISP_OVL0 11
-#define MT2712_MUTEX_MOD_DISP_OVL1 12
-#define MT2712_MUTEX_MOD_DISP_RDMA013
-#define MT2712_MUTEX_MOD_DISP_RDMA114
-#define MT2712_MUTEX_MOD_DISP_RDMA215
-#define MT2712_MUTEX_MOD_DISP_WDMA016
-#define MT2712_MUTEX_MOD_DISP_WDMA117
-#define MT2712_MUTEX_MOD_DISP_COLOR0   18
-#define MT2712_MUTEX_MOD_DISP_COLOR1   19
-#define MT2712_MUTEX_MOD_DISP_AAL0 20
-#define MT2712_MUTEX_MOD_DISP_UFOE 22
-#define MT2712_MUTEX_MOD_DISP_PWM0 23
-#define MT2712_MUTEX_MOD_DISP_PWM1 24
-#define MT2712_MUTEX_MOD_DISP_OD0  25
-#define MT2712_MUTEX_MOD2_DISP_AAL133
-#define MT2712_MUTEX_MOD2_DISP_OD1 34
-
-#define MT2701_MUTEX_MOD_DISP_OVL  3
-#define MT2701_MUTEX_M

[PATCH v3 05/15] dt-bindings: reset: mt8195: add vdosys1 reset control bit

2021-08-18 Thread Nancy . Lin
Add vdosys1 reset control bit for MT8195 platform.

Signed-off-by: Nancy.Lin 
---
 include/dt-bindings/reset/mt8195-resets.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/dt-bindings/reset/mt8195-resets.h 
b/include/dt-bindings/reset/mt8195-resets.h
index a26bccc8b957..eaaa882c09bd 100644
--- a/include/dt-bindings/reset/mt8195-resets.h
+++ b/include/dt-bindings/reset/mt8195-resets.h
@@ -26,4 +26,16 @@
 
 #define MT8195_TOPRGU_SW_RST_NUM   16
 
+/* VDOSYS1 */
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC 25
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC 26
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC 27
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC 28
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC 29
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC 51
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC 52
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC 53
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC 54
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC 55
+
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
-- 
2.18.0



[PATCH v3 12/15] drm/mediatek: add display MDP RDMA support for MT8195

2021-08-18 Thread Nancy . Lin
Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of
the ovl_adaptor component.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/Makefile   |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  12 ++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 275 
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h |  39 
 4 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 538e0087a44c..38ec2354a894 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -12,7 +12,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
  mtk_drm_gem.o \
  mtk_drm_plane.o \
  mtk_dsi.o \
- mtk_dpi.o
+ mtk_dpi.o \
+ mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index f407cd9d873e..7129ba061ecb 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -8,6 +8,7 @@
 
 #include 
 #include "mtk_drm_plane.h"
+#include "mtk_mdp_rdma.h"
 
 void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state);
 int mtk_ccorr_clk_enable(struct device *dev);
@@ -97,4 +98,15 @@ void mtk_rdma_enable_vblank(struct device *dev,
void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+void mtk_mdp_rdma_start(void __iomem *base,
+   struct cmdq_pkt *cmdq_pkt,
+   struct cmdq_client_reg *cmdq_base);
+void mtk_mdp_rdma_stop(void __iomem *base,
+  struct cmdq_pkt *cmdq_pkt,
+  struct cmdq_client_reg *cmdq_base);
+void mtk_mdp_rdma_config(void __iomem *base,
+struct mtk_mdp_rdma_cfg *cfg,
+struct cmdq_pkt *cmdq_pkt,
+struct cmdq_client_reg *cmdq_base);
+
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c 
b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
new file mode 100644
index ..95e762eda4a8
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include "mtk_drm_drv.h"
+#include "mtk_mdp_rdma.h"
+
+#define REG_FLD(width, shift) \
+   ((unsigned int)width) & 0xff) << 16) | ((shift) & 0xff)))
+
+#define REG_FLD_WIDTH(field) ((unsigned int)(((field) >> 16) & 0xff))
+
+#define REG_FLD_SHIFT(field) ((unsigned int)((field) & 0xff))
+
+#define REG_FLD_MASK(field) \
+   ((unsigned int)((1ULL << REG_FLD_WIDTH(field)) - 1) \
+<< REG_FLD_SHIFT(field))
+
+#define REG_FLD_VAL(field, val) \
+   (((val) << REG_FLD_SHIFT(field)) & REG_FLD_MASK(field))
+
+#define MDP_RDMA_EN0x000
+#define FLD_ROT_ENABLEREG_FLD(1, 0)
+
+#define MDP_RDMA_RESET 0x008
+
+#define MDP_RDMA_CON   0x020
+#define FLD_OUTPUT_10BREG_FLD(1, 5)
+#define FLD_SIMPLE_MODE   REG_FLD(1, 4)
+
+#define MDP_RDMA_GMCIF_CON 0x028
+#define FLD_EXT_ULTRA_EN  REG_FLD(1, 18)
+#define FLD_PRE_ULTRA_EN  REG_FLD(2, 16)
+#define FLD_ULTRA_EN  REG_FLD(2, 12)
+#define FLD_RD_REQ_TYPE   REG_FLD(4, 4)
+#define VAL_RD_REQ_TYPE_BURST_8_ACCESS   7
+#define FLD_EXT_PREULTRA_EN   REG_FLD(1, 3)
+#define FLD_COMMAND_DIV   REG_FLD(1, 0)
+
+#define MDP_RDMA_SRC_CON   0x030
+#define FLD_OUTPUT_ARGB   REG_FLD(1, 25)
+#define FLD_BIT_NUMBERREG_FLD(2, 18)
+#define FLD_UNIFORM_CONFIGREG_FLD(1, 17)
+#define FLD_SWAP  REG_FLD(1, 14)
+#define FLD_SRC_FORMATREG_FLD(4, 0)
+
+#define MDP_RDMA_COMP_CON  0x038
+#define FLD_AFBC_EN   REG_FLD(1, 22)
+#define FLD_AFBC_YUV_TRANSFORMREG_FLD(1, 21)
+#define FLD_UFBDC_EN  REG_FLD(1, 12)
+
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE  0x060
+#define FLD_MF_BKGD_WBREG_FLD(23, 0)
+
+#define MDP_RDMA_MF_BKGD_SIZE_IN_PIXEL 0x068
+#define FLD_MF_BKGD_WPREG_FLD(23, 0)
+
+#define MDP_RDMA_MF_SRC_SIZE   0x070
+#define FLD_MF_SRC_H

[PATCH v3 09/15] soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195 vdosys1

2021-08-18 Thread Nancy . Lin
Add cmdq support for mtk-mmsys config API.
The mmsys config register settings need to take effect with the other
HW settings(like OVL_ADAPTOR...) at the same vblanking time.

If we use CPU to write the mmsys reg, we can't guarantee all the
settings can be written in the same vblanking time.
Cmdq is used for this purpose. We prepare all the related HW settings
in one cmdq packet. The first command in the packet is "wait stream done",
and then following with all the HW settings. After the cmdq packet is
flush to GCE HW. The GCE waits for the "stream done event" to coming
and then starts flushing all the HW settings. This can guarantee all
the settings flush in the same vblanking.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mtk-mmsys.c   | 28 +-
 include/linux/soc/mediatek/mtk-mmsys.h |  6 +-
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index cd59a4157731..e2bcd701ceb0 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -77,6 +77,7 @@ static const struct mtk_mmsys_driver_data 
mt8195_vdosys1_driver_data = {
 struct mtk_mmsys {
void __iomem *regs;
const struct mtk_mmsys_driver_data *data;
+   struct cmdq_client_reg cmdq_base;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -117,7 +118,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type 
config,
- u32 id, u32 val)
+ u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
@@ -140,10 +141,20 @@ void mtk_mmsys_ddp_config(struct device *dev, enum 
mtk_mmsys_config_type config,
mask = mmsys_config[i].mask;
reg_val = val << mmsys_config[i].shift;
 
-   u32 tmp = readl(mmsys->regs + offset);
-
-   tmp = (tmp & ~mask) | reg_val;
-   writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   if (cmdq_pkt && mmsys->cmdq_base.size) {
+   cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+   mmsys->cmdq_base.offset + offset, reg_val,
+   mask);
+   } else {
+#endif
+   u32 tmp = readl(mmsys->regs + offset);
+
+   tmp = (tmp & ~mask) | reg_val;
+   writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   }
+#endif
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
@@ -167,6 +178,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
}
 
mmsys->data = of_device_get_match_data(&pdev->dev);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
+   if (ret)
+   dev_dbg(dev, "No mediatek,gce-client-reg!\n");
+#endif
+
platform_set_drvdata(pdev, mmsys);
 
clks = platform_device_register_data(&pdev->dev, 
mmsys->data->clk_driver,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h 
b/include/linux/soc/mediatek/mtk-mmsys.h
index ef2a6d9a834b..9705d242849a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -6,6 +6,10 @@
 #ifndef __MTK_MMSYS_H
 #define __MTK_MMSYS_H
 
+#include 
+#include 
+#include 
+
 enum mtk_ddp_comp_id;
 struct device;
 
@@ -75,6 +79,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
  enum mtk_ddp_comp_id next);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type 
config,
- u32 id, u32 val);
+ u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
 
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



[PATCH v3 13/15] drm/mediatek: add ovl_adaptor support for MT8195

2021-08-18 Thread Nancy . Lin
Add ovl_adaptor driver for MT8195.
Ovl_adaptor is an encapsulated module and designed for simplified
DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
an ETHDR. Two RDMAs merge into one layer, so this module support 4
layers.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/Makefile |   3 +-
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 528 ++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.h   |  19 +
 3 files changed, 549 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 38ec2354a894..f04ac86c9593 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
  mtk_drm_plane.o \
  mtk_dsi.o \
  mtk_dpi.o \
- mtk_mdp_rdma.o
+ mtk_mdp_rdma.o \
+ mtk_disp_ovl_adaptor.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
new file mode 100644
index ..8222ec5ff799
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_drm_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_disp_drv.h"
+#include "mtk_disp_ovl_adaptor.h"
+
+#define DISP_MERGE_ENABLE  0x0
+   #define MERGE_ENABLE BIT(0)
+#define DISP_MERGE_CFG_0   0x10
+#define DISP_MERGE_CFG_1   0x14
+#define DISP_MERGE_CFG_4   0x20
+#define DISP_MERGE_CFG_5   0x24
+#define DISP_MERGE_CFG_10  0x38
+   #define CFG_10_NO_SWAP 0
+#define DISP_MERGE_CFG_12  0x40
+   #define CFG12_10_10_1PI_2PO_BUF_MODE 6
+   #define CFG12_11_10_1PI_2PO_MERGE 18
+#define DISP_MERGE_CFG_24  0x70
+#define DISP_MERGE_CFG_25  0x74
+#define DISP_MERGE_CFG_26  0x78
+#define DISP_MERGE_CFG_27  0x7c
+#define DISP_MERGE_MUTE_0  0xf00
+
+#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
+#define MTK_OVL_ADAPTOR_LAYER_NUM 4
+
+enum mtk_ovl_adaptor_comp_type {
+   OVL_ADAPTOR_TYPE_RDMA = 0,
+   OVL_ADAPTOR_TYPE_MERGE,
+   OVL_ADAPTOR_TYPE_NUM,
+};
+
+enum mtk_ovl_adaptor_comp_id {
+   OVL_ADAPTOR_MDP_RDMA0,
+   OVL_ADAPTOR_MDP_RDMA1,
+   OVL_ADAPTOR_MDP_RDMA2,
+   OVL_ADAPTOR_MDP_RDMA3,
+   OVL_ADAPTOR_MDP_RDMA4,
+   OVL_ADAPTOR_MDP_RDMA5,
+   OVL_ADAPTOR_MDP_RDMA6,
+   OVL_ADAPTOR_MDP_RDMA7,
+   OVL_ADAPTOR_MERGE0,
+   OVL_ADAPTOR_MERGE1,
+   OVL_ADAPTOR_MERGE2,
+   OVL_ADAPTOR_MERGE3,
+   OVL_ADAPTOR_ID_MAX
+};
+
+struct ovl_adaptor_comp_match {
+   enum mtk_ovl_adaptor_comp_type type;
+   int alias_id;
+};
+
+struct ovl_adaptor_merge_config {
+   unsigned int fmt;
+   unsigned int merge_mode;
+   unsigned int in_w[2];
+   unsigned int out_w[2];
+   unsigned int in_h;
+};
+
+struct mtk_ovl_adaptor_comp {
+   struct device *dev;
+   struct clk *clks[2];
+   struct cmdq_client_reg cmdq_base;
+   void __iomem *regs;
+};
+
+struct mtk_disp_ovl_adaptor {
+   struct mtk_ovl_adaptor_comp ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
+   struct device *mmsys_dev;
+};
+
+static const char * const ovl_adaptor_comp_str[] = {
+   "OVL_ADAPTOR_MDP_RDMA0",
+   "OVL_ADAPTOR_MDP_RDMA1",
+   "OVL_ADAPTOR_MDP_RDMA2",
+   "OVL_ADAPTOR_MDP_RDMA3",
+   "OVL_ADAPTOR_MDP_RDMA4",
+   "OVL_ADAPTOR_MDP_RDMA5",
+   "OVL_ADAPTOR_MDP_RDMA6",
+   "OVL_ADAPTOR_MDP_RDMA7",
+   "OVL_ADAPTOR_MERGE0",
+   "OVL_ADAPTOR_MERGE1",
+   "OVL_ADAPTOR_MERGE2",
+   "OVL_ADAPTOR_MERGE3",
+   "OVL_ADAPTOR_ID_MAX"
+};
+
+static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
+   [OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma",
+   [OVL_ADAPTOR_TYPE_MERGE] = "merge",
+};
+
+static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
+   [OVL_ADAPTOR_MDP_RDMA0] =   { OVL_ADAPTOR_TYPE_RDMA, 0 },
+   [OVL_ADAPTOR_MDP_RDMA1] =   { OVL_ADAPTOR_TYPE_RDMA, 1 },
+   [OVL_ADAPTOR_MDP_RDMA2] =   { OVL_ADAPTOR_TYPE_RDMA, 2 },
+   [OVL_ADAPTOR_MDP_RDMA3] =   { OVL_ADAPTOR_TYPE_RDMA, 3 },
+   [OVL_ADAPTOR_MDP_RDMA4] =   { OVL_ADAPTOR_TYPE_RDMA, 4 },
+   [OVL_ADAPTOR_MDP_RDMA5] =   { OVL_ADAPTOR_TYPE_RDMA, 5 },
+   [OVL_ADAPTOR_MDP_RDMA6] =   { OVL_ADAPTOR_TYPE_RDMA, 6 },
+   [OVL_ADAPTOR_MDP_RDMA7] =   { OVL_ADAPTOR_TYPE_RDMA, 7 },
+   [OVL_ADAPTOR_MERGE0] =  { OVL_ADAPTOR_TYPE_MERGE, 1 },
+   [OVL_ADAPTOR_MERGE1] =  { OVL

[PATCH v3 08/15] soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1

2021-08-18 Thread Nancy . Lin
Add mmsys config API. The config API is used for config mmsys reg.
Some mmsys regs need to be setting according to the HW engine binding
to the mmsys simultaneously.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mt8195-mmsys.h| 62 ++
 drivers/soc/mediatek/mtk-mmsys.c   | 33 ++
 drivers/soc/mediatek/mtk-mmsys.h   | 10 +
 include/linux/soc/mediatek/mtk-mmsys.h | 16 +++
 4 files changed, 121 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h 
b/drivers/soc/mediatek/mt8195-mmsys.h
index 3c2b1d43dcc4..0b079cba443f 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -123,6 +123,21 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN  0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER   (0 << 0)
 
+#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD0xe30
+#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD0xe40
+#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD0xe50
+#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD0xe60
+#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD 0xe70
+#define MT8195_VDO1_HDR_TOP_CFG0xd00
+#define MT8195_VDO1_MIXER_IN1_ALPHA0xd30
+#define MT8195_VDO1_MIXER_IN2_ALPHA0xd34
+#define MT8195_VDO1_MIXER_IN3_ALPHA0xd38
+#define MT8195_VDO1_MIXER_IN4_ALPHA0xd3c
+#define MT8195_VDO1_MIXER_IN1_PAD  0xd40
+#define MT8195_VDO1_MIXER_IN2_PAD  0xd44
+#define MT8195_VDO1_MIXER_IN3_PAD  0xd48
+#define MT8195_VDO1_MIXER_IN4_PAD  0xd4c
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
{
DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -247,4 +262,51 @@ static const struct mtk_mmsys_routes 
mmsys_mt8195_routing_table[] = {
}
 };
 
+/*
+ * mtk_mmsys_config table is used for config mmsys reg in runtime.
+ * MMSYS_CONFIG_MERGE_ASYNC_WIDTH: config merge async width
+ * MMSYS_CONFIG_MERGE_ASYNC_HEIGHT: config merge async height
+ * MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH: config hdr_be async width
+ * MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT: config hdr_be async height
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_ODD: config mixer odd channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN: config mixer even channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_CH_SWAP: config mixer input RGB channel swap
+ * MMSYS_CONFIG_HDR_ALPHA_SEL: config alpha source
+ * MMSYS_CONFIG_MIXER_IN_MODE: config mixer pad mode(bypass/even extend mode)
+ * MMSYS_CONFIG_MIXER_IN_BIWIDTH: config mixer pad width. formula: width / 2 - 
1
+ */
+static const struct mtk_mmsys_config mmsys_mt8195_config_table[] = {
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1, MT8195_VDO1_MIXER_IN1_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1, MT8195_VDO1_MIXER_IN1_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2, MT8195_VDO1_MIXER_IN2_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2, MT8195_VDO1_MIXER_IN2_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3, MT8195_VDO1_MIXER_IN3_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3, MT8195_VDO1_MIXER_IN3_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4, MT8195_VDO1_MIXER_IN4_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4, MT8195_VDO1_MIXER_IN4_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD, 
GENMASK(4, 4), 4},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG, GENMASK(20, 
20), 20},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG, GENMASK(21, 
21), 21},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG, GENMASK(22, 
22), 22},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG, GENMASK(23, 
23), 23},
+   { MMSYS_CONFIG_MIXER_IN_MODE, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(1, 
0), 0},
+   { MMSYS_CONFIG_MIXER_IN_MODE, 2, MT8195_VDO1_MIXER_

[PATCH v3 00/15] Add MediaTek SoC DRM (vdosys1) support for mt8195

2021-08-18 Thread Nancy . Lin
The hardware path of vdosys1 with DPTx output need to go through by several 
modules, such as, OVL_ADAPTOR and MERGE.

Add DRM and these modules support by the patches below:

Changes in v3:
- modify for reviewer's comment in v2.
- add vdosys1 2 pixels align limit.
- add mixer odd offset support.

Changes in v2:
- Merge PSEUDO_OVL and ETHDR into one DRM component.
- Add mmsys config API for vdosys1 hardware setting.
- Add mmsys reset control using linux reset framework.

Signed-off-by: Nancy.Lin 

This series are based on the following patch:
[1] arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile

https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.w...@mediatek.com/
[2] arm64: dts: mt8195: add IOMMU and smi nodes

https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.s...@mediatek.com/
[3] [01/24] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU

https://patchwork.kernel.org/project/linux-mediatek/patch/20210630023504.18177-2-yong...@mediatek.com/
[4] Add gce support for mt8195
https://patchwork.kernel.org/project/linux-mediatek/list/?series=515599
[5] Add MediaTek SoC DRM (vdosys0) support for mt8195
https://patchwork.kernel.org/project/linux-mediatek/list/?series=531695
[6] [v8,1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header file

https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-christine@mediatek.com/

Nancy.Lin (15):
  dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
  dt-bindings: mediatek: add vdosys1 MERGE definition for mt8195
  dt-bindings: mediatek: add ethdr definition for mt8195
  dt-bindings: mediatek: Add #reset-cells to mmsys system controller
  dt-bindings: reset: mt8195: add vdosys1 reset control bit
  arm64: dts: mt8195: add display node for vdosys1
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
  soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
  soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195
vdosys1
  soc: mediatek: mmsys: Add reset controller support for MT8195 vdosys1
  soc: mediatek: add mtk-mutex support for mt8195 vdosys1
  drm/mediatek: add display MDP RDMA support for MT8195
  drm/mediatek: add ovl_adaptor support for MT8195
  drm/mediatek: add ETHDR support for MT8195
  drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |   3 +
 .../display/mediatek/mediatek,ethdr.yaml  | 144 +
 .../display/mediatek/mediatek,mdp-rdma.yaml   |  77 +++
 .../display/mediatek/mediatek,merge.yaml  |   2 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi  | 217 +++
 drivers/gpu/drm/mediatek/Makefile |   5 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  28 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c |   4 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 528 ++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.h   |  19 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c   |  25 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h   |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  15 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c| 375 +++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|   9 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c  | 440 +++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c   | 275 +
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h   |  39 ++
 drivers/soc/mediatek/mt8195-mmsys.h   | 199 +++
 drivers/soc/mediatek/mtk-mmsys.c  | 137 +
 drivers/soc/mediatek/mtk-mmsys.h  |  11 +
 drivers/soc/mediatek/mtk-mutex.c  | 270 +
 include/dt-bindings/reset/mt8195-resets.h |  12 +
 include/linux/soc/mediatek/mtk-mmsys.h|  22 +
 25 files changed, 2677 insertions(+), 183 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

-- 
2.18.0



[PATCH v3 15/15] drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

2021-08-18 Thread Nancy . Lin
Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm for
multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
up two drm drivers, only one drm driver register as the drm device.
Each drm driver binds its own component. The first bind drm driver
will allocate the drm device, and the last bind drm driver registers
the drm device to drm core. Each crtc path is created with the
corresponding drm driver data.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  25 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  15 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 372 
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   8 +-
 7 files changed, 354 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index ebcb646bde9c..c61f5bafd22c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -4,6 +4,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -87,6 +88,9 @@ void mtk_merge_stop(struct device *dev)
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+
+   if (priv->async_clk)
+   device_reset_optional(dev);
 }
 
 static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 40df2c823187..0da78adf3b4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -737,21 +737,28 @@ static int mtk_drm_crtc_init_comp_planes(struct 
drm_device *drm_dev,
 }
 
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
-   const enum mtk_ddp_comp_id *path, unsigned int path_len)
+   const enum mtk_ddp_comp_id *path, unsigned int path_len,
+   int priv_data_index)
 {
struct mtk_drm_private *priv = drm_dev->dev_private;
struct device *dev = drm_dev->dev;
struct mtk_drm_crtc *mtk_crtc;
unsigned int num_comp_planes = 0;
-   int pipe = priv->num_pipes;
int ret;
int i;
bool has_ctm = false;
uint gamma_lut_size = 0;
+   struct drm_crtc *tmp;
+   int crtc_i = 0;
 
if (!path)
return 0;
 
+   priv = priv->all_drm_private[priv_data_index];
+
+   drm_for_each_crtc(tmp, drm_dev)
+   crtc_i++;
+
for (i = 0; i < path_len; i++) {
enum mtk_ddp_comp_id comp_id = path[i];
struct device_node *node;
@@ -760,7 +767,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (!node) {
dev_info(dev,
 "Not creating crtc %d because component %d is 
disabled or missing\n",
-pipe, comp_id);
+crtc_i, comp_id);
return 0;
}
}
@@ -816,25 +823,25 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
-   pipe);
+   crtc_i);
if (ret)
return ret;
}
 
-   ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
+   ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
if (ret < 0)
return ret;
 
if (gamma_lut_size)
drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
-   priv->num_pipes++;
mutex_init(&mtk_crtc->hw_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   i = (priv->data->mmsys_dev_num > 1) ? 0 : 
drm_crtc_index(&mtk_crtc->base);
+
mtk_crtc->cmdq_client =
-   cmdq_mbox_create(mtk_crtc->mmsys_dev,
-drm_crtc_index(&mtk_crtc->base));
+   cmdq_mbox_create(mtk_crtc->mmsys_dev, i);
if (IS_ERR(mtk_crtc->cmdq_client)) {
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, 
writing register by CPU now\n",
drm_crtc_index(&mtk_crtc->base));
@@ -844,7 +851,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (mtk_crtc->cmdq_client) {
ret = of_property_read_u32_index(priv->mutex_node,
 "mediatek,gce-events",
-
drm_crtc_index(&mtk_crtc->base),
+i,
   

[PATCH v3 04/15] dt-bindings: mediatek: Add #reset-cells to mmsys system controller

2021-08-18 Thread Nancy . Lin
The mmsys system controller exposes a set of memory client resets and
needs to specify the #reset-cells property in order to advertise the
number of cells needed to describe each of the resets

Signed-off-by: Nancy.Lin 
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml   | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml 
b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 68cb330d7595..5678d55b032a 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -50,6 +50,9 @@ properties:
   "#clock-cells":
 const: 1
 
+  "#reset-cells":
+const: 1
+
 required:
   - compatible
   - reg
-- 
2.18.0



[PATCH v3 06/15] arm64: dts: mt8195: add display node for vdosys1

2021-08-18 Thread Nancy . Lin
Add display node for vdosys1.

Signed-off-by: Nancy.Lin 
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 217 +++
 1 file changed, 217 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index aa2a7849b822..b2e377515a52 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
compatible = "mediatek,mt8195";
@@ -20,6 +21,21 @@
aliases {
gce0 = &gce0;
gce1 = &gce1;
+   mutex0 = &mutex;
+   mutex1 = &mutex1;
+   merge1 = &merge1;
+   merge2 = &merge2;
+   merge3 = &merge3;
+   merge4 = &merge4;
+   merge5 = &merge5;
+   vdo1_rdma0 = &vdo1_rdma0;
+   vdo1_rdma1 = &vdo1_rdma1;
+   vdo1_rdma2 = &vdo1_rdma2;
+   vdo1_rdma3 = &vdo1_rdma3;
+   vdo1_rdma4 = &vdo1_rdma4;
+   vdo1_rdma5 = &vdo1_rdma5;
+   vdo1_rdma6 = &vdo1_rdma6;
+   vdo1_rdma7 = &vdo1_rdma7;
};
 
clocks {
@@ -1275,7 +1291,208 @@
vdosys1: syscon@1c10 {
compatible = "mediatek,mt8195-vdosys1", "syscon";
reg = <0 0x1c10 0 0x1000>;
+   mboxes = <&gce1 1 CMDQ_THR_PRIO_4>;
+   mediatek,gce-client-reg = <&gce1 SUBSYS_1c10 0x 
0x1000>;
#clock-cells = <1>;
+   #reset-cells = <1>;
+   };
+
+   mutex1: disp_mutex0@1c101000 {
+   compatible = "mediatek,mt8195-disp-mutex";
+   reg = <0 0x1c101000 0 0x1000>;
+   reg-names = "vdo1_mutex";
+   interrupts = ;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
+   clock-names = "vdo1_mutex";
+   mediatek,gce-events = 
;
+   };
+
+   vdo1_rdma0: vdo1_rdma@1c104000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c104000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+   mediatek,gce-client-reg = <&gce1 SUBSYS_1c10 0x4000 
0x1000>;
+   };
+
+   vdo1_rdma1: vdo1_rdma@1c105000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c105000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA1>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>;
+   mediatek,gce-client-reg = <&gce1 SUBSYS_1c10 0x5000 
0x1000>;
+   };
+
+   vdo1_rdma2: vdo1_rdma@1c106000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c106000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA2>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>;
+   mediatek,gce-client-reg = <&gce1 SUBSYS_1c10 0x6000 
0x1000>;
+   };
+
+   vdo1_rdma3: vdo1_rdma@1c107000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c107000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA3>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>;
+   mediatek,gce-client-reg = <&gce1 SUBSYS_1c10 0x7000 
0x1000>;
+   };
+
+   vdo1_rdma4: vdo1_rdma@1c108000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c108000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA4>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>;
+   mediatek,gce-client-reg = <&gce1 SUBSYS_1c10 0x8000 
0x1000>;
+   };
+
+   vdo1_rdma5: vdo1_rdma@1c109000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c109000 0 0x1000>

[PATCH v3 02/15] dt-bindings: mediatek: add vdosys1 MERGE definition for mt8195

2021-08-18 Thread Nancy . Lin
Add vdosys1 MERGE definition.

Signed-off-by: Nancy.Lin 
---
 .../devicetree/bindings/display/mediatek/mediatek,merge.yaml| 2 ++
 1 file changed, 2 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 1a27b037086b..ba1e0c837988 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -23,6 +23,8 @@ properties:
   - const: mediatek,mt8173-disp-merge
   - items:
   - const: mediatek,mt8195-disp-merge
+  - items:
+  - const: mediatek,mt8195-vdo1-merge
 
   reg:
 maxItems: 1
-- 
2.18.0



Re: [Intel-gfx] [PATCH 1/1] drm/i915: Check if engine has heartbeat when closing a context

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 2:28 AM John Harrison  wrote:
> On 8/9/2021 23:36, Daniel Vetter wrote:
> > On Mon, Aug 09, 2021 at 04:12:52PM -0700, John Harrison wrote:
> >> On 8/6/2021 12:46, Daniel Vetter wrote:
> >>> Seen this fly by and figured I dropped a few thoughts in here. At the
> >>> likely cost of looking a bit out of whack :-)
> >>>
> >>> On Fri, Aug 6, 2021 at 8:01 PM John Harrison  
> >>> wrote:
>  On 8/2/2021 02:40, Tvrtko Ursulin wrote:
> > On 30/07/2021 19:13, John Harrison wrote:
> >> On 7/30/2021 02:49, Tvrtko Ursulin wrote:
> >>> On 30/07/2021 01:13, John Harrison wrote:
>  On 7/28/2021 17:34, Matthew Brost wrote:
> > If an engine associated with a context does not have a heartbeat,
> > ban it
> > immediately. This is needed for GuC submission as a idle pulse
> > doesn't
> > kick the context off the hardware where it then can check for a
> > heartbeat and ban the context.
> >>> Pulse, that is a request with I915_PRIORITY_BARRIER, does not
> >>> preempt a running normal priority context?
> >>>
> >>> Why does it matter then whether or not heartbeats are enabled - when
> >>> heartbeat just ends up sending the same engine pulse (eventually,
> >>> with raising priority)?
> >> The point is that the pulse is pointless. See the rest of my comments
> >> below, specifically "the context will get resubmitted to the hardware
> >> after the pulse completes". To re-iterate...
> >>
> >> Yes, it preempts the context. Yes, it does so whether heartbeats are
> >> enabled or not. But so what? Who cares? You have preempted a context.
> >> It is no longer running on the hardware. BUT IT IS STILL A VALID
> >> CONTEXT.
> > It is valid yes, and it even may be the current ABI so another
> > question is whether it is okay to change that.
> >
> >> The backend scheduler will just resubmit it to the hardware as soon
> >> as the pulse completes. The only reason this works at all is because
> >> of the horrid hack in the execlist scheduler's back end
> >> implementation (in __execlists_schedule_in):
> >>if (unlikely(intel_context_is_closed(ce) &&
> >> !intel_engine_has_heartbeat(engine)))
> >>intel_context_set_banned(ce);
> > Right, is the above code then needed with this patch - when ban is
> > immediately applied on the higher level?
> >
> >> The actual back end scheduler is saying "Is this a zombie context? Is
> >> the heartbeat disabled? Then ban it". No other scheduler backend is
> >> going to have knowledge of zombie context status or of the heartbeat
> >> status. Nor are they going to call back into the higher levels of the
> >> i915 driver to trigger a ban operation. Certainly a hardware
> >> implemented scheduler is not going to be looking at private i915
> >> driver information to decide whether to submit a context or whether
> >> to tell the OS to kill it off instead.
> >>
> >> For persistence to work with a hardware scheduler (or a non-Intel
> >> specific scheduler such as the DRM one), the handling of zombie
> >> contexts, banning, etc. *must* be done entirely in the front end. It
> >> cannot rely on any backend hacks. That means you can't rely on any
> >> fancy behaviour of pulses.
> >>
> >> If you want to ban a context then you must explicitly ban that
> >> context. If you want to ban it at some later point then you need to
> >> track it at the top level as a zombie and then explicitly ban that
> >> zombie at whatever later point.
> > I am still trying to understand it all. If I go by the commit message:
> >
> > """
> > This is needed for GuC submission as a idle pulse doesn't
> > kick the context off the hardware where it then can check for a
> > heartbeat and ban the context.
> > """
> >
> > That did not explain things for me. Sentence does not appear to make
> > sense. Now, it seems "kick off the hardware" is meant as revoke and
> > not just preempt. Which is fine, perhaps just needs to be written more
> > explicitly. But the part of checking for heartbeat after idle pulse
> > does not compute for me. It is the heartbeat which emits idle pulses,
> > not idle pulse emitting heartbeats.
>  I am in agreement that the commit message is confusing and does not
>  explain either the problem or the solution.
> 
> 
> > But anyway, I can buy the handling at the front end story completely.
> > It makes sense. We just need to agree that a) it is okay to change the
> > ABI and b) remove the backend check from execlists if it is not needed
> > any longer.
> >
> > And if ABI change is okay then commit message needs to talk about it
> > loudly and clearly.
>  I don't think we have a choice. The current ABI is not

Re: [PATCH v2 49/63] btrfs: Use memset_startat() to clear end of struct

2021-08-18 Thread David Sterba
On Tue, Aug 17, 2021 at 11:05:19PM -0700, Kees Cook wrote:
> In preparation for FORTIFY_SOURCE performing compile-time and run-time
> field bounds checking for memset(), avoid intentionally writing across
> neighboring fields.
> 
> Use memset_startat() so memset() doesn't get confused about writing
> beyond the destination member that is intended to be the starting point
> of zeroing through the end of the struct.
> 
> Cc: Chris Mason 
> Cc: Josef Bacik 
> Cc: David Sterba 
> Cc: linux-bt...@vger.kernel.org
> Signed-off-by: Kees Cook 

Acked-by: David Sterba 


Re: [RFC] Make use of non-dynamic dmabuf in RDMA

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 9:45 AM Gal Pressman  wrote:
>
> Hey all,
>
> Currently, the RDMA subsystem can only work with dynamic dmabuf
> attachments, which requires the RDMA device to support on-demand-paging
> (ODP) which is not common on most devices (only supported by mlx5).
>
> While the dynamic requirement makes sense for certain GPUs, some devices
> (such as habanalabs) have device memory that is always "pinned" and do
> not need/use the move_notify operation.
>
> The motivation of this RFC is to use habanalabs as the dmabuf exporter,
> and EFA as the importer to allow for peer2peer access through libibverbs.
>
> This draft patch changes the dmabuf driver to differentiate between
> static/dynamic attachments by looking at the move_notify op instead of
> the importer_ops struct, and allowing the peer2peer flag to be enabled
> in case of a static exporter.
>
> Thanks
>
> Signed-off-by: Gal Pressman 

Given that habanalabs dma-buf support is very firmly in limbo (at
least it's not yet in linux-next or anywhere else) I think you want to
solve that problem first before we tackle the additional issue of
making p2p work without dynamic dma-buf. Without that it just doesn't
make a lot of sense really to talk about solutions here.
-Daniel

> ---
>  drivers/dma-buf/dma-buf.c | 5 +++--
>  drivers/infiniband/core/umem_dmabuf.c | 2 +-
>  include/linux/dma-buf.h   | 2 +-
>  3 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 511fe0d217a0..e3faad8f492c 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -727,7 +727,8 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct 
> device *dev,
> if (WARN_ON(!dmabuf || !dev))
> return ERR_PTR(-EINVAL);
>
> -   if (WARN_ON(importer_ops && !importer_ops->move_notify))
> +   if (WARN_ON(importer_ops && !importer_ops->move_notify &&
> +   dma_buf_is_dynamic(attach->dmabuf)))
> return ERR_PTR(-EINVAL);
>
> attach = kzalloc(sizeof(*attach), GFP_KERNEL);
> @@ -1048,7 +1049,7 @@ void dma_buf_move_notify(struct dma_buf *dmabuf)
> dma_resv_assert_held(dmabuf->resv);
>
> list_for_each_entry(attach, &dmabuf->attachments, node)
> -   if (attach->importer_ops)
> +   if (attach->importer_ops && attach->importer_ops->move_notify)
> attach->importer_ops->move_notify(attach);
>  }
>  EXPORT_SYMBOL_GPL(dma_buf_move_notify);
> diff --git a/drivers/infiniband/core/umem_dmabuf.c 
> b/drivers/infiniband/core/umem_dmabuf.c
> index c6e875619fac..c502ae828bd3 100644
> --- a/drivers/infiniband/core/umem_dmabuf.c
> +++ b/drivers/infiniband/core/umem_dmabuf.c
> @@ -118,7 +118,7 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct 
> ib_device *device,
> if (check_add_overflow(offset, (unsigned long)size, &end))
> return ret;
>
> -   if (unlikely(!ops || !ops->move_notify))
> +   if (unlikely(!ops))
> return ret;
>
> dmabuf = dma_buf_get(fd);
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index efdc56b9d95f..4b2e99012cb1 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -473,7 +473,7 @@ static inline bool dma_buf_is_dynamic(struct dma_buf 
> *dmabuf)
>  static inline bool
>  dma_buf_attachment_is_dynamic(struct dma_buf_attachment *attach)
>  {
> -   return !!attach->importer_ops;
> +   return !!attach->importer_ops->move_notify;
>  }
>
>  struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
> --
> 2.32.0
>


-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v2 26/63] lib/string: Move helper functions out of string.c

2021-08-18 Thread Andy Shevchenko
On Tue, Aug 17, 2021 at 11:04:56PM -0700, Kees Cook wrote:
> The core functions of string.c are those that may be implemented by
> per-architecture functions, or overloaded by FORTIFY_SOURCE. As a
> result, it needs to be built with __NO_FORTIFY. Without this, macros
> will collide with function declarations. This was accidentally working
> due to -ffreestanding (on some architectures). Make this deterministic
> by explicitly setting __NO_FORTIFY and move all the helper functions
> into string_helpers.c so that they gain the fortification coverage they
> had been missing.

No objections
Acked-by: Andy Shevchenko 

> Cc: Andy Shevchenko 
> Cc: Andrew Morton 
> Cc: Nick Desaulniers 
> Cc: Andy Lavr 
> Cc: Nathan Chancellor 
> Cc: Alexey Dobriyan 
> Cc: Stephen Rothwell 
> Cc: Bartosz Golaszewski 
> Signed-off-by: Kees Cook 
> ---
>  arch/arm/boot/compressed/string.c |   1 +
>  arch/s390/lib/string.c|   3 +
>  arch/x86/boot/compressed/misc.h   |   2 +
>  arch/x86/boot/compressed/pgtable_64.c |   2 +
>  arch/x86/lib/string_32.c  |   1 +
>  lib/string.c  | 210 +-
>  lib/string_helpers.c  | 193 +++
>  7 files changed, 208 insertions(+), 204 deletions(-)
> 
> diff --git a/arch/arm/boot/compressed/string.c 
> b/arch/arm/boot/compressed/string.c
> index 8c0fa276d994..fcc678fce045 100644
> --- a/arch/arm/boot/compressed/string.c
> +++ b/arch/arm/boot/compressed/string.c
> @@ -5,6 +5,7 @@
>   * Small subset of simple string routines
>   */
>  
> +#define __NO_FORTIFY
>  #include 
>  
>  /*
> diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c
> index cfcdf76d6a95..392fb9f4f4db 100644
> --- a/arch/s390/lib/string.c
> +++ b/arch/s390/lib/string.c
> @@ -8,6 +8,9 @@
>   */
>  
>  #define IN_ARCH_STRING_C 1
> +#ifndef __NO_FORTIFY
> +# define __NO_FORTIFY
> +#endif
>  
>  #include 
>  #include 
> diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
> index 31139256859f..49bde196da9b 100644
> --- a/arch/x86/boot/compressed/misc.h
> +++ b/arch/x86/boot/compressed/misc.h
> @@ -14,6 +14,8 @@
>  #undef CONFIG_KASAN
>  #undef CONFIG_KASAN_GENERIC
>  
> +#define __NO_FORTIFY
> +
>  /* cpu_feature_enabled() cannot be used this early */
>  #define USE_EARLY_PGTABLE_L5
>  
> diff --git a/arch/x86/boot/compressed/pgtable_64.c 
> b/arch/x86/boot/compressed/pgtable_64.c
> index 2a78746f5a4c..a1733319a22a 100644
> --- a/arch/x86/boot/compressed/pgtable_64.c
> +++ b/arch/x86/boot/compressed/pgtable_64.c
> @@ -1,3 +1,5 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include "misc.h"
>  #include 
>  #include 
>  #include 
> diff --git a/arch/x86/lib/string_32.c b/arch/x86/lib/string_32.c
> index d15fdae9656e..53b3f202267c 100644
> --- a/arch/x86/lib/string_32.c
> +++ b/arch/x86/lib/string_32.c
> @@ -11,6 +11,7 @@
>   * strings.
>   */
>  
> +#define __NO_FORTIFY
>  #include 
>  #include 
>  
> diff --git a/lib/string.c b/lib/string.c
> index 4fec38fc6e58..4e111d9dd6d5 100644
> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -6,20 +6,15 @@
>   */
>  
>  /*
> - * stupid library routines.. The optimized versions should generally be found
> - * as inline code in 
> + * This file should be used only for "library" routines that may have
> + * alternative implementations on specific architectures (generally
> + * found in ), or get overloaded by FORTIFY_SOURCE.
> + * (Specifically, this file is built with __NO_FORTIFY.)
>   *
> - * These are buggy as well..
> - *
> - * * Fri Jun 25 1999, Ingo Oeser 
> - * -  Added strsep() which will replace strtok() soon (because strsep() is
> - *reentrant and should be faster). Use only strsep() in new code, please.
> - *
> - * * Sat Feb 09 2002, Jason Thomas ,
> - *Matthew Hawkins 
> - * -  Kissed strtok() goodbye
> + * Other helper functions should live in string_helpers.c.
>   */
>  
> +#define __NO_FORTIFY
>  #include 
>  #include 
>  #include 
> @@ -254,40 +249,6 @@ ssize_t strscpy(char *dest, const char *src, size_t 
> count)
>  EXPORT_SYMBOL(strscpy);
>  #endif
>  
> -/**
> - * strscpy_pad() - Copy a C-string into a sized buffer
> - * @dest: Where to copy the string to
> - * @src: Where to copy the string from
> - * @count: Size of destination buffer
> - *
> - * Copy the string, or as much of it as fits, into the dest buffer.  The
> - * behavior is undefined if the string buffers overlap.  The destination
> - * buffer is always %NUL terminated, unless it's zero-sized.
> - *
> - * If the source string is shorter than the destination buffer, zeros
> - * the tail of the destination buffer.
> - *
> - * For full explanation of why you may want to consider using the
> - * 'strscpy' functions please see the function docstring for strscpy().
> - *
> - * Returns:
> - * * The number of characters copied (not including the trailing %NUL)
> - * * -E2BIG if count is 0 or @src was truncated.
> - */
> -ssize_t strscpy_pad(char *dest, const char *s

Re: [PATCH v8 01/34] opp: Add dev_pm_opp_sync() helper

2021-08-18 Thread Ulf Hansson
On Wed, 18 Aug 2021 at 11:14, Viresh Kumar  wrote:
>
> On 18-08-21, 10:29, Ulf Hansson wrote:
> > Me and Dmitry discussed adding a new genpd callback for this. I agreed
> > that it seems like a reasonable thing to add, if he insists.
> >
> > The intent was to invoke the new callback from __genpd_dev_pm_attach()
> > when the device has been attached to its genpd. This allows the
> > callback, to invoke clk_get_rate() and then dev_pm_opp_set_rate(), to
> > update the vote according to the current state of the HW.
>
> I wouldn't call dev_pm_opp_set_rate() from there, since it means
> configure and enable (both) for different resources, clk, regulator,
> genpd, etc..

Right, good point!

dev_pm_opp_set_rate() is best called from consumer drivers, as they
need to be in control.

>
> What we need here is just configure. So something like this then:
>
> - genpd->get_performance_state()
>   -> dev_pm_opp_get_current_opp() //New API
>   -> dev_pm_genpd_set_performance_state(dev, current_opp->pstate);
>
> This can be done just once from probe() then.

How would dev_pm_opp_get_current_opp() work? Do you have a suggestion?

>
> > I am not sure if/why that approach seemed insufficient?
> >
> > Another option to solve the problem, I think, is simply to patch
> > drivers to let them call dev_pm_opp_set_rate() during ->probe(), this
> > should synchronize the HW state too.
>
> Dmitry already mentioned that this will make the device start
> consuming power, and he doesn't want that, else we need an explicit
> disble call as well.

I am sure I understand the problem. When a device is getting probed,
it needs to consume power, how else can the corresponding driver
successfully probe it?

>
> --
> viresh

Kind regards
Uffe


Re: [PATCH v8 01/34] opp: Add dev_pm_opp_sync() helper

2021-08-18 Thread Ulf Hansson
On Wed, 18 Aug 2021 at 11:41, Ulf Hansson  wrote:
>
> On Wed, 18 Aug 2021 at 11:14, Viresh Kumar  wrote:
> >
> > On 18-08-21, 10:29, Ulf Hansson wrote:
> > > Me and Dmitry discussed adding a new genpd callback for this. I agreed
> > > that it seems like a reasonable thing to add, if he insists.
> > >
> > > The intent was to invoke the new callback from __genpd_dev_pm_attach()
> > > when the device has been attached to its genpd. This allows the
> > > callback, to invoke clk_get_rate() and then dev_pm_opp_set_rate(), to
> > > update the vote according to the current state of the HW.
> >
> > I wouldn't call dev_pm_opp_set_rate() from there, since it means
> > configure and enable (both) for different resources, clk, regulator,
> > genpd, etc..
>
> Right, good point!
>
> dev_pm_opp_set_rate() is best called from consumer drivers, as they
> need to be in control.
>
> >
> > What we need here is just configure. So something like this then:
> >
> > - genpd->get_performance_state()
> >   -> dev_pm_opp_get_current_opp() //New API
> >   -> dev_pm_genpd_set_performance_state(dev, current_opp->pstate);
> >
> > This can be done just once from probe() then.
>
> How would dev_pm_opp_get_current_opp() work? Do you have a suggestion?
>
> >
> > > I am not sure if/why that approach seemed insufficient?
> > >
> > > Another option to solve the problem, I think, is simply to patch
> > > drivers to let them call dev_pm_opp_set_rate() during ->probe(), this
> > > should synchronize the HW state too.
> >
> > Dmitry already mentioned that this will make the device start
> > consuming power, and he doesn't want that, else we need an explicit
> > disble call as well.
>
> I am sure I understand the problem. When a device is getting probed,

/s/I am sure/I am not sure

> it needs to consume power, how else can the corresponding driver
> successfully probe it?
>
> >
> > --
> > viresh
>
> Kind regards
> Uffe


Re: [Intel-gfx] [PATCH 0/1] Fix gem_ctx_persistence failures with GuC submission

2021-08-18 Thread Daniel Vetter
On Tue, Aug 17, 2021 at 05:08:02PM -0700, John Harrison wrote:
> On 8/9/2021 23:38, Daniel Vetter wrote:
> > On Wed, Jul 28, 2021 at 05:33:59PM -0700, Matthew Brost wrote:
> > > Should fix below failures with GuC submission for the following tests:
> > > gem_exec_balancer --r noheartbeat
> > > gem_ctx_persistence --r heartbeat-close
> > > 
> > > Not going to fix:
> > > gem_ctx_persistence --r heartbeat-many
> > > gem_ctx_persistence --r heartbeat-stop
> > After looking at that big thread and being very confused: Are we fixing an
> > actual use-case here, or is this another case of blindly following igts
> > tests just because they exist?
> My understanding is that this is established behaviour and therefore must be
> maintained because the UAPI (whether documented or not) is inviolate.
> Therefore IGTs have been written to validate this past behaviour and now we
> must conform to the IGTs in order to keep the existing behaviour unchanged.

No, we do not need to blindly conform to igts. We've found enough examples
in the past few months where the igt tests where just testing stuff
because it's possible, not because any UMD actually needs the behaviour.

And drm subsystem rules are very clear that low-level tests do _not_
qualify as userspace, so if they're wrong we just have to fix them.

> Whether anybody actually makes use of this behaviour or not is another
> matter entirely. I am certainly not aware of any vital use case. Others
> might have more recollection. I do know that we tell the UMD teams to
> explicitly disable persistence on every context they create.

Does that include mesa?

> > I'm leaning towards that we should stall on this, and first document what
> > exactly is the actual intention behind all this, and then fix up the tests
> I'm not sure there ever was an 'intention'. The rumour I heard way back when
> was that persistence was a bug on earlier platforms (or possibly we didn't
> have hardware support for doing engine resets?). But once the bug was
> realised (or the hardware support was added), it was too late to change the
> default behaviour because existing kernel behaviour must never change on
> pain of painful things. Thus the persistence flag was added so that people
> could opt out of the broken, leaky behaviour and have their contexts clean
> up properly.
> 
> Feel free to document what you believe should be the behaviour from a
> software architect point of view. Any documentation I produce is basically
> going to be created by reverse engineering the existing code. That is the
> only 'spec' that I am aware of and as I keep saying, I personally think it
> is a totally broken concept that should just be removed.

There is most likely no spec except "what does current userspace actually
expect". Yes this sucks. Also if you expect me to do this, I'm backlogged
by a few months on random studies here, and largely this boils down to
checking all the umds and checking what they actually need.

Important: What igt does doesn't matter if there's not a corresponding
real world umd use-case.

> > to match (if needed). And only then fix up GuC to match whatever we
> > actually want to do.
> I also still maintain there is no 'fix up the GuC'. This is not behaviour we
> should be adding to a hardware scheduler. It is behaviour that should be
> implemented at the front end not the back end. If we absolutely need to do
> this then we need to do it solely at the context management level not at the
> back end submission level. And the solution should work by default on any
> submission back end.

With "Fix up GuC" I dont mean necessarily the guc fw, but our entire
backend. We can very much fix that to fix most anything reasonable.

Also we don't actually need the same solution on all backends, because the
uapi can have slight differences across platforms. That's why changing the
defaults is so hard once they're set in stone.
-Daniel

> 
> John.
> 
> 
> > -Daniel
> > 
> > > As the above tests change the heartbeat value to 0 (off) after the
> > > context is closed and we have no way to detect that with GuC submission
> > > unless we keep a list of closed but running contexts which seems like
> > > overkill for a non-real world use case. We likely should just skip these
> > > tests with GuC submission.
> > > 
> > > Signed-off-by: Matthew Brost 
> > > 
> > > Matthew Brost (1):
> > >drm/i915: Check if engine has heartbeat when closing a context
> > > 
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.c   |  5 +++--
> > >   drivers/gpu/drm/i915/gt/intel_context_types.h |  2 ++
> > >   drivers/gpu/drm/i915/gt/intel_engine.h| 21 ++-
> > >   .../drm/i915/gt/intel_execlists_submission.c  | 14 +
> > >   .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  6 +-
> > >   .../gpu/drm/i915/gt/uc/intel_guc_submission.h |  2 --
> > >   6 files changed, 26 insertions(+), 24 deletions(-)
> > > 
> > > -- 
> > > 2.28.0
> > > 
> 

-- 
Daniel Vetter
Software Engineer, Intel Corpo

Re: [PATCH v8 01/34] opp: Add dev_pm_opp_sync() helper

2021-08-18 Thread Viresh Kumar
On 18-08-21, 11:41, Ulf Hansson wrote:
> On Wed, 18 Aug 2021 at 11:14, Viresh Kumar  wrote:
> > What we need here is just configure. So something like this then:
> >
> > - genpd->get_performance_state()
> >   -> dev_pm_opp_get_current_opp() //New API
> >   -> dev_pm_genpd_set_performance_state(dev, current_opp->pstate);
> >
> > This can be done just once from probe() then.
> 
> How would dev_pm_opp_get_current_opp() work? Do you have a suggestion?

The opp core already has a way of finding current OPP, that's what
Dmitry is trying to use here. It finds it using clk_get_rate(), if
that is zero, it picks the lowest freq possible.

> I am sure I understand the problem. When a device is getting probed,
> it needs to consume power, how else can the corresponding driver
> successfully probe it?

Dmitry can answer that better, but a device doesn't necessarily need
to consume energy in probe. It can consume bus clock, like APB we
have, but the more energy consuming stuff can be left disabled until
the time a user comes up. Probe will just end up registering the
driver and initializing it.

-- 
viresh


Re: [Intel-gfx] [PATCH] drm/damage_helper: Fix handling of cursor dirty buffers

2021-08-18 Thread Daniel Vetter
On Tue, Aug 17, 2021 at 04:26:04PM -0700, José Roberto de Souza wrote:
> Cursors don't have a framebuffer so the fb comparisson was always
> failing and atomic state was being committed without any plane state.
> 
> So here checking if objects match when checking cursors.

This looks extremely backwards ... what exactly is this fixing? If this
isn't based on a real world compositor usage but some igt, then I'd say
the igt here is very wrong.
-Daniel

> Fixes: b9fc5e01d1ce ("drm: Add helper to implement legacy dirtyfb")
> Cc: Daniel Vetter 
> Cc: Rob Clark 
> Cc: Deepak Rawat 
> Cc: Gwan-gyeong Mun 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/drm_damage_helper.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_damage_helper.c 
> b/drivers/gpu/drm/drm_damage_helper.c
> index 8eeff0c7bdd47..595187d97c131 100644
> --- a/drivers/gpu/drm/drm_damage_helper.c
> +++ b/drivers/gpu/drm/drm_damage_helper.c
> @@ -157,12 +157,18 @@ int drm_atomic_helper_dirtyfb(struct drm_framebuffer 
> *fb,
>  retry:
>   drm_for_each_plane(plane, fb->dev) {
>   struct drm_plane_state *plane_state;
> + bool match;
>  
>   ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
>   if (ret)
>   goto out;
>  
> - if (plane->state->fb != fb) {
> + match = plane->state->fb == fb;
> + /* Check if objs match to handle dirty buffers of cursors */
> + if (plane->type == DRM_PLANE_TYPE_CURSOR && plane->state->fb)
> + match |= fb->obj[0] == plane->state->fb->obj[0];
> +
> + if (!match) {
>   drm_modeset_unlock(&plane->mutex);
>   continue;
>   }
> -- 
> 2.32.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH] drm/i915: Use designated initializers for init/exit table

2021-08-18 Thread Daniel Vetter
On Tue, Aug 17, 2021 at 04:33:57PM -0700, Kees Cook wrote:
> The kernel builds with -Werror=designated-init, and __designated_init
> is used by CONFIG_GCC_PLUGIN_RANDSTRUCT for automatically selected (all
> function pointer) structures. Include the field names in the init/exit
> table. Avoids warnings like:
> 
> drivers/gpu/drm/i915/i915_module.c:59:4: error: positional initialization of 
> field in 'struct' declared with 'designated_init' attribute 
> [-Werror=designated-init]
> 
> Cc: Jani Nikula 
> Cc: Joonas Lahtinen 
> Cc: Rodrigo Vivi 
> Cc: David Airlie 
> Cc: intel-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org
> Fixes: a04ea6ae7c67 ("drm/i915: Use a table for i915_init/exit (v2)")
> Signed-off-by: Kees Cook 

Applied to drm-intel-gt-next, should show up in linux-next/next merge
window eventually (that branch isn't in linux-next for reasons).
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_module.c | 37 +++---
>  1 file changed, 24 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_module.c 
> b/drivers/gpu/drm/i915/i915_module.c
> index c578ea8f56a0..d8b4482c69d0 100644
> --- a/drivers/gpu/drm/i915/i915_module.c
> +++ b/drivers/gpu/drm/i915/i915_module.c
> @@ -47,19 +47,30 @@ static const struct {
> int (*init)(void);
> void (*exit)(void);
>  } init_funcs[] = {
> - { i915_check_nomodeset, NULL },
> - { i915_active_module_init, i915_active_module_exit },
> - { i915_buddy_module_init, i915_buddy_module_exit },
> - { i915_context_module_init, i915_context_module_exit },
> - { i915_gem_context_module_init, i915_gem_context_module_exit },
> - { i915_objects_module_init, i915_objects_module_exit },
> - { i915_request_module_init, i915_request_module_exit },
> - { i915_scheduler_module_init, i915_scheduler_module_exit },
> - { i915_vma_module_init, i915_vma_module_exit },
> - { i915_mock_selftests, NULL },
> - { i915_pmu_init, i915_pmu_exit },
> - { i915_register_pci_driver, i915_unregister_pci_driver },
> - { i915_perf_sysctl_register, i915_perf_sysctl_unregister },
> + { .init = i915_check_nomodeset },
> + { .init = i915_active_module_init,
> +   .exit = i915_active_module_exit },
> + { .init = i915_buddy_module_init,
> +   .exit = i915_buddy_module_exit },
> + { .init = i915_context_module_init,
> +   .exit = i915_context_module_exit },
> + { .init = i915_gem_context_module_init,
> +   .exit = i915_gem_context_module_exit },
> + { .init = i915_objects_module_init,
> +   .exit = i915_objects_module_exit },
> + { .init = i915_request_module_init,
> +   .exit = i915_request_module_exit },
> + { .init = i915_scheduler_module_init,
> +   .exit = i915_scheduler_module_exit },
> + { .init = i915_vma_module_init,
> +   .exit = i915_vma_module_exit },
> + { .init = i915_mock_selftests },
> + { .init = i915_pmu_init,
> +   .exit = i915_pmu_exit },
> + { .init = i915_register_pci_driver,
> +   .exit = i915_unregister_pci_driver },
> + { .init = i915_perf_sysctl_register,
> +   .exit = i915_perf_sysctl_unregister },
>  };
>  static int init_progress;
>  
> -- 
> 2.30.2
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v3 3/9] drm: check for null master in drm_is_current_master_locked

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 03:38:18PM +0800, Desmond Cheong Zhi Xi wrote:
> There is a window after calling drm_master_release, and before a file
> is freed, where drm_file can have is_master set to true, but both the
> drm_file and drm_device have no master.
> 
> This could result in wrongly approving permissions in
> drm_is_current_master_locked. Add a check that fpriv->master is
> non-NULl to guard against this scenario.
> 
> Signed-off-by: Desmond Cheong Zhi Xi 

This should be impossible, drm_master_release is only called when the
struct file is released, which means all ioctls and anything else have
finished (they hold a temporary reference).

fpriv->master can change (if the drm_file becomes newly minted master and
wasnt one before through the setmaster ioctl), but it cannot become NULL
before it's completely gone from the system.
-Daniel


> ---
>  drivers/gpu/drm/drm_auth.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> index 8c0e0dba1611..f9267b21556e 100644
> --- a/drivers/gpu/drm/drm_auth.c
> +++ b/drivers/gpu/drm/drm_auth.c
> @@ -66,7 +66,8 @@ static bool drm_is_current_master_locked(struct drm_file 
> *fpriv)
>   
> lockdep_assert_once(lockdep_is_held(&fpriv->minor->dev->master_lookup_lock) ||
>   lockdep_is_held(&fpriv->minor->dev->master_mutex));
>  
> - return fpriv->is_master && drm_lease_owner(fpriv->master) == 
> fpriv->minor->dev->master;
> + return (fpriv->is_master && fpriv->master &&
> + drm_lease_owner(fpriv->master) == fpriv->minor->dev->master);
>  }
>  
>  /**
> -- 
> 2.25.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v3 2/9] drm: hold master_lookup_lock when releasing a drm_file's master

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 03:38:17PM +0800, Desmond Cheong Zhi Xi wrote:
> When drm_file.master changes value, the corresponding
> drm_device.master_lookup_lock should be held.
> 
> In drm_master_release, a call to drm_master_put sets the
> file_priv->master to NULL, so we protect this section with
> drm_device.master_lookup_lock.
> 
> Signed-off-by: Desmond Cheong Zhi Xi 

At this points all refcounts to drm_file have disappeared, so yeah this is
a lockless access, but also no one can observe it anymore. See also next
patch.

Hence I think the current code is fine.
-Daniel

> ---
>  drivers/gpu/drm/drm_auth.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> index 8efb58aa7d95..8c0e0dba1611 100644
> --- a/drivers/gpu/drm/drm_auth.c
> +++ b/drivers/gpu/drm/drm_auth.c
> @@ -373,8 +373,11 @@ void drm_master_release(struct drm_file *file_priv)
>   }
>  
>   /* drop the master reference held by the file priv */
> - if (file_priv->master)
> + if (file_priv->master) {
> + spin_lock(&dev->master_lookup_lock);
>   drm_master_put(&file_priv->master);
> + spin_unlock(&dev->master_lookup_lock);
> + }
>   mutex_unlock(&dev->master_mutex);
>  }
>  
> -- 
> 2.25.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v8 01/34] opp: Add dev_pm_opp_sync() helper

2021-08-18 Thread Ulf Hansson
On Wed, 18 Aug 2021 at 11:50, Viresh Kumar  wrote:
>
> On 18-08-21, 11:41, Ulf Hansson wrote:
> > On Wed, 18 Aug 2021 at 11:14, Viresh Kumar  wrote:
> > > What we need here is just configure. So something like this then:
> > >
> > > - genpd->get_performance_state()
> > >   -> dev_pm_opp_get_current_opp() //New API
> > >   -> dev_pm_genpd_set_performance_state(dev, current_opp->pstate);
> > >
> > > This can be done just once from probe() then.
> >
> > How would dev_pm_opp_get_current_opp() work? Do you have a suggestion?
>
> The opp core already has a way of finding current OPP, that's what
> Dmitry is trying to use here. It finds it using clk_get_rate(), if
> that is zero, it picks the lowest freq possible.
>
> > I am sure I understand the problem. When a device is getting probed,
> > it needs to consume power, how else can the corresponding driver
> > successfully probe it?
>
> Dmitry can answer that better, but a device doesn't necessarily need
> to consume energy in probe. It can consume bus clock, like APB we
> have, but the more energy consuming stuff can be left disabled until
> the time a user comes up. Probe will just end up registering the
> driver and initializing it.

That's perfectly fine, as then it's likely that it won't vote for an
OPP, but can postpone that as well.

Perhaps the problem is rather that the HW may already carry a non-zero
vote made from a bootloader. If the consumer driver tries to clear
that vote (calling dev_pm_opp_set_rate(dev, 0), for example), it would
still not lead to any updates of the performance state in genpd,
because genpd internally has initialized the performance-state to
zero.

Dmitry?

>
> --
> viresh

Kind regards
Uffe


Re: [PATCH v3 4/9] drm: fix potential null ptr dereferences in drm_{auth,ioctl}

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 03:38:19PM +0800, Desmond Cheong Zhi Xi wrote:
> There are three areas where we dereference struct drm_master without
> checking if the pointer is non-NULL.
> 
> 1. drm_getmagic is called from the ioctl_handler. Since
> DRM_IOCTL_GET_MAGIC has no ioctl flags, drm_getmagic is run without
> any check that drm_file.master has been set.
> 
> 2. Similarly, drm_getunique is called from the ioctl_handler, but
> DRM_IOCTL_GET_UNIQUE has no ioctl flags. So there is no guarantee that
> drm_file.master has been set.

I think the above two are impossible, due to the refcounting rules for
struct file.

> 3. drm_master_release can also be called without having a
> drm_file.master set. Here is one error path:
>   drm_open():
> drm_open_helper():
>   drm_master_open():
> drm_new_set_master(); <--- returns -ENOMEM,
>drm_file.master not set
>   drm_file_free():
> drm_master_release(); <--- NULL ptr dereference
>(file_priv->master->magic_map)
> 
> Fix these by checking if the master pointers are NULL before use.
> 
> Signed-off-by: Desmond Cheong Zhi Xi 
> ---
>  drivers/gpu/drm/drm_auth.c  | 16 ++--
>  drivers/gpu/drm/drm_ioctl.c |  5 +
>  2 files changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> index f9267b21556e..b7230604496b 100644
> --- a/drivers/gpu/drm/drm_auth.c
> +++ b/drivers/gpu/drm/drm_auth.c
> @@ -95,11 +95,18 @@ EXPORT_SYMBOL(drm_is_current_master);
>  int drm_getmagic(struct drm_device *dev, void *data, struct drm_file 
> *file_priv)
>  {
>   struct drm_auth *auth = data;
> + struct drm_master *master;
>   int ret = 0;
>  
>   mutex_lock(&dev->master_mutex);
> + master = file_priv->master;
> + if (!master) {
> + mutex_unlock(&dev->master_mutex);
> + return -EINVAL;
> + }
> +
>   if (!file_priv->magic) {
> - ret = idr_alloc(&file_priv->master->magic_map, file_priv,
> + ret = idr_alloc(&master->magic_map, file_priv,
>   1, 0, GFP_KERNEL);
>   if (ret >= 0)
>   file_priv->magic = ret;
> @@ -355,8 +362,12 @@ void drm_master_release(struct drm_file *file_priv)
>  
>   mutex_lock(&dev->master_mutex);
>   master = file_priv->master;
> +
> + if (!master)
> + goto unlock;

This is a bit convoluted, since we're in the single-threaded release path
we don't need any locking for file_priv related things. Therefore we can
pull the master check out and just directly return.

But since it's a bit surprising maybe a comment that this can happen when
drm_master_open in drm_open_helper fails?

Another option, and maybe cleaner, would be to move the drm_master_release
from drm_file_free into drm_close_helper. That would be fully symmetrical
and should also fix the bug here?
-Daniel


> +
>   if (file_priv->magic)
> - idr_remove(&file_priv->master->magic_map, file_priv->magic);
> + idr_remove(&master->magic_map, file_priv->magic);
>  
>   if (!drm_is_current_master_locked(file_priv))
>   goto out;
> @@ -379,6 +390,7 @@ void drm_master_release(struct drm_file *file_priv)
>   drm_master_put(&file_priv->master);
>   spin_unlock(&dev->master_lookup_lock);
>   }
> +unlock:
>   mutex_unlock(&dev->master_mutex);
>  }
>  
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index 26f3a9ede8fe..4d029d3061d9 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -121,6 +121,11 @@ int drm_getunique(struct drm_device *dev, void *data,
>  
>   mutex_lock(&dev->master_mutex);
>   master = file_priv->master;
> + if (!master) {
> + mutex_unlock(&dev->master_mutex);
> + return -EINVAL;
> + }
> +
>   if (u->unique_len >= master->unique_len) {
>   if (copy_to_user(u->unique, master->unique, 
> master->unique_len)) {
>   mutex_unlock(&dev->master_mutex);
> -- 
> 2.25.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH v1 3/4] arm64: dts: qcom: sc7280: Add DSI display nodes

2021-08-18 Thread Krishna Manikandan
From: Rajeev Nandan 

Add DSI controller and PHY nodes for sc7280.

Signed-off-by: Rajeev Nandan 
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 101 +++
 1 file changed, 101 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi 
b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index fd7ff1c..aadf55d 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -1483,6 +1483,18 @@
 
status = "disabled";
 
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   dpu_intf1_out: endpoint {
+   remote-endpoint = 
<&dsi0_in>;
+   };
+   };
+   };
+
mdp_opp_table: mdp-opp-table {
compatible = "operating-points-v2";
 
@@ -1507,6 +1519,95 @@
};
};
};
+
+   dsi0: dsi@ae94000 {
+   compatible = "qcom,mdss-dsi-ctrl";
+   reg = <0 0x0ae94000 0 0x400>;
+   reg-names = "dsi_ctrl";
+
+   interrupt-parent = <&mdss>;
+   interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+
+   clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
+<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
+<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
+<&dispcc DISP_CC_MDSS_ESC0_CLK>,
+<&dispcc DISP_CC_MDSS_AHB_CLK>,
+<&gcc GCC_DISP_HF_AXI_CLK>;
+   clock-names = "byte",
+ "byte_intf",
+ "pixel",
+ "core",
+ "iface",
+ "bus";
+
+   operating-points-v2 = <&dsi_opp_table>;
+   power-domains = <&rpmhpd SC7280_CX>;
+
+   phys = <&dsi_phy>;
+   phy-names = "dsi";
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   dsi0_in: endpoint {
+   remote-endpoint = 
<&dpu_intf1_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   dsi0_out: endpoint {
+   };
+   };
+   };
+
+   dsi_opp_table: dsi-opp-table {
+   compatible = "operating-points-v2";
+
+   opp-18750 {
+   opp-hz = /bits/ 64 <18750>;
+   required-opps = 
<&rpmhpd_opp_low_svs>;
+   };
+
+   opp-3 {
+   opp-hz = /bits/ 64 <3>;
+   required-opps = 
<&rpmhpd_opp_svs>;
+   };
+
+   opp-35800 {
+   opp-hz = /bits/ 64 <35800>;
+   required-opps = 
<&rpmhpd_opp_svs_l1>;
+   };
+   };
+   };
+
+   dsi_phy: dsi-phy@ae94400 {
+   compatible = "qcom,sc7280-dsi-phy-7nm";
+   reg = <0 0x0ae94400 0 0x200>,
+ <0 0x0ae94600 0 0x280>,
+  

[PATCH v1 2/4] arm64: dts: qcom: sc7280: add display dt nodes

2021-08-18 Thread Krishna Manikandan
Add mdss and mdp DT nodes for sc7280.

Signed-off-by: Krishna Manikandan 
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 85 
 1 file changed, 85 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi 
b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 53a21d0..fd7ff1c 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -5,6 +5,7 @@
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -1424,6 +1425,90 @@
#power-domain-cells = <1>;
};
 
+   mdss: mdss@ae0 {
+   compatible = "qcom,sc7280-mdss";
+   reg = <0 0x0ae0 0 0x1000>;
+   reg-names = "mdss";
+
+   power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>;
+
+   clocks = <&gcc GCC_DISP_AHB_CLK>,
+<&dispcc DISP_CC_MDSS_AHB_CLK>,
+   <&dispcc DISP_CC_MDSS_MDP_CLK>;
+   clock-names = "iface", "ahb", "core";
+
+   assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>;
+   assigned-clock-rates = <3>;
+
+   interrupts = ;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt 
SLAVE_EBI1 0>;
+   interconnect-names = "mdp0-mem";
+
+   iommus = <&apps_smmu 0x900 0x402>;
+
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+
+   status = "disabled";
+
+   mdp: mdp@ae01000 {
+   compatible = "qcom,sc7280-dpu";
+   reg = <0 0x0ae01000 0 0x8f030>,
+   <0 0x0aeb 0 0x2008>;
+   reg-names = "mdp", "vbif";
+
+   clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+   <&gcc GCC_DISP_SF_AXI_CLK>,
+   <&dispcc DISP_CC_MDSS_AHB_CLK>,
+   <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
+   <&dispcc DISP_CC_MDSS_MDP_CLK>,
+   <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+   clock-names = "bus", "nrt_bus", "iface", "lut", 
"core",
+ "vsync";
+   assigned-clocks = <&dispcc 
DISP_CC_MDSS_MDP_CLK>,
+   <&dispcc 
DISP_CC_MDSS_VSYNC_CLK>,
+   <&dispcc DISP_CC_MDSS_AHB_CLK>;
+   assigned-clock-rates = <3>,
+   <1920>,
+   <1920>;
+   operating-points-v2 = <&mdp_opp_table>;
+   power-domains = <&rpmhpd SC7280_CX>;
+
+   interrupt-parent = <&mdss>;
+   interrupts = <0>;
+
+   status = "disabled";
+
+   mdp_opp_table: mdp-opp-table {
+   compatible = "operating-points-v2";
+
+   opp-2 {
+   opp-hz = /bits/ 64 <2>;
+   required-opps = 
<&rpmhpd_opp_low_svs>;
+   };
+
+   opp-3 {
+   opp-hz = /bits/ 64 <3>;
+   required-opps = 
<&rpmhpd_opp_svs>;
+   };
+
+   opp-38000 {
+   opp-hz = /bits/ 64 <38000>;
+   required-opps = 
<&rpmhpd_opp_svs_l1>;
+   };
+
+   opp-50667 {
+   opp-hz = /bits/ 64 <50667>;
+   required-opps = 
<&rpmhpd_opp_nom>;
+   };
+   };
+   };
+   };
+
pdc: interrupt-controller@b22 {
compatible = "qcom,sc7280-pdc", "qcom,pdc";
reg = <0 0x0b22 0 0x3>;
-- 
2.7.4



[PATCH v1 1/4] dt-bindings: msm: add DT bindings for sc7280

2021-08-18 Thread Krishna Manikandan
MSM Mobile Display Subsystem (MDSS) encapsulates sub-blocks
like DPU display controller, DSI, EDP etc. Add required DPU
device tree bindings for SC7280.

Signed-off-by: Krishna Manikandan 
---
 .../bindings/display/msm/dpu-sc7280.yaml   | 228 +
 1 file changed, 228 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml

diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml 
b/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
new file mode 100644
index 000..3d256c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
@@ -0,0 +1,228 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/dpu-sc7280.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display DPU dt properties for SC7280 target
+
+maintainers:
+  - Krishna Manikandan 
+
+description: |
+  Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
+  sub-blocks like DPU display controller, DSI and DP interfaces etc. Device 
tree
+  bindings of MDSS and DPU are mentioned for SC7280 target.
+
+properties:
+  compatible:
+items:
+  - const: qcom,sc7280-mdss
+
+  reg:
+maxItems: 1
+
+  reg-names:
+const: mdss
+
+  power-domains:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Display AHB clock from gcc
+  - description: Display AHB clock from dispcc
+  - description: Display core clock
+
+  clock-names:
+items:
+  - const: iface
+  - const: ahb
+  - const: core
+
+  interrupts:
+maxItems: 1
+
+  interrupt-controller: true
+
+  "#address-cells": true
+
+  "#size-cells": true
+
+  "#interrupt-cells":
+const: 1
+
+  iommus:
+items:
+  - description: Phandle to apps_smmu node with SID mask for Hard-Fail 
port0
+
+  ranges: true
+
+  interconnects:
+items:
+  - description: Interconnect path specifying the port ids for data bus
+
+  interconnect-names:
+const: mdp0-mem
+
+patternProperties:
+  "^display-controller@[0-9a-f]+$":
+type: object
+description: Node containing the properties of DPU.
+
+properties:
+  compatible:
+items:
+  - const: qcom,sc7280-dpu
+
+  reg:
+items:
+  - description: Address offset and size for mdp register set
+  - description: Address offset and size for vbif register set
+
+  reg-names:
+items:
+  - const: mdp
+  - const: vbif
+
+  clocks:
+items:
+  - description: Display hf axi clock
+  - description: Display sf axi clock
+  - description: Display ahb clock
+  - description: Display lut clock
+  - description: Display core clock
+  - description: Display vsync clock
+
+  clock-names:
+items:
+  - const: bus
+  - const: nrt_bus
+  - const: iface
+  - const: lut
+  - const: core
+  - const: vsync
+
+  interrupts:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+  operating-points-v2: true
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+description: |
+  Contains the list of output ports from DPU device. These ports
+  connect to interfaces that are external to the DPU hardware,
+  such as DSI, DP etc. Each output port contains an endpoint that
+  describes how it is connected to an external interface.
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: DPU_INTF1 (DSI)
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: DPU_INTF5 (EDP)
+
+required:
+  - port@0
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - interrupts
+  - power-domains
+  - operating-points-v2
+  - ports
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - power-domains
+  - clocks
+  - interrupts
+  - interrupt-controller
+  - iommus
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+#include 
+#include 
+
+display-subsystem@ae0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,sc7280-mdss";
+ reg = <0xae0 0x1000>;
+ reg-names = "mdss";
+ power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>;
+ clocks = <&gcc GCC_DISP_AHB_CLK>,
+  <&dispcc DISP_CC_MDSS_AHB_CLK>,
+  <&dispcc DISP_CC_MDSS_MDP_CLK>;
+ clock-names = "iface", "ahb", "core";
+
+ interrupts = ;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
+ interconnect-names = "mdp0-mem";
+
+ i

[PATCH v1 4/4] arm64: dts: qcom: sc7280: add edp display dt nodes

2021-08-18 Thread Krishna Manikandan
From: Sankeerth Billakanti 

Add edp controller and phy DT nodes for sc7280.

Signed-off-by: Sankeerth Billakanti 
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 127 ++-
 1 file changed, 126 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi 
b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index aadf55d..5be318e 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -1412,7 +1412,7 @@
reg = <0 0xaf0 0 0x2>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
 <&gcc GCC_DISP_GPLL0_CLK_SRC>,
-<0>, <0>, <0>, <0>, <0>, <0>;
+<0>, <0>, <0>, <0>, <&edp_phy 0>, <&edp_phy 1>;
clock-names = "bi_tcxo", "gcc_disp_gpll0_clk",
  "dsi0_phy_pll_out_byteclk",
  "dsi0_phy_pll_out_dsiclk",
@@ -1493,6 +1493,12 @@
remote-endpoint = 
<&dsi0_in>;
};
};
+   port@1 {
+   reg = <1>;
+   dpu_intf5_out: endpoint {
+   remote-endpoint = 
<&edp_in>;
+   };
+   };
};
 
mdp_opp_table: mdp-opp-table {
@@ -1608,6 +1614,101 @@
 
status = "disabled";
};
+
+   msm_edp: edp@aea {
+   status = "disabled";
+   compatible = "qcom,sc7280-edp";
+   reg = <0 0xaea 0 0x200>,
+ <0 0xaea0200 0 0x200>,
+ <0 0xaea0400 0 0xc00>,
+ <0 0xaea1000 0 0x400>;
+
+   interrupt-parent = <&mdss>;
+   interrupts = <14 IRQ_TYPE_NONE>;
+
+   clocks = <&rpmhcc RPMH_CXO_CLK>,
+<&gcc GCC_EDP_CLKREF_EN>,
+<&dispcc DISP_CC_MDSS_AHB_CLK>,
+<&dispcc DISP_CC_MDSS_EDP_AUX_CLK>,
+<&dispcc DISP_CC_MDSS_EDP_LINK_CLK>,
+<&dispcc 
DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
+<&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK>;
+   clock-names = "core_xo", "core_ref",
+ "core_iface", "core_aux", 
"ctrl_link",
+ "ctrl_link_iface", "stream_pixel";
+   #clock-cells = <1>;
+   assigned-clocks = <&dispcc 
DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
+ <&dispcc 
DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
+   assigned-clock-parents = <&edp_phy 0>, 
<&edp_phy 1>;
+
+   phys = <&edp_phy>;
+   phy-names = "dp";
+
+   vdda-1p2-supply = <&vreg_l6b_1p2>;
+   vdda-0p9-supply = <&vreg_l10c_0p8>;
+   operating-points-v2 = <&edp_opp_table>;
+   power-domains = <&rpmhpd SC7280_CX>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&edp_hot_plug_det>, 
<&edp_panel_power_on>;
+
+   panel-bklt-gpio = <&pm8350c_gpios 7 
GPIO_ACTIVE_HIGH>;
+   panel-pwm-gpio = <&pm8350c_gpios 8 
GPIO_ACTIVE_HIGH>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   port@0 {
+   reg = <0>;
+   edp_in: endpoint {
+   remote-endpoint = 
<&dpu_intf5_out>;
+   };
+   };
+   };
+
+   edp_opp_table: edp-opp-table {
+   compatible = "operating-points-v2";
+
+   opp-16000 {
+   opp-hz = /bits/ 64 <16000>;
+   required-op

Re: [PATCH v3 5/9] drm: protect magic_map,unique{_len} with master_lookup_lock

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 03:38:20PM +0800, Desmond Cheong Zhi Xi wrote:
> Currently, drm_device.master_mutex is used to serialize writes to the
> drm_master.magic_map idr and to protect drm_master.unique{_len}.
> 
> In preparation for converting drm_device.master_mutex into an outer
> rwsem that might be read locked before entering some of these
> functions, we can instead serialize access to drm_master.magic_map and
> drm_master.unique{_len} using drm_device.master_lookup_lock which is
> an inner lock.
> 
> Signed-off-by: Desmond Cheong Zhi Xi 
> ---
>  drivers/gpu/drm/drm_auth.c  | 12 +++-
>  drivers/gpu/drm/drm_ioctl.c | 10 ++
>  include/drm/drm_auth.h  |  6 +++---
>  include/drm/drm_device.h|  7 ++-
>  4 files changed, 22 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> index b7230604496b..0acb444fbbac 100644
> --- a/drivers/gpu/drm/drm_auth.c
> +++ b/drivers/gpu/drm/drm_auth.c
> @@ -98,10 +98,10 @@ int drm_getmagic(struct drm_device *dev, void *data, 
> struct drm_file *file_priv)
>   struct drm_master *master;
>   int ret = 0;
>  
> - mutex_lock(&dev->master_mutex);
> + spin_lock(&dev->master_lookup_lock);
>   master = file_priv->master;
>   if (!master) {
> - mutex_unlock(&dev->master_mutex);
> + spin_unlock(&dev->master_lookup_lock);
>   return -EINVAL;
>   }
>  
> @@ -112,7 +112,7 @@ int drm_getmagic(struct drm_device *dev, void *data, 
> struct drm_file *file_priv)
>   file_priv->magic = ret;
>   }
>   auth->magic = file_priv->magic;
> - mutex_unlock(&dev->master_mutex);
> + spin_unlock(&dev->master_lookup_lock);
>  
>   DRM_DEBUG("%u\n", auth->magic);
>  
> @@ -127,13 +127,13 @@ int drm_authmagic(struct drm_device *dev, void *data,
>  
>   DRM_DEBUG("%u\n", auth->magic);
>  
> - mutex_lock(&dev->master_mutex);
> + spin_lock(&dev->master_lookup_lock);
>   file = idr_find(&file_priv->master->magic_map, auth->magic);
>   if (file) {
>   file->authenticated = 1;
>   idr_replace(&file_priv->master->magic_map, NULL, auth->magic);
>   }
> - mutex_unlock(&dev->master_mutex);
> + spin_unlock(&dev->master_lookup_lock);
>  
>   return file ? 0 : -EINVAL;
>  }
> @@ -366,8 +366,10 @@ void drm_master_release(struct drm_file *file_priv)
>   if (!master)
>   goto unlock;
>  
> + spin_lock(&dev->master_lookup_lock);
>   if (file_priv->magic)
>   idr_remove(&master->magic_map, file_priv->magic);
> + spin_unlock(&dev->master_lookup_lock);
>  
>   if (!drm_is_current_master_locked(file_priv))
>   goto out;
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index 4d029d3061d9..e5c3845b6e62 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -119,21 +119,21 @@ int drm_getunique(struct drm_device *dev, void *data,
>   struct drm_unique *u = data;
>   struct drm_master *master;
>  
> - mutex_lock(&dev->master_mutex);
> + spin_lock(&dev->master_lookup_lock);
>   master = file_priv->master;
>   if (!master) {
> - mutex_unlock(&dev->master_mutex);
> + spin_unlock(&dev->master_lookup_lock);
>   return -EINVAL;
>   }
>  
>   if (u->unique_len >= master->unique_len) {
>   if (copy_to_user(u->unique, master->unique, 
> master->unique_len)) {
> - mutex_unlock(&dev->master_mutex);
> + spin_unlock(&dev->master_lookup_lock);

copy_to_user while holding a spinlock isn't going to work well, at least
when we take a fault. The might_fault() annotations (if enabled) should
catch that.

Which is really annoying, because it kinda puts a wrench into this neat
plan here :-/

>   return -EFAULT;
>   }
>   }
>   u->unique_len = master->unique_len;
> - mutex_unlock(&dev->master_mutex);
> + spin_unlock(&dev->master_lookup_lock);
>  
>   return 0;
>  }
> @@ -405,7 +405,9 @@ static int drm_setversion(struct drm_device *dev, void 
> *data, struct drm_file *f
>* Version 1.1 includes tying of DRM to specific device
>* Version 1.4 has proper PCI domain support
>*/
> + spin_lock(&dev->master_lookup_lock);
>   retcode = drm_set_busid(dev, file_priv);
> + spin_unlock(&dev->master_lookup_lock);

Similar issue with drm_set_busid, calling kmalloc under a spinlock isn't a
good idea. This one here is at least much easier to fix by pushing the
locking down a lot.

I'm wondering a bit whether a better fix for these ioctls wouldn't be to
- drop the DRM_MASTER flag from the ioctl table
- take the rwsem in write mode (which would replace our current
  dev->master_lock) and check for master status while holdin

[PATCH 1/2] dma-buf: nuke DMA_FENCE_TRACE macros v2

2021-08-18 Thread Christian König
Only the DRM GPU scheduler, radeon and amdgpu where using them and they depend
on a non existing config option to actually emit some code.

v2: keep the signal path as is for now

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 10 +-
 drivers/gpu/drm/radeon/radeon_fence.c | 24 ---
 drivers/gpu/drm/scheduler/sched_fence.c   | 18 ++---
 include/linux/dma-fence.h | 22 -
 4 files changed, 7 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 0b1c48590c43..c65994e382bd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -246,7 +246,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
struct amdgpu_fence_driver *drv = &ring->fence_drv;
struct amdgpu_device *adev = ring->adev;
uint32_t seq, last_seq;
-   int r;
 
do {
last_seq = atomic_read(&ring->fence_drv.last_seq);
@@ -278,12 +277,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
if (!fence)
continue;
 
-   r = dma_fence_signal(fence);
-   if (!r)
-   DMA_FENCE_TRACE(fence, "signaled from irq context\n");
-   else
-   BUG();
-
+   dma_fence_signal(fence);
dma_fence_put(fence);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -639,8 +633,6 @@ static bool amdgpu_fence_enable_signaling(struct dma_fence 
*f)
if (!timer_pending(&ring->fence_drv.fallback_timer))
amdgpu_fence_schedule_fallback(ring);
 
-   DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx);
-
return true;
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 18f2c2e0dfb3..3f351d222cbb 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -176,18 +176,11 @@ static int radeon_fence_check_signaled(wait_queue_entry_t 
*wait, unsigned mode,
 */
seq = atomic64_read(&fence->rdev->fence_drv[fence->ring].last_seq);
if (seq >= fence->seq) {
-   int ret = dma_fence_signal_locked(&fence->base);
-
-   if (!ret)
-   DMA_FENCE_TRACE(&fence->base, "signaled from irq 
context\n");
-   else
-   DMA_FENCE_TRACE(&fence->base, "was already signaled\n");
-
+   dma_fence_signal_locked(&fence->base);
radeon_irq_kms_sw_irq_put(fence->rdev, fence->ring);
__remove_wait_queue(&fence->rdev->fence_queue, 
&fence->fence_wake);
dma_fence_put(&fence->base);
-   } else
-   DMA_FENCE_TRACE(&fence->base, "pending\n");
+   }
return 0;
 }
 
@@ -422,8 +415,6 @@ static bool radeon_fence_enable_signaling(struct dma_fence 
*f)
fence->fence_wake.func = radeon_fence_check_signaled;
__add_wait_queue(&rdev->fence_queue, &fence->fence_wake);
dma_fence_get(f);
-
-   DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", fence->ring);
return true;
 }
 
@@ -441,11 +432,7 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
return true;
 
if (radeon_fence_seq_signaled(fence->rdev, fence->seq, fence->ring)) {
-   int ret;
-
-   ret = dma_fence_signal(&fence->base);
-   if (!ret)
-   DMA_FENCE_TRACE(&fence->base, "signaled from 
radeon_fence_signaled\n");
+   dma_fence_signal(&fence->base);
return true;
}
return false;
@@ -550,7 +537,6 @@ long radeon_fence_wait_timeout(struct radeon_fence *fence, 
bool intr, long timeo
 {
uint64_t seq[RADEON_NUM_RINGS] = {};
long r;
-   int r_sig;
 
/*
 * This function should not be called on !radeon fences.
@@ -567,9 +553,7 @@ long radeon_fence_wait_timeout(struct radeon_fence *fence, 
bool intr, long timeo
return r;
}
 
-   r_sig = dma_fence_signal(&fence->base);
-   if (!r_sig)
-   DMA_FENCE_TRACE(&fence->base, "signaled from fence_wait\n");
+   dma_fence_signal(&fence->base);
return r;
 }
 
diff --git a/drivers/gpu/drm/scheduler/sched_fence.c 
b/drivers/gpu/drm/scheduler/sched_fence.c
index 69de2c76731f..3736746c47bd 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -50,26 +50,12 @@ static void __exit drm_sched_fence_slab_fini(void)
 
 void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
 {
-   int ret = dma_fence_signal(&fence->scheduled);
-
-   if (!ret)
-   DMA_FENCE_TRACE(&fence->scheduled,
-

[PATCH 2/2] dma-buf: taint the kernel on sw_sync use

2021-08-18 Thread Christian König
As we now knew allowing userspace control over dma_fence synchronization
is fundamentally broken and can cause deadlocks inside the kernel memory
management.

Because of this harden the wording for CONFIG_SW_SYNC and taint the kernel
as soon as it is used.

Signed-off-by: Christian König 
---
 drivers/dma-buf/Kconfig   | 5 +++--
 drivers/dma-buf/sw_sync.c | 5 -
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig
index 9561e3d2d428..61e0f3c5ba8b 100644
--- a/drivers/dma-buf/Kconfig
+++ b/drivers/dma-buf/Kconfig
@@ -27,8 +27,9 @@ config SW_SYNC
  synchronization.  Useful when there is no hardware primitive backing
  the synchronization.
 
- WARNING: improper use of this can result in deadlocking kernel
- drivers from userspace. Intended for test and debug only.
+ WARNING: improper use of this can result in deadlocking the kernel
+ memory management from userspace. Intended for test and debug only.
+ Use at your own risk.
 
 config UDMABUF
bool "userspace dmabuf misc driver"
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 348b3a9170fa..c2bcb9062f51 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -286,7 +286,8 @@ static struct sync_pt *sync_pt_create(struct sync_timeline 
*obj,
 /*
  * *WARNING*
  *
- * improper use of this can result in deadlocking kernel drivers from 
userspace.
+ * improper use of this can result in deadlocking kernel memory management
+ * from userspace.
  */
 
 /* opening sw_sync create a new sync obj */
@@ -295,6 +296,8 @@ static int sw_sync_debugfs_open(struct inode *inode, struct 
file *file)
struct sync_timeline *obj;
char task_comm[TASK_COMM_LEN];
 
+   add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK);
+
get_task_comm(task_comm, current);
 
obj = sync_timeline_create(task_comm);
-- 
2.25.1



Re: [PATCH v3 7/9] drm: update global mutex lock in the ioctl handler

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 03:38:22PM +0800, Desmond Cheong Zhi Xi wrote:
> In a future patch, a read lock on drm_device.master_rwsem is
> held in the ioctl handler before the check for ioctl
> permissions. However, this produces the following lockdep splat:
> 
> ==
> WARNING: possible circular locking dependency detected
> 5.14.0-rc6-CI-Patchwork_20831+ #1 Tainted: G U
> --
> kms_lease/1752 is trying to acquire lock:
> 827bad88 (drm_global_mutex){+.+.}-{3:3}, at: drm_open+0x64/0x280
> 
> but task is already holding lock:
> 88812e350108 (&dev->master_rwsem){}-{3:3}, at:
> drm_ioctl_kernel+0xfb/0x1a0
> 
> which lock already depends on the new lock.
> 
> the existing dependency chain (in reverse order) is:
> 
> -> #2 (&dev->master_rwsem){}-{3:3}:
>lock_acquire+0xd3/0x310
>down_read+0x3b/0x140
>drm_master_internal_acquire+0x1d/0x60
>drm_client_modeset_commit+0x10/0x40
>__drm_fb_helper_restore_fbdev_mode_unlocked+0x88/0xb0
>drm_fb_helper_set_par+0x34/0x40
>intel_fbdev_set_par+0x11/0x40 [i915]
>fbcon_init+0x270/0x4f0
>visual_init+0xc6/0x130
>do_bind_con_driver+0x1de/0x2c0
>do_take_over_console+0x10e/0x180
>do_fbcon_takeover+0x53/0xb0
>register_framebuffer+0x22d/0x310
>__drm_fb_helper_initial_config_and_unlock+0x36c/0x540
>intel_fbdev_initial_config+0xf/0x20 [i915]
>async_run_entry_fn+0x28/0x130
>process_one_work+0x26d/0x5c0
>worker_thread+0x37/0x390
>kthread+0x13b/0x170
>ret_from_fork+0x1f/0x30
> 
> -> #1 (&helper->lock){+.+.}-{3:3}:
>lock_acquire+0xd3/0x310
>__mutex_lock+0xa8/0x930
>__drm_fb_helper_restore_fbdev_mode_unlocked+0x44/0xb0
>intel_fbdev_restore_mode+0x2b/0x50 [i915]
>drm_lastclose+0x27/0x50
>drm_release_noglobal+0x42/0x60
>__fput+0x9e/0x250
>task_work_run+0x6b/0xb0
>exit_to_user_mode_prepare+0x1c5/0x1d0
>syscall_exit_to_user_mode+0x19/0x50
>do_syscall_64+0x46/0xb0
>entry_SYSCALL_64_after_hwframe+0x44/0xae
> 
> -> #0 (drm_global_mutex){+.+.}-{3:3}:
>validate_chain+0xb39/0x1e70
>__lock_acquire+0x5a1/0xb70
>lock_acquire+0xd3/0x310
>__mutex_lock+0xa8/0x930
>drm_open+0x64/0x280
>drm_stub_open+0x9f/0x100
>chrdev_open+0x9f/0x1d0
>do_dentry_open+0x14a/0x3a0
>dentry_open+0x53/0x70
>drm_mode_create_lease_ioctl+0x3cb/0x970
>drm_ioctl_kernel+0xc9/0x1a0
>drm_ioctl+0x201/0x3d0
>__x64_sys_ioctl+0x6a/0xa0
>do_syscall_64+0x37/0xb0
>entry_SYSCALL_64_after_hwframe+0x44/0xae
> 
> other info that might help us debug this:
> Chain exists of:
>   drm_global_mutex --> &helper->lock --> &dev->master_rwsem
>  Possible unsafe locking scenario:
>CPU0CPU1
>
>   lock(&dev->master_rwsem);
>lock(&helper->lock);
>lock(&dev->master_rwsem);
>   lock(drm_global_mutex);
> 
>  *** DEADLOCK ***
> 
> The lock hierarchy inversion happens because we grab the
> drm_global_mutex while already holding on to master_rwsem. To avoid
> this, we do some prep work to grab the drm_global_mutex before
> checking for ioctl permissions.
> 
> At the same time, we update the check for the global mutex to use the
> drm_dev_needs_global_mutex helper function.

This is intentional, essentially we force all non-legacy drivers to have
unlocked ioctl (otherwise everyone forgets to set that flag).

For non-legacy drivers the global lock only ensures ordering between
drm_open and lastclose (I think at least), and between
drm_dev_register/unregister and the backwards ->load/unload callbacks
(which are called in the wrong place, but we cannot fix that for legacy
drivers).

->load/unload should be completely unused (maybe radeon still uses it),
and ->lastclose is also on the decline.

Maybe we should update the comment of drm_global_mutex to explain what it
protects and why.

I'm also confused how this patch connects to the splat, since for i915 we
shouldn't be taking the drm_global_lock here at all. The problem seems to
be the drm_open_helper when we create a new lease, which is an entirely
different can of worms.

I'm honestly not sure how to best do that, but we should be able to create
a file and then call drm_open_helper directly, or well a version of that
which never takes the drm_global_mutex. Because that is not needed for
nested drm_file opening:
- legacy drivers never go down this path because leases are only supported
  with modesetting, and modesetting is only supported for non-legacy
  drivers
- the races against dev->open_count due to last_close or ->load callbacks
  don't matter, because for the entire ioctl we already have an open
 

Re: [PATCH v3 8/9] kernel: export task_work_add

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 03:38:23PM +0800, Desmond Cheong Zhi Xi wrote:
> The task_work_add function is needed to prevent userspace races with
> DRM modesetting rights.
> 
> Some DRM ioctls can change modesetting permissions while other
> concurrent users are performing modesetting. To prevent races with
> userspace, such functions should flush readers of old permissions
> before returning to user mode. As the function that changes
> permissions might itself be a reader of the old permissions, we intend
> to schedule this flush using task_work_add.
> 
> However, when DRM is compiled as a loadable kernel module without
> exporting task_work_add, we get the following compilation error:
> 
> ERROR: modpost: "task_work_add" [drivers/gpu/drm/drm.ko] undefined!
> 
> Reported-by: kernel test robot 
> Signed-off-by: Desmond Cheong Zhi Xi 

Just realized another benefit of pushing the dev->master_rwsem write
locks down into ioctls that need them: We wouldn't need this function here
exported for use in drm. But also I'm not sure that works any better than
the design in your current patch set ...
-Daniel

> ---
>  kernel/task_work.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/kernel/task_work.c b/kernel/task_work.c
> index 1698fbe6f0e1..9404af2b 100644
> --- a/kernel/task_work.c
> +++ b/kernel/task_work.c
> @@ -60,6 +60,7 @@ int task_work_add(struct task_struct *task, struct 
> callback_head *work,
>  
>   return 0;
>  }
> +EXPORT_SYMBOL(task_work_add);
>  
>  /**
>   * task_work_cancel_match - cancel a pending work added by task_work_add()
> -- 
> 2.25.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [BUG - BISECTED] display not detected anymore

2021-08-18 Thread Heiko Carstens
On Sat, Aug 14, 2021 at 02:46:27PM +0200, Heiko Carstens wrote:
> Hello,
> 
> I have Fedora 33 running, and with the Fedore kernel update from 5.11
> series to 5.12 my external monitor was not detected anymore. Same is
> true with the Fedora supplied 5.13 kernel version.
> 
> So I tried with vanilla kernel 5.11 and latest git head from Linus'
> tree. 5.11 works while latest git head does not. Bisecting the problem
> points to commit 32c3d9b0f51e ("Merge tag 'drm-intel-next-2021-01-27'
> of git://anongit.freedesktop.org/drm/drm-intel into drm-next").
> 
> Unfortunately it is a merge commit, so it looks like conflicting
> changes have been made in the parent branches.
> 
> Hardware in use:
> 
> - ThinkPad X1 Yoga 4th / Carbon 7th
> - Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
> 
> The Thinkpad is connected to a ThinkPad Thunderbolt 3 Dock with a
> Thunderbolt cable and a monitor (Eizo EV3285) is connected via
> Displayport to the docking station.
> 
> The monitor is detected and works without any problems (4k@60HZ)
> before the above mentioned merge commit. With the commit and
> afterwards it is not detected anymore and only the Thinkpad builtin
> display can be used.
> 
> Any idea what went wrong? I can provide more information, or test
> debug patches if wanted. Just let me know.

So looks like I made a mistake when bisecting (it literally took me
two days due to the low power machine, even with a minimized kernel
config). Anyway, looking into it again the first bad commit is

ef79d62b5ce5 ("drm/i915: Encapsulate dbuf state handling harder")

With that commit the display is not detected anymore, one commit
before that it still works. So this one seems to be broken.

Ville, Stanislav, any idea how to fix this?

commit ef79d62b5ce53851901d6c1d21b74cbb9e27219b
Author: Ville Syrjälä 
Date:   Fri Jan 22 22:56:32 2021 +0200

drm/i915: Encapsulate dbuf state handling harder

In order to make the dbuf state computation less fragile
let's make it stand on its own feet by not requiring someone
to peek into a crystall ball ahead of time to figure out
which pipes need to be added to the state under which potential
future conditions. Instead we compute each piece of the state
as we go along, and if any fallout occurs that affects more than
the current set of pipes we add the affected pipes to the state
naturally.

That requires that we track a few extra thigns in the global
dbuf state: dbuf slices for each pipe, and the weight each
pipe has when distributing the same set of slice(s) between
multiple pipes. Easy enough.

We do need to follow a somewhat careful sequence of computations
though as there are several steps involved in cooking up the dbuf
state. Thoguh we could avoid some of that by computing more things
on demand instead of relying on earlier step of the algorithm to
have filled it out. I think the end result is still reasonable
as the entire sequence is pretty much consolidated into a single
function instead of being spread around all over.

The rough sequence is this:
1. calculate active_pipes
2. calculate dbuf slices for every pipe
3. calculate total enabled slices
4. calculate new dbuf weights for any crtc in the state
5. calculate new ddb entry for every pipe based on the sets of
   slices and weights, and add any affected crtc to the state
6. calculate new plane ddb entries for all crtcs in the state,
   and add any affected plane to the state so that we'll perform
   the requisite hw reprogramming

And as a nice bonus we get to throw dev_priv->wm.distrust_bios_wm
out the window.

v2: Keep crtc_state->wm.skl.ddb

Reviewed-by: Stanislav Lisovskiy 
Signed-off-by: Ville Syrjälä 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210122205633.18492-8-ville.syrj...@linux.intel.com


Re: [PATCH] drm/ttm: optimize the pool shrinker a bit v3

2021-08-18 Thread Christian König

Just a gentle ping?

Does anybody have any objections? It's just switching back to using a 
spinlock in the hot path instead of a mutex.


Thanks,
Christian.

Am 22.07.21 um 13:34 schrieb Christian König:

Switch back to using a spinlock again by moving the IOMMU unmap outside
of the locked region.

v2: Add a comment explaining why we need sync_shrinkers().
v3: Drop sync_shrinkers() and use an SRCU instead.

Signed-off-by: Christian König 
---
  drivers/gpu/drm/ttm/ttm_pool.c | 45 --
  1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index cb38b1a17b09..cee664c487b5 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -70,7 +70,8 @@ static struct ttm_pool_type global_uncached[MAX_ORDER];
  static struct ttm_pool_type global_dma32_write_combined[MAX_ORDER];
  static struct ttm_pool_type global_dma32_uncached[MAX_ORDER];
  
-static struct mutex shrinker_lock;

+static spinlock_t shrinker_lock;
+DEFINE_STATIC_SRCU(shrinker_srcu);
  static struct list_head shrinker_list;
  static struct shrinker mm_shrinker;
  
@@ -263,9 +264,9 @@ static void ttm_pool_type_init(struct ttm_pool_type *pt, struct ttm_pool *pool,

spin_lock_init(&pt->lock);
INIT_LIST_HEAD(&pt->pages);
  
-	mutex_lock(&shrinker_lock);

+   spin_lock(&shrinker_lock);
list_add_tail(&pt->shrinker_list, &shrinker_list);
-   mutex_unlock(&shrinker_lock);
+   spin_unlock(&shrinker_lock);
  }
  
  /* Remove a pool_type from the global shrinker list and free all pages */

@@ -273,9 +274,9 @@ static void ttm_pool_type_fini(struct ttm_pool_type *pt)
  {
struct page *p;
  
-	mutex_lock(&shrinker_lock);

+   spin_lock(&shrinker_lock);
list_del(&pt->shrinker_list);
-   mutex_unlock(&shrinker_lock);
+   spin_unlock(&shrinker_lock);
  
  	while ((p = ttm_pool_type_take(pt)))

ttm_pool_free_page(pt->pool, pt->caching, pt->order, p);
@@ -313,24 +314,27 @@ static struct ttm_pool_type *ttm_pool_select_type(struct 
ttm_pool *pool,
  static unsigned int ttm_pool_shrink(void)
  {
struct ttm_pool_type *pt;
-   unsigned int num_freed;
+   unsigned int num_pages;
struct page *p;
+   int idx;
  
-	mutex_lock(&shrinker_lock);

+   idx = srcu_read_lock(&shrinker_srcu);
+
+   spin_lock(&shrinker_lock);
pt = list_first_entry(&shrinker_list, typeof(*pt), shrinker_list);
+   list_move_tail(&pt->shrinker_list, &shrinker_list);
+   spin_unlock(&shrinker_lock);
  
  	p = ttm_pool_type_take(pt);

if (p) {
ttm_pool_free_page(pt->pool, pt->caching, pt->order, p);
-   num_freed = 1 << pt->order;
+   num_pages = 1 << pt->order;
} else {
-   num_freed = 0;
+   num_pages = 0;
}
  
-	list_move_tail(&pt->shrinker_list, &shrinker_list);

-   mutex_unlock(&shrinker_lock);
-
-   return num_freed;
+   srcu_read_unlock(&shrinker_srcu, idx);
+   return num_pages;
  }
  
  /* Return the allocation order based for a page */

@@ -530,6 +534,11 @@ void ttm_pool_fini(struct ttm_pool *pool)
for (j = 0; j < MAX_ORDER; ++j)
ttm_pool_type_fini(&pool->caching[i].orders[j]);
}
+
+   /* We removed the pool types from the LRU, but we need to also make sure
+* that no shrinker is concurrently freeing pages from the pool.
+*/
+   synchronize_srcu(&shrinker_srcu);
  }
  
  /* As long as pages are available make sure to release at least one */

@@ -604,7 +613,7 @@ static int ttm_pool_debugfs_globals_show(struct seq_file 
*m, void *data)
  {
ttm_pool_debugfs_header(m);
  
-	mutex_lock(&shrinker_lock);

+   spin_lock(&shrinker_lock);
seq_puts(m, "wc\t:");
ttm_pool_debugfs_orders(global_write_combined, m);
seq_puts(m, "uc\t:");
@@ -613,7 +622,7 @@ static int ttm_pool_debugfs_globals_show(struct seq_file 
*m, void *data)
ttm_pool_debugfs_orders(global_dma32_write_combined, m);
seq_puts(m, "uc 32\t:");
ttm_pool_debugfs_orders(global_dma32_uncached, m);
-   mutex_unlock(&shrinker_lock);
+   spin_unlock(&shrinker_lock);
  
  	ttm_pool_debugfs_footer(m);
  
@@ -640,7 +649,7 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m)
  
  	ttm_pool_debugfs_header(m);
  
-	mutex_lock(&shrinker_lock);

+   spin_lock(&shrinker_lock);
for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) {
seq_puts(m, "DMA ");
switch (i) {
@@ -656,7 +665,7 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file 
*m)
}
ttm_pool_debugfs_orders(pool->caching[i].orders, m);
}
-   mutex_unlock(&shrinker_lock);
+   spin_unlock(&shrinker_lock);
  
  	ttm_pool_debugfs_footer(m);

return 0;
@@ -693,7 +702,7 @@ int ttm_pool_mg

Re: [PATCH v2 13/63] iommu/amd: Use struct_group() for memcpy() region

2021-08-18 Thread Joerg Roedel
On Tue, Aug 17, 2021 at 11:04:43PM -0700, Kees Cook wrote:
> In preparation for FORTIFY_SOURCE performing compile-time and run-time
> field bounds checking for memcpy(), memmove(), and memset(), avoid
> intentionally writing across neighboring fields.
> 
> Use struct_group() in struct ivhd_entry around members ext and hidh, so
> they can be referenced together. This will allow memcpy() and sizeof()
> to more easily reason about sizes, improve readability, and avoid future
> warnings about writing beyond the end of ext.
> 
> "pahole" shows no size nor member offset changes to struct ivhd_entry.
> "objdump -d" shows no object code changes.
> 
> Cc: Joerg Roedel 
> Cc: Will Deacon 
> Cc: io...@lists.linux-foundation.org
> Signed-off-by: Kees Cook 

Acked-by: Joerg Roedel 



Re: [PATCH v2 18/63] drm/amd/pm: Use struct_group() for memcpy() region

2021-08-18 Thread Lazar, Lijo



On 8/18/2021 11:34 AM, Kees Cook wrote:

In preparation for FORTIFY_SOURCE performing compile-time and run-time
field bounds checking for memcpy(), memmove(), and memset(), avoid
intentionally writing across neighboring fields.

Use struct_group() in structs:
struct atom_smc_dpm_info_v4_5
struct atom_smc_dpm_info_v4_6
struct atom_smc_dpm_info_v4_7
struct atom_smc_dpm_info_v4_10
PPTable_t
so the grouped members can be referenced together. This will allow
memcpy() and sizeof() to more easily reason about sizes, improve
readability, and avoid future warnings about writing beyond the end of
the first member.

"pahole" shows no size nor member offset changes to any structs.
"objdump -d" shows no object code changes.

Cc: "Christian König" 
Cc: "Pan, Xinhui" 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Hawking Zhang 
Cc: Feifei Xu 
Cc: Lijo Lazar 
Cc: Likun Gao 
Cc: Jiawei Gu 
Cc: Evan Quan 
Cc: amd-...@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Kees Cook 
Acked-by: Alex Deucher 
Link: 
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Flkml%2FCADnq5_Npb8uYvd%2BR4UHgf-w8-cQj3JoODjviJR_Y9w9wqJ71mQ%40mail.gmail.com&data=04%7C01%7Clijo.lazar%40amd.com%7C92b8d2f072f0444b9f8508d9620f6971%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637648640625729624%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=rKh5LUXCRUsorYM3kSpG2tkB%2Fczwl9I9EBnWBCtbg6Q%3D&reserved=0
---
  drivers/gpu/drm/amd/include/atomfirmware.h   |  9 -
  .../gpu/drm/amd/pm/inc/smu11_driver_if_arcturus.h|  3 ++-
  drivers/gpu/drm/amd/pm/inc/smu11_driver_if_navi10.h  |  3 ++-
  .../gpu/drm/amd/pm/inc/smu13_driver_if_aldebaran.h   |  3 ++-


Hi Kees,

The headers which define these structs are firmware/VBIOS interfaces and 
are picked directly from those components. There are difficulties in 
grouping them to structs at the original source as that involves other 
component changes.


The driver_if_* files updates are frequent and it is error prone to 
manually group them each time we pick them for any update. Our usage of 
memcpy in this way is restricted only to a very few places.


As another option - is it possible to have a helper function/macro like 
memcpy_fortify() which takes the extra arguments and does the extra 
compile time checks? We will use the helper whenever we have such kind 
of usage.


Thanks,
Lijo


  drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c|  6 +++---
  drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c  | 12 
  drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c   |  6 +++---
  7 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h 
b/drivers/gpu/drm/amd/include/atomfirmware.h
index 44955458fe38..7bf3edf15410 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -2081,6 +2081,7 @@ struct atom_smc_dpm_info_v4_5
  {
struct   atom_common_table_header  table_header;
  // SECTION: BOARD PARAMETERS
+  struct_group(dpm_info,
  // I2C Control
struct smudpm_i2c_controller_config_v2  I2cControllers[8];
  
@@ -2159,7 +2160,7 @@ struct atom_smc_dpm_info_v4_5

uint32_t MvddRatio; // This is used for MVDD Vid workaround. It has 16 
fractional bits (Q16.16)

uint32_t BoardReserved[9];

-
+  );
  };
  
  struct atom_smc_dpm_info_v4_6

@@ -2168,6 +2169,7 @@ struct atom_smc_dpm_info_v4_6
// section: board parameters
uint32_t i2c_padding[3];   // old i2c control are moved to new area
  
+  struct_group(dpm_info,

uint16_t maxvoltagestepgfx; // in mv(q2) max voltage step that smu will 
request. multiple steps are taken if voltage change exceeds this value.
uint16_t maxvoltagestepsoc; // in mv(q2) max voltage step that smu will 
request. multiple steps are taken if voltage change exceeds this value.
  
@@ -2246,12 +2248,14 @@ struct atom_smc_dpm_info_v4_6
  
// reserved

uint32_t   boardreserved[10];
+  );
  };
  
  struct atom_smc_dpm_info_v4_7

  {
struct   atom_common_table_header  table_header;
  // SECTION: BOARD PARAMETERS
+  struct_group(dpm_info,
  // I2C Control
struct smudpm_i2c_controller_config_v2  I2cControllers[8];
  
@@ -2348,6 +2352,7 @@ struct atom_smc_dpm_info_v4_7

uint8_t  Padding8_Psi2;
  
uint32_t BoardReserved[5];

+  );
  };
  
  struct smudpm_i2c_controller_config_v3

@@ -2478,6 +2483,7 @@ struct atom_smc_dpm_info_v4_10
struct   atom_common_table_header  table_header;
  
// SECTION: BOARD PARAMETERS

+  struct_group(dpm_info,
// Telemetry Settings
uint16_t GfxMaxCurrent; // in Amps
uint8_t   GfxOffset; // in Amps
@@ -2524,6 +2530,7 @@ struct atom_smc_dpm_info_v4_10
uint16_t spare5;
  
uint32_t reserved[16];

+  );
  };
  
  /*

diff --git a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_arcturus.h 
b/d

Re: [PATCH v2] drm/i915: Ditch the i915_gem_ww_ctx loop member

2021-08-18 Thread Matthew Auld
On Mon, 16 Aug 2021 at 18:14, Thomas Hellström
 wrote:
>
> It's only used by the for_i915_gem_ww() macro and we can use
> the (typically) on-stack _err variable in its place.
>
> v2:
> - Don't clear the _err variable when entering the loop
>   (Matthew Auld, Maarten Lankhorst).
> - Use parentheses around the _err macro argument.
> - Fix up comment.
>
> Cc: Matthew Auld 
> Suggested-by: Maarten Lankhorst 
> Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 


[PATCH] drm: Remove unused code to load the non-existing fbcon.ko

2021-08-18 Thread Javier Martinez Canillas
Commit 6104c37094e7 ("fbcon: Make fbcon a built-time depency for fbdev")
changed the FRAMEBUFFER_CONSOLE Kconfig symbol from tristate to bool.

But the drm_kms_helper_init() function still attempts to load the fbcon
module, even when this is always built-in since the mentioned change.

Signed-off-by: Javier Martinez Canillas 
---

 drivers/gpu/drm/drm_kms_helper_common.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_kms_helper_common.c 
b/drivers/gpu/drm/drm_kms_helper_common.c
index f933da1656eb..47e92400548d 100644
--- a/drivers/gpu/drm/drm_kms_helper_common.c
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -64,17 +64,6 @@ MODULE_PARM_DESC(edid_firmware,
 
 static int __init drm_kms_helper_init(void)
 {
-   /*
-* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT)
-* but the module doesn't depend on any fb console symbols.  At least
-* attempt to load fbcon to avoid leaving the system without a usable
-* console.
-*/
-   if (IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) &&
-   IS_MODULE(CONFIG_FRAMEBUFFER_CONSOLE) &&
-   !IS_ENABLED(CONFIG_EXPERT))
-   request_module_nowait("fbcon");
-
return drm_dp_aux_dev_init();
 }
 
-- 
2.31.1



Re: [PATCH] dma-buf: return -EINVAL if dmabuf object is NULL

2021-08-18 Thread Christian König
To be honest I think the if(WARN_ON(!dmabuf)) return -EINVAL handling 
here is misleading in the first place.


Returning -EINVAL on a hard coding error is not good practice and should 
probably be removed from the DMA-buf subsystem in general.


Christian.

Am 18.08.21 um 13:58 schrieb Nuno Sá:

On top of warning about a NULL object, we also want to return with a
proper error code (as done in 'dma_buf_begin_cpu_access()'). Otherwise,
we will get a NULL pointer dereference.

Fixes: fc13020e086b ("dma-buf: add support for kernel cpu access")
Signed-off-by: Nuno Sá 
---
  drivers/dma-buf/dma-buf.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 63d32261b63f..8ec7876dd523 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1231,7 +1231,8 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf,
  {
int ret = 0;
  
-	WARN_ON(!dmabuf);

+   if (WARN_ON(!dmabuf))
+   return -EINVAL;
  
  	might_lock(&dmabuf->resv->lock.base);
  




Re: [PATCH] dma-buf: return -EINVAL if dmabuf object is NULL

2021-08-18 Thread Christian König

Am 18.08.21 um 14:17 schrieb Sa, Nuno:

From: Christian König 
Sent: Wednesday, August 18, 2021 2:10 PM
To: Sa, Nuno ; linaro-mm-...@lists.linaro.org;
dri-devel@lists.freedesktop.org; linux-me...@vger.kernel.org
Cc: Rob Clark ; Sumit Semwal

Subject: Re: [PATCH] dma-buf: return -EINVAL if dmabuf object is
NULL

[External]

To be honest I think the if(WARN_ON(!dmabuf)) return -EINVAL
handling
here is misleading in the first place.

Returning -EINVAL on a hard coding error is not good practice and
should
probably be removed from the DMA-buf subsystem in general.

Would you say to just return 0 then? I don't think that having the
dereference is also good..


No, just run into the dereference.

Passing NULL as the core object you are working on is a hard coding 
error and not something we should bubble up as recoverable error.



I used -EINVAL to be coherent with the rest of the code.


I rather suggest to remove the check elsewhere as well.

Christian.



- Nuno Sá


Christian.

Am 18.08.21 um 13:58 schrieb Nuno Sá:

On top of warning about a NULL object, we also want to return with a
proper error code (as done in 'dma_buf_begin_cpu_access()').

Otherwise,

we will get a NULL pointer dereference.

Fixes: fc13020e086b ("dma-buf: add support for kernel cpu access")
Signed-off-by: Nuno Sá 
---
   drivers/dma-buf/dma-buf.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-

buf.c

index 63d32261b63f..8ec7876dd523 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1231,7 +1231,8 @@ int dma_buf_end_cpu_access(struct

dma_buf *dmabuf,

   {
int ret = 0;

-   WARN_ON(!dmabuf);
+   if (WARN_ON(!dmabuf))
+   return -EINVAL;

might_lock(&dmabuf->resv->lock.base);





Re: [PATCH] drm/ttm: optimize the pool shrinker a bit v3

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 01:27:13PM +0200, Christian König wrote:
> Just a gentle ping?
> 
> Does anybody have any objections? It's just switching back to using a
> spinlock in the hot path instead of a mutex.
> 
> Thanks,
> Christian.
> 
> Am 22.07.21 um 13:34 schrieb Christian König:
> > Switch back to using a spinlock again by moving the IOMMU unmap outside
> > of the locked region.
> > 
> > v2: Add a comment explaining why we need sync_shrinkers().
> > v3: Drop sync_shrinkers() and use an SRCU instead.

Why did you move to your own hand-rolled thing here? From the old thread
it just looked like Andrew wanted some proper explanation. And the
sychronize_shrinkers is imo much clearer than some hand-rolled srcu thing.

Also on the spinlock covnersion, do you have some benchmarks/profile
flamegraphs/numbers that show it matters? Would be realy good to record
that kind of stuff in the commit message instead of just having the
implication that this optimizes stuff.
-Daniel

> > 
> > Signed-off-by: Christian König 
> > ---
> >   drivers/gpu/drm/ttm/ttm_pool.c | 45 --
> >   1 file changed, 27 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
> > index cb38b1a17b09..cee664c487b5 100644
> > --- a/drivers/gpu/drm/ttm/ttm_pool.c
> > +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> > @@ -70,7 +70,8 @@ static struct ttm_pool_type global_uncached[MAX_ORDER];
> >   static struct ttm_pool_type global_dma32_write_combined[MAX_ORDER];
> >   static struct ttm_pool_type global_dma32_uncached[MAX_ORDER];
> > -static struct mutex shrinker_lock;
> > +static spinlock_t shrinker_lock;
> > +DEFINE_STATIC_SRCU(shrinker_srcu);
> >   static struct list_head shrinker_list;
> >   static struct shrinker mm_shrinker;
> > @@ -263,9 +264,9 @@ static void ttm_pool_type_init(struct ttm_pool_type 
> > *pt, struct ttm_pool *pool,
> > spin_lock_init(&pt->lock);
> > INIT_LIST_HEAD(&pt->pages);
> > -   mutex_lock(&shrinker_lock);
> > +   spin_lock(&shrinker_lock);
> > list_add_tail(&pt->shrinker_list, &shrinker_list);
> > -   mutex_unlock(&shrinker_lock);
> > +   spin_unlock(&shrinker_lock);
> >   }
> >   /* Remove a pool_type from the global shrinker list and free all pages */
> > @@ -273,9 +274,9 @@ static void ttm_pool_type_fini(struct ttm_pool_type *pt)
> >   {
> > struct page *p;
> > -   mutex_lock(&shrinker_lock);
> > +   spin_lock(&shrinker_lock);
> > list_del(&pt->shrinker_list);
> > -   mutex_unlock(&shrinker_lock);
> > +   spin_unlock(&shrinker_lock);
> > while ((p = ttm_pool_type_take(pt)))
> > ttm_pool_free_page(pt->pool, pt->caching, pt->order, p);
> > @@ -313,24 +314,27 @@ static struct ttm_pool_type 
> > *ttm_pool_select_type(struct ttm_pool *pool,
> >   static unsigned int ttm_pool_shrink(void)
> >   {
> > struct ttm_pool_type *pt;
> > -   unsigned int num_freed;
> > +   unsigned int num_pages;
> > struct page *p;
> > +   int idx;
> > -   mutex_lock(&shrinker_lock);
> > +   idx = srcu_read_lock(&shrinker_srcu);
> > +
> > +   spin_lock(&shrinker_lock);
> > pt = list_first_entry(&shrinker_list, typeof(*pt), shrinker_list);
> > +   list_move_tail(&pt->shrinker_list, &shrinker_list);
> > +   spin_unlock(&shrinker_lock);
> > p = ttm_pool_type_take(pt);
> > if (p) {
> > ttm_pool_free_page(pt->pool, pt->caching, pt->order, p);
> > -   num_freed = 1 << pt->order;
> > +   num_pages = 1 << pt->order;
> > } else {
> > -   num_freed = 0;
> > +   num_pages = 0;
> > }
> > -   list_move_tail(&pt->shrinker_list, &shrinker_list);
> > -   mutex_unlock(&shrinker_lock);
> > -
> > -   return num_freed;
> > +   srcu_read_unlock(&shrinker_srcu, idx);
> > +   return num_pages;
> >   }
> >   /* Return the allocation order based for a page */
> > @@ -530,6 +534,11 @@ void ttm_pool_fini(struct ttm_pool *pool)
> > for (j = 0; j < MAX_ORDER; ++j)
> > ttm_pool_type_fini(&pool->caching[i].orders[j]);
> > }
> > +
> > +   /* We removed the pool types from the LRU, but we need to also make sure
> > +* that no shrinker is concurrently freeing pages from the pool.
> > +*/
> > +   synchronize_srcu(&shrinker_srcu);
> >   }
> >   /* As long as pages are available make sure to release at least one */
> > @@ -604,7 +613,7 @@ static int ttm_pool_debugfs_globals_show(struct 
> > seq_file *m, void *data)
> >   {
> > ttm_pool_debugfs_header(m);
> > -   mutex_lock(&shrinker_lock);
> > +   spin_lock(&shrinker_lock);
> > seq_puts(m, "wc\t:");
> > ttm_pool_debugfs_orders(global_write_combined, m);
> > seq_puts(m, "uc\t:");
> > @@ -613,7 +622,7 @@ static int ttm_pool_debugfs_globals_show(struct 
> > seq_file *m, void *data)
> > ttm_pool_debugfs_orders(global_dma32_write_combined, m);
> > seq_puts(m, "uc 32\t:");
> > ttm_pool_debugfs_orders(global_dma32_uncached, m);
> > -   mutex_unlock(&shrinker_loc

Re: [PATCH] drm: Remove unused code to load the non-existing fbcon.ko

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 02:09:48PM +0200, Javier Martinez Canillas wrote:
> Commit 6104c37094e7 ("fbcon: Make fbcon a built-time depency for fbdev")
> changed the FRAMEBUFFER_CONSOLE Kconfig symbol from tristate to bool.
> 
> But the drm_kms_helper_init() function still attempts to load the fbcon
> module, even when this is always built-in since the mentioned change.
> 
> Signed-off-by: Javier Martinez Canillas 

Nice catch. Merged to drm-misc-next for 5.16, thanks.
-Daniel

> ---
> 
>  drivers/gpu/drm/drm_kms_helper_common.c | 11 ---
>  1 file changed, 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_kms_helper_common.c 
> b/drivers/gpu/drm/drm_kms_helper_common.c
> index f933da1656eb..47e92400548d 100644
> --- a/drivers/gpu/drm/drm_kms_helper_common.c
> +++ b/drivers/gpu/drm/drm_kms_helper_common.c
> @@ -64,17 +64,6 @@ MODULE_PARM_DESC(edid_firmware,
>  
>  static int __init drm_kms_helper_init(void)
>  {
> - /*
> -  * The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT)
> -  * but the module doesn't depend on any fb console symbols.  At least
> -  * attempt to load fbcon to avoid leaving the system without a usable
> -  * console.
> -  */
> - if (IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) &&
> - IS_MODULE(CONFIG_FRAMEBUFFER_CONSOLE) &&
> - !IS_ENABLED(CONFIG_EXPERT))
> - request_module_nowait("fbcon");
> -
>   return drm_dp_aux_dev_init();
>  }
>  
> -- 
> 2.31.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 0/5] Kconfig symbol clean-up on gpu

2021-08-18 Thread Lukas Bulwahn
Dear DRM maintainers,

The script ./scripts/checkkconfigsymbols.py warns on invalid references to
Kconfig symbols (often, minor typos, name confusions or outdated references).

This patch series addresses all issues reported by 
./scripts/checkkconfigsymbols.py
in ./drivers/gpu/ for Kconfig and Makefile files. Issues in the Kconfig and
Makefile files indicate some shortcomings in the overall build definitions, and
often are true actionable issues to address.

These issues can be identified and filtered by:

  ./scripts/checkkconfigsymbols.py | grep -E "drivers/gpu/.*(Kconfig|Makefile)" 
-B 1 -A 1

After applying this patch series on linux-next (next-20210817), the command
above yields just one further issues to address:

DRM_AMD_DC_DCE11_0
Referencing files: drivers/gpu/drm/amd/display/dc/dce100/Makefile

  Conclusion: No action required.
  Rationale:
drivers/gpu/drm/amd/display/dc/dce100/Makefile refers to
DRM_AMD_DC_DCE11_0 in a comment, after an "ifdef 0".


Please pick this patch series into your drm-next tree.

Best regards,

Lukas

Lukas Bulwahn (5):
  drm: rockchip: remove reference to non-existing config DRM_RGB
  drm: amdgpu: remove obsolete reference to config CHASH
  drm: v3d: correct reference to config ARCH_BRCMSTB
  drm: zte: remove obsolete DRM Support for ZTE SoCs
  drm: omap: remove obsolete selection of OMAP2_DSS in config DRM_OMAP

 drivers/gpu/drm/Kconfig  |   1 -
 drivers/gpu/drm/Makefile |   1 -
 drivers/gpu/drm/omapdrm/Kconfig  |   1 -
 drivers/gpu/drm/rockchip/Kconfig |   1 -
 drivers/gpu/drm/v3d/Kconfig  |   2 +-
 drivers/gpu/drm/zte/Kconfig  |  10 -
 drivers/gpu/drm/zte/Makefile |  10 -
 drivers/gpu/drm/zte/zx_common_regs.h |  28 -
 drivers/gpu/drm/zte/zx_drm_drv.c | 184 --
 drivers/gpu/drm/zte/zx_drm_drv.h |  34 -
 drivers/gpu/drm/zte/zx_hdmi.c| 760 --
 drivers/gpu/drm/zte/zx_hdmi_regs.h   |  66 --
 drivers/gpu/drm/zte/zx_plane.c   | 537 
 drivers/gpu/drm/zte/zx_plane.h   |  26 -
 drivers/gpu/drm/zte/zx_plane_regs.h  | 120 
 drivers/gpu/drm/zte/zx_tvenc.c   | 400 
 drivers/gpu/drm/zte/zx_tvenc_regs.h  |  27 -
 drivers/gpu/drm/zte/zx_vga.c | 527 ---
 drivers/gpu/drm/zte/zx_vga_regs.h|  33 -
 drivers/gpu/drm/zte/zx_vou.c | 921 ---
 drivers/gpu/drm/zte/zx_vou.h |  64 --
 drivers/gpu/drm/zte/zx_vou_regs.h| 212 --
 22 files changed, 1 insertion(+), 3964 deletions(-)
 delete mode 100644 drivers/gpu/drm/zte/Kconfig
 delete mode 100644 drivers/gpu/drm/zte/Makefile
 delete mode 100644 drivers/gpu/drm/zte/zx_common_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.c
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.h
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi.c
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.c
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc.c
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vga.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vga_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou_regs.h

-- 
2.26.2



[PATCH 1/5] drm: rockchip: remove reference to non-existing config DRM_RGB

2021-08-18 Thread Lukas Bulwahn
commit 1f0f01515172 ("drm/rockchip: Add support for Rockchip Soc RGB
output interface") accidently adds to select the non-existing config
DRM_RGB in ./drivers/gpu/drm/rockchip/Kconfig.

Luckily, ./scripts/checkkconfigsymbols.py warns on non-existing configs:

DRM_RGB
Referencing files: drivers/gpu/drm/rockchip/Kconfig

So, remove the reference to the non-existing config DRM_RGB.

Signed-off-by: Lukas Bulwahn 
---
 drivers/gpu/drm/rockchip/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 558f1b58bd69..9f1ecefc3933 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -9,7 +9,6 @@ config DRM_ROCKCHIP
select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
-   select DRM_RGB if ROCKCHIP_RGB
select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
-- 
2.26.2



[PATCH 2/5] drm: amdgpu: remove obsolete reference to config CHASH

2021-08-18 Thread Lukas Bulwahn
Commit 04ed8459f334 ("drm/amdgpu: remove chash") removes the chash
architecture and its corresponding config CHASH.

There is still a reference to CHASH in the config DRM_AMDGPU in
./drivers/gpu/drm/Kconfig.

Remove this obsolete reference to config CHASH.

Signed-off-by: Lukas Bulwahn 
---
 drivers/gpu/drm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f3bc90baca61..8fc40317f2b7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -257,7 +257,6 @@ config DRM_AMDGPU
select HWMON
select BACKLIGHT_CLASS_DEVICE
select INTERVAL_TREE
-   select CHASH
help
  Choose this option if you have a recent AMD Radeon graphics card.
 
-- 
2.26.2



[PATCH 3/5] drm: v3d: correct reference to config ARCH_BRCMSTB

2021-08-18 Thread Lukas Bulwahn
Commit 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D
V3.x+") adds the config DRM_V3D, which depends on "ARCH_BCMSTB".

Although, a bit confusing: all Broadcom architectures in
./arch/arm/mach-bcm/Kconfig have the prefix "ARCH_BCM", except for
ARCH_BRCMSTB, i.e., the config for Broadcom BCM7XXX based boards.

So, correct the reference ARCH_BCMSTB to the intended ARCH_BRCMSTB.

Signed-off-by: Lukas Bulwahn 
---
 drivers/gpu/drm/v3d/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/Kconfig b/drivers/gpu/drm/v3d/Kconfig
index 9a5c44606337..e973ec487484 100644
--- a/drivers/gpu/drm/v3d/Kconfig
+++ b/drivers/gpu/drm/v3d/Kconfig
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config DRM_V3D
tristate "Broadcom V3D 3.x and newer"
-   depends on ARCH_BCM || ARCH_BCMSTB || COMPILE_TEST
+   depends on ARCH_BCM || ARCH_BRCMSTB || COMPILE_TEST
depends on DRM
depends on COMMON_CLK
depends on MMU
-- 
2.26.2



[PATCH 4/5] drm: zte: remove obsolete DRM Support for ZTE SoCs

2021-08-18 Thread Lukas Bulwahn
Commit 89d4f98ae90d ("ARM: remove zte zx platform") removes the config
ARCH_ZX. So, since then, the DRM Support for ZTE SoCs (config DRM_ZTE)
depends on this removed config ARCH_ZX and cannot be selected.

Fortunately, ./scripts/checkkconfigsymbols.py detects this and warns:

ARCH_ZX
Referencing files: drivers/gpu/drm/zte/Kconfig

So, remove this obsolete DRM support.

Signed-off-by: Lukas Bulwahn 
---
 drivers/gpu/drm/Makefile |   1 -
 drivers/gpu/drm/zte/Kconfig  |  10 -
 drivers/gpu/drm/zte/Makefile |  10 -
 drivers/gpu/drm/zte/zx_common_regs.h |  28 -
 drivers/gpu/drm/zte/zx_drm_drv.c | 184 --
 drivers/gpu/drm/zte/zx_drm_drv.h |  34 -
 drivers/gpu/drm/zte/zx_hdmi.c| 760 --
 drivers/gpu/drm/zte/zx_hdmi_regs.h   |  66 --
 drivers/gpu/drm/zte/zx_plane.c   | 537 
 drivers/gpu/drm/zte/zx_plane.h   |  26 -
 drivers/gpu/drm/zte/zx_plane_regs.h  | 120 
 drivers/gpu/drm/zte/zx_tvenc.c   | 400 
 drivers/gpu/drm/zte/zx_tvenc_regs.h  |  27 -
 drivers/gpu/drm/zte/zx_vga.c | 527 ---
 drivers/gpu/drm/zte/zx_vga_regs.h|  33 -
 drivers/gpu/drm/zte/zx_vou.c | 921 ---
 drivers/gpu/drm/zte/zx_vou.h |  64 --
 drivers/gpu/drm/zte/zx_vou_regs.h| 212 --
 18 files changed, 3960 deletions(-)
 delete mode 100644 drivers/gpu/drm/zte/Kconfig
 delete mode 100644 drivers/gpu/drm/zte/Makefile
 delete mode 100644 drivers/gpu/drm/zte/zx_common_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.c
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.h
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi.c
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.c
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc.c
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vga.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vga_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou_regs.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index ad1112154898..0dff40bb863c 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -113,7 +113,6 @@ obj-y   += bridge/
 obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
 obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
 obj-y  += hisilicon/
-obj-$(CONFIG_DRM_ZTE)  += zte/
 obj-$(CONFIG_DRM_MXSFB)+= mxsfb/
 obj-y  += tiny/
 obj-$(CONFIG_DRM_PL111) += pl111/
diff --git a/drivers/gpu/drm/zte/Kconfig b/drivers/gpu/drm/zte/Kconfig
deleted file mode 100644
index aa8594190b50..
--- a/drivers/gpu/drm/zte/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config DRM_ZTE
-   tristate "DRM Support for ZTE SoCs"
-   depends on DRM && ARCH_ZX
-   select DRM_KMS_CMA_HELPER
-   select DRM_KMS_HELPER
-   select SND_SOC_HDMI_CODEC if SND_SOC
-   select VIDEOMODE_HELPERS
-   help
- Choose this option to enable DRM on ZTE ZX SoCs.
diff --git a/drivers/gpu/drm/zte/Makefile b/drivers/gpu/drm/zte/Makefile
deleted file mode 100644
index b6d966d849dd..
--- a/drivers/gpu/drm/zte/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-zxdrm-y := \
-   zx_drm_drv.o \
-   zx_hdmi.o \
-   zx_plane.o \
-   zx_tvenc.o \
-   zx_vga.o \
-   zx_vou.o
-
-obj-$(CONFIG_DRM_ZTE) += zxdrm.o
diff --git a/drivers/gpu/drm/zte/zx_common_regs.h 
b/drivers/gpu/drm/zte/zx_common_regs.h
deleted file mode 100644
index b7b996db129d..
--- a/drivers/gpu/drm/zte/zx_common_regs.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2017 Sanechips Technology Co., Ltd.
- * Copyright 2017 Linaro Ltd.
- */
-
-#ifndef __ZX_COMMON_REGS_H__
-#define __ZX_COMMON_REGS_H__
-
-/* CSC registers */
-#define CSC_CTRL0  0x30
-#define CSC_COV_MODE_SHIFT 16
-#define CSC_COV_MODE_MASK  (0x << CSC_COV_MODE_SHIFT)
-#define CSC_BT601_IMAGE_RGB2YCBCR  0
-#define CSC_BT601_IMAGE_YCBCR2RGB  1
-#define CSC_BT601_VIDEO_RGB2YCBCR  2
-#define CSC_BT601_VIDEO_YCBCR2RGB  3
-#define CSC_BT709_IMAGE_RGB2YCBCR  4
-#define CSC_BT709_IMAGE_YCBCR2RGB  5
-#define CSC_BT709_VIDEO_RGB2YCBCR  6
-#define CSC_BT709_VIDEO_YCBCR2RGB  7
-#define CSC_BT2020_IMAGE_RGB2YCBCR 8
-#define CSC_BT2020_IMAGE_YCBCR2RGB 9
-#define CSC_BT2020_VIDEO_RGB2YCBCR 10
-#define CSC_BT2020_VIDEO_YCBCR2RGB 11
-#define CSC_WORK_ENABLEBIT(0)
-
-#endif /* __ZX_COMMON_REGS_H__ */
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
deleted file mode 100644

[PATCH 5/5] drm: omap: remove obsolete selection of OMAP2_DSS in config DRM_OMAP

2021-08-18 Thread Lukas Bulwahn
Commit 55b68fb856b5 ("drm/omap: squash omapdrm sub-modules into one")
removes the config OMAP2_DSS in ./drivers/gpu/drm/omapdrm/dss/Kconfig,
while moving the other configs into./drivers/gpu/drm/omapdrm/Kconfig, but
misses to remove an obsolete selection of OMAP2_DSS in config DRM_OMAP.

Hence, ./scripts/checkkconfigsymbols.py warns:

OMAP2_DSS
Referencing files: drivers/gpu/drm/omapdrm/Kconfig

Remove this reference in an obsolete selection.

Signed-off-by: Lukas Bulwahn 
---
 drivers/gpu/drm/omapdrm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index e7281da5bc6a..d6e4df291d6f 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -3,7 +3,6 @@ config DRM_OMAP
tristate "OMAP DRM"
depends on DRM
depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
-   select OMAP2_DSS
select DRM_KMS_HELPER
select VIDEOMODE_HELPERS
select HDMI
-- 
2.26.2



Re: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel compatibles

2021-08-18 Thread Maxime Ripard
Hi Rob, Sam,

On Wed, Jul 21, 2021 at 08:29:47PM -0600, Rob Herring wrote:
> On Wed, Jul 21, 2021 at 04:03:40PM +0200, Maxime Ripard wrote:
> > The binding mentions that all the drivers using that driver must use a
> > vendor-specific compatible but never enforces it, nor documents the
> > vendor-specific compatibles.
> > 
> > Let's make we document all of them, and that the binding will create an
> > error if we add one that isn't.
> > 
> > Cc: dri-devel@lists.freedesktop.org
> > Cc: Laurent Pinchart 
> > Cc: Sam Ravnborg 
> > Cc: Thierry Reding 
> > Signed-off-by: Maxime Ripard 
> > ---
> >  .../bindings/display/panel/lvds.yaml   | 18 --
> >  1 file changed, 12 insertions(+), 6 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml 
> > b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > index 49460c9dceea..d1513111eb48 100644
> > --- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > +++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > @@ -31,12 +31,18 @@ allOf:
> >  
> >  properties:
> >compatible:
> > -contains:
> > -  const: panel-lvds
> > -description:
> > -  Shall contain "panel-lvds" in addition to a mandatory panel-specific
> > -  compatible string defined in individual panel bindings. The 
> > "panel-lvds"
> > -  value shall never be used on its own.
> > +items:
> > +  - enum:
> > +  - advantech,idk-1110wr
> 
> At least this one is documented elsewhere.

Indeed, I missed it.

> You can add 'minItems: 2' if you want to just enforce having 2 compatibles. 
> Or do:
> 
> items:
>   - {}
>   - const: panel-lvds
> 
> Which also enforces the order.

It's not just about the order since a missing compatible will also raise
a warning.

Some of those panels have a binding of their own, but some probably
won't (and I can't find anything specific about the one I'm most
interested in: tbs,a711-panel)

Can we have something like:

compatible:
  oneOf:
- items:
  - enum:
- tbs,a711-panel
  - const: panel-lvds

- items:
  - {}
  - const: panel-lvds

That would work for both cases I guess?

Maxime


signature.asc
Description: PGP signature


Re: [Linaro-mm-sig] [PATCH] dma-buf: return -EINVAL if dmabuf object is NULL

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 02:31:34PM +0200, Christian König wrote:
> Am 18.08.21 um 14:17 schrieb Sa, Nuno:
> > > From: Christian König 
> > > Sent: Wednesday, August 18, 2021 2:10 PM
> > > To: Sa, Nuno ; linaro-mm-...@lists.linaro.org;
> > > dri-devel@lists.freedesktop.org; linux-me...@vger.kernel.org
> > > Cc: Rob Clark ; Sumit Semwal
> > > 
> > > Subject: Re: [PATCH] dma-buf: return -EINVAL if dmabuf object is
> > > NULL
> > > 
> > > [External]
> > > 
> > > To be honest I think the if(WARN_ON(!dmabuf)) return -EINVAL
> > > handling
> > > here is misleading in the first place.
> > > 
> > > Returning -EINVAL on a hard coding error is not good practice and
> > > should
> > > probably be removed from the DMA-buf subsystem in general.
> > Would you say to just return 0 then? I don't think that having the
> > dereference is also good..
> 
> No, just run into the dereference.
> 
> Passing NULL as the core object you are working on is a hard coding error
> and not something we should bubble up as recoverable error.
> 
> > I used -EINVAL to be coherent with the rest of the code.
> 
> I rather suggest to remove the check elsewhere as well.

It's a lot more complicated, and WARN_ON + bail out is rather
well-established code-pattern. There's been plenty of discussions in the
past that a BUG_ON is harmful since it makes debugging a major pain, e.g.

https://lore.kernel.org/lkml/CA+55aFwyNTLuZgOWMTRuabWobF27ygskuxvFd-P0n-3UNT=0...@mail.gmail.com/

There's also a checkpatch check for this.

commit 9d3e3c705eb395528fd8f17208c87581b134da48
Author: Joe Perches 
Date:   Wed Sep 9 15:37:27 2015 -0700

checkpatch: add warning on BUG/BUG_ON use

Anyone who is paranoid about security crashes their machine on any WARNING
anyway (like syzkaller does).

My rule of thumb is that if the WARN_ON + bail-out code is just an if
(WARN_ON()) return; then it's fine, if it's more then BUG_ON is the better
choice perhaps.

I think the worst choice is just removing all these checks, because a few
code reorgs later you might not Oops immediately afterwards anymore, and
then we'll merge potentially very busted new code. Which is no good.
-Daniel



> 
> Christian.
> 
> > 
> > - Nuno Sá
> > 
> > > Christian.
> > > 
> > > Am 18.08.21 um 13:58 schrieb Nuno Sá:
> > > > On top of warning about a NULL object, we also want to return with a
> > > > proper error code (as done in 'dma_buf_begin_cpu_access()').
> > > Otherwise,
> > > > we will get a NULL pointer dereference.
> > > > 
> > > > Fixes: fc13020e086b ("dma-buf: add support for kernel cpu access")
> > > > Signed-off-by: Nuno Sá 
> > > > ---
> > > >drivers/dma-buf/dma-buf.c | 3 ++-
> > > >1 file changed, 2 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-
> > > buf.c
> > > > index 63d32261b63f..8ec7876dd523 100644
> > > > --- a/drivers/dma-buf/dma-buf.c
> > > > +++ b/drivers/dma-buf/dma-buf.c
> > > > @@ -1231,7 +1231,8 @@ int dma_buf_end_cpu_access(struct
> > > dma_buf *dmabuf,
> > > >{
> > > > int ret = 0;
> > > > 
> > > > -   WARN_ON(!dmabuf);
> > > > +   if (WARN_ON(!dmabuf))
> > > > +   return -EINVAL;
> > > > 
> > > > might_lock(&dmabuf->resv->lock.base);
> > > > 
> 
> ___
> Linaro-mm-sig mailing list
> linaro-mm-...@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/linaro-mm-sig

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [Linaro-mm-sig] [PATCH] dma-buf: return -EINVAL if dmabuf object is NULL

2021-08-18 Thread Christian König

Am 18.08.21 um 14:46 schrieb Daniel Vetter:

On Wed, Aug 18, 2021 at 02:31:34PM +0200, Christian König wrote:

Am 18.08.21 um 14:17 schrieb Sa, Nuno:

From: Christian König 
Sent: Wednesday, August 18, 2021 2:10 PM
To: Sa, Nuno ; linaro-mm-...@lists.linaro.org;
dri-devel@lists.freedesktop.org; linux-me...@vger.kernel.org
Cc: Rob Clark ; Sumit Semwal

Subject: Re: [PATCH] dma-buf: return -EINVAL if dmabuf object is
NULL

[External]

To be honest I think the if(WARN_ON(!dmabuf)) return -EINVAL
handling
here is misleading in the first place.

Returning -EINVAL on a hard coding error is not good practice and
should
probably be removed from the DMA-buf subsystem in general.

Would you say to just return 0 then? I don't think that having the
dereference is also good..

No, just run into the dereference.

Passing NULL as the core object you are working on is a hard coding error
and not something we should bubble up as recoverable error.


I used -EINVAL to be coherent with the rest of the code.

I rather suggest to remove the check elsewhere as well.

It's a lot more complicated, and WARN_ON + bail out is rather
well-established code-pattern. There's been plenty of discussions in the
past that a BUG_ON is harmful since it makes debugging a major pain, e.g.

https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Flkml%2FCA%2B55aFwyNTLuZgOWMTRuabWobF27ygskuxvFd-P0n-3UNT%3D0Og%40mail.gmail.com%2F&data=04%7C01%7Cchristian.koenig%40amd.com%7C19f53e2a2d1843b65adc08d962463b78%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637648876076613233%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=ajyBnjePRak3o7ObpBAuJNd08HgkANM9C%2BgzOAeHrMk%3D&reserved=0

There's also a checkpatch check for this.

commit 9d3e3c705eb395528fd8f17208c87581b134da48
Author: Joe Perches 
Date:   Wed Sep 9 15:37:27 2015 -0700

 checkpatch: add warning on BUG/BUG_ON use

Anyone who is paranoid about security crashes their machine on any WARNING
anyway (like syzkaller does).

My rule of thumb is that if the WARN_ON + bail-out code is just an if
(WARN_ON()) return; then it's fine, if it's more then BUG_ON is the better
choice perhaps.

I think the worst choice is just removing all these checks, because a few
code reorgs later you might not Oops immediately afterwards anymore, and
then we'll merge potentially very busted new code. Which is no good.


Well BUG_ON(some_codition) is a different problem which I agree on with 
Linus that this is problematic.


But "if (WARN_ON(!dmabuf)) return -EINVAL;" is really bad coding style 
as well since it hides real problems which are hard errors behind warnings.


Returning -EINVAL indicates a recoverable error which is usually caused 
by userspace giving invalid parameters and should never be abused to 
indicate a driver coding error.


Functions are either intended to take NULL as valid parameter, e.g. like 
kfree(NULL). Or they are intended to work on an object which is 
mandatory to provide.


Christian.


-Daniel




Christian.


- Nuno Sá


Christian.

Am 18.08.21 um 13:58 schrieb Nuno Sá:

On top of warning about a NULL object, we also want to return with a
proper error code (as done in 'dma_buf_begin_cpu_access()').

Otherwise,

we will get a NULL pointer dereference.

Fixes: fc13020e086b ("dma-buf: add support for kernel cpu access")
Signed-off-by: Nuno Sá 
---
drivers/dma-buf/dma-buf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-

buf.c

index 63d32261b63f..8ec7876dd523 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1231,7 +1231,8 @@ int dma_buf_end_cpu_access(struct

dma_buf *dmabuf,

{
int ret = 0;

-   WARN_ON(!dmabuf);
+   if (WARN_ON(!dmabuf))
+   return -EINVAL;

might_lock(&dmabuf->resv->lock.base);


___
Linaro-mm-sig mailing list
linaro-mm-...@lists.linaro.org
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.linaro.org%2Fmailman%2Flistinfo%2Flinaro-mm-sig&data=04%7C01%7Cchristian.koenig%40amd.com%7C19f53e2a2d1843b65adc08d962463b78%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637648876076613233%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0E5L4Kid5ZPeKT8Uxx7K61fBXmI4TOsz%2F5ILsFpLB%2Fo%3D&reserved=0




Re: [PATCH] drm/ttm: optimize the pool shrinker a bit v3

2021-08-18 Thread Christian König

Am 18.08.21 um 14:32 schrieb Daniel Vetter:

On Wed, Aug 18, 2021 at 01:27:13PM +0200, Christian König wrote:

Just a gentle ping?

Does anybody have any objections? It's just switching back to using a
spinlock in the hot path instead of a mutex.

Thanks,
Christian.

Am 22.07.21 um 13:34 schrieb Christian König:

Switch back to using a spinlock again by moving the IOMMU unmap outside
of the locked region.

v2: Add a comment explaining why we need sync_shrinkers().
v3: Drop sync_shrinkers() and use an SRCU instead.

Why did you move to your own hand-rolled thing here? From the old thread
it just looked like Andrew wanted some proper explanation. And the
sychronize_shrinkers is imo much clearer than some hand-rolled srcu thing.


Well I agree that it is minimal cleaner, but I've pinged Andrew a couple 
of times and he seems to be busy.



Also on the spinlock covnersion, do you have some benchmarks/profile
flamegraphs/numbers that show it matters? Would be realy good to record
that kind of stuff in the commit message instead of just having the
implication that this optimizes stuff.


The spinlock conversion doesn't matter that much, but what makes the 
difference is that we don't do all IOMMU mapping/unmapping under a 
single mutex any more.


I've promised to take another look at it when we fixed that and somebody 
from an internal team complained about this as well.


Not sure if that really helps or if we then have the next bottleneck in 
the IOMMU code, but it is at least a start.


Christian.


-Daniel


Signed-off-by: Christian König 
---
   drivers/gpu/drm/ttm/ttm_pool.c | 45 --
   1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index cb38b1a17b09..cee664c487b5 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -70,7 +70,8 @@ static struct ttm_pool_type global_uncached[MAX_ORDER];
   static struct ttm_pool_type global_dma32_write_combined[MAX_ORDER];
   static struct ttm_pool_type global_dma32_uncached[MAX_ORDER];
-static struct mutex shrinker_lock;
+static spinlock_t shrinker_lock;
+DEFINE_STATIC_SRCU(shrinker_srcu);
   static struct list_head shrinker_list;
   static struct shrinker mm_shrinker;
@@ -263,9 +264,9 @@ static void ttm_pool_type_init(struct ttm_pool_type *pt, 
struct ttm_pool *pool,
spin_lock_init(&pt->lock);
INIT_LIST_HEAD(&pt->pages);
-   mutex_lock(&shrinker_lock);
+   spin_lock(&shrinker_lock);
list_add_tail(&pt->shrinker_list, &shrinker_list);
-   mutex_unlock(&shrinker_lock);
+   spin_unlock(&shrinker_lock);
   }
   /* Remove a pool_type from the global shrinker list and free all pages */
@@ -273,9 +274,9 @@ static void ttm_pool_type_fini(struct ttm_pool_type *pt)
   {
struct page *p;
-   mutex_lock(&shrinker_lock);
+   spin_lock(&shrinker_lock);
list_del(&pt->shrinker_list);
-   mutex_unlock(&shrinker_lock);
+   spin_unlock(&shrinker_lock);
while ((p = ttm_pool_type_take(pt)))
ttm_pool_free_page(pt->pool, pt->caching, pt->order, p);
@@ -313,24 +314,27 @@ static struct ttm_pool_type *ttm_pool_select_type(struct 
ttm_pool *pool,
   static unsigned int ttm_pool_shrink(void)
   {
struct ttm_pool_type *pt;
-   unsigned int num_freed;
+   unsigned int num_pages;
struct page *p;
+   int idx;
-   mutex_lock(&shrinker_lock);
+   idx = srcu_read_lock(&shrinker_srcu);
+
+   spin_lock(&shrinker_lock);
pt = list_first_entry(&shrinker_list, typeof(*pt), shrinker_list);
+   list_move_tail(&pt->shrinker_list, &shrinker_list);
+   spin_unlock(&shrinker_lock);
p = ttm_pool_type_take(pt);
if (p) {
ttm_pool_free_page(pt->pool, pt->caching, pt->order, p);
-   num_freed = 1 << pt->order;
+   num_pages = 1 << pt->order;
} else {
-   num_freed = 0;
+   num_pages = 0;
}
-   list_move_tail(&pt->shrinker_list, &shrinker_list);
-   mutex_unlock(&shrinker_lock);
-
-   return num_freed;
+   srcu_read_unlock(&shrinker_srcu, idx);
+   return num_pages;
   }
   /* Return the allocation order based for a page */
@@ -530,6 +534,11 @@ void ttm_pool_fini(struct ttm_pool *pool)
for (j = 0; j < MAX_ORDER; ++j)
ttm_pool_type_fini(&pool->caching[i].orders[j]);
}
+
+   /* We removed the pool types from the LRU, but we need to also make sure
+* that no shrinker is concurrently freeing pages from the pool.
+*/
+   synchronize_srcu(&shrinker_srcu);
   }
   /* As long as pages are available make sure to release at least one */
@@ -604,7 +613,7 @@ static int ttm_pool_debugfs_globals_show(struct seq_file 
*m, void *data)
   {
ttm_pool_debugfs_header(m);
-   mutex_lock(&shrinker_lock);
+   spin_lock(&shrinker_lock);

Re: [PATCH v3 1/3] dt-bindings: Add YAML bindings for NVDEC

2021-08-18 Thread Thierry Reding
On Wed, Aug 18, 2021 at 11:24:28AM +0300, Mikko Perttunen wrote:
> On 8/18/21 12:20 AM, Rob Herring wrote:
> > On Wed, Aug 11, 2021 at 01:50:28PM +0300, Mikko Perttunen wrote:
> > > Add YAML device tree bindings for NVDEC, now in a more appropriate
> > > place compared to the old textual Host1x bindings.
> > > 
> > > Signed-off-by: Mikko Perttunen 
> > > ---
> > > v3:
> > > * Drop host1x bindings
> > > * Change read2 to read-1 in interconnect names
> > > v2:
> > > * Fix issues pointed out in v1
> > > * Add T194 nvidia,instance property
> > > ---
> > >   .../gpu/host1x/nvidia,tegra210-nvdec.yaml | 109 ++
> > >   MAINTAINERS   |   1 +
> > >   2 files changed, 110 insertions(+)
> > >   create mode 100644 
> > > Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
> > > 
> > > diff --git 
> > > a/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml 
> > > b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
> > > new file mode 100644
> > > index ..571849625da8
> > > --- /dev/null
> > > +++ 
> > > b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
> > > @@ -0,0 +1,109 @@
> > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: 
> > > "http://devicetree.org/schemas/gpu/host1x/nvidia,tegra210-nvdec.yaml#";
> > > +$schema: "http://devicetree.org/meta-schemas/core.yaml#";
> > > +
> > > +title: Device tree binding for NVIDIA Tegra NVDEC
> > > +
> > > +description: |
> > > +  NVDEC is the hardware video decoder present on NVIDIA Tegra210
> > > +  and newer chips. It is located on the Host1x bus and typically
> > > +  programmed through Host1x channels.
> > > +
> > > +maintainers:
> > > +  - Thierry Reding 
> > > +  - Mikko Perttunen 
> > > +
> > > +properties:
> > > +  $nodename:
> > > +pattern: "^nvdec@[0-9a-f]*$"
> > > +
> > > +  compatible:
> > > +enum:
> > > +  - nvidia,tegra210-nvdec
> > > +  - nvidia,tegra186-nvdec
> > > +  - nvidia,tegra194-nvdec
> > > +
> > > +  reg:
> > > +maxItems: 1
> > > +
> > > +  clocks:
> > > +maxItems: 1
> > > +
> > > +  clock-names:
> > > +items:
> > > +  - const: nvdec
> > > +
> > > +  resets:
> > > +maxItems: 1
> > > +
> > > +  reset-names:
> > > +items:
> > > +  - const: nvdec
> > > +
> > > +  power-domains:
> > > +maxItems: 1
> > > +
> > > +  iommus:
> > > +maxItems: 1
> > > +
> > > +  interconnects:
> > > +items:
> > > +  - description: DMA read memory client
> > > +  - description: DMA read 2 memory client
> > > +  - description: DMA write memory client
> > > +
> > > +  interconnect-names:
> > > +items:
> > > +  - const: dma-mem
> > > +  - const: read-1
> > > +  - const: write
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - clocks
> > > +  - clock-names
> > > +  - resets
> > > +  - reset-names
> > > +  - power-domains
> > > +
> > > +if:
> > > +  properties:
> > > +compatible:
> > > +  contains:
> > > +const: nvidia,tegra194-host1x
> > 
> > host1x? This will never be true as the schema is only applied to nodes
> > with the nvdec compatible.
> 
> Argh, it's a typo indeed. Should be nvidia,tegra194-nvdec.
> 
> > 
> > > +then:
> > > +  properties:
> > > +nvidia,instance:
> > > +  items:
> > > +- description: 0 for NVDEC0, or 1 for NVDEC1
> > 
> > What's this for? We generally don't do indices in DT.
> 
> When programming the hardware through Host1x, we need to know the "class ID"
> of the hardware, specific to each instance. So we need to know which
> instance it is. Technically of course we could derive this from the MMIO
> address but that seems more confusing.
> 
> > 
> > > +
> > > +additionalProperties: true
> > 
> > This should be false or 'unevaluatedProperties: false'
> 
> I tried that but it resulted in validation failures; please see the
> discussion in v2.

Rob mentioned that there is now support for unevaluatedProperties in
dt-schema. I was able to test this, though with only limited success. I
made the following changes on top of this patch:

--- >8 ---
diff --git 
a/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml 
b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
index d2681c98db7e..0bdf05fc8fc7 100644
--- a/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
+++ b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml
@@ -73,14 +73,18 @@ if:
   properties:
 compatible:
   contains:
-const: nvidia,tegra194-host1x
+const: nvidia,tegra194-nvdec
 then:
   properties:
 nvidia,instance:
+  $ref: /schemas/types.yaml#/definitions/uint32
   items:
 - description: 0 for NVDEC0, or 1 for NVDEC1
 
-additionalProperties: true
+  required:
+- nvidia,instance
+
+unevaluatedProperties: false
 
 examples:
   - |
@@ -105,3 +109

Re: [PATCH] drm/prime: fix a potential double put (release) bug

2021-08-18 Thread Christian König

Am 18.08.21 um 15:02 schrieb Wentao_Liang:

In line 317 (#1), drm_gem_prime_import() is called, it will call
drm_gem_prime_import_dev(). At the end of the function
drm_gem_prime_import_dev() (line 956, #2), "dma_buf_put(dma_buf);" puts
dma_buf->file and may cause it to be released. However, after
drm_gem_prime_import() returning, the dma_buf may be put again by the
same put function in lines 342, 351 and 358 (#3, #4, #5). Putting the
dma_buf improperly more than once can lead to an incorrect dma_buf-

file put.

We believe that the put of the dma_buf in the function
drm_gem_prime_import() is unnecessary (#2). We can fix the above bug by
removing the redundant "dma_buf_put(dma_buf);" in line 956.


Guys I'm getting tired of NAKing those incorrect reference count analysis.

The dma_buf_put() in the error handling of drm_gem_prime_import_dev() 
function is balanced with the get_dma_buf() in the same function 
directly above.


This is for the creating a GEM object for a DMA-buf imported from other 
device use case and certainly correct.


The various dma_buf_put() in drm_gem_prime_fd_to_handle() is balanced 
with the dma_buf_get(prime_fd) at the beginning of the function.


This is for extracting the DMA-buf from the file descriptor and keeping 
a reference to it while we are busy importing it (e.g. to prevent a race 
when somebody changes the fd at the same time).


As far as I can see this is correct as well.

Regards,
Christian.



  314 if (dev->driver->gem_prime_import)
  315 obj = dev->driver->gem_prime_import(dev, dma_buf);
  316 else
  317 obj = drm_gem_prime_import(dev, dma_buf);
//#1 call to drm_gem_prime_import
//   ->drm_gem_prime_import_dev
//   ->dma_buf_put
  ...

  336 ret = drm_prime_add_buf_handle(&file_priv->prime,
  337 dma_buf, *handle);

  ...

  342 dma_buf_put(dma_buf);  //#3 put again
  343
  344 return 0;
  345
  346 fail:

  351 dma_buf_put(dma_buf); //#4 put again
  352 return ret;

  356 out_put:
  357 mutex_unlock(&file_priv->prime.lock);
  358 dma_buf_put(dma_buf);  //#5 put again
  359 return ret;
  360 }

  905 struct drm_gem_object *drm_gem_prime_import_dev
(struct drm_device *dev,
  906 struct dma_buf *dma_buf,
  907 struct device *attach_dev)
  908 {

  ...

  952 fail_unmap:
  953 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
  954 fail_detach:
  955 dma_buf_detach(dma_buf, attach);
  956 dma_buf_put(dma_buf);  //#2 the first put of dma_buf
//   
(unnecessary)
  957
  958 return ERR_PTR(ret);
  959 }

Signed-off-by: Wentao_Liang 
---
  drivers/gpu/drm/drm_prime.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 2a54f86856af..cef03ad0d5cd 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -953,7 +953,6 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct 
drm_device *dev,
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
  fail_detach:
dma_buf_detach(dma_buf, attach);
-   dma_buf_put(dma_buf);
  
  	return ERR_PTR(ret);

  }




Re: [Linaro-mm-sig] [PATCH] dma-buf: return -EINVAL if dmabuf object is NULL

2021-08-18 Thread Christian König

Am 18.08.21 um 15:13 schrieb Sa, Nuno:

From: Christian König 
Sent: Wednesday, August 18, 2021 2:58 PM
To: Daniel Vetter 
Cc: Sa, Nuno ; linaro-mm-...@lists.linaro.org;
dri-devel@lists.freedesktop.org; linux-me...@vger.kernel.org; Rob
Clark 
Subject: Re: [Linaro-mm-sig] [PATCH] dma-buf: return -EINVAL if
dmabuf object is NULL

[External]

Am 18.08.21 um 14:46 schrieb Daniel Vetter:

On Wed, Aug 18, 2021 at 02:31:34PM +0200, Christian König wrote:

Am 18.08.21 um 14:17 schrieb Sa, Nuno:

From: Christian König 
Sent: Wednesday, August 18, 2021 2:10 PM
To: Sa, Nuno ; linaro-mm-

s...@lists.linaro.org;

dri-devel@lists.freedesktop.org; linux-me...@vger.kernel.org
Cc: Rob Clark ; Sumit Semwal

Subject: Re: [PATCH] dma-buf: return -EINVAL if dmabuf object

is

NULL

[External]

To be honest I think the if(WARN_ON(!dmabuf)) return -EINVAL
handling
here is misleading in the first place.

Returning -EINVAL on a hard coding error is not good practice and
should
probably be removed from the DMA-buf subsystem in general.

Would you say to just return 0 then? I don't think that having the
dereference is also good..

No, just run into the dereference.

Passing NULL as the core object you are working on is a hard coding

error

and not something we should bubble up as recoverable error.


I used -EINVAL to be coherent with the rest of the code.

I rather suggest to remove the check elsewhere as well.

It's a lot more complicated, and WARN_ON + bail out is rather
well-established code-pattern. There's been plenty of discussions in

the

past that a BUG_ON is harmful since it makes debugging a major

pain, e.g.



https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.com%2Fv3%2F__https%3A%2F%2Fnam11.safelinks.protection.outl&data=04%7C01%7Cchristian.koenig%40amd.com%7C6355660e526b4da23fa408d9624a0160%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637648892261202104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=pkZg9vDm4RTgmAD6vtugsLmUuL0fG9ExgTWedxOxCW8%3D&reserved=0
ook.com/?url=https*3A*2F*2Flore.kernel.org*2Flkml*2FCA*2B55aFw
yNTLuZgOWMTRuabWobF27ygskuxvFd-P0n-
3UNT*3D0Og*40mail.gmail.com*2F&data=04*7C01*7Cchristian.k
oenig*40amd.com*7C19f53e2a2d1843b65adc08d962463b78*7C3dd896
1fe4884e608e11a82d994e183d*7C0*7C0*7C637648876076613233*7CU
nknown*7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiL
CJBTiI6Ik1haWwiLCJXVCI6Mn0*3D*7C1000&sdata=ajyBnjePRak3
o7ObpBAuJNd08HgkANM9C*2BgzOAeHrMk*3D&reserved=0__;J
SUlJSUlJSUlJSUlJSUlJSUlJSUlJSU!!A3Ni8CS0y2Y!qiDegx4svPUMZrvnzUo
X7VKvvFpDcedH9gYbRCiWfe_N3fw4zpmA54qxefvMiQ$

There's also a checkpatch check for this.

commit 9d3e3c705eb395528fd8f17208c87581b134da48
Author: Joe Perches 
Date:   Wed Sep 9 15:37:27 2015 -0700

  checkpatch: add warning on BUG/BUG_ON use

Anyone who is paranoid about security crashes their machine on any

WARNING

anyway (like syzkaller does).

My rule of thumb is that if the WARN_ON + bail-out code is just an if
(WARN_ON()) return; then it's fine, if it's more then BUG_ON is the

better

choice perhaps.

I think the worst choice is just removing all these checks, because a

few

code reorgs later you might not Oops immediately afterwards

anymore, and

then we'll merge potentially very busted new code. Which is no

good.

Well BUG_ON(some_codition) is a different problem which I agree on
with
Linus that this is problematic.

But "if (WARN_ON(!dmabuf)) return -EINVAL;" is really bad coding
style
as well since it hides real problems which are hard errors behind
warnings.

I agree that doing these kind of checks in the core object of an API is
abusing parameter "validation". I guess a good pattern is having the
warning and let the code flow. But since these checks are already all
over the place I'm not sure the way to go. I'm very new to dma-buf
and I was just checking the code and saw this was not be coherent with
the rest of the API so I thought it would be a straight easy patch... Well,
I could not be more wrong :)


Well that existing stuff might actually depend on this is a really good 
argument to keep it for now or at least until we have a consent on what 
to do.



Anyways, depending on what's decided, I can send another patch trying
to make these stuff more coherent. At this point, my feeling is that this
patch is to be dropped...


At least for now I would hold it back.

Thanks,
Christian.



- Nuno Sá


Returning -EINVAL indicates a recoverable error which is usually caused
by userspace giving invalid parameters and should never be abused to
indicate a driver coding error.

Functions are either intended to take NULL as valid parameter, e.g. like
kfree(NULL). Or they are intended to work on an object which is
mandatory to provide.

Christian.


-Daniel




Christian.


- Nuno Sá


Christian.

Am 18.08.21 um 13:58 schrieb Nuno Sá:

On top of warning about a NULL object, we also want to return

with a

proper error code (as done in 'dma_buf_begin_cpu_access()').

Otherw

Re: [PATCH v2 50/63] tracing: Use memset_startat() to zero struct trace_iterator

2021-08-18 Thread Steven Rostedt
On Tue, 17 Aug 2021 23:05:20 -0700
Kees Cook  wrote:

> In preparation for FORTIFY_SOURCE performing compile-time and run-time
> field bounds checking for memset(), avoid intentionally writing across
> neighboring fields.
> 
> Use memset_startat() to avoid confusing memset() about writing beyond
> the target struct member.
> 
> Cc: Steven Rostedt 
> Cc: Ingo Molnar 
> Signed-off-by: Kees Cook 
> ---
>  kernel/trace/trace.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 13587e771567..9ff8c31975cd 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -6691,9 +6691,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
>   cnt = PAGE_SIZE - 1;
>  
>   /* reset all but tr, trace, and overruns */
> - memset(&iter->seq, 0,
> -sizeof(struct trace_iterator) -
> -offsetof(struct trace_iterator, seq));
> + memset_startat(iter, 0, seq);

I can't find memset_startat() in mainline nor linux-next. I don't see it
in this thread either, but since this has 63 patches, I could have
easily missed it.

This change really should belong to a patch set that just introduces
memset_startat() (and perhaps memset_after()) and then updates all the
places that should use it. That way I can give it a proper review. In
other words, you should break this patch set up into smaller, more
digestible portions for the reviewers.

Thanks,

-- Steve



>   cpumask_clear(iter->started);
>   trace_seq_init(&iter->seq);
>   iter->pos = -1;



Re: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel compatibles

2021-08-18 Thread Rob Herring
On Wed, Aug 18, 2021 at 7:43 AM Maxime Ripard  wrote:
>
> Hi Rob, Sam,
>
> On Wed, Jul 21, 2021 at 08:29:47PM -0600, Rob Herring wrote:
> > On Wed, Jul 21, 2021 at 04:03:40PM +0200, Maxime Ripard wrote:
> > > The binding mentions that all the drivers using that driver must use a
> > > vendor-specific compatible but never enforces it, nor documents the
> > > vendor-specific compatibles.
> > >
> > > Let's make we document all of them, and that the binding will create an
> > > error if we add one that isn't.
> > >
> > > Cc: dri-devel@lists.freedesktop.org
> > > Cc: Laurent Pinchart 
> > > Cc: Sam Ravnborg 
> > > Cc: Thierry Reding 
> > > Signed-off-by: Maxime Ripard 
> > > ---
> > >  .../bindings/display/panel/lvds.yaml   | 18 --
> > >  1 file changed, 12 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml 
> > > b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > index 49460c9dceea..d1513111eb48 100644
> > > --- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > +++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > @@ -31,12 +31,18 @@ allOf:
> > >
> > >  properties:
> > >compatible:
> > > -contains:
> > > -  const: panel-lvds
> > > -description:
> > > -  Shall contain "panel-lvds" in addition to a mandatory 
> > > panel-specific
> > > -  compatible string defined in individual panel bindings. The 
> > > "panel-lvds"
> > > -  value shall never be used on its own.
> > > +items:
> > > +  - enum:
> > > +  - advantech,idk-1110wr
> >
> > At least this one is documented elsewhere.
>
> Indeed, I missed it.
>
> > You can add 'minItems: 2' if you want to just enforce having 2 compatibles. 
> > Or do:
> >
> > items:
> >   - {}
> >   - const: panel-lvds
> >
> > Which also enforces the order.
>
> It's not just about the order since a missing compatible will also raise
> a warning.
>
> Some of those panels have a binding of their own, but some probably
> won't (and I can't find anything specific about the one I'm most
> interested in: tbs,a711-panel)
>
> Can we have something like:
>
> compatible:
>   oneOf:
> - items:
>   - enum:
> - tbs,a711-panel
>   - const: panel-lvds
>
> - items:
>   - {}
>   - const: panel-lvds
>
> That would work for both cases I guess?

No, both conditions will be true. If you use 'anyOf', then we're never
really checking the specific compatible.

I think the problem here is trying to mix a common binding (aka an
incomplete collection of properties) and a specific binding. The
former is characterized with 'additionalProperties: true' as we have
here. You need to create a 'panel-simple-lvds.yaml' schema file that
references this one, defines all the 'simple' compatibles, and sets
'unevaluatedProperties: false'.

Rob


Re: [PATCH v8 06/34] dt-bindings: clock: tegra-car: Document new tegra-clocks sub-node

2021-08-18 Thread Thierry Reding
On Wed, Aug 18, 2021 at 04:44:30AM +0300, Dmitry Osipenko wrote:
> 18.08.2021 04:15, Rob Herring пишет:
> >> +  tegra-clocks:
> >> +description: child nodes are the output clocks from the CAR
> >> +type: object
> >> +
> >> +patternProperties:
> >> +  "^[a-z]+[0-9]+$":
> >> +type: object
> >> +properties:
> >> +  compatible:
> >> +allOf:
> >> +  - items:
> >> +  - enum:
> >> +  - nvidia,tegra20-sclk
> >> +  - nvidia,tegra30-sclk
> >> +  - nvidia,tegra30-pllc
> >> +  - nvidia,tegra30-plle
> >> +  - nvidia,tegra30-pllm
> >> +  - const: nvidia,tegra-clock
> > You are saying the first string must be both one of the enums and 
> > 'nvidia,tegra-clock'. You don't get an error because your pattern 
> > doesn't match 'sclk'.
> > 
> 
> Could you please rephrase or clarify? If pattern doesn't match 'sclk',
> then it must match any other enum. I'm not sure what you're meaning.

"sclk" doesn't match "^[a-z]+[0-9]+$" because it's missing at least one
digit at the end. Perhaps that last + was supposed to be *?

> 
> The 'nvidia,tegra-clock' actually could be removed since it's
> superfluous now. I'll consider the removal in v9.

It also looks like your schema was meant to be something like:

compatible:
  - items:
  - enum:
  - nvidia,tegra20-sclk
  - nvidia,tegra30-sclk
  - nvidia,tegra30-pllc
  - nvidia,tegra30-plle
  - nvidia,tegra30-pllm
  - const: nvidia,tegra-clock

Note how the const: element is indented one more level. Now this means:
one of the enumeration values, followed by the constant value. That
matches what the example has.

That said, I agree that nvidia,tegra-clock seems a bit useless. There's
really no such thing as a generic clock, they're all different in some
way.

Thierry


signature.asc
Description: PGP signature


Re: [PATCH v8 06/34] dt-bindings: clock: tegra-car: Document new tegra-clocks sub-node

2021-08-18 Thread Thierry Reding
On Tue, Aug 17, 2021 at 04:27:26AM +0300, Dmitry Osipenko wrote:
> Document tegra-clocks sub-node which describes Tegra SoC clocks that
> require a higher voltage of the core power domain in order to operate
> properly on a higher clock rates.  Each node contains a phandle to OPP
> table and power domain.
> 
> The root PLLs and system clocks don't have any specific device dedicated
> to them, clock controller is in charge of managing power for them.
> 
> Signed-off-by: Dmitry Osipenko 
> ---
>  .../bindings/clock/nvidia,tegra20-car.yaml| 51 +++
>  1 file changed, 51 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml 
> b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml
> index 459d2a525393..7f5cd27e4ce0 100644
> --- a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml
> +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml
> @@ -42,6 +42,48 @@ properties:
>"#reset-cells":
>  const: 1
>  
> +  tegra-clocks:
> +description: child nodes are the output clocks from the CAR
> +type: object
> +
> +patternProperties:
> +  "^[a-z]+[0-9]+$":
> +type: object
> +properties:
> +  compatible:
> +allOf:
> +  - items:
> +  - enum:
> +  - nvidia,tegra20-sclk
> +  - nvidia,tegra30-sclk
> +  - nvidia,tegra30-pllc
> +  - nvidia,tegra30-plle
> +  - nvidia,tegra30-pllm
> +  - const: nvidia,tegra-clock
> +
> +  operating-points-v2:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  Phandle to OPP table that contains frequencies, voltages and
> +  opp-supported-hw property, which is a bitfield indicating
> +  SoC process or speedo ID mask.
> +
> +  clocks:
> +items:
> +  - description: node's clock
> +
> +  power-domains:
> +maxItems: 1
> +description: phandle to the core SoC power domain
> +
> +required:
> +  - compatible
> +  - operating-points-v2
> +  - clocks
> +  - power-domains
> +
> +additionalProperties: false
> +
>  required:
>- compatible
>- reg
> @@ -59,6 +101,15 @@ examples:
>  reg = <0x60006000 0x1000>;
>  #clock-cells = <1>;
>  #reset-cells = <1>;
> +
> +tegra-clocks {
> +sclk {
> +compatible = "nvidia,tegra20-sclk", "nvidia,tegra-clock";
> +operating-points-v2 = <&opp_table>;
> +clocks = <&tegra_car TEGRA20_CLK_SCLK>;
> +power-domains = <&domain>;
> +};
> +};

I wonder if it'd be better to match on the name of the node rather than
add an artificial compatible string. We usually use the compatible
string to match a device, but here you're really trying to add
information about a resource provided by the CAR controller.

We do similar things for example in PMIC bindings where the individual
regulators are represented in the device tree via nodes named after the
regulator.

You could then also leave out the clocks property, which is weird as it
is because it's basically a self-reference. But you don't really need
the reference here in the first place because the CAR is already the
parent of SCLK.

Also, I don't think the tegra- prefix is necessary here. The parent node
is already identified as Tegra via the compatible string.

In the case of CAR, I'd imagine something like:

clocks {
sclk {
operating-points-v2 = <&opp_table>;
power-domains = <&domain>;
};
};

Now you've only got the bare minimum in here that you actually add. All
the other data that you used to have is simply derived from the parent.

Thierry

>  };
>  
>  usb-controller@c5004000 {
> -- 
> 2.32.0
> 


signature.asc
Description: PGP signature


Re: [PATCH v2] Revert "drm/scheduler: Avoid accessing freed bad job."

2021-08-18 Thread Alex Deucher
+ dri-devel

Since scheduler is a shared component, please add dri-devel on all
scheduler patches.

On Wed, Aug 18, 2021 at 7:21 AM Jingwen Chen  wrote:
>
> [Why]
> for bailing job, this commit will delete it from pending list thus the
> bailing job will never have a chance to be resubmitted even in advance
> tdr mode.
>
> [How]
> after embeded hw_fence into amdgpu_job is done, the race condition that
> this commit tries to work around is completely solved.So revert this
> commit.
> This reverts commit 135517d3565b48f4def3b1b82008bc17eb5d1c90.
> v2:
> add dma_fence_get/put() around timedout_job to avoid concurrent delete
> during processing timedout_job
>
> Signed-off-by: Jingwen Chen 
> ---
>  drivers/gpu/drm/scheduler/sched_main.c | 23 +--
>  1 file changed, 5 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> b/drivers/gpu/drm/scheduler/sched_main.c
> index a2a953693b45..f9b9b3aefc4a 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -314,6 +314,7 @@ static void drm_sched_job_timedout(struct work_struct 
> *work)
>  {
> struct drm_gpu_scheduler *sched;
> struct drm_sched_job *job;
> +   struct dma_fence *fence;
> enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_NOMINAL;
>
> sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
> @@ -325,11 +326,10 @@ static void drm_sched_job_timedout(struct work_struct 
> *work)
>
> if (job) {
> /*
> -* Remove the bad job so it cannot be freed by concurrent
> -* drm_sched_cleanup_jobs. It will be reinserted back after 
> sched->thread
> -* is parked at which point it's safe.
> +* Get job->s_fence->parent here to avoid concurrent delete 
> during
> +* processing timedout_job
>  */
> -   list_del_init(&job->list);
> +   fence = dma_fence_get(job->s_fence->parent);
> spin_unlock(&sched->job_list_lock);
>
> status = job->sched->ops->timedout_job(job);
> @@ -342,6 +342,7 @@ static void drm_sched_job_timedout(struct work_struct 
> *work)
> job->sched->ops->free_job(job);
> sched->free_guilty = false;
> }
> +   dma_fence_put(fence);
> } else {
> spin_unlock(&sched->job_list_lock);
> }
> @@ -392,20 +393,6 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
> struct drm_sched_job *bad)
>
> kthread_park(sched->thread);
>
> -   /*
> -* Reinsert back the bad job here - now it's safe as
> -* drm_sched_get_cleanup_job cannot race against us and release the
> -* bad job at this point - we parked (waited for) any in progress
> -* (earlier) cleanups and drm_sched_get_cleanup_job will not be called
> -* now until the scheduler thread is unparked.
> -*/
> -   if (bad && bad->sched == sched)
> -   /*
> -* Add at the head of the queue to reflect it was the earliest
> -* job extracted.
> -*/
> -   list_add(&bad->list, &sched->pending_list);
> -
> /*
>  * Iterate the job list from later to  earlier one and either deactive
>  * their HW callbacks or remove them from pending list if they already
> --
> 2.25.1
>


Re: [PATCH v8 07/34] clk: tegra: Support runtime PM and power domain

2021-08-18 Thread Thierry Reding
On Tue, Aug 17, 2021 at 04:27:27AM +0300, Dmitry Osipenko wrote:
[...]
> +struct clk *tegra_clk_register(struct clk_hw *hw)
> +{
> + struct platform_device *pdev;
> + struct device *dev = NULL;
> + struct device_node *np;
> + const char *dev_name;
> +
> + np = tegra_clk_get_of_node(hw);
> +
> + if (!of_device_is_available(np))
> + goto put_node;
> +
> + dev_name = kasprintf(GFP_KERNEL, "tegra_clk_%s", hw->init->name);
> + if (!dev_name)
> + goto put_node;
> +
> + pdev = of_platform_device_create(np, dev_name, NULL);
> + if (!pdev) {
> + pr_err("%s: failed to create device for %pOF\n", __func__, np);
> + kfree(dev_name);
> + goto put_node;
> + }
> +
> + dev = &pdev->dev;
> + pm_runtime_enable(dev);
> +put_node:
> + of_node_put(np);
> +
> + return clk_register(dev, hw);
> +}

This looks wrong. Why do we need struct platform_device objects for each
of these clocks? That's going to be a massive amount of platform devices
and they will completely mess up sysfs.

Thierry


signature.asc
Description: PGP signature


Re: [PATCH] drm/prime: fix a potential double put (release) bug

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 03:25:59PM +0200, Christian König wrote:
> Am 18.08.21 um 15:02 schrieb Wentao_Liang:
> > In line 317 (#1), drm_gem_prime_import() is called, it will call
> > drm_gem_prime_import_dev(). At the end of the function
> > drm_gem_prime_import_dev() (line 956, #2), "dma_buf_put(dma_buf);" puts
> > dma_buf->file and may cause it to be released. However, after
> > drm_gem_prime_import() returning, the dma_buf may be put again by the
> > same put function in lines 342, 351 and 358 (#3, #4, #5). Putting the
> > dma_buf improperly more than once can lead to an incorrect dma_buf-
> > > file put.
> > We believe that the put of the dma_buf in the function
> > drm_gem_prime_import() is unnecessary (#2). We can fix the above bug by
> > removing the redundant "dma_buf_put(dma_buf);" in line 956.
> 
> Guys I'm getting tired of NAKing those incorrect reference count analysis.
> 
> The dma_buf_put() in the error handling of drm_gem_prime_import_dev()
> function is balanced with the get_dma_buf() in the same function directly
> above.
> 
> This is for the creating a GEM object for a DMA-buf imported from other
> device use case and certainly correct.
> 
> The various dma_buf_put() in drm_gem_prime_fd_to_handle() is balanced with
> the dma_buf_get(prime_fd) at the beginning of the function.
> 
> This is for extracting the DMA-buf from the file descriptor and keeping a
> reference to it while we are busy importing it (e.g. to prevent a race when
> somebody changes the fd at the same time).
> 
> As far as I can see this is correct as well.

Yeah the analysis is just high-grade nonsense. The current code looks
correct, the analysis presented here, not.
-Daniel


> 
> Regards,
> Christian.
> 
> > 
> >   314 if (dev->driver->gem_prime_import)
> >   315 obj = dev->driver->gem_prime_import(dev, dma_buf);
> >   316 else
> >   317 obj = drm_gem_prime_import(dev, dma_buf);
> > //#1 call to drm_gem_prime_import
> > //   ->drm_gem_prime_import_dev
> > //   ->dma_buf_put
> >   ...
> > 
> >   336 ret = drm_prime_add_buf_handle(&file_priv->prime,
> >   337 dma_buf, *handle);
> > 
> >   ...
> > 
> >   342 dma_buf_put(dma_buf);  //#3 put again
> >   343
> >   344 return 0;
> >   345
> >   346 fail:
> > 
> >   351 dma_buf_put(dma_buf); //#4 put again
> >   352 return ret;
> > 
> >   356 out_put:
> >   357 mutex_unlock(&file_priv->prime.lock);
> >   358 dma_buf_put(dma_buf);  //#5 put again
> >   359 return ret;
> >   360 }
> > 
> >   905 struct drm_gem_object *drm_gem_prime_import_dev
> > (struct drm_device *dev,
> >   906 struct dma_buf *dma_buf,
> >   907 struct device *attach_dev)
> >   908 {
> > 
> >   ...
> > 
> >   952 fail_unmap:
> >   953 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
> >   954 fail_detach:
> >   955 dma_buf_detach(dma_buf, attach);
> >   956 dma_buf_put(dma_buf);  //#2 the first put of dma_buf
> > //   
> > (unnecessary)
> >   957
> >   958 return ERR_PTR(ret);
> >   959 }
> > 
> > Signed-off-by: Wentao_Liang 
> > ---
> >   drivers/gpu/drm/drm_prime.c | 1 -
> >   1 file changed, 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> > index 2a54f86856af..cef03ad0d5cd 100644
> > --- a/drivers/gpu/drm/drm_prime.c
> > +++ b/drivers/gpu/drm/drm_prime.c
> > @@ -953,7 +953,6 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct 
> > drm_device *dev,
> > dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
> >   fail_detach:
> > dma_buf_detach(dma_buf, attach);
> > -   dma_buf_put(dma_buf);
> > return ERR_PTR(ret);
> >   }
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v5, 00/15] Using component framework to support multi hardware decode

2021-08-18 Thread Ezequiel Garcia
+danvet

Hi,

On Tue, 10 Aug 2021 at 23:58, Yunfei Dong  wrote:
>
> This series adds support for multi hardware decode into mtk-vcodec, by first
> adding component framework to manage each hardware information: interrupt,
> clock, register bases and power. Secondly add core thread to deal with core
> hardware message, at the same time, add msg queue for different hardware
> share messages. Lastly, the architecture of different specs are not the same,
> using specs type to separate them.
>

I don't think it's a good idea to introduce the component API in the
media subsystem. It doesn't seem to be maintained, IRC there's not even
a maintainer for it, and it has some issues that were never addressed.

It would be really important to avoid it. Is it really needed in the
first place?

Thanks,
Ezequiel


Re: [Intel-gfx] [PATCH 2/4] drm/i915/guc: Print error name on CTB (de)registration failure

2021-08-18 Thread Daniel Vetter
On Thu, Jul 01, 2021 at 05:55:11PM +0200, Michal Wajdeczko wrote:
> Instead of plain error value (%d) print more user friendly error
> name (%pe).
> 
> Signed-off-by: Michal Wajdeczko 
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> 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 a26bb55c0898..18d52c39f0c2 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> @@ -167,8 +167,8 @@ static int ct_register_buffer(struct intel_guc_ct *ct, 
> u32 type,
>   err = guc_action_register_ct_buffer(ct_to_guc(ct), type,
>   desc_addr, buff_addr, size);
>   if (unlikely(err))
> - CT_ERROR(ct, "Failed to register %s buffer (err=%d)\n",
> -  guc_ct_buffer_type_to_str(type), err);
> + CT_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> +  guc_ct_buffer_type_to_str(type), ERR_PTR(err));

errname() is what you want here, not this convoluted jumping through hoops
to fake an error pointer.

With that: Reviewed-by: Daniel Vetter 
>   return err;
>  }
>  
> @@ -195,8 +195,8 @@ static int ct_deregister_buffer(struct intel_guc_ct *ct, 
> u32 type)
>   int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type);
>  
>   if (unlikely(err))
> - CT_ERROR(ct, "Failed to deregister %s buffer (err=%d)\n",
> -  guc_ct_buffer_type_to_str(type), err);
> + CT_ERROR(ct, "Failed to deregister %s buffer (%pe)\n",
> +  guc_ct_buffer_type_to_str(type), ERR_PTR(err));
>   return err;
>  }
>  
> -- 
> 2.25.1
> 
> ___
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [Intel-gfx] [PATCH 1/4] drm/i915/guc: Verify result from CTB (de)register action

2021-08-18 Thread Daniel Vetter
On Thu, Jul 01, 2021 at 05:55:10PM +0200, Michal Wajdeczko wrote:
> In commit b839a869dfc9 ("drm/i915/guc: Add support for data
> reporting in GuC responses") we missed the hypothetical case
> that GuC might return positive non-zero value as success data.
> 
> While that would be lucky treated as error case, and at the
> end will result in reporting valid -EIO, in the meantime this
> value will be passed to ERR_PTR that could be misleading.
> 
> v2: rebased
> 
> Reported-by: Dan Carpenter 
> Signed-off-by: Michal Wajdeczko 
> Cc: Dan Carpenter 

Return value where all integers are possible is always a bit fragile,
especially here where the meaning additionally depends upon whether you
supply a reply buffer or not.

Would be good to document this with some kerneldoc, but maybe the CTB
interface is a bit too unclear here and that's not worth it (there's at
least a ton of functions/variants that just arent used).

Reviewed-by: Daniel Vetter 

> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> 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 43409044528e..a26bb55c0898 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> @@ -148,12 +148,15 @@ static int guc_action_register_ct_buffer(struct 
> intel_guc *guc, u32 type,
>   FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR, 
> desc_addr),
>   FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR, 
> buff_addr),
>   };
> + int ret;
>  
>   GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != 
> GUC_CTB_TYPE_GUC2HOST);
>   GEM_BUG_ON(size % SZ_4K);
>  
>   /* CT registration must go over MMIO */
> - return intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> + ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> +
> + return ret > 0 ? -EPROTO : ret;
>  }
>  
>  static int ct_register_buffer(struct intel_guc_ct *ct, u32 type,
> @@ -177,11 +180,14 @@ static int guc_action_deregister_ct_buffer(struct 
> intel_guc *guc, u32 type)
>   FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, 
> GUC_ACTION_HOST2GUC_DEREGISTER_CTB),
>   FIELD_PREP(HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE, type),
>   };
> + int ret;
>  
>   GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != 
> GUC_CTB_TYPE_GUC2HOST);
>  
>   /* CT deregistration must go over MMIO */
> - return intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> + ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> +
> + return ret > 0 ? -EPROTO : ret;
>  }
>  
>  static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type)
> -- 
> 2.25.1
> 
> ___
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [Intel-gfx] [PATCH 3/4] drm/i915/guc: Print error name on CTB send failure

2021-08-18 Thread Daniel Vetter
On Thu, Jul 01, 2021 at 05:55:12PM +0200, Michal Wajdeczko wrote:
> Instead of plain error value (%d) print more user friendly error
> name (%pe).
> 
> Signed-off-by: Michal Wajdeczko 
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> 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 18d52c39f0c2..8110586ce1fd 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> @@ -580,8 +580,8 @@ int intel_guc_ct_send(struct intel_guc_ct *ct, const u32 
> *action, u32 len,
>  
>   ret = ct_send(ct, action, len, response_buf, response_buf_size, 
> &status);
>   if (unlikely(ret < 0)) {
> - CT_ERROR(ct, "Sending action %#x failed (err=%d status=%#X)\n",
> -  action[0], ret, status);
> + CT_ERROR(ct, "Sending action %#x failed (%pe) status=%#X\n",
> +  action[0], ERR_PTR(ret), status);

errname(), not this, with that:

Reviewed-by: Daniel Vetter 

>   } else if (unlikely(ret)) {
>   CT_DEBUG(ct, "send action %#x returned %d (%#x)\n",
>action[0], ret, ret);
> -- 
> 2.25.1
> 
> ___
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [Intel-gfx] [PATCH 4/4] drm/i915/guc: Move and improve error message for missed CTB reply

2021-08-18 Thread Daniel Vetter
On Thu, Jul 01, 2021 at 05:55:13PM +0200, Michal Wajdeczko wrote:
> If we timeout waiting for a CT reply we print very simple error
> message. Improve that and by moving error reporting to the caller
> we can use CT_ERROR instead of DRM_ERROR and report just fence
> as error code will be reported later anyway.
> 
> Signed-off-by: Michal Wajdeczko 

Look reasonable.

Btw for within the driver we generally never document static inline
functions with full kerneldoc. That's overkill and they get stale real
fast. What would be useful to document is the interface with the driver at
large (i.e. non-static functions), especially for something that's used
all over like CTB will be. But then we're back to responsibilities and
especialy aroung gpu reset, so not sure whether documenting the current
code before that's sorted is the best idea.

Reviewed-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> 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 8110586ce1fd..f488a51e1ebe 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> @@ -490,9 +490,6 @@ static int wait_for_ct_request_update(struct ct_request 
> *req, u32 *status)
>   err = wait_for(done, 10);
>  #undef done
>  
> - if (unlikely(err))
> - DRM_ERROR("CT: fence %u err %d\n", req->fence, err);
> -
>   *status = req->status;
>   return err;
>  }
> @@ -536,8 +533,11 @@ static int ct_send(struct intel_guc_ct *ct,
>   intel_guc_notify(ct_to_guc(ct));
>  
>   err = wait_for_ct_request_update(&request, status);
> - if (unlikely(err))
> + if (unlikely(err)) {
> + CT_ERROR(ct, "No response for request %#x (fence %u)\n",
> +  action[0], request.fence);
>   goto unlink;
> + }
>  
>   if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) != 
> GUC_HXG_TYPE_RESPONSE_SUCCESS) {
>   err = -EIO;
> -- 
> 2.25.1
> 
> ___
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v2] Revert "drm/scheduler: Avoid accessing freed bad job."

2021-08-18 Thread Andrey Grodzovsky

On 2021-08-18 10:02 a.m., Alex Deucher wrote:


+ dri-devel

Since scheduler is a shared component, please add dri-devel on all
scheduler patches.

On Wed, Aug 18, 2021 at 7:21 AM Jingwen Chen  wrote:

[Why]
for bailing job, this commit will delete it from pending list thus the
bailing job will never have a chance to be resubmitted even in advance
tdr mode.

[How]
after embeded hw_fence into amdgpu_job is done, the race condition that
this commit tries to work around is completely solved.So revert this
commit.
This reverts commit 135517d3565b48f4def3b1b82008bc17eb5d1c90.
v2:
add dma_fence_get/put() around timedout_job to avoid concurrent delete
during processing timedout_job

Signed-off-by: Jingwen Chen 
---
  drivers/gpu/drm/scheduler/sched_main.c | 23 +--
  1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a953693b45..f9b9b3aefc4a 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -314,6 +314,7 @@ static void drm_sched_job_timedout(struct work_struct *work)
  {
 struct drm_gpu_scheduler *sched;
 struct drm_sched_job *job;
+   struct dma_fence *fence;
 enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_NOMINAL;

 sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
@@ -325,11 +326,10 @@ static void drm_sched_job_timedout(struct work_struct 
*work)

 if (job) {
 /*
-* Remove the bad job so it cannot be freed by concurrent
-* drm_sched_cleanup_jobs. It will be reinserted back after 
sched->thread
-* is parked at which point it's safe.
+* Get job->s_fence->parent here to avoid concurrent delete 
during
+* processing timedout_job
  */
-   list_del_init(&job->list);
+   fence = dma_fence_get(job->s_fence->parent);



While this is true for amdgpu, it has no meaning for other drivers for 
whom we haven't
done the refactoring of embedding HW fence (parent) into the job 
structure. In fact thinking
about it, unless you do the HW fence embedding for all the drivers using 
the scheduler you cannot

revert this patch or you will just break them.

Andrey



 spin_unlock(&sched->job_list_lock);

 status = job->sched->ops->timedout_job(job);
@@ -342,6 +342,7 @@ static void drm_sched_job_timedout(struct work_struct *work)
 job->sched->ops->free_job(job);
 sched->free_guilty = false;
 }
+   dma_fence_put(fence);
 } else {
 spin_unlock(&sched->job_list_lock);
 }
@@ -392,20 +393,6 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
struct drm_sched_job *bad)

 kthread_park(sched->thread);

-   /*
-* Reinsert back the bad job here - now it's safe as
-* drm_sched_get_cleanup_job cannot race against us and release the
-* bad job at this point - we parked (waited for) any in progress
-* (earlier) cleanups and drm_sched_get_cleanup_job will not be called
-* now until the scheduler thread is unparked.
-*/
-   if (bad && bad->sched == sched)
-   /*
-* Add at the head of the queue to reflect it was the earliest
-* job extracted.
-*/
-   list_add(&bad->list, &sched->pending_list);
-
 /*
  * Iterate the job list from later to  earlier one and either deactive
  * their HW callbacks or remove them from pending list if they already
--
2.25.1



Re: [PATCH v2] Revert "drm/scheduler: Avoid accessing freed bad job."

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 10:02:06AM -0400, Alex Deucher wrote:
> + dri-devel
> 
> Since scheduler is a shared component, please add dri-devel on all
> scheduler patches.

Do we need a MAINTAINRS entry specifically for this, or just oversight?

> On Wed, Aug 18, 2021 at 7:21 AM Jingwen Chen  wrote:
> >
> > [Why]
> > for bailing job, this commit will delete it from pending list thus the
> > bailing job will never have a chance to be resubmitted even in advance
> > tdr mode.
> >
> > [How]
> > after embeded hw_fence into amdgpu_job is done, the race condition that
> > this commit tries to work around is completely solved.So revert this
> > commit.

Does this also hold for all other drivers? In general the commit message
feels rather rushed and I have no idea what's really going on.

Also at least around tdr there's been some solid clarifications around
how this is supposed to work between tdr and main scheduler thread, would
be good to explain how that all fits together. Or should fit together.
-Daniel

> > This reverts commit 135517d3565b48f4def3b1b82008bc17eb5d1c90.
> > v2:
> > add dma_fence_get/put() around timedout_job to avoid concurrent delete
> > during processing timedout_job
> >
> > Signed-off-by: Jingwen Chen 
> > ---
> >  drivers/gpu/drm/scheduler/sched_main.c | 23 +--
> >  1 file changed, 5 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > b/drivers/gpu/drm/scheduler/sched_main.c
> > index a2a953693b45..f9b9b3aefc4a 100644
> > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > @@ -314,6 +314,7 @@ static void drm_sched_job_timedout(struct work_struct 
> > *work)
> >  {
> > struct drm_gpu_scheduler *sched;
> > struct drm_sched_job *job;
> > +   struct dma_fence *fence;
> > enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_NOMINAL;
> >
> > sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
> > @@ -325,11 +326,10 @@ static void drm_sched_job_timedout(struct work_struct 
> > *work)
> >
> > if (job) {
> > /*
> > -* Remove the bad job so it cannot be freed by concurrent
> > -* drm_sched_cleanup_jobs. It will be reinserted back after 
> > sched->thread
> > -* is parked at which point it's safe.
> > +* Get job->s_fence->parent here to avoid concurrent delete 
> > during
> > +* processing timedout_job
> >  */
> > -   list_del_init(&job->list);
> > +   fence = dma_fence_get(job->s_fence->parent);
> > spin_unlock(&sched->job_list_lock);
> >
> > status = job->sched->ops->timedout_job(job);
> > @@ -342,6 +342,7 @@ static void drm_sched_job_timedout(struct work_struct 
> > *work)
> > job->sched->ops->free_job(job);
> > sched->free_guilty = false;
> > }
> > +   dma_fence_put(fence);
> > } else {
> > spin_unlock(&sched->job_list_lock);
> > }
> > @@ -392,20 +393,6 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
> > struct drm_sched_job *bad)
> >
> > kthread_park(sched->thread);
> >
> > -   /*
> > -* Reinsert back the bad job here - now it's safe as
> > -* drm_sched_get_cleanup_job cannot race against us and release the
> > -* bad job at this point - we parked (waited for) any in progress
> > -* (earlier) cleanups and drm_sched_get_cleanup_job will not be 
> > called
> > -* now until the scheduler thread is unparked.
> > -*/
> > -   if (bad && bad->sched == sched)
> > -   /*
> > -* Add at the head of the queue to reflect it was the 
> > earliest
> > -* job extracted.
> > -*/
> > -   list_add(&bad->list, &sched->pending_list);
> > -
> > /*
> >  * Iterate the job list from later to  earlier one and either 
> > deactive
> >  * their HW callbacks or remove them from pending list if they 
> > already
> > --
> > 2.25.1
> >

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v2] Revert "drm/scheduler: Avoid accessing freed bad job."

2021-08-18 Thread Daniel Vetter
On Wed, Aug 18, 2021 at 10:26:25AM -0400, Andrey Grodzovsky wrote:
> On 2021-08-18 10:02 a.m., Alex Deucher wrote:
> 
> > + dri-devel
> > 
> > Since scheduler is a shared component, please add dri-devel on all
> > scheduler patches.
> > 
> > On Wed, Aug 18, 2021 at 7:21 AM Jingwen Chen  wrote:
> > > [Why]
> > > for bailing job, this commit will delete it from pending list thus the
> > > bailing job will never have a chance to be resubmitted even in advance
> > > tdr mode.
> > > 
> > > [How]
> > > after embeded hw_fence into amdgpu_job is done, the race condition that
> > > this commit tries to work around is completely solved.So revert this
> > > commit.
> > > This reverts commit 135517d3565b48f4def3b1b82008bc17eb5d1c90.
> > > v2:
> > > add dma_fence_get/put() around timedout_job to avoid concurrent delete
> > > during processing timedout_job
> > > 
> > > Signed-off-by: Jingwen Chen 
> > > ---
> > >   drivers/gpu/drm/scheduler/sched_main.c | 23 +--
> > >   1 file changed, 5 insertions(+), 18 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > > b/drivers/gpu/drm/scheduler/sched_main.c
> > > index a2a953693b45..f9b9b3aefc4a 100644
> > > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > > @@ -314,6 +314,7 @@ static void drm_sched_job_timedout(struct work_struct 
> > > *work)
> > >   {
> > >  struct drm_gpu_scheduler *sched;
> > >  struct drm_sched_job *job;
> > > +   struct dma_fence *fence;
> > >  enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_NOMINAL;
> > > 
> > >  sched = container_of(work, struct drm_gpu_scheduler, 
> > > work_tdr.work);
> > > @@ -325,11 +326,10 @@ static void drm_sched_job_timedout(struct 
> > > work_struct *work)
> > > 
> > >  if (job) {
> > >  /*
> > > -* Remove the bad job so it cannot be freed by concurrent
> > > -* drm_sched_cleanup_jobs. It will be reinserted back 
> > > after sched->thread
> > > -* is parked at which point it's safe.
> > > +* Get job->s_fence->parent here to avoid concurrent 
> > > delete during
> > > +* processing timedout_job
> > >   */
> > > -   list_del_init(&job->list);
> > > +   fence = dma_fence_get(job->s_fence->parent);
> 
> 
> While this is true for amdgpu, it has no meaning for other drivers for whom
> we haven't
> done the refactoring of embedding HW fence (parent) into the job structure.
> In fact thinking
> about it, unless you do the HW fence embedding for all the drivers using the
> scheduler you cannot
> revert this patch or you will just break them.

btw, why did you do that embedding? I do still have my patches with
dma_fence annotations floating around, but my idea at least was to fix
that issue with a mempool, not with embeddeding. What was the motivation
for embedding the wh fence?
-Daniel


> 
> Andrey
> 
> 
> > >  spin_unlock(&sched->job_list_lock);
> > > 
> > >  status = job->sched->ops->timedout_job(job);
> > > @@ -342,6 +342,7 @@ static void drm_sched_job_timedout(struct work_struct 
> > > *work)
> > >  job->sched->ops->free_job(job);
> > >  sched->free_guilty = false;
> > >  }
> > > +   dma_fence_put(fence);
> > >  } else {
> > >  spin_unlock(&sched->job_list_lock);
> > >  }
> > > @@ -392,20 +393,6 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
> > > struct drm_sched_job *bad)
> > > 
> > >  kthread_park(sched->thread);
> > > 
> > > -   /*
> > > -* Reinsert back the bad job here - now it's safe as
> > > -* drm_sched_get_cleanup_job cannot race against us and release 
> > > the
> > > -* bad job at this point - we parked (waited for) any in progress
> > > -* (earlier) cleanups and drm_sched_get_cleanup_job will not be 
> > > called
> > > -* now until the scheduler thread is unparked.
> > > -*/
> > > -   if (bad && bad->sched == sched)
> > > -   /*
> > > -* Add at the head of the queue to reflect it was the 
> > > earliest
> > > -* job extracted.
> > > -*/
> > > -   list_add(&bad->list, &sched->pending_list);
> > > -
> > >  /*
> > >   * Iterate the job list from later to  earlier one and either 
> > > deactive
> > >   * their HW callbacks or remove them from pending list if they 
> > > already
> > > --
> > > 2.25.1
> > > 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v2] Revert "drm/scheduler: Avoid accessing freed bad job."

2021-08-18 Thread Andrey Grodzovsky



On 2021-08-18 10:32 a.m., Daniel Vetter wrote:

On Wed, Aug 18, 2021 at 10:26:25AM -0400, Andrey Grodzovsky wrote:

On 2021-08-18 10:02 a.m., Alex Deucher wrote:


+ dri-devel

Since scheduler is a shared component, please add dri-devel on all
scheduler patches.

On Wed, Aug 18, 2021 at 7:21 AM Jingwen Chen  wrote:

[Why]
for bailing job, this commit will delete it from pending list thus the
bailing job will never have a chance to be resubmitted even in advance
tdr mode.

[How]
after embeded hw_fence into amdgpu_job is done, the race condition that
this commit tries to work around is completely solved.So revert this
commit.
This reverts commit 135517d3565b48f4def3b1b82008bc17eb5d1c90.
v2:
add dma_fence_get/put() around timedout_job to avoid concurrent delete
during processing timedout_job

Signed-off-by: Jingwen Chen 
---
   drivers/gpu/drm/scheduler/sched_main.c | 23 +--
   1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a953693b45..f9b9b3aefc4a 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -314,6 +314,7 @@ static void drm_sched_job_timedout(struct work_struct *work)
   {
  struct drm_gpu_scheduler *sched;
  struct drm_sched_job *job;
+   struct dma_fence *fence;
  enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_NOMINAL;

  sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
@@ -325,11 +326,10 @@ static void drm_sched_job_timedout(struct work_struct 
*work)

  if (job) {
  /*
-* Remove the bad job so it cannot be freed by concurrent
-* drm_sched_cleanup_jobs. It will be reinserted back after 
sched->thread
-* is parked at which point it's safe.
+* Get job->s_fence->parent here to avoid concurrent delete 
during
+* processing timedout_job
   */
-   list_del_init(&job->list);
+   fence = dma_fence_get(job->s_fence->parent);


While this is true for amdgpu, it has no meaning for other drivers for whom
we haven't
done the refactoring of embedding HW fence (parent) into the job structure.
In fact thinking
about it, unless you do the HW fence embedding for all the drivers using the
scheduler you cannot
revert this patch or you will just break them.

btw, why did you do that embedding? I do still have my patches with
dma_fence annotations floating around, but my idea at least was to fix
that issue with a mempool, not with embeddeding. What was the motivation
for embedding the wh fence?
-Daniel



The motivation was 2 fold, avoid memory allocation during jobs submissions
(HW fence allocation) because as Christian explained this leads to 
deadlock with
mm code during evictions due to memory pressure (Christian can clarify 
if I messed
this explanation). Second is to exactly revert this patch because while 
it solved the issue
described in the patch it created another with drivers who baildc out 
early during TDR handling
for various reason and the job would just leak because it was already 
removed form pending list.


Andrey






Andrey



  spin_unlock(&sched->job_list_lock);

  status = job->sched->ops->timedout_job(job);
@@ -342,6 +342,7 @@ static void drm_sched_job_timedout(struct work_struct *work)
  job->sched->ops->free_job(job);
  sched->free_guilty = false;
  }
+   dma_fence_put(fence);
  } else {
  spin_unlock(&sched->job_list_lock);
  }
@@ -392,20 +393,6 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
struct drm_sched_job *bad)

  kthread_park(sched->thread);

-   /*
-* Reinsert back the bad job here - now it's safe as
-* drm_sched_get_cleanup_job cannot race against us and release the
-* bad job at this point - we parked (waited for) any in progress
-* (earlier) cleanups and drm_sched_get_cleanup_job will not be called
-* now until the scheduler thread is unparked.
-*/
-   if (bad && bad->sched == sched)
-   /*
-* Add at the head of the queue to reflect it was the earliest
-* job extracted.
-*/
-   list_add(&bad->list, &sched->pending_list);
-
  /*
   * Iterate the job list from later to  earlier one and either deactive
   * their HW callbacks or remove them from pending list if they already
--
2.25.1



  1   2   3   >