Re: [PATCH v2 02/34] component: Introduce the aggregate bus_type

2021-10-06 Thread Greg Kroah-Hartman
On Wed, Oct 06, 2021 at 12:37:47PM -0700, Stephen Boyd wrote:
> The component driver only provides 'bind' and 'unbind' callbacks to tell
> the host driver that it is time to assemble the aggregate driver now
> that all the components have probed. The component driver model doesn't
> attempt to resolve runtime PM or suspend/resume ordering, and explicitly
> mentions this in the code. This lack of support leads to some pretty
> gnarly usages of the 'prepare' and 'complete' power management hooks in
> drivers that host the aggregate device, and it fully breaks down when
> faced with ordering shutdown between the various components, the
> aggregate driver, and the host driver that registers the whole thing.
> 
> In a concrete example, the MSM display driver at drivers/gpu/drm/msm is
> using 'prepare' and 'complete' to call the drm helpers
> drm_mode_config_helper_suspend() and drm_mode_config_helper_resume()
> respectively, so that it can move the aggregate driver suspend/resume
> callbacks to be before and after the components that make up the drm
> device call any suspend/resume hooks they have. This only works as long
> as the component devices don't do anything in their own 'prepare' and
> 'complete' callbacks. If they did, then the ordering would be incorrect
> and we would be doing something in the component drivers before the
> aggregate driver could do anything. Yuck!
> 
> Similarly, when trying to add shutdown support to the MSM driver we run
> across a problem where we're trying to shutdown the drm device via
> drm_atomic_helper_shutdown(), but some of the devices in the encoder
> chain have already been shutdown. This time, the component devices
> aren't the problem (although they could be if they did anything in their
> shutdown callbacks), but there's a DSI to eDP bridge in the encoder
> chain that has already been shutdown before the driver hosting the
> aggregate device runs shutdown. The ordering of driver probe is like
> this:
> 
>  1. msm_pdev_probe() (host driver)
>  2. DSI bridge
>  3. aggregate bind
> 
> When it comes to shutdown we have this order:
> 
>  1. DSI bridge
>  2. msm_pdev_shutdown() (host driver)
> 
> and so the bridge is already off, but we want to communicate to it to
> turn things off on the display during msm_pdev_shutdown(). Double yuck!
> Unfortunately, this time we can't split shutdown into multiple phases
> and swap msm_pdev_shutdown() with the DSI bridge.
> 
> Let's make the component driver into an actual device driver that has
> probe/remove/shutdown functions. The driver will only be bound to the
> aggregate device once all component drivers have called component_add()
> to indicate they're ready to assemble the aggregate driver. This allows
> us to attach shutdown logic (and in the future runtime PM logic) to the
> aggregate driver so that it runs the hooks in the correct order.

Why are you creating a new bus type and not using the auxiliary bus
instead?

You have seen Documentation/driver-api/auxiliary_bus.rst, right?

thanks,

greg k-h


[tegra-drm:drm/tegra/for-next 5/12] drivers/gpu/host1x/job.c:141:30: warning: variable 'domain' set but not used

2021-10-06 Thread kernel test robot
tree:   git://anongit.freedesktop.org/tegra/linux.git drm/tegra/for-next
head:   29e08b1e60b429c2bb30a1578db4a2db354d8a36
commit: df77f99c7c11f1cfc37ba071e7efa3ad0d46d986 [5/12] drm/tegra: Implement 
correct DMA-BUF semantics
config: arm-randconfig-c002-20211004 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
git remote add tegra-drm git://anongit.freedesktop.org/tegra/linux.git
git fetch --no-tags tegra-drm drm/tegra/for-next
git checkout df77f99c7c11f1cfc37ba071e7efa3ad0d46d986
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross 
ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   drivers/gpu/host1x/job.c: In function 'pin_job':
>> drivers/gpu/host1x/job.c:141:30: warning: variable 'domain' set but not used 
>> [-Wunused-but-set-variable]
 141 | struct iommu_domain *domain;
 |  ^~


vim +/domain +141 drivers/gpu/host1x/job.c

e902585fc8b639f1 Mikko Perttunen 2021-06-10  134  
404bfb78daf3beda Mikko Perttunen 2016-12-14  135  static unsigned int 
pin_job(struct host1x *host, struct host1x_job *job)
6579324a41cc4140 Terje Bergstrom 2013-03-22  136  {
df77f99c7c11f1cf Thierry Reding  2021-09-09  137unsigned long mask = 
HOST1X_RELOC_READ | HOST1X_RELOC_WRITE;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  138struct host1x_client 
*client = job->client;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  139struct device *dev = 
client->dev;
fd323e9ef0a19112 Dmitry Osipenko 2020-06-29  140struct 
host1x_job_gather *g;
273da5a046965ccf Thierry Reding  2020-02-04 @141struct iommu_domain 
*domain;
6579324a41cc4140 Terje Bergstrom 2013-03-22  142unsigned int i;
404bfb78daf3beda Mikko Perttunen 2016-12-14  143int err;
6579324a41cc4140 Terje Bergstrom 2013-03-22  144  
273da5a046965ccf Thierry Reding  2020-02-04  145domain = 
iommu_get_domain_for_dev(dev);
6579324a41cc4140 Terje Bergstrom 2013-03-22  146job->num_unpins = 0;
6579324a41cc4140 Terje Bergstrom 2013-03-22  147  
6579324a41cc4140 Terje Bergstrom 2013-03-22  148for (i = 0; i < 
job->num_relocs; i++) {
06490bb99e1840ab Thierry Reding  2018-05-16  149struct 
host1x_reloc *reloc = >relocs[i];
df77f99c7c11f1cf Thierry Reding  2021-09-09  150enum 
dma_data_direction direction;
df77f99c7c11f1cf Thierry Reding  2021-09-09  151struct 
host1x_bo_mapping *map;
df77f99c7c11f1cf Thierry Reding  2021-09-09  152struct 
host1x_bo *bo;
6579324a41cc4140 Terje Bergstrom 2013-03-22  153  
961e3beae3b29ae9 Thierry Reding  2014-06-10  154
reloc->target.bo = host1x_bo_get(reloc->target.bo);
404bfb78daf3beda Mikko Perttunen 2016-12-14  155if 
(!reloc->target.bo) {
404bfb78daf3beda Mikko Perttunen 2016-12-14  156err = 
-EINVAL;
6579324a41cc4140 Terje Bergstrom 2013-03-22  157goto 
unpin;
404bfb78daf3beda Mikko Perttunen 2016-12-14  158}
6579324a41cc4140 Terje Bergstrom 2013-03-22  159  
df77f99c7c11f1cf Thierry Reding  2021-09-09  160bo = 
reloc->target.bo;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  161  
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  162switch 
(reloc->flags & mask) {
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  163case 
HOST1X_RELOC_READ:
df77f99c7c11f1cf Thierry Reding  2021-09-09  164
direction = DMA_TO_DEVICE;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  165break;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  166  
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  167case 
HOST1X_RELOC_WRITE:
df77f99c7c11f1cf Thierry Reding  2021-09-09  168
direction = DMA_FROM_DEVICE;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  169break;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  170  
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  171case 
HOST1X_RELOC_READ | HOST1X_RELOC_WRITE:
df77f99c7c11f1cf Thierry Reding  2021-09-09  172
direction = DMA_BIDIRECTIONAL;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  173break;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  174  
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  175default:
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  176err = 
-EINVAL;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  177goto 
unpin;
af1cbfb9bf0fe079 Thierry Reding  2019-10-28  178}
af1cbfb9bf0fe079 Thierry 

Re: [PATCH v6 3/3] drm/bridge: ti-sn65dsi86: Implement the pwm_chip

2021-10-06 Thread Bjorn Andersson
On Wed 29 Sep 20:05 PDT 2021, Bjorn Andersson wrote:

> The SN65DSI86 provides the ability to supply a PWM signal on GPIO 4,
> with the primary purpose of controlling the backlight of the attached
> panel. Add an implementation that exposes this using the standard PWM
> framework, to allow e.g. pwm-backlight to expose this to the user.
> 
> Signed-off-by: Bjorn Andersson 

Any feedback on this?

Thanks,
Bjorn

> ---
> 
> Changes since v5:
> - Make ti_sn65dsi86_read_u16() use regmap_bulk_read()
> - Update the wording related to the formula for the period being wrong to not
>   just say I'm "assuming because it's easier".
> - Updated comment related to minimum period
> - Clamp duty <= period in get_state()
> 
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 366 +-
>  1 file changed, 360 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c 
> b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> index 412fb6f564ea..ccf6496cc9ff 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> @@ -4,7 +4,9 @@
>   * datasheet: https://www.ti.com/lit/ds/symlink/sn65dsi86.pdf
>   */
>  
> +#include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -15,6 +17,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  
> @@ -91,6 +94,13 @@
>  #define SN_ML_TX_MODE_REG0x96
>  #define  ML_TX_MAIN_LINK_OFF 0
>  #define  ML_TX_NORMAL_MODE   BIT(0)
> +#define SN_PWM_PRE_DIV_REG   0xA0
> +#define SN_BACKLIGHT_SCALE_REG   0xA1
> +#define  BACKLIGHT_SCALE_MAX 0x
> +#define SN_BACKLIGHT_REG 0xA3
> +#define SN_PWM_EN_INV_REG0xA5
> +#define  SN_PWM_INV_MASK BIT(0)
> +#define  SN_PWM_EN_MASK  BIT(1)
>  #define SN_AUX_CMD_STATUS_REG0xF4
>  #define  AUX_IRQ_STATUS_AUX_RPLY_TOUTBIT(3)
>  #define  AUX_IRQ_STATUS_AUX_SHORTBIT(5)
> @@ -113,11 +123,14 @@
>  
>  #define SN_LINK_TRAINING_TRIES   10
>  
> +#define SN_PWM_GPIO_IDX  3 /* 4th GPIO */
> +
>  /**
>   * struct ti_sn65dsi86 - Platform data for ti-sn65dsi86 driver.
>   * @bridge_aux:   AUX-bus sub device for MIPI-to-eDP bridge functionality.
>   * @gpio_aux: AUX-bus sub device for GPIO controller functionality.
>   * @aux_aux:  AUX-bus sub device for eDP AUX channel functionality.
> + * @pwm_aux:  AUX-bus sub device for PWM controller functionality.
>   *
>   * @dev:  Pointer to the top level (i2c) device.
>   * @regmap:   Regmap for accessing i2c.
> @@ -145,11 +158,17 @@
>   *bitmap so we can do atomic ops on it without an extra
>   *lock so concurrent users of our 4 GPIOs don't stomp on
>   *each other's read-modify-write.
> + *
> + * @pchip:pwm_chip if the PWM is exposed.
> + * @pwm_enabled:  Used to track if the PWM signal is currently enabled.
> + * @pwm_pin_busy: Track if GPIO4 is currently requested for GPIO or PWM.
> + * @pwm_refclk_freq: Cache for the reference clock input to the PWM.
>   */
>  struct ti_sn65dsi86 {
>   struct auxiliary_device bridge_aux;
>   struct auxiliary_device gpio_aux;
>   struct auxiliary_device aux_aux;
> + struct auxiliary_device pwm_aux;
>  
>   struct device   *dev;
>   struct regmap   *regmap;
> @@ -172,6 +191,12 @@ struct ti_sn65dsi86 {
>   struct gpio_chipgchip;
>   DECLARE_BITMAP(gchip_output, SN_NUM_GPIOS);
>  #endif
> +#if defined(CONFIG_PWM)
> + struct pwm_chip pchip;
> + boolpwm_enabled;
> + atomic_tpwm_pin_busy;
> +#endif
> + unsigned intpwm_refclk_freq;
>  };
>  
>  static const struct regmap_range ti_sn65dsi86_volatile_ranges[] = {
> @@ -190,6 +215,21 @@ static const struct regmap_config 
> ti_sn65dsi86_regmap_config = {
>   .cache_type = REGCACHE_NONE,
>  };
>  
> +static int ti_sn65dsi86_read_u16(struct ti_sn65dsi86 *pdata,
> +  unsigned int reg, u16 *val)
> +{
> + u8 buf[2];
> + int ret;
> +
> + ret = regmap_bulk_read(pdata->regmap, reg, buf, ARRAY_SIZE(buf));
> + if (ret)
> + return ret;
> +
> + *val = buf[0] | (buf[1] << 8);
> +
> + return 0;
> +}
> +
>  static void ti_sn65dsi86_write_u16(struct ti_sn65dsi86 *pdata,
>  unsigned int reg, u16 val)
>  {
> @@ -254,6 +294,12 @@ static void ti_sn_bridge_set_refclk_freq(struct 
> ti_sn65dsi86 *pdata)
>  
>   regmap_update_bits(pdata->regmap, SN_DPPLL_SRC_REG, REFCLK_FREQ_MASK,
>  REFCLK_FREQ(i));
> +
> + /*
> +  * The PWM refclk is based on the value written to 

Re: [PATCH 04/26] drm/i915/guc: Don't call switch_to_kernel_context with GuC submission

2021-10-06 Thread John Harrison

On 10/4/2021 15:06, Matthew Brost wrote:

Calling switch_to_kernel_context isn't needed if the engine PM reference
is taken while all user contexts are pinned as if don't have PM ref that
guarantees that all user contexts scheduling is disabled. By not calling
switch_to_kernel_context we save on issuing a request to the engine.

v2:
  (Daniel Vetter)
   - Add FIXME comment about pushing switch_to_kernel_context to backend
v3:
  (John Harrison)
   - Update commit message
   - Fix workding comment

Signed-off-by: Matthew Brost 
Reviewed-by: Daniel Vetter 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/intel_engine_pm.c | 13 +
  1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index dacd62773735..a1334b48dde7 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -162,6 +162,19 @@ static bool switch_to_kernel_context(struct 
intel_engine_cs *engine)
unsigned long flags;
bool result = true;
  
+	/*

+* This is execlist specific behaviour intended to ensure the GPU is
+* idle by switching to a known 'safe' context. With GuC submission, the
+* same idle guarantee is achieved by other means (disabling
+* scheduling). Further, switching to a 'safe' context has no effect
+* with GuC submission as the scheduler can just switch back again.
+*
+* FIXME: Move this backend scheduler specific behaviour into the
+* scheduler backend.
+*/
+   if (intel_engine_uses_guc(engine))
+   return true;
+
/* GPU is pointing to the void, as good as in the kernel context. */
if (intel_gt_is_wedged(engine->gt))
return true;




Re: [PATCH 03/26] drm/i915/guc: Take engine PM when a context is pinned with GuC submission

2021-10-06 Thread John Harrison

On 10/4/2021 15:06, Matthew Brost wrote:

Taking a PM reference to prevent intel_gt_wait_for_idle from short
circuiting while a scheduling of user context could be enabled.
I'm not sure what 'while a scheduling of user context could be enabled' 
means.


John.


Returning GT idle when it is not can cause all sorts of issues
throughout the stack.

v2:
  (Daniel Vetter)
   - Add might_lock annotations to pin / unpin function
v3:
  (CI)
   - Drop intel_engine_pm_might_put from unpin path as an async put is
 used
v4:
  (John Harrison)
   - Make intel_engine_pm_might_get/put work with GuC virtual engines
   - Update commit message

Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/intel_context.c   |  2 ++
  drivers/gpu/drm/i915/gt/intel_engine_pm.h | 32 +
  drivers/gpu/drm/i915/gt/intel_gt_pm.h | 10 ++
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 36 +--
  drivers/gpu/drm/i915/intel_wakeref.h  | 12 +++
  5 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 1076066f41e0..f601323b939f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -240,6 +240,8 @@ int __intel_context_do_pin_ww(struct intel_context *ce,
if (err)
goto err_post_unpin;
  
+	intel_engine_pm_might_get(ce->engine);

+
if (unlikely(intel_context_is_closed(ce))) {
err = -ENOENT;
goto err_unlock;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
index 6fdeae668e6e..d68675925b79 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
@@ -6,9 +6,11 @@
  #ifndef INTEL_ENGINE_PM_H
  #define INTEL_ENGINE_PM_H
  
+#include "i915_drv.h"

  #include "i915_request.h"
  #include "intel_engine_types.h"
  #include "intel_wakeref.h"
+#include "intel_gt_pm.h"
  
  static inline bool

  intel_engine_pm_is_awake(const struct intel_engine_cs *engine)
@@ -31,6 +33,21 @@ static inline bool intel_engine_pm_get_if_awake(struct 
intel_engine_cs *engine)
return intel_wakeref_get_if_active(>wakeref);
  }
  
+static inline void intel_engine_pm_might_get(struct intel_engine_cs *engine)

+{
+   if (!intel_engine_is_virtual(engine)) {
+   intel_wakeref_might_get(>wakeref);
+   } else {
+   struct intel_gt *gt = engine->gt;
+   struct intel_engine_cs *tengine;
+   intel_engine_mask_t tmp, mask = engine->mask;
+
+   for_each_engine_masked(tengine, gt, mask, tmp)
+   intel_wakeref_might_get(>wakeref);
+   }
+   intel_gt_pm_might_get(engine->gt);
+}
+
  static inline void intel_engine_pm_put(struct intel_engine_cs *engine)
  {
intel_wakeref_put(>wakeref);
@@ -52,6 +69,21 @@ static inline void intel_engine_pm_flush(struct 
intel_engine_cs *engine)
intel_wakeref_unlock_wait(>wakeref);
  }
  
+static inline void intel_engine_pm_might_put(struct intel_engine_cs *engine)

+{
+   if (!intel_engine_is_virtual(engine)) {
+   intel_wakeref_might_put(>wakeref);
+   } else {
+   struct intel_gt *gt = engine->gt;
+   struct intel_engine_cs *tengine;
+   intel_engine_mask_t tmp, mask = engine->mask;
+
+   for_each_engine_masked(tengine, gt, mask, tmp)
+   intel_wakeref_might_put(>wakeref);
+   }
+   intel_gt_pm_might_put(engine->gt);
+}
+
  static inline struct i915_request *
  intel_engine_create_kernel_request(struct intel_engine_cs *engine)
  {
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index 05de6c1af25b..bc898df7a48c 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
@@ -31,6 +31,11 @@ static inline bool intel_gt_pm_get_if_awake(struct intel_gt 
*gt)
return intel_wakeref_get_if_active(>wakeref);
  }
  
+static inline void intel_gt_pm_might_get(struct intel_gt *gt)

+{
+   intel_wakeref_might_get(>wakeref);
+}
+
  static inline void intel_gt_pm_put(struct intel_gt *gt)
  {
intel_wakeref_put(>wakeref);
@@ -41,6 +46,11 @@ static inline void intel_gt_pm_put_async(struct intel_gt *gt)
intel_wakeref_put_async(>wakeref);
  }
  
+static inline void intel_gt_pm_might_put(struct intel_gt *gt)

+{
+   intel_wakeref_might_put(>wakeref);
+}
+
  #define with_intel_gt_pm(gt, tmp) \
for (tmp = 1, intel_gt_pm_get(gt); tmp; \
 intel_gt_pm_put(gt), tmp = 0)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 17da2fea1bff..8b82da50c2bc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1571,7 +1571,12 @@ static int 

Re: [PATCH 02/26] drm/i915/guc: Take GT PM ref when deregistering context

2021-10-06 Thread John Harrison

On 10/4/2021 15:06, Matthew Brost wrote:

Taking a PM reference to prevent intel_gt_wait_for_idle from short
circuiting while a deregister context H2G is in flight. To do this must
issue the deregister H2G from a worker as context can be destroyed from
an atomic context and taking GT PM ref blows up. Previously we took a
runtime PM from this atomic context which worked but will stop working
once runtime pm autosuspend in enabled.

So this patch is two fold, stop intel_gt_wait_for_idle from short
circuting and fix runtime pm autosuspend.

v2:
  (John Harrison)
   - Split structure changes out in different patch
  (Tvrtko)
   - Don't drop lock in deregister_destroyed_contexts

Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/intel_context.c   |   2 +
  drivers/gpu/drm/i915/gt/intel_context_types.h |   7 +
  drivers/gpu/drm/i915/gt/intel_engine_pm.h |   5 +
  drivers/gpu/drm/i915/gt/intel_gt_pm.h |   4 +
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|  11 ++
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 146 +++---
  6 files changed, 121 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e9a0cad5c34d..1076066f41e0 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -399,6 +399,8 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
ce->guc_id.id = GUC_INVALID_LRC_ID;
INIT_LIST_HEAD(>guc_id.link);
  
+	INIT_LIST_HEAD(>destroyed_link);

+
/*
 * Initialize fence to be complete as this is expected to be complete
 * unless there is a pending schedule disable outstanding.
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index e7e3984aab78..4613d027cbc3 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -213,6 +213,13 @@ struct intel_context {
struct list_head link;
} guc_id;
  
+	/**

+* @destroyed_link: link in guc->submission_state.destroyed_contexts, in
+* list when context is pending to be destroyed (deregistered with the
+* GuC), protected by guc->submission_state.lock
+*/
+   struct list_head destroyed_link;
+
  #ifdef CONFIG_DRM_I915_SELFTEST
/**
 * @drop_schedule_enable: Force drop of schedule enable G2H for selftest
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
index 8520c595f5e1..6fdeae668e6e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
@@ -16,6 +16,11 @@ intel_engine_pm_is_awake(const struct intel_engine_cs 
*engine)
return intel_wakeref_is_active(>wakeref);
  }
  
+static inline void __intel_engine_pm_get(struct intel_engine_cs *engine)

+{
+   __intel_wakeref_get(>wakeref);
+}
+
  static inline void intel_engine_pm_get(struct intel_engine_cs *engine)
  {
intel_wakeref_get(>wakeref);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index d0588d8aaa44..05de6c1af25b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
@@ -41,6 +41,10 @@ static inline void intel_gt_pm_put_async(struct intel_gt *gt)
intel_wakeref_put_async(>wakeref);
  }
  
+#define with_intel_gt_pm(gt, tmp) \

+   for (tmp = 1, intel_gt_pm_get(gt); tmp; \
+intel_gt_pm_put(gt), tmp = 0)
+
  static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt)
  {
return intel_wakeref_wait_for_idle(>wakeref);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 65b5e8eeef96..25a598e2b6e8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -84,6 +84,17 @@ struct intel_guc {
 * refs
 */
struct list_head guc_id_list;
+   /**
+* @destroyed_contexts: list of contexts waiting to be destroyed
+* (deregistered with the GuC)
+*/
+   struct list_head destroyed_contexts;
+   /**
+* @destroyed_worker: worker to deregister contexts, need as we
+* need to take a GT PM reference and can't from destroy
+* function as it might be in an atomic context (no sleeping)
+*/
+   struct work_struct destroyed_worker;
} submission_state;
  
  	/**

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ad5c18119d92..17da2fea1bff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -90,8 +90,8 @@
   * used for all of GuC submission but that could change in 

Re: [PATCH 01/26] drm/i915/guc: Move GuC guc_id allocation under submission state sub-struct

2021-10-06 Thread John Harrison

On 10/4/2021 15:06, Matthew Brost wrote:

Move guc_id allocation under submission state sub-struct as a future
patch will reuse the spin lock as a global submission state lock. Moving
this into sub-struct makes ownership of fields / lock clear.

Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/intel_context_types.h |  6 +-
  drivers/gpu/drm/i915/gt/uc/intel_guc.h| 26 +
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 56 ++-
  3 files changed, 47 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 12252c411159..e7e3984aab78 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -197,18 +197,18 @@ struct intel_context {
struct {
/**
 * @id: handle which is used to uniquely identify this context
-* with the GuC, protected by guc->contexts_lock
+* with the GuC, protected by guc->submission_state.lock
 */
u16 id;
/**
 * @ref: the number of references to the guc_id, when
 * transitioning in and out of zero protected by
-* guc->contexts_lock
+* guc->submission_state.lock
 */
atomic_t ref;
/**
 * @link: in guc->guc_id_list when the guc_id has no refs but is
-* still valid, protected by guc->contexts_lock
+* still valid, protected by guc->submission_state.lock
 */
struct list_head link;
} guc_id;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 5dd174babf7a..65b5e8eeef96 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -70,17 +70,21 @@ struct intel_guc {
void (*disable)(struct intel_guc *guc);
} interrupts;
  
-	/**

-* @contexts_lock: protects guc_ids, guc_id_list, ce->guc_id.id, and
-* ce->guc_id.ref when transitioning in and out of zero
-*/
-   spinlock_t contexts_lock;
-   /** @guc_ids: used to allocate unique ce->guc_id.id values */
-   struct ida guc_ids;
-   /**
-* @guc_id_list: list of intel_context with valid guc_ids but no refs
-*/
-   struct list_head guc_id_list;
+   struct {
+   /**
+* @lock: protects everything in submission_state
+*/
+   spinlock_t lock;
The old version also mentioned 'ce->guc_id.ref'. Should this not also 
mention that transition? Or was the old comment inaccurate. I'm not 
seeing any actual behaviour changes in the patch.




+   /**
+* @guc_ids: used to allocate new guc_ids
+*/
+   struct ida guc_ids;
+   /**
+* @guc_id_list: list of intel_context with valid guc_ids but no
+* refs
+*/
+   struct list_head guc_id_list;
+   } submission_state;
  
  	/**

 * @submission_supported: tracks whether we support GuC submission on
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ba0de35f6323..ad5c18119d92 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -68,16 +68,16 @@
   * fence is used to stall all requests associated with this guc_id until the
   * corresponding G2H returns indicating the guc_id has been deregistered.
   *
- * guc_ids:
+ * submission_state.guc_ids:
   * Unique number associated with private GuC context data passed in during
   * context registration / submission / deregistration. 64k available. Simple 
ida
   * is used for allocation.
   *
- * Stealing guc_ids:
- * If no guc_ids are available they can be stolen from another context at
- * request creation time if that context is unpinned. If a guc_id can't be 
found
- * we punt this problem to the user as we believe this is near impossible to 
hit
- * during normal use cases.
+ * Stealing submission_state.guc_ids:
+ * If no submission_state.guc_ids are available they can be stolen from another
I would abbreviate this instance as well, submission_state.guc_id is 
quite the mouthful. Unless this somehow magically links back to the 
structure entry in the kerneldoc output?


John.


+ * context at request creation time if that context is unpinned. If a guc_id
+ * can't be found we punt this problem to the user as we believe this is near
+ * impossible to hit during normal use cases.
   *
   * Locking:
   * In the GuC submission code we have 3 basic spin locks which protect
@@ -89,7 +89,7 @@
   * sched_engine can be submitting at a time. Currently only one sched_engine 
is
   * used for all of 

[GIT PULL FOR v5.16] R-Car DU & other misc enhancements

2021-10-06 Thread Laurent Pinchart
Hi Dave and Daniel,

The following changes since commit 1e3944578b749449bd7fa6bf0bae4c3d3f5f1733:

  Merge tag 'amd-drm-next-5.16-2021-09-27' of 
https://gitlab.freedesktop.org/agd5f/linux into drm-next (2021-09-28 17:08:26 
+1000)

are available in the Git repository at:

  git://linuxtv.org/pinchartl/media.git tags/du-next-20211007

for you to fetch changes up to b291fdcf51140fef69a9734caaca704d010dd02f:

  drm: rcar-du: Add r8a779a0 device support (2021-10-07 05:59:54 +0300)


R-Car DU improvements & enhancements to misc drivers

Most notably,

- Non-contiguous buffer import support for rcar-du
- r8a779a0 support preparation for rcar-du
- COMPILE_TEST fixes for omapdrm and sti


Cai Huoqing (2):
  drm/shmobile: Make use of the helper function 
devm_platform_ioremap_resource()
  drm: rcar-du: Make use of the helper function 
devm_platform_ioremap_resource()

Kieran Bingham (6):
  dt-bindings: display: renesas,du: Provide bindings for r8a779a0
  drm: rcar-du: Sort the DU outputs
  drm: rcar-du: Only initialise TVM_TVSYNC mode when supported
  drm: rcar-du: Fix DIDSR field name
  drm: rcar-du: Split CRTC IRQ and Clock features
  drm: rcar-du: Add r8a779a0 device support

Laurent Pinchart (9):
  drm: rcar-du: Don't create encoder for unconnected LVDS outputs
  drm: rcar-du: Improve kernel log messages when initializing encoders
  drm: rcar-du: Set the DMA coherent mask for the DU device
  drm: rcar-du: Allow importing non-contiguous dma-buf with VSP
  drm: property: Replace strncpy() with strscpy_pad()
  drm/omap: Use correct printk format specifiers for size_t
  drm/omap: Cast pointer to integer without generating warning
  drm/omap: Depend on CONFIG_OF
  drm/sti: Use correct printk format specifiers for size_t

 .../devicetree/bindings/display/renesas,du.yaml|  51 ++
 drivers/gpu/drm/drm_property.c |   9 +-
 drivers/gpu/drm/omapdrm/Kconfig|   2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c  |   4 +-
 drivers/gpu/drm/omapdrm/omap_drv.c |   2 +-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c |   9 +-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  11 ---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 108 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  26 -
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c  |  28 --
 drivers/gpu/drm/rcar-du/rcar_du_group.c|   6 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c  |  50 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.h  |   7 ++
 drivers/gpu/drm/rcar-du/rcar_du_regs.h |   9 +-
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  36 ++-
 drivers/gpu/drm/rcar-du/rcar_lvds.c|  15 ++-
 drivers/gpu/drm/rcar-du/rcar_lvds.h|   5 +
 drivers/gpu/drm/shmobile/shmob_drm_drv.c   |   4 +-
 drivers/gpu/drm/sti/sti_hqvdp.c|   4 +-
 19 files changed, 308 insertions(+), 78 deletions(-)

-- 
Regards,

Laurent Pinchart


Re: [PATCH v8 09/12] media: mtk-vcodec: Get rid of mtk_smi_larb_get/put

2021-10-06 Thread Yong Wu
On Thu, 2021-09-30 at 12:57 +0200, Dafna Hirschfeld wrote:
> 
> On 30.09.21 05:28, Yong Wu wrote:
> > Hi Dafna,
> > 
> > Thanks very much for the review.
> > 
> > On Wed, 2021-09-29 at 14:13 +0200, Dafna Hirschfeld wrote:
> > > 
> > > On 29.09.21 03:37, Yong Wu wrote:
> > > > MediaTek IOMMU has already added the device_link between the
> > > > consumer
> > > > and smi-larb device. If the vcodec device call the
> > > > pm_runtime_get_sync,
> > > > the smi-larb's pm_runtime_get_sync also be called
> > > > automatically.
> > > > 
> > > > CC: Tiffany Lin 
> > > > CC: Irui Wang 
> > > > Signed-off-by: Yong Wu 
> > > > Reviewed-by: Evan Green 
> > > > Acked-by: Tiffany Lin 
> > > > Reviewed-by: Dafna Hirschfeld 
> > > > ---
> > > >.../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 37 +++
> > > > ---
> > > > --
> > > >.../platform/mtk-vcodec/mtk_vcodec_drv.h  |  3 --
> > > >.../platform/mtk-vcodec/mtk_vcodec_enc.c  |  1 -
> > > >.../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 44 +++
> > > > ---

[snip]

> > > >void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
> > > >{
> > > > pm_runtime_disable(dev->pm.dev);
> > > > -   put_device(dev->pm.larbvdec);
> > > >}
> > > 
> > > Now that functions only do  'pm_runtime_disable(dev->pm.dev);' so
> > > it
> > > will be more
> > > readable to remove the function mtk_vcodec_release_dec_pm
> > > and replace with pm_runtime_disable(dev->pm.dev);
> > > Same for the 'enc' equivalent.
> > 
> > Make sense. But It may be not proper if using pm_runtime_disable
> > as the symmetry with mtk_vcodec_init_dec_pm in the
> > mtk_vcodec_probe.
> > 
> > Maybe we should move pm_runtime_enable out from
> > mtk_vcodec_init_dec_pm
> > into mtk_vcodec_probe. I could do a new patch for this. Is this ok
> > for
> > you?
> 
> yes, there is also asymettry when calling pm_runtime* in general,
> I see in the decoder it is called from mtk_vcodec_dec_pm.c
> but in the encoder it is called from mtk_vcodec_enc.c,
> 
> I think all calls to pm_runtime* should be out of the *_pm.c files

OK. I will try this.

> since for example 'mtk_vcodec_dec_pw_on' also do just one call to
> pm_runtime_resume_and_get so this function can also be removed.

I guess this one should be reserved to vcodec guys. I see this function
is changed at [1]. Let's keep this patchset clean.

[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20210901083215.25984-10-yunfei.d...@mediatek.com/

> 
> thanks,
> Dafna
> 
> > 
> > > 
> > > Thanks,
> > > Dafna
> > 
> > [snip]
> > ___
> > Linux-mediatek mailing list
> > linux-media...@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek
> > 


Re: [PATCH v2 01/34] component: Introduce struct aggregate_device

2021-10-06 Thread Laurent Pinchart
Hi Stephen,

Thank you for the patch.

On Wed, Oct 06, 2021 at 12:37:46PM -0700, Stephen Boyd wrote:
> Replace 'struct master' with 'struct aggregate_device' and then rename
> 'master' to 'adev' everywhere in the code. While we're here, put a
> struct device inside the aggregate device so that we can register it
> with a bus_type in the next patch.

Not "while at it" please. The signal to noise ratio is very high here.
Adding the struct device in the structure is the important change that
needs to be properly reviewed and discussed, the rename is noise. You're
even adding an IDA and an id without mentioning it at all in the commit
message. This should be split in two patches, you can decide whether to
perform the rename at the bottom or top of the series (it would be more
logical to group all renames together though, there's currently one in
01/34 and one in 34/34, so please group them both at the top or bottom).

> The diff is large but that's because this is mostly a rename, where
> sometimes 'master' is replaced with 'adev' and other times it is
> replaced with 'parent' to indicate that the struct device that was being
> used is actually the parent of the aggregate device and driver.
> 
> Cc: Daniel Vetter 
> Cc: "Rafael J. Wysocki" 
> Cc: Rob Clark 
> Cc: Russell King 
> Cc: Saravana Kannan 
> Signed-off-by: Stephen Boyd 
> ---
>  drivers/base/component.c  | 250 --
>  include/linux/component.h |   2 +-
>  2 files changed, 134 insertions(+), 118 deletions(-)
> 
> diff --git a/drivers/base/component.c b/drivers/base/component.c
> index 5e79299f6c3f..0a41bbe14981 100644
> --- a/drivers/base/component.c
> +++ b/drivers/base/component.c
> @@ -9,6 +9,7 @@
>   */
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -58,18 +59,21 @@ struct component_match {
>   struct component_match_array *compare;
>  };
>  
> -struct master {
> +struct aggregate_device {
>   struct list_head node;
>   bool bound;
>  
>   const struct component_master_ops *ops;
>   struct device *parent;
> + struct device dev;
>   struct component_match *match;
> +
> + int id;
>  };
>  
>  struct component {
>   struct list_head node;
> - struct master *master;
> + struct aggregate_device *adev;
>   bool bound;
>  
>   const struct component_ops *ops;
> @@ -79,7 +83,9 @@ struct component {
>  
>  static DEFINE_MUTEX(component_mutex);
>  static LIST_HEAD(component_list);
> -static LIST_HEAD(masters);
> +static LIST_HEAD(aggregate_devices);
> +
> +static DEFINE_IDA(aggregate_ida);
>  
>  #ifdef CONFIG_DEBUG_FS
>  
> @@ -87,12 +93,12 @@ static struct dentry *component_debugfs_dir;
>  
>  static int component_devices_show(struct seq_file *s, void *data)
>  {
> - struct master *m = s->private;
> + struct aggregate_device *m = s->private;
>   struct component_match *match = m->match;
>   size_t i;
>  
>   mutex_lock(_mutex);
> - seq_printf(s, "%-40s %20s\n", "master name", "status");
> + seq_printf(s, "%-40s %20s\n", "aggregate_device name", "status");
>   seq_puts(s, 
> "-\n");
>   seq_printf(s, "%-40s %20s\n\n",
>  dev_name(m->parent), m->bound ? "bound" : "not bound");
> @@ -122,46 +128,46 @@ static int __init component_debug_init(void)
>  
>  core_initcall(component_debug_init);
>  
> -static void component_master_debugfs_add(struct master *m)
> +static void component_master_debugfs_add(struct aggregate_device *m)
>  {
>   debugfs_create_file(dev_name(m->parent), 0444, component_debugfs_dir, m,
>   _devices_fops);
>  }
>  
> -static void component_master_debugfs_del(struct master *m)
> +static void component_master_debugfs_del(struct aggregate_device *m)
>  {
>   debugfs_remove(debugfs_lookup(dev_name(m->parent), 
> component_debugfs_dir));
>  }
>  
>  #else
>  
> -static void component_master_debugfs_add(struct master *m)
> +static void component_master_debugfs_add(struct aggregate_device *m)
>  { }
>  
> -static void component_master_debugfs_del(struct master *m)
> +static void component_master_debugfs_del(struct aggregate_device *m)
>  { }
>  
>  #endif
>  
> -static struct master *__master_find(struct device *parent,
> +static struct aggregate_device *__aggregate_find(struct device *parent,
>   const struct component_master_ops *ops)
>  {
> - struct master *m;
> + struct aggregate_device *m;
>  
> - list_for_each_entry(m, , node)
> + list_for_each_entry(m, _devices, node)
>   if (m->parent == parent && (!ops || m->ops == ops))
>   return m;
>  
>   return NULL;
>  }
>  
> -static struct component *find_component(struct master *master,
> +static struct component *find_component(struct aggregate_device *adev,
>   struct component_match_array *mc)
>  {
>   struct component *c;
>  
>   list_for_each_entry(c, _list, 

[PATCH -next] drm/connector: fix all kernel-doc warnings

2021-10-06 Thread Randy Dunlap
Clean up all of the kernel-doc issues in drm_connector.c:

drivers/gpu/drm/drm_connector.c:2611: warning: Excess function parameter 
'connector' description in 'drm_connector_oob_hotplug_event'
drivers/gpu/drm/drm_connector.c:2611: warning: Function parameter or member 
'connector_fwnode' not described in 'drm_connector_oob_hotplug_event'

drm_connector.c:630: warning: No description found for return value of 
'drm_get_connector_status_name'
drm_connector.c:715: warning: No description found for return value of 
'drm_connector_list_iter_next'
drm_connector.c:785: warning: No description found for return value of 
'drm_get_subpixel_order_name'
drm_connector.c:816: warning: No description found for return value of 
'drm_display_info_set_bus_formats'
drm_connector.c:1331: warning: No description found for return value of 
'drm_mode_create_dvi_i_properties'
drm_connector.c:1412: warning: No description found for return value of 
'drm_connector_attach_content_type_property'
drm_connector.c:1492: warning: No description found for return value of 
'drm_mode_create_tv_margin_properties'
drm_connector.c:1534: warning: No description found for return value of 
'drm_mode_create_tv_properties'
drm_connector.c:1627: warning: No description found for return value of 
'drm_mode_create_scaling_mode_property'
drm_connector.c:1944: warning: No description found for return value of 
'drm_mode_create_suggested_offset_properties'

drm_connector.c:2315: warning: missing initial short description on line:
 * drm_connector_set_panel_orientation_with_quirk -

[The last warning listed is probably a quirk/bug in scripts/kernel-doc.]

Fixes: 613051dac40d ("drm: locking iterators for connector_list")
Fixes: 522171951761 ("drm: Extract drm_connector.[hc]")
Fixes: b3c6c8bfe378 ("drm: document drm_display_info")
Fixes: 50525c332b55 ("drm: content-type property for HDMI connector")
Fixes: 6c4f52dca36f ("drm/connector: Allow creation of margin props alone")
Fixes: 69654c632d80 ("drm/connector: Split out orientation quirk detection 
(v2)")
Fixes: 72ad49682dde ("drm/connector: Add support for out-of-band hotplug 
notification (v3)")
Signed-off-by: Randy Dunlap 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel@lists.freedesktop.org
Cc: Stanislav Lisovskiy 
Cc: Ville Syrjälä 
Cc: Boris Brezillon 
Cc: Derek Basehore 
Cc: Hans de Goede 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
---
72ad49682dde ("drm/connector: Add support for out-of-band hotplug notification 
(v3)")
  is only in linux-next. The others are in mainline.

 drivers/gpu/drm/drm_connector.c |   30 ++
 1 file changed, 26 insertions(+), 4 deletions(-)

--- linux-next-20211006.orig/drivers/gpu/drm/drm_connector.c
+++ linux-next-20211006/drivers/gpu/drm/drm_connector.c
@@ -625,6 +625,8 @@ int drm_connector_register_all(struct dr
  *
  * In contrast to the other drm_get_*_name functions this one here returns a
  * const pointer and hence is threadsafe.
+ *
+ * Returns: connector status string
  */
 const char *drm_get_connector_status_name(enum drm_connector_status status)
 {
@@ -707,7 +709,7 @@ __drm_connector_put_safe(struct drm_conn
  * drm_connector_list_iter_next - return next connector
  * @iter: connector_list iterator
  *
- * Returns the next connector for @iter, or NULL when the list walk has
+ * Returns: the next connector for @iter, or NULL when the list walk has
  * completed.
  */
 struct drm_connector *
@@ -780,6 +782,8 @@ static const struct drm_prop_enum_list d
  *
  * Note you could abuse this and return something out of bounds, but that
  * would be a caller error.  No unscrubbed user data should make it here.
+ *
+ * Returns: string describing an enumerated subpixel property
  */
 const char *drm_get_subpixel_order_name(enum subpixel_order order)
 {
@@ -809,6 +813,9 @@ static const struct drm_prop_enum_list d
  * Store the supported bus formats in display info structure.
  * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for
  * a full list of available formats.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
  */
 int drm_display_info_set_bus_formats(struct drm_display_info *info,
 const u32 *formats,
@@ -1326,6 +1333,8 @@ int drm_connector_create_standard_proper
  * @dev: DRM device
  *
  * Called by a driver the first time a DVI-I connector is made.
+ *
+ * Returns: %0
  */
 int drm_mode_create_dvi_i_properties(struct drm_device *dev)
 {
@@ -1407,6 +1416,8 @@ EXPORT_SYMBOL(drm_connector_attach_dp_su
  * @connector: connector to attach content type property on.
  *
  * Called by a driver the first time a HDMI connector is made.
+ *
+ * Returns: %0
  */
 int drm_connector_attach_content_type_property(struct drm_connector *connector)
 {
@@ -1487,6 +1498,9 @@ EXPORT_SYMBOL(drm_connector_attach_tv_ma
  * creates the TV margin properties for a given device. N

Re: [PATCH v13 06/35] clk: tegra: Support runtime PM and power domain

2021-10-06 Thread Dmitry Osipenko
07.10.2021 01:01, Dmitry Osipenko пишет:
> 07.10.2021 00:14, Dmitry Osipenko пишет:
>> 06.10.2021 15:43, Ulf Hansson пишет:
>>> On Wed, 6 Oct 2021 at 00:43, Dmitry Osipenko  wrote:

 06.10.2021 01:19, Dmitry Osipenko пишет:
 ...
> I reproduced the OFF problem by removing the clk prepare/unprepare from
> the suspend/resume of the clk driver and making some extra changes to
> clock tree topology and etc to trigger the problem on Nexus 7.
>
> tegra-pmc 7000e400.pmc: failed to turn off PM domain heg: -13
>
> It happens from genpd_suspend_noirq() -> tegra_genpd_power_off() -> clk
> -> GENPD -> I2C -> runtime-pm.
>
> -13 is EACCES, it comes from the runtime PM of I2C device. RPM is
> prohibited/disabled during late (NOIRQ) suspend by the drivers core.

 My bad, I double-checked and it's not I2C RPM that is failing now, but
 the clock's RPM [1], which is also unavailable during NOIRQ.
>>>
>>> Yes, that sounds reasonable.
>>>
>>> You would then need a similar patch for the tegra clock driver as I
>>> suggested for tegra I2C driver. That should solve the problem, I
>>> think.
>>>

 [1]
 https://elixir.free-electrons.com/linux/v5.15-rc4/source/drivers/clk/clk.c#L116

 Previously it was I2C RPM that was failing in a similar way, but code
 changed a tad since that time.
>>>
>>> Alright. In any case, as long as the devices gets suspended in the
>>> correct order, I think it should be fine to cook a patch along the
>>> lines of what I suggest for the I2C driver as well.
>>>
>>> It should work, I think. Although, maybe you want to avoid runtime
>>> resuming the I2C device, unless it's the device belonging to the PMIC
>>> interface, if there is a way to distinguish that for the driver.
>>
>> Ulf, thank you very much for the suggestions! I was thinking about this
>> all once again and concluded that the simplest variant will be to just
>> remove the suspend ops from the clk driver since neither of PLLs require
>> high voltage. We now have voltage bumped to a nominal level during
>> suspend by Tegra's regulator-coupler driver and it's much higher than
>> voltage needed by PLLs. So the problem I was trying to work around
>> doesn't really exist anymore.
> 
> I hurried a bit with the conclusion, keep forgetting that I need to
> change the clock tree in order to test it all properly :/ It's not fixed
> yet.
> 

Please let me iterate once again. The problem we currently have is that
clock may be enabled during NOIRQ time. In order to enable clock, it
needs to be prepared. In order to prepare clock, the clock's device
needs to be runtime-resumed. The runtime PM is unavailable at the NOIRQ
time.

To solve this problem we need to prepare clock beforehand.

The clock will stay prepared during suspend, but this is not a problem
since all the clocks we care about don't require high voltage and
voltage is guaranteed to be bumped high during suspend by Tegra's
regulator-coupler driver anyways.

So everything we need to do is to keep clocks prepared. There are two
options how to do that:

[1] this patch which explicitly prepares clocks using clk API.

[2] Use runtime PM API, like this:

static const struct dev_pm_ops tegra_clock_pm = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_resume_and_get, pm_runtime_put)
};

Ulf, are you now okay with the current variant [1] of the patch or you
prefer the second [2] option more?


Re: [PATCH v2 33/34] component: Remove component_master_ops and friends

2021-10-06 Thread kernel test robot
Hi Stephen,

I love your patch! Yet something to improve:

[auto build test ERROR on e4e737bb5c170df6135a127739a9e6148ee3da82]

url:
https://github.com/0day-ci/linux/commits/Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
base:   e4e737bb5c170df6135a127739a9e6148ee3da82
config: hexagon-randconfig-r045-20211006 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
c0039de2953d15815448b4b3c3bafb45607781e0)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/b2ecd8598795ffcc3d4e766c4c4cc93865f3ff33
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
git checkout b2ecd8598795ffcc3d4e766c4c4cc93865f3ff33
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/base/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> drivers/base/component.c:412:15: error: no member named 'ops' in 'struct 
>> aggregate_device'
   return adev->ops->bind(adev->parent);
    ^
   drivers/base/component.c:417:8: error: no member named 'ops' in 'struct 
aggregate_device'
   adev->ops->unbind(adev->parent);
     ^
   drivers/base/component.c:488:13: error: incompatible function pointer types 
initializing 'void (*)(struct device *)' with an expression of type 'int 
(struct device *)' [-Werror,-Wincompatible-function-pointer-types]
   .remove = aggregate_driver_remove,
 ^~~
   drivers/base/component.c:540:8: error: no member named 'ops' in 'struct 
aggregate_device'
   adev->ops = ops;
     ^
>> drivers/base/component.c:540:14: error: use of undeclared identifier 'ops'
   adev->ops = ops;
   ^
>> drivers/base/component.c:572:50: error: too many arguments to function call, 
>> expected 3, have 4
   adev = aggregate_device_add(parent, NULL, adrv, match);
   ^
   drivers/base/component.c:514:33: note: 'aggregate_device_add' declared here
   static struct aggregate_device *aggregate_device_add(struct device *parent,
   ^
>> drivers/base/component.c:599:34: error: too many arguments to function call, 
>> expected single argument 'parent', have 2 arguments
   adev = __aggregate_find(parent, NULL);
   ^~~~
   include/linux/stddef.h:8:14: note: expanded from macro 'NULL'
   #define NULL ((void *)0)
^~~
   drivers/base/component.c:493:33: note: '__aggregate_find' declared here
   static struct aggregate_device *__aggregate_find(struct device *parent)
   ^
   drivers/base/component.c:645:34: error: too many arguments to function call, 
expected single argument 'parent', have 2 arguments
   adev = __aggregate_find(parent, NULL);
   ^~~~
   include/linux/stddef.h:8:14: note: expanded from macro 'NULL'
   #define NULL ((void *)0)
^~~
   drivers/base/component.c:493:33: note: '__aggregate_find' declared here
   static struct aggregate_device *__aggregate_find(struct device *parent)
   ^
   drivers/base/component.c:734:34: error: too many arguments to function call, 
expected single argument 'parent', have 2 arguments
   adev = __aggregate_find(parent, NULL);
   ^~~~
   include/linux/stddef.h:8:14: note: expanded from macro 'NULL'
   #define NULL ((void *)0)
^~~
   drivers/base/component.c:493:33: note: '__aggregate_find' declared here
   static struct aggregate_device *__aggregate_find(struct device *parent)
   ^
   9 errors generated.


vim +412 drivers/base/component.c

b7f12127fd97fe Stephen Boyd 2021-10-06  408  
b7f12127fd97fe Stephen Boyd 2021-10-06  409  /* TODO: Remove once all aggregate 
drivers use component_aggregate_register() */
b7f12127fd97fe Stephen Boyd 2021-10-06  410  static int 
component_probe_bind(struct aggregate_device *adev)
b7f12127fd97fe Stephen Boyd 2021-10-06  411  {
b7f12127fd97fe Stephen Boyd 2021-10-06 @412 return 
adev->ops->bind(adev->parent);
b7f12127fd97fe Stephen Boyd 2021-10-06  413  }
b7f12127fd97fe Stephen Boyd 2021-10-06  414  
b7f12127fd97fe Stephen Boyd 2021-10-06  415  s

Re: [PATCH v2] drm/edid: In connector_bad_edid() cap num_of_ext by num_blocks read

2021-10-06 Thread Ville Syrjälä
On Wed, Oct 06, 2021 at 03:45:07PM -0700, Doug Anderson wrote:
> Hi,
> 
> On Tue, Oct 5, 2021 at 7:29 PM Douglas Anderson  wrote:
> >
> > In commit e11f5bd8228f ("drm: Add support for DP 1.4 Compliance edid
> > corruption test") the function connector_bad_edid() started assuming
> > that the memory for the EDID passed to it was big enough to hold
> > `edid[0x7e] + 1` blocks of data (1 extra for the base block). It
> > completely ignored the fact that the function was passed `num_blocks`
> > which indicated how much memory had been allocated for the EDID.
> >
> > Let's fix this by adding a bounds check.
> >
> > This is important for handling the case where there's an error in the
> > first block of the EDID. In that case we will call
> > connector_bad_edid() without having re-allocated memory based on
> > `edid[0x7e]`.
> >
> > Fixes: e11f5bd8228f ("drm: Add support for DP 1.4 Compliance edid 
> > corruption test")
> > Reported-by: Ville Syrjälä 
> > Signed-off-by: Douglas Anderson 
> > Reviewed-by: Ville Syrjälä 
> > ---
> > This problem report came up in the context of a patch I sent out [1]
> > and this is my attempt at a fix. The problem predates my patch,
> > though. I don't personally know anything about DP compliance testing
> > and what should be happening here, nor do I apparently have any
> > hardware that actually reports a bad EDID. Thus this is just compile
> > tested. I'm hoping that someone here can test this and make sure it
> > seems OK to them.
> >
> > Changes in v2:
> > - Added a comment/changed math to help make it easier to grok.
> >
> >  drivers/gpu/drm/drm_edid.c | 15 ---
> >  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> Pushed this to drm-misc-fixes since the commit it fixes is fairly old.
> 
> fdc21c35aaa1 drm/edid: In connector_bad_edid() cap num_of_ext by num_blocks 
> read

BTW seems kasan caught this for us [1]. I didn't notice we had a bug
open about it until now. Just Chris Wilson mentioned it to me in passing
quite a while ago, and I totally forgot about it until I saw your other
patch poking around the same code.

[1] https://gitlab.freedesktop.org/drm/intel/-/issues/4106

-- 
Ville Syrjälä
Intel


Re: [PATCH v2] drm/edid: In connector_bad_edid() cap num_of_ext by num_blocks read

2021-10-06 Thread Doug Anderson
Hi,

On Tue, Oct 5, 2021 at 7:29 PM Douglas Anderson  wrote:
>
> In commit e11f5bd8228f ("drm: Add support for DP 1.4 Compliance edid
> corruption test") the function connector_bad_edid() started assuming
> that the memory for the EDID passed to it was big enough to hold
> `edid[0x7e] + 1` blocks of data (1 extra for the base block). It
> completely ignored the fact that the function was passed `num_blocks`
> which indicated how much memory had been allocated for the EDID.
>
> Let's fix this by adding a bounds check.
>
> This is important for handling the case where there's an error in the
> first block of the EDID. In that case we will call
> connector_bad_edid() without having re-allocated memory based on
> `edid[0x7e]`.
>
> Fixes: e11f5bd8228f ("drm: Add support for DP 1.4 Compliance edid corruption 
> test")
> Reported-by: Ville Syrjälä 
> Signed-off-by: Douglas Anderson 
> Reviewed-by: Ville Syrjälä 
> ---
> This problem report came up in the context of a patch I sent out [1]
> and this is my attempt at a fix. The problem predates my patch,
> though. I don't personally know anything about DP compliance testing
> and what should be happening here, nor do I apparently have any
> hardware that actually reports a bad EDID. Thus this is just compile
> tested. I'm hoping that someone here can test this and make sure it
> seems OK to them.
>
> Changes in v2:
> - Added a comment/changed math to help make it easier to grok.
>
>  drivers/gpu/drm/drm_edid.c | 15 ---
>  1 file changed, 12 insertions(+), 3 deletions(-)

Pushed this to drm-misc-fixes since the commit it fixes is fairly old.

fdc21c35aaa1 drm/edid: In connector_bad_edid() cap num_of_ext by num_blocks read

-Doug


Re: [PATCH v2 02/34] component: Introduce the aggregate bus_type

2021-10-06 Thread kernel test robot
Hi Stephen,

I love your patch! Yet something to improve:

[auto build test ERROR on e4e737bb5c170df6135a127739a9e6148ee3da82]

url:
https://github.com/0day-ci/linux/commits/Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
base:   e4e737bb5c170df6135a127739a9e6148ee3da82
config: hexagon-randconfig-r045-20211006 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
c0039de2953d15815448b4b3c3bafb45607781e0)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/b7f12127fd97fe811eaf9600a6677fb1cbb66554
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
git checkout b7f12127fd97fe811eaf9600a6677fb1cbb66554
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
ARCH=hexagon 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> drivers/base/component.c:509:13: error: incompatible function pointer types 
>> initializing 'void (*)(struct device *)' with an expression of type 'int 
>> (struct device *)' [-Werror,-Wincompatible-function-pointer-types]
   .remove = aggregate_driver_remove,
 ^~~
   1 error generated.


vim +509 drivers/base/component.c

   504  
   505  static struct bus_type aggregate_bus_type = {
   506  .name   = "aggregate",
   507  .match  = aggregate_device_match,
   508  .probe  = aggregate_driver_probe,
 > 509  .remove = aggregate_driver_remove,
   510  .shutdown   = aggregate_driver_shutdown,
   511  };
   512  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH v2 06/34] drm/of: Add a drm_of_aggregate_probe() API

2021-10-06 Thread kernel test robot
Hi Stephen,

I love your patch! Perhaps something to improve:

[auto build test WARNING on e4e737bb5c170df6135a127739a9e6148ee3da82]

url:
https://github.com/0day-ci/linux/commits/Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
base:   e4e737bb5c170df6135a127739a9e6148ee3da82
config: s390-randconfig-r044-20211006 (attached as .config)
compiler: s390-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/8de4fafdac42c316be0fc23e4176e13043031a38
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
git checkout 8de4fafdac42c316be0fc23e4176e13043031a38
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross 
O=build_dir ARCH=s390 SHELL=/bin/bash drivers/gpu/drm/bridge/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/bridge/chipone-icn6211.c:7:
>> include/drm/drm_of.h:45:35: warning: 'struct aggregate_driver' declared 
>> inside parameter list will not be visible outside of this definition or 
>> declaration
  45 |struct aggregate_driver *adrv);
 |   ^~~~


vim +45 include/drm/drm_of.h

30  
31  #ifdef CONFIG_OF
32  uint32_t drm_of_crtc_port_mask(struct drm_device *dev,
33  struct device_node *port);
34  uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
35  struct device_node *port);
36  void drm_of_component_match_add(struct device *master,
37  struct component_match **matchptr,
38  int (*compare)(struct device *, void *),
39  struct device_node *node);
40  int drm_of_component_probe(struct device *dev,
41 int (*compare_of)(struct device *, void *),
42 const struct component_master_ops *m_ops);
43  int drm_of_aggregate_probe(struct device *dev,
44 int (*compare_of)(struct device *, void *),
  > 45 struct aggregate_driver *adrv);
46  int drm_of_encoder_active_endpoint(struct device_node *node,
47 struct drm_encoder *encoder,
48 struct of_endpoint *endpoint);
49  int drm_of_find_panel_or_bridge(const struct device_node *np,
50  int port, int endpoint,
51  struct drm_panel **panel,
52  struct drm_bridge **bridge);
53  int drm_of_lvds_get_dual_link_pixel_order(const struct device_node 
*port1,
54const struct device_node 
*port2);
55  #else
56  static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev,
57struct device_node *port)
58  {
59  return 0;
60  }
61  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH v2 06/34] drm/of: Add a drm_of_aggregate_probe() API

2021-10-06 Thread kernel test robot
Hi Stephen,

I love your patch! Perhaps something to improve:

[auto build test WARNING on e4e737bb5c170df6135a127739a9e6148ee3da82]

url:
https://github.com/0day-ci/linux/commits/Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
base:   e4e737bb5c170df6135a127739a9e6148ee3da82
config: hexagon-randconfig-r041-20211006 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
c0039de2953d15815448b4b3c3bafb45607781e0)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/8de4fafdac42c316be0fc23e4176e13043031a38
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Stephen-Boyd/component-Make-into-an-aggregate-bus/20211007-034200
git checkout 8de4fafdac42c316be0fc23e4176e13043031a38
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
ARCH=hexagon 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/bridge/synopsys/dw-hdmi.c:32:
>> include/drm/drm_of.h:45:14: warning: declaration of 'struct 
>> aggregate_driver' will not be visible outside of this function [-Wvisibility]
  struct aggregate_driver *adrv);
 ^
   1 warning generated.


vim +45 include/drm/drm_of.h

30  
31  #ifdef CONFIG_OF
32  uint32_t drm_of_crtc_port_mask(struct drm_device *dev,
33  struct device_node *port);
34  uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
35  struct device_node *port);
36  void drm_of_component_match_add(struct device *master,
37  struct component_match **matchptr,
38  int (*compare)(struct device *, void *),
39  struct device_node *node);
40  int drm_of_component_probe(struct device *dev,
41 int (*compare_of)(struct device *, void *),
42 const struct component_master_ops *m_ops);
43  int drm_of_aggregate_probe(struct device *dev,
44 int (*compare_of)(struct device *, void *),
  > 45 struct aggregate_driver *adrv);
46  int drm_of_encoder_active_endpoint(struct device_node *node,
47 struct drm_encoder *encoder,
48 struct of_endpoint *endpoint);
49  int drm_of_find_panel_or_bridge(const struct device_node *np,
50  int port, int endpoint,
51  struct drm_panel **panel,
52  struct drm_bridge **bridge);
53  int drm_of_lvds_get_dual_link_pixel_order(const struct device_node 
*port1,
54const struct device_node 
*port2);
55  #else
56  static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev,
57struct device_node *port)
58  {
59  return 0;
60  }
61  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH v13 06/35] clk: tegra: Support runtime PM and power domain

2021-10-06 Thread Dmitry Osipenko
06.10.2021 15:38, Ulf Hansson пишет:
>>> Right, so the PM domain managed in tegra_genpd_power_on|off() can
>>> still be powered on/off, as long as the clock remains ungated?
>> Not ungated, but prepared.
> Okay, thanks for clarifying!
> 
> In summary, it sounds like you should be able to fix this problem in
> the I2C driver as I suggested above. If that works, that seems much
> better.

I'll try this variant, thank you.

> Moreover, it would leave the clocks gated/unprepared when the system
> is fully suspended, which I guess is better from an energy point of
> view?

The clocks are kept gated, it wasn't a problem. The problem was that
clocks were needed to be enabled temporarily. In order to enable a
clock, it needs to be prepared first. When clock is prepared, it resumes
clock's device RPM.

Keeping clocks prepared shouldn't make a noticeable difference from the
energy POV since clocks are gated. It's only voltage that is kept high,
but we need to keep it high during suspend anyways in order to resume
successfully. The hardware is mostly gated during suspend, depending on
suspend mode, so the power consumption difference is negligible. At
least I haven't seen any problems, battery doesn't drain during suspend.


Re: [PATCH v13 06/35] clk: tegra: Support runtime PM and power domain

2021-10-06 Thread Dmitry Osipenko
07.10.2021 00:14, Dmitry Osipenko пишет:
> 06.10.2021 15:43, Ulf Hansson пишет:
>> On Wed, 6 Oct 2021 at 00:43, Dmitry Osipenko  wrote:
>>>
>>> 06.10.2021 01:19, Dmitry Osipenko пишет:
>>> ...
 I reproduced the OFF problem by removing the clk prepare/unprepare from
 the suspend/resume of the clk driver and making some extra changes to
 clock tree topology and etc to trigger the problem on Nexus 7.

 tegra-pmc 7000e400.pmc: failed to turn off PM domain heg: -13

 It happens from genpd_suspend_noirq() -> tegra_genpd_power_off() -> clk
 -> GENPD -> I2C -> runtime-pm.

 -13 is EACCES, it comes from the runtime PM of I2C device. RPM is
 prohibited/disabled during late (NOIRQ) suspend by the drivers core.
>>>
>>> My bad, I double-checked and it's not I2C RPM that is failing now, but
>>> the clock's RPM [1], which is also unavailable during NOIRQ.
>>
>> Yes, that sounds reasonable.
>>
>> You would then need a similar patch for the tegra clock driver as I
>> suggested for tegra I2C driver. That should solve the problem, I
>> think.
>>
>>>
>>> [1]
>>> https://elixir.free-electrons.com/linux/v5.15-rc4/source/drivers/clk/clk.c#L116
>>>
>>> Previously it was I2C RPM that was failing in a similar way, but code
>>> changed a tad since that time.
>>
>> Alright. In any case, as long as the devices gets suspended in the
>> correct order, I think it should be fine to cook a patch along the
>> lines of what I suggest for the I2C driver as well.
>>
>> It should work, I think. Although, maybe you want to avoid runtime
>> resuming the I2C device, unless it's the device belonging to the PMIC
>> interface, if there is a way to distinguish that for the driver.
> 
> Ulf, thank you very much for the suggestions! I was thinking about this
> all once again and concluded that the simplest variant will be to just
> remove the suspend ops from the clk driver since neither of PLLs require
> high voltage. We now have voltage bumped to a nominal level during
> suspend by Tegra's regulator-coupler driver and it's much higher than
> voltage needed by PLLs. So the problem I was trying to work around
> doesn't really exist anymore.

I hurried a bit with the conclusion, keep forgetting that I need to
change the clock tree in order to test it all properly :/ It's not fixed
yet.


Re: [igt-dev] [PATCH i-g-t 1/1] tests/i915_pxp: Use ioctl_wrapper for DRM_IOCTL_PRIME_HANDLE_TO_FD

2021-10-06 Thread Rodrigo Vivi
On Wed, Oct 06, 2021 at 05:11:02PM +, Ruhl, Michael J wrote:
> >-Original Message-
> >From: Teres Alexis, Alan Previn 
> >Sent: Wednesday, October 6, 2021 12:52 PM
> >To: igt-...@lists.freedesktop.org
> >Cc: Teres Alexis, Alan Previn ; dri-
> >de...@lists.freedesktop.org; Ruhl; Ruhl, Michael J
> >; Vivi, Rodrigo 
> >Subject: [PATCH i-g-t 1/1] tests/i915_pxp: Use ioctl_wrapper for
> >DRM_IOCTL_PRIME_HANDLE_TO_FD
> >
> >Replace private helper with call to ioctl_wrapper for
> >DRM_IOCTL_PRIME_HANDLE_TO_FD.
> 
> Reviewed-by: Michael J. Ruhl 

pushed, thanks

> 
> M
> 
> >Signed-off-by: Alan Previn 
> >---
> > tests/i915/gem_pxp.c | 20 +---
> > 1 file changed, 1 insertion(+), 19 deletions(-)
> >
> >diff --git a/tests/i915/gem_pxp.c b/tests/i915/gem_pxp.c
> >index 79040165..0430f4b8 100644
> >--- a/tests/i915/gem_pxp.c
> >+++ b/tests/i915/gem_pxp.c
> >@@ -622,23 +622,6 @@ static void test_render_pxp_protsrc_to_protdest(int
> >i915)
> > buf_ops_destroy(bops);
> > }
> >
> >-static int export_handle(int fd, uint32_t handle, int *outfd)
> >-{
> >-struct drm_prime_handle args;
> >-int ret;
> >-
> >-args.handle = handle;
> >-args.flags = DRM_CLOEXEC;
> >-args.fd = -1;
> >-
> >-ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, );
> >-if (ret)
> >-ret = errno;
> >-*outfd = args.fd;
> >-
> >-return ret;
> >-}
> >-
> > static void test_pxp_dmabuffshare_refcnt(void)
> > {
> > uint32_t ctx[2], sbo[2], dbo[2];
> >@@ -659,8 +642,7 @@ static void test_pxp_dmabuffshare_refcnt(void)
> > dbo[0] = alloc_and_fill_dest_buff(fd[0], true,
> >TSTSURF_SIZE,
> >
> >TSTSURF_INITCOLOR1);
> > } else {
> >-ret = export_handle(fd[0], dbo[0], _fd);
> >-igt_assert(ret == 0);
> >+dmabuf_fd = prime_handle_to_fd(fd[0], dbo[0]);
> > dbo[1] = prime_fd_to_handle(fd[1], dmabuf_fd);
> > igt_assert(dbo[1]);
> > }
> >--
> >2.25.1
> 


Re: [PATCH v13 06/35] clk: tegra: Support runtime PM and power domain

2021-10-06 Thread Dmitry Osipenko
06.10.2021 15:38, Ulf Hansson пишет:
>> I'm also wondering if we could add some 'was_enabled' flag to GENPDs,
>> setting it by genpd_suspend_noirq() for the enabled domains, and then
>> powering-on GENPDs from genpd_resume_noirq() only if they were in the
>> enabled state during genpd_suspend_noirq() time. It actually puzzled me
>> for a quite long time why GENPD core enables domains unconditionally
>> during early resume. This should solve a part of the problem and it
>> makes suspend/resume a bit safer because there is a smaller chance to
>> crash hardware during suspend, at least it's easier to debug.
> Just because the PM domain was already off at genpd_suspend_noirq(),
> doesn't mean that it can stay powered off at genpd_resume_noirq(). At
> least as is today.
> 
> The main reason why genpd_resume_noirq() powers on the PM domain, is
> because it's not possible for the consumer drivers to rely on runtime
> PM to do it (because runtime PM has been disabled by the PM core).

At least Tegra doesn't need to have domains force-resumed. This should
be a platform-specific behaviour. We may add a new flag for that, I
suppose. I'll try to keep this in mind for a future improvement. Thank
you for the clarification.


Re: [PATCH v13 06/35] clk: tegra: Support runtime PM and power domain

2021-10-06 Thread Dmitry Osipenko
06.10.2021 15:38, Ulf Hansson пишет:
> In principle what you ask for, is if we can avoid calling
> __pm_runtime_disable() in __device_suspend_late() (and vice versa in
> device_resume_early()).
> 
> I think the short answer is no, at least from a generic point of view.
> Maybe we can figure out a way to allow this on a per device basis, as
> an opt-in solution. I am not sure what Rafael would think about this,
> let's see.
> 
> Another option to address the problem is already available to use for
> these kinds of cases. This would be to add also a pair of
> ->suspend|resume() callbacks to I2C driver. Along the lines of the
> below.
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index c883044715f3..589bf872ab25 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -1918,6 +1918,7 @@ static int __maybe_unused
> tegra_i2c_resume(struct device *dev)
>  }
> 
>  static const struct dev_pm_ops tegra_i2c_pm = {
> +   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_put_noidle, pm_runtime_get_sync)
> SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume)
> SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, 
> tegra_i2c_runtime_resume,
>NULL)
> 
> In this way, the device would already be runtime resumed, if there is
> call to pm_runtime_get_sync() from the clock framework due to the
> clk_prepare|unprepare() being called. If that also turns out to happen
> *after* runtime PM has been disabled for the device, the call to
> pm_runtime_get_sync() would still succeed (returning 1, see
> rpm_resume()), rather than a negative error code.
> 
> Yes, we may end up runtime resuming the device during system suspend,
> even if it turns out not to be needed. Although, that doesn't seem to
> be the case for the Tegra I2C driver, right?

Tegra I2C will turn off clocks on suspend regardless of RPM state.
Overall, it's a plausible solution, thank you!

As I said in the other reply, I'll simply remove the suspend ops from
clk driver, they are not needed anymore. The problem is gone.


Re: [PATCH v13 06/35] clk: tegra: Support runtime PM and power domain

2021-10-06 Thread Dmitry Osipenko
06.10.2021 15:43, Ulf Hansson пишет:
> On Wed, 6 Oct 2021 at 00:43, Dmitry Osipenko  wrote:
>>
>> 06.10.2021 01:19, Dmitry Osipenko пишет:
>> ...
>>> I reproduced the OFF problem by removing the clk prepare/unprepare from
>>> the suspend/resume of the clk driver and making some extra changes to
>>> clock tree topology and etc to trigger the problem on Nexus 7.
>>>
>>> tegra-pmc 7000e400.pmc: failed to turn off PM domain heg: -13
>>>
>>> It happens from genpd_suspend_noirq() -> tegra_genpd_power_off() -> clk
>>> -> GENPD -> I2C -> runtime-pm.
>>>
>>> -13 is EACCES, it comes from the runtime PM of I2C device. RPM is
>>> prohibited/disabled during late (NOIRQ) suspend by the drivers core.
>>
>> My bad, I double-checked and it's not I2C RPM that is failing now, but
>> the clock's RPM [1], which is also unavailable during NOIRQ.
> 
> Yes, that sounds reasonable.
> 
> You would then need a similar patch for the tegra clock driver as I
> suggested for tegra I2C driver. That should solve the problem, I
> think.
> 
>>
>> [1]
>> https://elixir.free-electrons.com/linux/v5.15-rc4/source/drivers/clk/clk.c#L116
>>
>> Previously it was I2C RPM that was failing in a similar way, but code
>> changed a tad since that time.
> 
> Alright. In any case, as long as the devices gets suspended in the
> correct order, I think it should be fine to cook a patch along the
> lines of what I suggest for the I2C driver as well.
> 
> It should work, I think. Although, maybe you want to avoid runtime
> resuming the I2C device, unless it's the device belonging to the PMIC
> interface, if there is a way to distinguish that for the driver.

Ulf, thank you very much for the suggestions! I was thinking about this
all once again and concluded that the simplest variant will be to just
remove the suspend ops from the clk driver since neither of PLLs require
high voltage. We now have voltage bumped to a nominal level during
suspend by Tegra's regulator-coupler driver and it's much higher than
voltage needed by PLLs. So the problem I was trying to work around
doesn't really exist anymore.


Re: [PATCH v1 1/3] dt-bindings: display: simple: add Innolux G070Y2-T02 panel

2021-10-06 Thread Rob Herring
On Thu, 30 Sep 2021 12:04:59 +0200, Oleksij Rempel wrote:
> Add binding for the Innolux G070Y2-T02 panel. It is 7" WVGA (800x480)
> TFT LCD panel with TTL interface and a backlight unit.
> 
> Signed-off-by: Oleksij Rempel 
> ---
>  .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring 


Re: [PATCH v1 2/2] drm/tegra: dc: rgb: Allow changing PLLD rate on Tegra30+

2021-10-06 Thread Dmitry Osipenko
06.10.2021 21:27, Dmitry Osipenko пишет:
> 06.10.2021 21:13, Thierry Reding пишет:
>> On Thu, Sep 30, 2021 at 01:28:05AM +0300, Dmitry Osipenko wrote:
>>> Asus Transformer TF700T is a Tegra30 tablet device which uses RGB->DSI
>>> bridge that requires a precise clock rate in order to operate properly.
>>> Tegra30 has a dedicated PLL for each display controller, hence the PLL
>>> rate can be changed freely. Allow PLL rate changes on Tegra30+ for RGB
>>> output. Configure the clock rate before display controller is enabled
>>> since DC itself may be running off this PLL and it's not okay to change
>>> the rate of the active PLL that doesn't support dynamic frequency
>>> switching since hardware will hang.
>>>
>>> Tested-by: Maxim Schwalm  #TF700T
>>> Signed-off-by: Dmitry Osipenko 
>>> ---
>>>  drivers/gpu/drm/tegra/dc.c  | 27 
>>>  drivers/gpu/drm/tegra/dc.h  |  1 +
>>>  drivers/gpu/drm/tegra/rgb.c | 49 +++--
>>>  3 files changed, 65 insertions(+), 12 deletions(-)
>>
>> This seems overly complicated. I especially don't like the way how
>> clocks are looked up with clk_get_sys() and then used in the comparison.
>> Could this not be achieved by using assigned-clocks and friends
>> properties in DT?
> 
> Assigned-clocks have nothing to do with this patch. We need to check
> whether PLLD *is* already pre-assigned as the parent.
> 
> Adding properties for describing the clk parents is overly complicated,
> clk_get_sys() is a much simpler solution that doesn't involve extra DT
> changes.
> 
> BTW, assigned-clocks can't be used for display controller  because
> controller is usually turned on during boot and reparenting of active DC
> will hang machine.
> 

To make it more clear, we change the DC's "parent" in TF700T device-tree
to PLLD [1] to match the bootloader's configuration, otherwise it will
hang on boot since default "parent" in tegra30.dtsi is PLLP, and thus,
tegra_dc_rgb_probe() will try to reparent it to PLLP. Display of TF700T
won't work with PLLP anyways since it needs a specific clock rate.

[1]
https://github.com/grate-driver/linux/blob/master/arch/arm/boot/dts/tegra30-asus-tf700t.dts#L13


Re: [Intel-gfx] [PATCH 21/26] drm/i915: Multi-BB execbuf

2021-10-06 Thread Matthew Brost
On Mon, Oct 04, 2021 at 03:06:32PM -0700, Matthew Brost wrote:
> Allow multiple batch buffers to be submitted in a single execbuf IOCTL
> after a context has been configured with the 'set_parallel' extension.
> The number batches is implicit based on the contexts configuration.
> 
> This is implemented with a series of loops. First a loop is used to find
> all the batches, a loop to pin all the HW contexts, a loop to create all
> the requests, a loop to submit (emit BB start, etc...) all the requests,
> a loop to tie the requests to the VMAs they touch, and finally a loop to
> commit the requests to the backend.
> 
> A composite fence is also created for the generated requests to return
> to the user and to stick in dma resv slots.
> 
> No behavior from the existing IOCTL should be changed aside from when
> throttling because the ring for a context is full, wait on the request
> while holding the object locks.
> 
> IGT: https://patchwork.freedesktop.org/patch/447008/?series=93071=1
> media UMD: https://github.com/intel/media-driver/pull/1252
> 
> v2:
>  (Matthew Brost)
>   - Return proper error value if i915_request_create fails
> v3:
>  (John Harrison)
>   - Add comment explaining create / add order loops + locking
>   - Update commit message explaining different in IOCTL behavior
>   - Line wrap some comments
>   - eb_add_request returns void
>   - Return -EINVAL rather triggering BUG_ON if cmd parser used
>  (Checkpatch)
>   - Check eb->batch_len[*current_batch]
> 
> Signed-off-by: Matthew Brost 
> ---
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 793 --
>  drivers/gpu/drm/i915/gt/intel_context.h   |   8 +-
>  drivers/gpu/drm/i915/gt/intel_context_types.h |  10 +
>  .../gpu/drm/i915/gt/uc/intel_guc_submission.c |   2 +
>  drivers/gpu/drm/i915/i915_request.h   |   9 +
>  drivers/gpu/drm/i915/i915_vma.c   |  21 +-
>  drivers/gpu/drm/i915/i915_vma.h   |  13 +-
>  7 files changed, 599 insertions(+), 257 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index 2f2434b52317..5c7fb6f68bbb 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -244,17 +244,25 @@ struct i915_execbuffer {
>   struct drm_i915_gem_exec_object2 *exec; /** ioctl execobj[] */
>   struct eb_vma *vma;
>  
> - struct intel_engine_cs *engine; /** engine to queue the request to */
> + struct intel_gt *gt; /* gt for the execbuf */
>   struct intel_context *context; /* logical state for the request */
>   struct i915_gem_context *gem_context; /** caller's context */
>  
> - struct i915_request *request; /** our request to build */
> - struct eb_vma *batch; /** identity of the batch obj/vma */
> + /** our requests to build */
> + struct i915_request *requests[MAX_ENGINE_INSTANCE + 1];
> + /** identity of the batch obj/vma */
> + struct eb_vma *batches[MAX_ENGINE_INSTANCE + 1];
>   struct i915_vma *trampoline; /** trampoline used for chaining */
>  
> + /** used for excl fence in dma_resv objects when > 1 BB submitted */
> + struct dma_fence *composite_fence;
> +
>   /** actual size of execobj[] as we may extend it for the cmdparser */
>   unsigned int buffer_count;
>  
> + /* number of batches in execbuf IOCTL */
> + unsigned int num_batches;
> +
>   /** list of vma not yet bound during reservation phase */
>   struct list_head unbound;
>  
> @@ -281,7 +289,8 @@ struct i915_execbuffer {
>  
>   u64 invalid_flags; /** Set of execobj.flags that are invalid */
>  
> - u64 batch_len; /** Length of batch within object */
> + /** Length of batch within object */
> + u64 batch_len[MAX_ENGINE_INSTANCE + 1];
>   u32 batch_start_offset; /** Location within object of batch */
>   u32 batch_flags; /** Flags composed for emit_bb_start() */
>   struct intel_gt_buffer_pool_node *batch_pool; /** pool node for batch 
> buffer */
> @@ -299,14 +308,13 @@ struct i915_execbuffer {
>  };
>  
>  static int eb_parse(struct i915_execbuffer *eb);
> -static struct i915_request *eb_pin_engine(struct i915_execbuffer *eb,
> -   bool throttle);
> +static int eb_pin_engine(struct i915_execbuffer *eb, bool throttle);
>  static void eb_unpin_engine(struct i915_execbuffer *eb);
>  
>  static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
>  {
> - return intel_engine_requires_cmd_parser(eb->engine) ||
> - (intel_engine_using_cmd_parser(eb->engine) &&
> + return intel_engine_requires_cmd_parser(eb->context->engine) ||
> + (intel_engine_using_cmd_parser(eb->context->engine) &&
>eb->args->batch_len);
>  }
>  
> @@ -544,11 +552,21 @@ eb_validate_vma(struct i915_execbuffer *eb,
>   return 0;
>  }
>  
> -static void
> +static inline bool
> +is_batch_buffer(struct 

[PATCH 2/2] drm/msm/dsi: stop setting clock parents manually

2021-10-06 Thread Dmitry Baryshkov
There is no reason to set clock parents manually, use device tree to
assign DSI/display clock parents to DSI PHY clocks. Dropping this manual
setup allows us to drop repeating code and to move registration of hw
clock providers to generic place.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/dsi.h |  2 -
 drivers/gpu/drm/msm/dsi/dsi_host.c| 53 ---
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 11 +-
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 11 --
 4 files changed, 2 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 7dfb6d198ca9..c03a8d09c764 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -173,8 +173,6 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy,
 void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
 void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
 enum msm_dsi_phy_usecase uc);
-int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy,
-   struct clk **byte_clk_provider, struct clk **pixel_clk_provider);
 void msm_dsi_phy_pll_save_state(struct msm_dsi_phy *phy);
 int msm_dsi_phy_pll_restore_state(struct msm_dsi_phy *phy);
 void msm_dsi_phy_snapshot(struct msm_disp_state *disp_state, struct 
msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 1ffcd0577e99..9600b4fa27eb 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2232,59 +2232,6 @@ void msm_dsi_host_set_phy_mode(struct mipi_dsi_host 
*host,
msm_host->cphy_mode = src_phy->cphy_mode;
 }
 
-int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
-   struct msm_dsi_phy *src_phy)
-{
-   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
-   struct clk *byte_clk_provider, *pixel_clk_provider;
-   int ret;
-
-   msm_host->cphy_mode = src_phy->cphy_mode;
-
-   ret = msm_dsi_phy_get_clk_provider(src_phy,
-   _clk_provider, _clk_provider);
-   if (ret) {
-   pr_info("%s: can't get provider from pll, don't set parent\n",
-   __func__);
-   return 0;
-   }
-
-   ret = clk_set_parent(msm_host->byte_clk_src, byte_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to byte_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-
-   ret = clk_set_parent(msm_host->pixel_clk_src, pixel_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to pixel_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-
-   if (msm_host->dsi_clk_src) {
-   ret = clk_set_parent(msm_host->dsi_clk_src, pixel_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to dsi_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-   }
-
-   if (msm_host->esc_clk_src) {
-   ret = clk_set_parent(msm_host->esc_clk_src, byte_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to esc_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-   }
-
-exit:
-   return ret;
-}
-
 void msm_dsi_host_reset_phy(struct mipi_dsi_host *host)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 49a0a0841487..9342a822ad20 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -78,10 +78,7 @@ static int dsi_mgr_setup_components(int id)
 
msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
-   ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy);
-   } else if (!other_dsi) {
-   ret = 0;
-   } else {
+   } else if (other_dsi) {
struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
msm_dsi : other_dsi;
struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
@@ -107,13 +104,9 @@ static int dsi_mgr_setup_components(int id)
MSM_DSI_PHY_SLAVE);
msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
-   ret = msm_dsi_host_set_src_pll(msm_dsi->host, 
clk_master_dsi->phy);
-   if (ret)
-   return ret;
-   ret = msm_dsi_host_set_src_pll(other_dsi->host, 
clk_master_dsi->phy);
}
 
-   return ret;
+   return 0;
 }
 
 static int 

[PATCH 1/2] drm/msm/dsi: untangle cphy setting from the src pll setting

2021-10-06 Thread Dmitry Baryshkov
Move DPHY/CPHY setting from msm_dsi_host_set_src_pll() to new function
msm_dsi_host_set_phy_mode().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/dsi.h | 2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c| 8 
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index b50db91cb8a7..7dfb6d198ca9 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -118,6 +118,8 @@ unsigned long msm_dsi_host_get_mode_flags(struct 
mipi_dsi_host *host);
 struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host);
 int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer);
 void msm_dsi_host_unregister(struct mipi_dsi_host *host);
+void msm_dsi_host_set_phy_mode(struct mipi_dsi_host *host,
+   struct msm_dsi_phy *src_phy);
 int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
struct msm_dsi_phy *src_phy);
 void msm_dsi_host_reset_phy(struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..1ffcd0577e99 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2224,6 +2224,14 @@ void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host 
*host, u32 dma_base,
wmb();
 }
 
+void msm_dsi_host_set_phy_mode(struct mipi_dsi_host *host,
+   struct msm_dsi_phy *src_phy)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   msm_host->cphy_mode = src_phy->cphy_mode;
+}
+
 int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
struct msm_dsi_phy *src_phy)
 {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index c41d39f5b7cf..49a0a0841487 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -77,6 +77,7 @@ static int dsi_mgr_setup_components(int id)
return ret;
 
msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
+   msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy);
} else if (!other_dsi) {
ret = 0;
@@ -104,6 +105,8 @@ static int dsi_mgr_setup_components(int id)
MSM_DSI_PHY_MASTER);
msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
MSM_DSI_PHY_SLAVE);
+   msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
+   msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
ret = msm_dsi_host_set_src_pll(msm_dsi->host, 
clk_master_dsi->phy);
if (ret)
return ret;
-- 
2.33.0



Re: [PATCH] drm/i915/pmu: Connect engine busyness stats from GuC to pmu

2021-10-06 Thread Umesh Nerlige Ramappa

On Wed, Oct 06, 2021 at 10:11:58AM +0100, Tvrtko Ursulin wrote:


On 05/10/2021 18:47, Umesh Nerlige Ramappa wrote:

With GuC handling scheduling, i915 is not aware of the time that a
context is scheduled in and out of the engine. Since i915 pmu relies on
this info to provide engine busyness to the user, GuC shares this info
with i915 for all engines using shared memory. For each engine, this
info contains:

- total busyness: total time that the context was running (total)
- id: id of the running context (id)
- start timestamp: timestamp when the context started running (start)

At the time (now) of sampling the engine busyness, if the id is valid
(!= ~0), and start is non-zero, then the context is considered to be
active and the engine busyness is calculated using the below equation

engine busyness = total + (now - start)

All times are obtained from the gt clock base. For inactive contexts,
engine busyness is just equal to the total.

The start and total values provided by GuC are 32 bits and wrap around
in a few minutes. Since perf pmu provides busyness as 64 bit
monotonically increasing values, there is a need for this implementation
to account for overflows and extend the time to 64 bits before returning
busyness to the user. In order to do that, a worker runs periodically at
frequency = 1/8th the time it takes for the timestamp to wrap. As an
example, that would be once in 27 seconds for a gt clock frequency of
19.2 MHz.

Opens and wip that are targeted for later patches:

1) On global gt reset the total busyness of engines resets and i915
   needs to fix that so that user sees monotonically increasing
   busyness.
2) In runtime suspend mode, the worker may not need to be run. We could
   stop the worker on suspend and rerun it on resume provided that the
   guc pm timestamp does not tick during suspend.


Second point had now been addressed, right?


Both were addressed actually. For reset, I was mainly running busy-hang 
and after adding your suggestion of maintaining a consistent view, the 
busy-hang is fixed too.


I will remove them from the commit msg.





Note:
There might be an overaccounting of busyness due to the fact that GuC
may be updating the total and start values while kmd is reading them.
(i.e kmd may read the updated total and the stale start). In such a
case, user may see higher busyness value followed by smaller ones which
would eventually catch up to the higher value.

v2: (Tvrtko)
- Include details in commit message
- Move intel engine busyness function into execlist code
- Use union inside engine->stats
- Use natural type for ping delay jiffies
- Drop active_work condition checks
- Use for_each_engine if iterating all engines
- Drop seq locking, use spinlock at guc level to update engine stats
- Document worker specific details

v3: (Tvrtko/Umesh)
- Demarcate guc and execlist stat objects with comments
- Document known over-accounting issue in commit
- Provide a consistent view of guc state
- Add hooks to gt park/unpark for guc busyness
- Stop/start worker in gt park/unpark path
- Drop inline
- Move spinlock and worker inits to guc initialization
- Drop helpers that are called only once

Signed-off-by: John Harrison 
Signed-off-by: Umesh Nerlige Ramappa 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  26 +-
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  90 +--
 .../drm/i915/gt/intel_execlists_submission.c  |  32 +++
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |   2 +
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  26 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  21 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h|   5 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  13 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 227 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.h |   2 +
 drivers/gpu/drm/i915/i915_reg.h   |   2 +
 12 files changed, 398 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 2ae57e4656a3..6fcc70a313d9 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -1873,22 +1873,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,
intel_engine_print_breadcrumbs(engine, m);
 }
-static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine,
-   ktime_t *now)
-{
-   ktime_t total = engine->stats.total;
-
-   /*
-* If the engine is executing something at the moment
-* add it to the total.
-*/
-   *now = ktime_get();
-   if (READ_ONCE(engine->stats.active))
-   total = ktime_add(total, ktime_sub(*now, engine->stats.start));
-
-   return total;
-}
-
 /**
  * intel_engine_get_busy_time() - Return current accumulated engine busyness
  * @engine: engine to report on
@@ -1898,15 +1882,7 @@ static 

[pull] amdgpu, amdkfd drm-fixes-5.15

2021-10-06 Thread Alex Deucher
Hi Dave, Daniel,

Fixes for 5.15.

The following changes since commit 9e1ff307c779ce1f0f810c7ecce3d95bbae40896:

  Linux 5.15-rc4 (2021-10-03 14:08:47 -0700)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-5.15-2021-10-06

for you to fetch changes up to 5a1fef027846e7635b9d320b2cc0b416fd11a3be:

  drm/amd/display: Fix detection of 4 lane for DPALT (2021-10-06 16:14:17 -0400)


amd-drm-fixes-5.15-2021-10-06:

amdgpu:
- DCN 3.1 DP alt mode fixes
- S0ix gfxoff fix
- Fix DRM_AMD_DC_SI dependencies
- PCIe DPC handling fix
- DCN 3.1 scaling fix
- Documentation fix

amdkfd:
- Fix potential memory leak
- IOMMUv2 init fixes


Alex Deucher (2):
  Documentation/gpu: remove spurious "+" in amdgpu.rst
  drm/amdgpu/display: fix dependencies for DRM_AMD_DC_SI

George Shen (1):
  drm/amd/display: Skip override for preferred link settings during link 
training

Guchun Chen (1):
  drm/amdgpu: handle the case of pci_channel_io_frozen only in 
amdgpu_pci_resume

Hansen (1):
  drm/amd/display: Fix detection of 4 lane for DPALT

Jude Shih (1):
  drm/amd/display: USB4 bring up set correct address

Lang Yu (1):
  drm/amdkfd: fix a potential ttm->sg memory leak

Lijo Lazar (1):
  drm/amdgpu: During s0ix don't wait to signal GFXOFF

Liu, Zhan (2):
  drm/amd/display: Fix B0 USB-C DP Alt mode
  drm/amd/display: Fix DCN3 B0 DP Alt Mapping

Nikola Cornij (1):
  drm/amd/display: Limit display scaling to up to 4k for DCN 3.1

Yifan Zhang (2):
  drm/amdkfd: remove redundant iommu cleanup code
  drm/amdgpu: init iommu after amdkfd device init

 Documentation/gpu/amdgpu.rst   |  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c   |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 14 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c| 14 -
 drivers/gpu/drm/amd/amdkfd/kfd_device.c|  8 +--
 drivers/gpu/drm/amd/display/Kconfig|  2 +
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |  6 --
 .../drm/amd/display/dc/dcn10/dcn10_link_encoder.h  |  1 +
 .../amd/display/dc/dcn31/dcn31_dio_link_encoder.c  | 66 +-
 .../amd/display/dc/dcn31/dcn31_dio_link_encoder.h  | 14 -
 .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c  |  8 ++-
 drivers/gpu/drm/amd/display/include/dal_asic_id.h  |  2 +-
 .../amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h  | 27 +
 14 files changed, 142 insertions(+), 26 deletions(-)


Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-06 Thread Bjorn Andersson
On Wed 06 Oct 11:59 PDT 2021, Stephen Boyd wrote:

> Quoting Bjorn Andersson (2021-10-06 11:05:09)
> > On Wed 06 Oct 10:19 PDT 2021, Stephen Boyd wrote:
> >
> > > Quoting Bjorn Andersson (2021-10-06 10:07:17)
> > > > On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:
> > > >
> > > > > Quoting Bjorn Andersson (2021-10-05 19:37:52)
> > > > > > On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:
> > > > > >
> > > > > > > Quoting Bjorn Andersson (2021-10-05 18:43:16)
> > > > > > > > On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:
> > > > > > > >
> > > > > > > > > Quoting Bjorn Andersson (2021-10-05 16:13:21)
> > > > > > > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > > > > > > > > > b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > > index bdaf227f05dc..674cddfee5b0 100644
> > > > > > > > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > > @@ -1233,7 +1239,7 @@ static int dp_display_probe(struct 
> > > > > > > > > > platform_device *pdev)
> > > > > > > > > > if (!dp)
> > > > > > > > > > return -ENOMEM;
> > > > > > > > > >
> > > > > > > > > > -   desc = dp_display_get_desc(pdev);
> > > > > > > > > > +   desc = dp_display_get_desc(pdev, >id);
> > > > > > > > >
> > > > > > > > > I'm sad that dp->id has to match the number in the SoC 
> > > > > > > > > specific
> > > > > > > > > dpu_intf_cfg array in 
> > > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > > > > > > > > still. Is there any way we can avoid that? Also, notice how 
> > > > > > > > > those arrays
> > > > > > > > > already have INTF_DP macros, which makes me think that it may 
> > > > > > > > > be better
> > > > > > > > > to connect this to those arrays instead of making an 
> > > > > > > > > msm_dp_desc
> > > > > > > > > structure and then make sure the 'type' member matches a 
> > > > > > > > > connector
> > > > > > > > > type number. Otherwise this code is super fragile.
> > > > > > > > >
> > > > > > > >
> > > > > > > > I'm afraid I don't understand what you're proposing. Or which 
> > > > > > > > part you
> > > > > > > > consider fragile, the indices of the INTF_DP instances aren't 
> > > > > > > > going to
> > > > > > > > move around...
> > > > > > > >
> > > > > > > > I have N instances of the DP driver that I need to match to N 
> > > > > > > > entries
> > > > > > > > from the platform specific intf array, I need some stable 
> > > > > > > > reference
> > > > > > > > between them. When I started this journey I figured I could 
> > > > > > > > rely on the
> > > > > > > > of_graph between the DPU and the interface controllers, but the 
> > > > > > > > values
> > > > > > > > used there today are just bogus, so that was a no go.
> > > > > > > >
> > > > > > > > We can use whatever, as long as 
> > > > > > > > _dpu_kms_initialize_displayport() can
> > > > > > > > come up with an identifier to put in h_tile_instance[0] so that
> > > > > > > > dpu_encoder_setup_display() can find the relevant INTF.
> > > > > > > >
> > > > > > >
> > > > > > > To make it more concrete we can look at sc7180
> > > > > > >
> > > > > > > static const struct dpu_intf_cfg sc7180_intf[] = {
> > > > > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
> > > > > > > INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > > > >  ^
> > > > > > >  |
> > > > > > >
> > > > > > > intf0 is irrelevant. Also the address is irrelevant. But here we 
> > > > > > > have a
> > > > > > > zero, the number after INTF_DP, and that is very relevant. That 
> > > > > > > number
> > > > > > > needs to match the dp->id. Somewhere we have a match between
> > > > > > > controller_id and dp->id in the code.
> > > > > >
> > > > > > That number (the 0, not INTF_0) is what the code matches against 
> > > > > > dp->id
> > > > > > in _dpu_kms_initialize_displayport(), in order to figure out that 
> > > > > > this
> > > > > > is INTF_0 in dpu_encoder_setup_display().
> > > > > >
> > > > > > I.e. look at the sc8180x patch:
> > > > > >
> > > > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, 
> > > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > > > INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, 
> > > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> > > > > > INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, 
> > > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> > > > > > /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index 
> > > > > > until this is supported */
> > > > > > INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, 
> > > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> > > > > > INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, 
> > > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
> > > > > > INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, 
> > > > > > INTF_SC8180X_MASK, 

Re: [PATCH v2 2/3] dt-bindings: drm/bridge: ps8640: Add aux-bus child

2021-10-06 Thread Rob Herring
On Wed, 29 Sep 2021 17:34:57 -0700, Philip Chen wrote:
> dp-aux-bus.yaml says we can list an eDP panel as a child of
> an eDP controller node to represent the fact that the panel
> is connected to the controller's DP AUX bus.
> 
> Let's add it to the ps8640 bindings.
> 
> Signed-off-by: Philip Chen 
> ---
> 
> (no changes since v1)
> 
>  .../bindings/display/bridge/ps8640.yaml   | 19 ++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring 


Re: [Nouveau] [PATCH v3 2/5] drm/nouveau/kms/nv50-: Explicitly check DPCD backlights for aux enable/brightness

2021-10-06 Thread Lyude Paul
On Wed, 2021-10-06 at 18:30 +0200, Karol Herbst wrote:
> On Wed, Oct 6, 2021 at 4:41 AM Lyude Paul  wrote:
> > 
> > Since we don't support hybrid AUX/PWM backlights in nouveau right now,
> > let's add some explicit checks so that we don't break nouveau once we
> > enable support for these backlights in other drivers.
> > 
> > Signed-off-by: Lyude Paul 
> > ---
> >  drivers/gpu/drm/nouveau/nouveau_backlight.c | 5 -
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> > b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> > index 1cbd71abc80a..ae2f2abc8f5a 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> > @@ -308,7 +308,10 @@ nv50_backlight_init(struct nouveau_backlight *bl,
> >     if (ret < 0)
> >     return ret;
> > 
> > -   if (drm_edp_backlight_supported(edp_dpcd)) {
> > +   /* TODO: Add support for hybrid PWM/DPCD panels */
> > +   if (drm_edp_backlight_supported(edp_dpcd) &&
> > +   (edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
> 
> where does the DP_EDP_BACKLIGHT_AUX_ENABLE_CAP come from? afaik
> drm_edp_backlight_supported checks for
> DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP and
> DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP so wondering if this was
> intentional or a typo

This is intentional - drm_edp_backlight_supported() does check for these, but
in the patch after this we remove the BRIGHTNESS_AUX_SET_CAP from
drm_edp_backlight_supported() in order to implement support for panels lacking
BRIGHTNESS_AUX_SET_CAP in i915. Since we don't have support for this in
nouveau yet but such backlights are likely to mostly work without the use of
DPCD if we avoid trying to set it up, this patch is just here to make sure
that the changes to drm_edp_backlight_supported() don't result in nouveau
suddenly trying (and failing) to enable DPCD backlight controls on those
backlights.

> 
> > +   (edp_dpcd[2] &
> > DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) {
> >     NV_DEBUG(drm, "DPCD backlight controls supported
> > on %s\n",
> >  nv_conn->base.name);
> > 
> > --
> > 2.31.1
> > 
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [PATCH v2] dt-bindings: display/bridge: sil, sii8620: Convert to YAML binding

2021-10-06 Thread Andrzej Hajda

On 06.10.2021 17:04, AngeloGioacchino Del Regno wrote:

Convert the Silicon Image SiI8620 HDMI/MHL bridge documentation to YAML.

Signed-off-by: AngeloGioacchino Del Regno 

---
  .../bindings/display/bridge/sil,sii8620.yaml  | 93 +++
  .../bindings/display/bridge/sil-sii8620.txt   | 33 ---
  2 files changed, 93 insertions(+), 33 deletions(-)
  create mode 100644 
Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml
  delete mode 100644 
Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt

diff --git a/Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml 
b/Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml
new file mode 100644
index ..5a38595b6687
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/sil,sii8620.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Silicon Image SiI8620 HDMI/MHL bridge
+
+maintainers:
+  - Andrzej Hajda 
+
+properties:
+  compatible:
+const: sil,sii8620
+
+  reg:
+description: I2C address of the bridge
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  clock-names:
+const: xtal
+
+  cvcc10-supply:
+description: Digital Core Supply Voltage, 1.0V
+
+  iovcc18-supply:
+description: I/O voltage supply, 1.8V
+
+  interrupts:
+maxItems: 1
+
+  reset-gpios:
+description: GPIO connected to the reset pin.
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Video port for HDMI input
+
+required:
+  - port@0
+
+required:
+  - compatible
+  - reg
+  - cvcc10-supply
+  - iovcc18-supply
+  - interrupts
+  - ports


What about gpios and other missing props.
With that fixed you can add my r-b.

Regards
Andrzej



+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+i2c1 {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  bridge@39 {
+compatible = "sil,sii8620";
+reg = <0x39>;
+cvcc10-supply = <_reg>;
+iovcc18-supply = <_reg>;
+interrupt-parent = <>;
+interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+reset-gpios = < 0 GPIO_ACTIVE_HIGH>;
+
+ports {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  port@0 {
+reg = <0>;
+mhl_to_hdmi: endpoint {
+  remote-endpoint = <_to_mhl>;
+};
+  };
+};
+  };
+};
+
+...
diff --git a/Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt 
b/Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt
deleted file mode 100644
index b05052f7d62f..
--- a/Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Silicon Image SiI8620 HDMI/MHL bridge bindings
-
-Required properties:
-   - compatible: "sil,sii8620"
-   - reg: i2c address of the bridge
-   - cvcc10-supply: Digital Core Supply Voltage (1.0V)
-   - iovcc18-supply: I/O Supply Voltage (1.8V)
-   - interrupts: interrupt specifier of INT pin
-   - reset-gpios: gpio specifier of RESET pin
-   - clocks, clock-names: specification and name of "xtal" clock
-   - video interfaces: Device node can contain video interface port
-   node for HDMI encoder according to [1].
-
-[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
-
-Example:
-   sii8620@39 {
-   reg = <0x39>;
-   compatible = "sil,sii8620";
-   cvcc10-supply = <_reg>;
-   iovcc18-supply = <_reg>;
-   interrupt-parent = <>;
-   interrupts = <2 0>;
-   reset-gpio = < 0 0>;
-   clocks = <_system_controller 0>;
-   clock-names = "xtal";
-
-   port {
-   mhl_to_hdmi: endpoint {
-   remote-endpoint = <_to_mhl>;
-   };
-   };
-   };





[PATCH v2 30/34] sound: hdac: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Jaroslav Kysela 
Cc: Takashi Iwai 
Cc: Kai Vehmanen 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 sound/hda/hdac_component.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c
index bb37e7e0bd79..9e4dab97f485 100644
--- a/sound/hda/hdac_component.c
+++ b/sound/hda/hdac_component.c
@@ -181,8 +181,9 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, 
hda_nid_t nid, int dev_id,
 }
 EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
 
-static int hdac_component_master_bind(struct device *dev)
+static int hdac_component_master_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_audio_component *acomp = hdac_get_acomp(dev);
int ret;
 
@@ -222,8 +223,9 @@ static int hdac_component_master_bind(struct device *dev)
return ret;
 }
 
-static void hdac_component_master_unbind(struct device *dev)
+static void hdac_component_master_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_audio_component *acomp = hdac_get_acomp(dev);
 
if (acomp->audio_ops && acomp->audio_ops->master_unbind)
@@ -233,9 +235,13 @@ static void hdac_component_master_unbind(struct device 
*dev)
WARN_ON(acomp->ops || acomp->dev);
 }
 
-static const struct component_master_ops hdac_component_master_ops = {
-   .bind = hdac_component_master_bind,
-   .unbind = hdac_component_master_unbind,
+static struct aggregate_driver hdac_aggregate_driver = {
+   .probe = hdac_component_master_bind,
+   .remove = hdac_component_master_unbind,
+   .driver = {
+   .name = "hdac_agg",
+   .owner = THIS_MODULE,
+   },
 };
 
 /**
@@ -303,8 +309,7 @@ int snd_hdac_acomp_init(struct hdac_bus *bus,
devres_add(dev, acomp);
 
component_match_add_typed(dev, , match_master, bus);
-   ret = component_master_add_with_match(dev, _component_master_ops,
- match);
+   ret = component_aggregate_register(dev, _aggregate_driver, match);
if (ret < 0)
goto out_err;
 
@@ -344,7 +349,7 @@ int snd_hdac_acomp_exit(struct hdac_bus *bus)
bus->display_power_active = 0;
bus->display_power_status = 0;
 
-   component_master_del(dev, _component_master_ops);
+   component_aggregate_unregister(dev, _aggregate_driver);
 
bus->audio_component = NULL;
devres_destroy(dev, hdac_acomp_release, NULL, NULL);
-- 
https://chromeos.dev



[PATCH v2 34/34] component: Remove all references to 'master'

2021-10-06 Thread Stephen Boyd
Remove all references to 'master' in the code now that we've migrated
all the users of the ops structure to the aggregate driver.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/base/component.c | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 939862b25b10..75323d35773c 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -1,11 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Componentized device handling.
- *
- * This is work in progress.  We gather up the component devices into a list,
- * and bind them when instructed.  At the moment, we're specific to the DRM
- * subsystem, and only handles one master device, but this doesn't have to be
- * the case.
  */
 #include 
 #include 
@@ -119,23 +114,23 @@ static int __init component_debug_init(void)
 
 core_initcall(component_debug_init);
 
-static void component_master_debugfs_add(struct aggregate_device *m)
+static void component_debugfs_add(struct aggregate_device *m)
 {
debugfs_create_file(dev_name(m->parent), 0444, component_debugfs_dir, m,
_devices_fops);
 }
 
-static void component_master_debugfs_del(struct aggregate_device *m)
+static void component_debugfs_del(struct aggregate_device *m)
 {
debugfs_remove(debugfs_lookup(dev_name(m->parent), 
component_debugfs_dir));
 }
 
 #else
 
-static void component_master_debugfs_add(struct aggregate_device *m)
+static void component_debugfs_add(struct aggregate_device *m)
 { }
 
-static void component_master_debugfs_del(struct aggregate_device *m)
+static void component_debugfs_del(struct aggregate_device *m)
 { }
 
 #endif
@@ -343,7 +338,7 @@ EXPORT_SYMBOL(component_match_add_release);
  * @compare_typed: compare function to match against all typed components
  * @compare_data: opaque pointer passed to the @compare function
  *
- * Adds a new component match to the list stored in @matchptr, which the 
@master
+ * Adds a new component match to the list stored in @matchptr, which the
  * aggregate driver needs to function. The list of component matches pointed to
  * by @matchptr must be initialized to NULL before adding the first match. This
  * only matches against components added with component_add_typed().
@@ -367,7 +362,7 @@ static void free_aggregate_device(struct aggregate_device 
*adev)
struct component_match *match = adev->match;
int i;
 
-   component_master_debugfs_del(adev);
+   component_debugfs_del(adev);
 
if (match) {
for (i = 0; i < match->num; i++) {
@@ -548,7 +543,7 @@ static struct aggregate_device *aggregate_device_add(struct 
device *parent,
return ERR_PTR(ret);
}
 
-   component_master_debugfs_add(adev);
+   component_debugfs_add(adev);
 
return adev;
 }
-- 
https://chromeos.dev



[PATCH v2 28/34] power: supply: ab8500: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Sebastian Reichel 
Cc: 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/power/supply/ab8500_charger.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/power/supply/ab8500_charger.c 
b/drivers/power/supply/ab8500_charger.c
index 15eadaf46f14..52d4105e28f2 100644
--- a/drivers/power/supply/ab8500_charger.c
+++ b/drivers/power/supply/ab8500_charger.c
@@ -3312,8 +3312,9 @@ static const struct power_supply_desc ab8500_usb_chg_desc 
= {
.get_property   = ab8500_charger_usb_get_property,
 };
 
-static int ab8500_charger_bind(struct device *dev)
+static int ab8500_charger_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct ab8500_charger *di = dev_get_drvdata(dev);
int ch_stat;
int ret;
@@ -3354,8 +3355,9 @@ static int ab8500_charger_bind(struct device *dev)
return 0;
 }
 
-static void ab8500_charger_unbind(struct device *dev)
+static void ab8500_charger_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct ab8500_charger *di = dev_get_drvdata(dev);
int ret;
 
@@ -3380,9 +3382,13 @@ static void ab8500_charger_unbind(struct device *dev)
component_unbind_all(dev, di);
 }
 
-static const struct component_master_ops ab8500_charger_comp_ops = {
-   .bind = ab8500_charger_bind,
-   .unbind = ab8500_charger_unbind,
+static struct aggregate_driver ab8500_charger_aggregate_driver = {
+   .probe = ab8500_charger_bind,
+   .remove = ab8500_charger_unbind,
+   .driver = {
+   .name = "ab8500_charger_agg",
+   .owner = THIS_MODULE,
+   },
 };
 
 static struct platform_driver *const ab8500_charger_component_drivers[] = {
@@ -3663,9 +3669,7 @@ static int ab8500_charger_probe(struct platform_device 
*pdev)
}
 
 
-   ret = component_master_add_with_match(>dev,
- _charger_comp_ops,
- match);
+   ret = component_aggregate_register(>dev, 
_charger_aggregate_driver, match);
if (ret) {
dev_err(dev, "failed to add component master\n");
goto free_notifier;
@@ -3688,7 +3692,7 @@ static int ab8500_charger_remove(struct platform_device 
*pdev)
 {
struct ab8500_charger *di = platform_get_drvdata(pdev);
 
-   component_master_del(>dev, _charger_comp_ops);
+   component_aggregate_unregister(>dev, 
_charger_aggregate_driver);
 
usb_unregister_notifier(di->usb_phy, >nb);
usb_put_phy(di->usb_phy);
-- 
https://chromeos.dev



[PATCH v2 25/34] drm/zte: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/zte/zx_drm_drv.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
index 064056503ebb..b46f677ea51d 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.c
+++ b/drivers/gpu/drm/zte/zx_drm_drv.c
@@ -45,8 +45,9 @@ static const struct drm_driver zx_drm_driver = {
.minor = 0,
 };
 
-static int zx_drm_bind(struct device *dev)
+static int zx_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm;
int ret;
 
@@ -97,8 +98,9 @@ static int zx_drm_bind(struct device *dev)
return ret;
 }
 
-static void zx_drm_unbind(struct device *dev)
+static void zx_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
 
drm_dev_unregister(drm);
@@ -110,9 +112,13 @@ static void zx_drm_unbind(struct device *dev)
drm_dev_put(drm);
 }
 
-static const struct component_master_ops zx_drm_master_ops = {
-   .bind = zx_drm_bind,
-   .unbind = zx_drm_unbind,
+static struct aggregate_driver zx_aggregate_driver = {
+   .probe = zx_drm_bind,
+   .remove = zx_drm_unbind,
+   .driver = {
+   .name = "zx_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int compare_of(struct device *dev, void *data)
@@ -135,12 +141,12 @@ static int zx_drm_probe(struct platform_device *pdev)
for_each_available_child_of_node(parent, child)
component_match_add(dev, , compare_of, child);
 
-   return component_master_add_with_match(dev, _drm_master_ops, match);
+   return component_aggregate_register(dev, _aggregate_driver, match);
 }
 
 static int zx_drm_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _drm_master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 29/34] fbdev: omap2: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: 
Cc: 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/video/fbdev/omap2/omapfb/dss/dss.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.c 
b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
index a6b1c1598040..f12663c39ceb 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
@@ -1067,8 +1067,9 @@ static int dss_video_pll_probe(struct platform_device 
*pdev)
 }
 
 /* DSS HW IP initialisation */
-static int dss_bind(struct device *dev)
+static int dss_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct platform_device *pdev = to_platform_device(dev);
struct resource *dss_mem;
u32 rev;
@@ -1167,8 +1168,9 @@ static int dss_bind(struct device *dev)
return r;
 }
 
-static void dss_unbind(struct device *dev)
+static void dss_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct platform_device *pdev = to_platform_device(dev);
 
dss_initialized = false;
@@ -1188,9 +1190,13 @@ static void dss_unbind(struct device *dev)
dss_put_clocks();
 }
 
-static const struct component_master_ops dss_component_ops = {
-   .bind = dss_bind,
-   .unbind = dss_unbind,
+static struct aggregate_driver dss_aggregate_driver = {
+   .probe = dss_bind,
+   .remove = dss_unbind,
+   .driver = {
+   .name = "dss_fbdev",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int dss_component_compare(struct device *dev, void *data)
@@ -1225,7 +1231,7 @@ static int dss_probe(struct platform_device *pdev)
/* add all the child devices as components */
device_for_each_child(>dev, , dss_add_child_component);
 
-   r = component_master_add_with_match(>dev, _component_ops, 
match);
+   r = component_aggregate_register(>dev, _aggregate_driver, 
match);
if (r)
return r;
 
@@ -1234,7 +1240,7 @@ static int dss_probe(struct platform_device *pdev)
 
 static int dss_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _component_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 31/34] ASoC: codecs: wcd938x: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Mark Brown 
Cc: Jaroslav Kysela 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 sound/soc/codecs/wcd938x.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
index f0daf8defcf1..6033de7f57ef 100644
--- a/sound/soc/codecs/wcd938x.c
+++ b/sound/soc/codecs/wcd938x.c
@@ -4316,8 +4316,9 @@ static struct snd_soc_dai_driver wcd938x_dais[] = {
},
 };
 
-static int wcd938x_bind(struct device *dev)
+static int wcd938x_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
int ret;
 
@@ -4400,8 +4401,9 @@ static int wcd938x_bind(struct device *dev)
 
 }
 
-static void wcd938x_unbind(struct device *dev)
+static void wcd938x_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
 
device_link_remove(dev, wcd938x->txdev);
@@ -4411,9 +4413,13 @@ static void wcd938x_unbind(struct device *dev)
component_unbind_all(dev, wcd938x);
 }
 
-static const struct component_master_ops wcd938x_comp_ops = {
-   .bind   = wcd938x_bind,
-   .unbind = wcd938x_unbind,
+static struct aggregate_driver wcd938x_aggregate_driver = {
+   .probe  = wcd938x_bind,
+   .remove = wcd938x_unbind,
+   .driver = {
+   .name = "wcd938x_snd",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int wcd938x_compare_of(struct device *dev, void *data)
@@ -4482,7 +4488,7 @@ static int wcd938x_probe(struct platform_device *pdev)
 
wcd938x_reset(wcd938x);
 
-   ret = component_master_add_with_match(dev, _comp_ops, match);
+   ret = component_aggregate_register(dev, _aggregate_driver, 
match);
if (ret)
return ret;
 
@@ -4498,7 +4504,7 @@ static int wcd938x_probe(struct platform_device *pdev)
 
 static int wcd938x_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _comp_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
 
return 0;
 }
-- 
https://chromeos.dev



[PATCH v2 32/34] component: Get rid of drm_of_component_probe()

2021-10-06 Thread Stephen Boyd
There aren't any users anymore so drop it.

Cc: Laurent Pinchart 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/drm_of.c | 87 +---
 include/drm/drm_of.h | 12 --
 2 files changed, 20 insertions(+), 79 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 58db65ad2770..78fe2b809872 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -99,18 +99,30 @@ void drm_of_component_match_add(struct device *master,
 }
 EXPORT_SYMBOL_GPL(drm_of_component_match_add);
 
-static int _drm_of_component_probe(struct device *dev,
-  int (*compare_of)(struct device *, void *),
-  struct component_match **matchptr)
+/**
+ * drm_of_aggregate_probe - Generic probe function for a component based 
aggregate host
+ * @dev: device containing the OF node
+ * @compare_of: compare function used for matching components
+ * @adrv: aggregate driver to be used
+ *
+ * Parse the platform device OF node and bind all the components associated
+ * with the aggregate device. Interface ports are added before the encoders in
+ * order to satisfy their .bind_component requirements
+ * See Documentation/devicetree/bindings/graph.txt for the bindings.
+ *
+ * Returns zero if successful, or one of the standard error codes if it fails.
+ */
+static int drm_of_aggregate_probe(struct device *dev,
+ int (*compare_of)(struct device *, void *),
+ struct aggregate_driver *adrv)
 {
struct device_node *ep, *port, *remote;
+   struct component_match *match = NULL;
int i;
 
if (!dev->of_node)
return -EINVAL;
 
-   *matchptr = NULL;
-
/*
 * Bind the crtc's ports first, so that drm_of_find_possible_crtcs()
 * called from encoder's .bind callbacks works as expected
@@ -121,7 +133,7 @@ static int _drm_of_component_probe(struct device *dev,
break;
 
if (of_device_is_available(port->parent))
-   drm_of_component_match_add(dev, matchptr, compare_of,
+   drm_of_component_match_add(dev, , compare_of,
   port);
 
of_node_put(port);
@@ -132,7 +144,7 @@ static int _drm_of_component_probe(struct device *dev,
return -ENODEV;
}
 
-   if (!*matchptr) {
+   if (!match) {
dev_err(dev, "no available port\n");
return -ENODEV;
}
@@ -162,72 +174,13 @@ static int _drm_of_component_probe(struct device *dev,
continue;
}
 
-   drm_of_component_match_add(dev, matchptr, compare_of,
+   drm_of_component_match_add(dev, , compare_of,
   remote);
of_node_put(remote);
}
of_node_put(port);
}
 
-   return 0;
-}
-
-/**
- * drm_of_component_probe - Generic probe function for a component based master
- * @dev: master device containing the OF node
- * @compare_of: compare function used for matching components
- * @m_ops: component master ops to be used
- *
- * Parse the platform device OF node and bind all the components associated
- * with the master. Interface ports are added before the encoders in order to
- * satisfy their .bind requirements
- * See Documentation/devicetree/bindings/graph.txt for the bindings.
- *
- * Deprecated: Use drm_of_aggregate_probe() instead.
- *
- * Returns zero if successful, or one of the standard error codes if it fails.
- */
-static int drm_of_component_probe(struct device *dev,
-  int (*compare_of)(struct device *, void *),
-  const struct component_master_ops *m_ops)
-{
-
-   struct component_match *match;
-   int ret;
-
-   ret = _drm_of_component_probe(dev, compare_of, );
-   if (ret)
-   return ret;
-
-   return component_master_add_with_match(dev, m_ops, match);
-}
-EXPORT_SYMBOL(drm_of_component_probe);
-
-
-/**
- * drm_of_aggregate_probe - Generic probe function for a component based 
aggregate host
- * @dev: device containing the OF node
- * @compare_of: compare function used for matching components
- * @adrv: aggregate driver to be used
- *
- * Parse the platform device OF node and bind all the components associated
- * with the aggregate device. Interface ports are added before the encoders in
- * order to satisfy their .bind_component requirements
- * See Documentation/devicetree/bindings/graph.txt for the bindings.
- *
- * Returns zero if successful, or one of the standard error codes if it fails.
- */
-static int drm_of_aggregate_probe(struct device *dev,
-  

[PATCH v2 23/34] drm/tilcdc: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Jyri Sarha 
Cc: Tomi Valkeinen 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 6b03f89a98d4..d5c6567eec8d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -531,13 +531,16 @@ static const struct dev_pm_ops tilcdc_pm_ops = {
 /*
  * Platform driver:
  */
-static int tilcdc_bind(struct device *dev)
+static int tilcdc_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
+
return tilcdc_init(_driver, dev);
 }
 
-static void tilcdc_unbind(struct device *dev)
+static void tilcdc_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *ddev = dev_get_drvdata(dev);
 
/* Check if a subcomponent has already triggered the unloading. */
@@ -547,9 +550,13 @@ static void tilcdc_unbind(struct device *dev)
tilcdc_fini(dev_get_drvdata(dev));
 }
 
-static const struct component_master_ops tilcdc_comp_ops = {
-   .bind = tilcdc_bind,
-   .unbind = tilcdc_unbind,
+static struct aggregate_driver tilcdc_aggregate_driver = {
+   .probe = tilcdc_bind,
+   .remove = tilcdc_unbind,
+   .driver = {
+   .name = "tilcdc_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int tilcdc_pdev_probe(struct platform_device *pdev)
@@ -566,12 +573,9 @@ static int tilcdc_pdev_probe(struct platform_device *pdev)
ret = tilcdc_get_external_components(>dev, );
if (ret < 0)
return ret;
-   else if (ret == 0)
+   if (ret == 0)
return tilcdc_init(_driver, >dev);
-   else
-   return component_master_add_with_match(>dev,
-  _comp_ops,
-  match);
+   return component_aggregate_register(>dev, 
_aggregate_driver, match);
 }
 
 static int tilcdc_pdev_remove(struct platform_device *pdev)
@@ -581,10 +585,10 @@ static int tilcdc_pdev_remove(struct platform_device 
*pdev)
ret = tilcdc_get_external_components(>dev, NULL);
if (ret < 0)
return ret;
-   else if (ret == 0)
+   if (ret == 0)
tilcdc_fini(platform_get_drvdata(pdev));
else
-   component_master_del(>dev, _comp_ops);
+   component_aggregate_unregister(>dev, 
_aggregate_driver);
 
return 0;
 }
-- 
https://chromeos.dev



[PATCH v2 24/34] drm/vc4: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Emma Anholt 
Cc: Maxime Ripard 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/vc4/vc4_drv.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index f6c16c5aee68..bccbde7a2f59 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -214,8 +214,9 @@ static void vc4_match_add_drivers(struct device *dev,
}
 }
 
-static int vc4_drm_bind(struct device *dev)
+static int vc4_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm;
struct vc4_dev *vc4;
@@ -286,8 +287,9 @@ static int vc4_drm_bind(struct device *dev)
return ret;
 }
 
-static void vc4_drm_unbind(struct device *dev)
+static void vc4_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
 
drm_dev_unregister(drm);
@@ -295,9 +297,13 @@ static void vc4_drm_unbind(struct device *dev)
drm_atomic_helper_shutdown(drm);
 }
 
-static const struct component_master_ops vc4_drm_ops = {
-   .bind = vc4_drm_bind,
-   .unbind = vc4_drm_unbind,
+static struct aggregate_driver vc4_aggregate_driver = {
+   .probe = vc4_drm_bind,
+   .remove = vc4_drm_unbind,
+   .driver = {
+   .name = "vc4_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 /*
@@ -328,12 +334,12 @@ static int vc4_platform_drm_probe(struct platform_device 
*pdev)
vc4_match_add_drivers(dev, ,
  component_drivers, ARRAY_SIZE(component_drivers));
 
-   return component_master_add_with_match(dev, _drm_ops, match);
+   return component_aggregate_register(dev, _aggregate_driver, match);
 }
 
 static int vc4_platform_drm_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _drm_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
 
return 0;
 }
-- 
https://chromeos.dev



[PATCH v2 26/34] iommu/mtk: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Yong Wu 
Cc: Joerg Roedel 
Cc: Will Deacon 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/iommu/mtk_iommu.c| 14 +-
 drivers/iommu/mtk_iommu.h|  6 --
 drivers/iommu/mtk_iommu_v1.c | 14 +-
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index d837adfd1da5..8b303c388a9b 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -750,9 +750,13 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
return 0;
 }
 
-static const struct component_master_ops mtk_iommu_com_ops = {
-   .bind   = mtk_iommu_bind,
-   .unbind = mtk_iommu_unbind,
+static struct aggregate_driver mtk_iommu_aggregate_driver = {
+   .probe  = mtk_iommu_bind,
+   .remove = mtk_iommu_unbind,
+   .driver = {
+   .name   = "mtk_iommu_agg",
+   .owner  = THIS_MODULE,
+   },
 };
 
 static int mtk_iommu_probe(struct platform_device *pdev)
@@ -893,7 +897,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
goto out_list_del;
}
 
-   ret = component_master_add_with_match(dev, _iommu_com_ops, match);
+   ret = component_aggregate_register(dev, _iommu_aggregate_driver, 
match);
if (ret)
goto out_bus_set_null;
return ret;
@@ -926,7 +930,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
device_link_remove(data->smicomm_dev, >dev);
pm_runtime_disable(>dev);
devm_free_irq(>dev, data->irq, data);
-   component_master_del(>dev, _iommu_com_ops);
+   component_aggregate_unregister(>dev, _iommu_aggregate_driver);
return 0;
 }
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index f81fa8862ed0..064fd4f4eade 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -94,15 +94,17 @@ static inline void release_of(struct device *dev, void 
*data)
of_node_put(data);
 }
 
-static inline int mtk_iommu_bind(struct device *dev)
+static inline int mtk_iommu_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct mtk_iommu_data *data = dev_get_drvdata(dev);
 
return component_bind_all(dev, >larb_imu);
 }
 
-static inline void mtk_iommu_unbind(struct device *dev)
+static inline void mtk_iommu_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct mtk_iommu_data *data = dev_get_drvdata(dev);
 
component_unbind_all(dev, >larb_imu);
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index be22fcf988ce..5fb29058a165 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -534,9 +534,13 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
{}
 };
 
-static const struct component_master_ops mtk_iommu_com_ops = {
-   .bind   = mtk_iommu_bind,
-   .unbind = mtk_iommu_unbind,
+static struct aggregate_driver mtk_iommu_aggregate_driver = {
+   .probe  = mtk_iommu_bind,
+   .remove = mtk_iommu_unbind,
+   .driver = {
+   .name   = "mtk_iommu_agg",
+   .owner  = THIS_MODULE,
+   },
 };
 
 static int mtk_iommu_probe(struct platform_device *pdev)
@@ -624,7 +628,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
goto out_dev_unreg;
}
 
-   ret = component_master_add_with_match(dev, _iommu_com_ops, match);
+   ret = component_aggregate_register(dev, _iommu_aggregate_driver, 
match);
if (ret)
goto out_bus_set_null;
return ret;
@@ -650,7 +654,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 
clk_disable_unprepare(data->bclk);
devm_free_irq(>dev, data->irq, data);
-   component_master_del(>dev, _iommu_com_ops);
+   component_aggregate_unregister(>dev, _iommu_aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 33/34] component: Remove component_master_ops and friends

2021-10-06 Thread Stephen Boyd
The struct is unused now so drop it along with the functions that use
it.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/base/component.c  | 109 +++---
 drivers/gpu/drm/drm_drv.c |   2 +-
 include/linux/component.h |  45 
 3 files changed, 8 insertions(+), 148 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index a6dd33d0ddeb..939862b25b10 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -140,18 +140,12 @@ static void component_master_debugfs_del(struct 
aggregate_device *m)
 
 #endif
 
-struct aggregate_bus_find_data {
-   const struct component_master_ops *ops;
-   struct device *parent;
-};
-
 static int aggregate_bus_find_match(struct device *dev, const void *_data)
 {
struct aggregate_device *adev = to_aggregate_device(dev);
-   const struct aggregate_bus_find_data *data = _data;
+   const struct device *parent = _data;
 
-   if (adev->parent == data->parent &&
-   (!data->ops || adev->ops == data->ops))
+   if (adev->parent == parent)
return 1;
 
return 0;
@@ -496,16 +490,11 @@ static struct bus_type aggregate_bus_type = {
 };
 
 /* Callers take ownership of return value, should call put_device() */
-static struct aggregate_device *__aggregate_find(struct device *parent,
-   const struct component_master_ops *ops)
+static struct aggregate_device *__aggregate_find(struct device *parent)
 {
struct device *dev;
-   struct aggregate_bus_find_data data = {
-   .ops = ops,
-   .parent = parent,
-   };
 
-   dev = bus_find_device(_bus_type, NULL, ,
+   dev = bus_find_device(_bus_type, NULL, parent,
  aggregate_bus_find_match);
 
return dev ? to_aggregate_device(dev) : NULL;
@@ -523,7 +512,7 @@ static void aggregate_driver_unregister(struct 
aggregate_driver *adrv)
 }
 
 static struct aggregate_device *aggregate_device_add(struct device *parent,
-   const struct component_master_ops *ops, struct aggregate_driver *adrv,
+   struct aggregate_driver *adrv,
struct component_match *match)
 {
struct aggregate_device *adev;
@@ -564,54 +553,6 @@ static struct aggregate_device 
*aggregate_device_add(struct device *parent,
return adev;
 }
 
-/**
- * component_master_add_with_match - register an aggregate driver
- * @parent: parent device of the aggregate driver
- * @ops: callbacks for the aggregate driver
- * @match: component match list for the aggregate driver
- *
- * Registers a new aggregate driver consisting of the components added to 
@match
- * by calling one of the component_match_add() functions. Once all components 
in
- * @match are available, it will be assembled by calling
- * _master_ops.bind from @ops. Must be unregistered by calling
- * component_master_del().
- *
- * Deprecated: Use component_aggregate_register() instead.
- */
-int component_master_add_with_match(struct device *parent,
-   const struct component_master_ops *ops,
-   struct component_match *match)
-{
-   struct aggregate_driver *adrv;
-   struct aggregate_device *adev;
-   int ret = 0;
-
-   adrv = kzalloc(sizeof(*adrv), GFP_KERNEL);
-   if (!adrv)
-   return -ENOMEM;
-
-   adev = aggregate_device_add(parent, ops, adrv, match);
-   if (IS_ERR(adev)) {
-   ret = PTR_ERR(adev);
-   goto err;
-   }
-
-   adrv->probe = component_probe_bind;
-   adrv->remove = component_remove_unbind;
-   adrv->driver.owner = THIS_MODULE;
-   adrv->driver.name = dev_name(>dev);
-
-   ret = aggregate_driver_register(adrv);
-   if (!ret)
-   return 0;
-
-   put_device(>dev);
-err:
-   kfree(adrv);
-   return ret;
-}
-EXPORT_SYMBOL_GPL(component_master_add_with_match);
-
 /**
  * component_aggregate_register - register an aggregate driver
  * @parent: parent device of the aggregate driver
@@ -640,42 +581,6 @@ int component_aggregate_register(struct device *parent,
 }
 EXPORT_SYMBOL_GPL(component_aggregate_register);
 
-/**
- * component_master_del - unregister an aggregate driver
- * @parent: parent device of the aggregate driver
- * @ops: callbacks for the aggregate driver
- *
- * Unregisters an aggregate driver registered with
- * component_master_add_with_match(). If necessary the aggregate driver is 
first
- * disassembled by calling _master_ops.unbind from @ops.
- *
- * Deprecated: Use component_aggregate_unregister() instead.
- */
-void component_master_del(struct device *parent,
-   const struct component_master_ops *ops)
-{
-   struct aggregate_device *adev;
-   struct aggregate_driver *adrv;
-   struct device_driver *drv;
-
-   mutex_lock(_mutex);
-   adev = __aggregate_find(parent, ops);
-   mutex_unlock(_mutex);
-
-   if 

[PATCH v2 18/34] drm/meson: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Neil Armstrong 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/meson/meson_drv.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_drv.c 
b/drivers/gpu/drm/meson/meson_drv.c
index bc0d60df04ae..109fb9d057e3 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -357,13 +357,16 @@ static int meson_drv_bind_master(struct device *dev, bool 
has_components)
return ret;
 }
 
-static int meson_drv_bind(struct device *dev)
+static int meson_drv_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
+
return meson_drv_bind_master(dev, true);
 }
 
-static void meson_drv_unbind(struct device *dev)
+static void meson_drv_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct meson_drm *priv = dev_get_drvdata(dev);
struct drm_device *drm = priv->drm;
 
@@ -387,9 +390,13 @@ static void meson_drv_unbind(struct device *dev)
}
 }
 
-static const struct component_master_ops meson_drv_master_ops = {
-   .bind   = meson_drv_bind,
-   .unbind = meson_drv_unbind,
+static struct aggregate_driver meson_aggregate_drv = {
+   .probe  = meson_drv_bind,
+   .remove = meson_drv_unbind,
+   .driver = {
+   .name = "meson_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int __maybe_unused meson_drv_pm_suspend(struct device *dev)
@@ -503,9 +510,7 @@ static int meson_drv_probe(struct platform_device *pdev)
if (count) {
dev_info(>dev, "Queued %d outputs on vpu\n", count);
 
-   return component_master_add_with_match(>dev,
-  _drv_master_ops,
-  match);
+   return component_aggregate_register(>dev, 
_aggregate_drv, match);
}
 
/* If no output endpoints were available, simply bail out */
-- 
https://chromeos.dev



[PATCH v2 27/34] mei: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Tomas Winkler 
Cc: Arnd Bergmann 
Cc: Greg Kroah-Hartman 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/misc/mei/hdcp/mei_hdcp.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index ec2a4fce8581..79dcc02277d2 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -732,8 +732,9 @@ static const struct i915_hdcp_component_ops mei_hdcp_ops = {
.close_hdcp_session = mei_hdcp_close_session,
 };
 
-static int mei_component_master_bind(struct device *dev)
+static int mei_component_master_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct mei_cl_device *cldev = to_mei_cl_device(dev);
struct i915_hdcp_comp_master *comp_master =
mei_cldev_get_drvdata(cldev);
@@ -749,8 +750,9 @@ static int mei_component_master_bind(struct device *dev)
return 0;
 }
 
-static void mei_component_master_unbind(struct device *dev)
+static void mei_component_master_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct mei_cl_device *cldev = to_mei_cl_device(dev);
struct i915_hdcp_comp_master *comp_master =
mei_cldev_get_drvdata(cldev);
@@ -759,9 +761,13 @@ static void mei_component_master_unbind(struct device *dev)
component_unbind_all(dev, comp_master);
 }
 
-static const struct component_master_ops mei_component_master_ops = {
-   .bind = mei_component_master_bind,
-   .unbind = mei_component_master_unbind,
+static struct aggregate_driver mei_aggregate_driver = {
+   .probe = mei_component_master_bind,
+   .remove = mei_component_master_unbind,
+   .driver = {
+   .name = "mei_agg",
+   .owner = THIS_MODULE,
+   },
 };
 
 /**
@@ -826,9 +832,7 @@ static int mei_hdcp_probe(struct mei_cl_device *cldev,
}
 
mei_cldev_set_drvdata(cldev, comp_master);
-   ret = component_master_add_with_match(>dev,
- _component_master_ops,
- master_match);
+   ret = component_aggregate_register(>dev, _aggregate_driver, 
master_match);
if (ret < 0) {
dev_err(>dev, "Master comp add failed %d\n", ret);
goto err_exit;
@@ -850,7 +854,7 @@ static void mei_hdcp_remove(struct mei_cl_device *cldev)
mei_cldev_get_drvdata(cldev);
int ret;
 
-   component_master_del(>dev, _component_master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
kfree(comp_master);
mei_cldev_set_drvdata(cldev, NULL);
 
-- 
https://chromeos.dev



[PATCH v2 15/34] drm/ingenic: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

TODO: Move the helpers to PM in aggregate driver hooks.

Cc: Paul Cercueil 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 24 +--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index a5df1c8d34cd..058b7bfe5610 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -1150,8 +1150,10 @@ static int ingenic_drm_bind(struct device *dev, bool 
has_components)
return ret;
 }
 
-static int ingenic_drm_bind_with_components(struct device *dev)
+static int ingenic_drm_bind_with_components(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
+
return ingenic_drm_bind(dev, true);
 }
 
@@ -1174,9 +1176,19 @@ static void ingenic_drm_unbind(struct device *dev)
drm_atomic_helper_shutdown(>drm);
 }
 
-static const struct component_master_ops ingenic_master_ops = {
-   .bind = ingenic_drm_bind_with_components,
-   .unbind = ingenic_drm_unbind,
+static void ingenic_aggregate_remove(struct aggregate_device *adev)
+{
+   struct device *dev = adev->parent;
+   ingenic_drm_unbind(dev);
+}
+
+static struct aggregate_driver ingenic_aggregate_driver = {
+   .probe = ingenic_drm_bind_with_components,
+   .remove = ingenic_aggregate_remove,
+   .driver = {
+   .name = "ingenic_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int ingenic_drm_probe(struct platform_device *pdev)
@@ -1196,7 +1208,7 @@ static int ingenic_drm_probe(struct platform_device *pdev)
drm_of_component_match_add(dev, , compare_of, np);
of_node_put(np);
 
-   return component_master_add_with_match(dev, _master_ops, match);
+   return component_aggregate_register(dev, _aggregate_driver, 
match);
 }
 
 static int ingenic_drm_remove(struct platform_device *pdev)
@@ -1206,7 +1218,7 @@ static int ingenic_drm_remove(struct platform_device 
*pdev)
if (!IS_ENABLED(CONFIG_DRM_INGENIC_IPU))
ingenic_drm_unbind(dev);
else
-   component_master_del(dev, _master_ops);
+   component_aggregate_unregister(dev, _aggregate_driver);
 
return 0;
 }
-- 
https://chromeos.dev



[PATCH v2 17/34] drm/mediatek: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Chun-Kuang Hu 
Cc: Philipp Zabel 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index aec39724ebeb..a3f27b8c9769 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -348,8 +348,9 @@ static int compare_of(struct device *dev, void *data)
return dev->of_node == data;
 }
 
-static int mtk_drm_bind(struct device *dev)
+static int mtk_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct mtk_drm_private *private = dev_get_drvdata(dev);
struct drm_device *drm;
int ret;
@@ -380,8 +381,9 @@ static int mtk_drm_bind(struct device *dev)
return ret;
 }
 
-static void mtk_drm_unbind(struct device *dev)
+static void mtk_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct mtk_drm_private *private = dev_get_drvdata(dev);
 
drm_dev_unregister(private->drm);
@@ -391,9 +393,13 @@ static void mtk_drm_unbind(struct device *dev)
private->drm = NULL;
 }
 
-static const struct component_master_ops mtk_drm_ops = {
-   .bind   = mtk_drm_bind,
-   .unbind = mtk_drm_unbind,
+static struct aggregate_driver mtk_drm_aggregate_driver = {
+   .probe  = mtk_drm_bind,
+   .remove = mtk_drm_unbind,
+   .driver = {
+   .name   = "mtk_drm",
+   .owner  = THIS_MODULE,
+   },
 };
 
 static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
@@ -593,7 +599,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, private);
 
-   ret = component_master_add_with_match(dev, _drm_ops, match);
+   ret = component_aggregate_register(dev, _drm_aggregate_driver, 
match);
if (ret)
goto err_pm;
 
@@ -616,7 +622,7 @@ static int mtk_drm_remove(struct platform_device *pdev)
struct mtk_drm_private *private = platform_get_drvdata(pdev);
int i;
 
-   component_master_del(>dev, _drm_ops);
+   component_aggregate_unregister(>dev, _drm_aggregate_driver);
pm_runtime_disable(>dev);
of_node_put(private->mutex_node);
for (i = 0; i < DDP_COMPONENT_ID_MAX; i++)
-- 
https://chromeos.dev



[PATCH v2 16/34] drm/mcde: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/mcde/mcde_drv.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index e60566a5739c..84fcfe77540e 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -215,8 +215,9 @@ static const struct drm_driver mcde_drm_driver = {
DRM_GEM_CMA_DRIVER_OPS,
 };
 
-static int mcde_drm_bind(struct device *dev)
+static int mcde_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
int ret;
 
@@ -247,8 +248,9 @@ static int mcde_drm_bind(struct device *dev)
return ret;
 }
 
-static void mcde_drm_unbind(struct device *dev)
+static void mcde_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
 
drm_dev_unregister(drm);
@@ -256,9 +258,13 @@ static void mcde_drm_unbind(struct device *dev)
component_unbind_all(drm->dev, drm);
 }
 
-static const struct component_master_ops mcde_drm_comp_ops = {
-   .bind = mcde_drm_bind,
-   .unbind = mcde_drm_unbind,
+static struct aggregate_driver mcde_drm_comp_driver = {
+   .probe = mcde_drm_bind,
+   .remove = mcde_drm_unbind,
+   .driver = {
+   .name = "mcde_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static struct platform_driver *const mcde_component_drivers[] = {
@@ -421,7 +427,7 @@ static int mcde_probe(struct platform_device *pdev)
 * Perform an invasive reset of the MCDE and all blocks by
 * cutting the power to the subsystem, then bring it back up
 * later when we enable the display as a result of
-* component_master_add_with_match().
+* component_aggregate_register().
 */
ret = regulator_disable(mcde->epod);
if (ret) {
@@ -431,8 +437,7 @@ static int mcde_probe(struct platform_device *pdev)
/* Wait 50 ms so we are sure we cut the power */
usleep_range(5, 7);
 
-   ret = component_master_add_with_match(>dev, _drm_comp_ops,
- match);
+   ret = component_aggregate_register(>dev, _drm_comp_driver, 
match);
if (ret) {
dev_err(dev, "failed to add component master\n");
/*
@@ -461,7 +466,7 @@ static int mcde_remove(struct platform_device *pdev)
struct drm_device *drm = platform_get_drvdata(pdev);
struct mcde *mcde = to_mcde(drm);
 
-   component_master_del(>dev, _drm_comp_ops);
+   component_aggregate_unregister(>dev, _drm_comp_driver);
clk_disable_unprepare(mcde->mcde_clk);
regulator_disable(mcde->vana);
regulator_disable(mcde->epod);
-- 
https://chromeos.dev



[PATCH v2 21/34] drm/sti: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Benjamin Gaignard 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/sti/sti_drv.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index c7efb43b83ee..b277cc679154 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -182,8 +182,9 @@ static void sti_cleanup(struct drm_device *ddev)
ddev->dev_private = NULL;
 }
 
-static int sti_bind(struct device *dev)
+static int sti_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *ddev;
int ret;
 
@@ -216,8 +217,9 @@ static int sti_bind(struct device *dev)
return ret;
 }
 
-static void sti_unbind(struct device *dev)
+static void sti_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *ddev = dev_get_drvdata(dev);
 
drm_dev_unregister(ddev);
@@ -225,9 +227,13 @@ static void sti_unbind(struct device *dev)
drm_dev_put(ddev);
 }
 
-static const struct component_master_ops sti_ops = {
-   .bind = sti_bind,
-   .unbind = sti_unbind,
+static struct aggregate_driver sti_aggregate_driver = {
+   .probe = sti_bind,
+   .remove = sti_unbind,
+   .driver = {
+   .name = "sti_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int sti_platform_probe(struct platform_device *pdev)
@@ -249,12 +255,12 @@ static int sti_platform_probe(struct platform_device 
*pdev)
child_np = of_get_next_available_child(node, child_np);
}
 
-   return component_master_add_with_match(dev, _ops, match);
+   return component_aggregate_register(dev, _aggregate_driver, match);
 }
 
 static int sti_platform_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
 
return 0;
 }
-- 
https://chromeos.dev



[PATCH v2 20/34] drm/rockchip: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Sandy Huang 
Cc: "Heiko Stübner" 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index bfba9793d238..cc63222c3ad0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -109,8 +109,9 @@ static void rockchip_iommu_cleanup(struct drm_device 
*drm_dev)
iommu_domain_free(private->domain);
 }
 
-static int rockchip_drm_bind(struct device *dev)
+static int rockchip_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm_dev;
struct rockchip_drm_private *private;
int ret;
@@ -186,8 +187,9 @@ static int rockchip_drm_bind(struct device *dev)
return ret;
 }
 
-static void rockchip_drm_unbind(struct device *dev)
+static void rockchip_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm_dev = dev_get_drvdata(dev);
 
drm_dev_unregister(drm_dev);
@@ -342,9 +344,13 @@ static struct component_match 
*rockchip_drm_match_add(struct device *dev)
return match ?: ERR_PTR(-ENODEV);
 }
 
-static const struct component_master_ops rockchip_drm_ops = {
-   .bind = rockchip_drm_bind,
-   .unbind = rockchip_drm_unbind,
+static struct aggregate_driver rockchip_aggregate_driver = {
+   .probe = rockchip_drm_bind,
+   .remove = rockchip_drm_unbind,
+   .driver = {
+   .name = "rockchip_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int rockchip_drm_platform_of_probe(struct device *dev)
@@ -415,7 +421,7 @@ static int rockchip_drm_platform_probe(struct 
platform_device *pdev)
if (IS_ERR(match))
return PTR_ERR(match);
 
-   ret = component_master_add_with_match(dev, _drm_ops, match);
+   ret = component_aggregate_register(dev, _aggregate_driver, 
match);
if (ret < 0) {
rockchip_drm_match_remove(dev);
return ret;
@@ -426,7 +432,7 @@ static int rockchip_drm_platform_probe(struct 
platform_device *pdev)
 
 static int rockchip_drm_platform_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _drm_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
 
rockchip_drm_match_remove(>dev);
 
-- 
https://chromeos.dev



[PATCH v2 22/34] drm/sun4i: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Maxime Ripard 
Cc: Chen-Yu Tsai 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c 
b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 54dd562e294c..700f5e32eaf7 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -56,8 +56,9 @@ static const struct drm_driver sun4i_drv_driver = {
DRM_GEM_CMA_DRIVER_OPS_VMAP_WITH_DUMB_CREATE(drm_sun4i_gem_dumb_create),
 };
 
-static int sun4i_drv_bind(struct device *dev)
+static int sun4i_drv_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm;
struct sun4i_drv *drv;
int ret;
@@ -125,8 +126,9 @@ static int sun4i_drv_bind(struct device *dev)
return ret;
 }
 
-static void sun4i_drv_unbind(struct device *dev)
+static void sun4i_drv_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
 
drm_dev_unregister(drm);
@@ -140,9 +142,13 @@ static void sun4i_drv_unbind(struct device *dev)
drm_dev_put(drm);
 }
 
-static const struct component_master_ops sun4i_drv_master_ops = {
-   .bind   = sun4i_drv_bind,
-   .unbind = sun4i_drv_unbind,
+static struct aggregate_driver sun4i_aggregate_driver = {
+   .probe  = sun4i_drv_bind,
+   .remove = sun4i_drv_unbind,
+   .driver = {
+   .name = "sun4i_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static bool sun4i_drv_node_is_connector(struct device_node *node)
@@ -398,16 +404,14 @@ static int sun4i_drv_probe(struct platform_device *pdev)
}
 
if (count)
-   return component_master_add_with_match(>dev,
-  _drv_master_ops,
-  match);
-   else
-   return 0;
+   return component_aggregate_register(>dev, 
_aggregate_driver, match);
+
+   return 0;
 }
 
 static int sun4i_drv_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _drv_master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
 
return 0;
 }
-- 
https://chromeos.dev



[PATCH v2 19/34] drm/omap: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Tomi Valkeinen 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/omapdrm/dss/dss.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index d6a5862b4dbf..6a6ae2786d7a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1304,8 +1304,9 @@ static const struct soc_device_attribute 
dss_soc_devices[] = {
{ /* sentinel */ }
 };
 
-static int dss_bind(struct device *dev)
+static int dss_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct dss_device *dss = dev_get_drvdata(dev);
struct platform_device *drm_pdev;
struct dss_pdata pdata;
@@ -1339,9 +1340,13 @@ static void dss_unbind(struct device *dev)
component_unbind_all(dev, NULL);
 }
 
-static const struct component_master_ops dss_component_ops = {
-   .bind = dss_bind,
-   .unbind = dss_unbind,
+static struct aggregate_driver dss_aggregate_driver = {
+   .probe = dss_bind,
+   .remove = dss_unbind,
+   .driver = {
+   .name = "dss_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int dss_component_compare(struct device *dev, void *data)
@@ -1504,7 +1509,7 @@ static int dss_probe(struct platform_device *pdev)
cmatch.match = 
device_for_each_child(>dev, , dss_add_child_component);
 
-   r = component_master_add_with_match(>dev, _component_ops, 
match);
+   r = component_aggregate_register(>dev, _aggregate_driver, 
match);
if (r)
goto err_of_depopulate;
 
@@ -1543,7 +1548,7 @@ static int dss_remove(struct platform_device *pdev)
 
of_platform_depopulate(>dev);
 
-   component_master_del(>dev, _component_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
 
dss_debugfs_remove_file(dss->debugfs.clk);
dss_debugfs_remove_file(dss->debugfs.dss);
-- 
https://chromeos.dev



[PATCH v2 14/34] drm/imx: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Philipp Zabel 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/imx/imx-drm-core.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-drm-core.c 
b/drivers/gpu/drm/imx/imx-drm-core.c
index 9558e9e1b431..dbf5cca5201d 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -198,8 +198,9 @@ static int compare_of(struct device *dev, void *data)
return dev->of_node == np;
 }
 
-static int imx_drm_bind(struct device *dev)
+static int imx_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm;
int ret;
 
@@ -266,8 +267,9 @@ static int imx_drm_bind(struct device *dev)
return ret;
 }
 
-static void imx_drm_unbind(struct device *dev)
+static void imx_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
 
drm_dev_unregister(drm);
@@ -281,14 +283,18 @@ static void imx_drm_unbind(struct device *dev)
dev_set_drvdata(dev, NULL);
 }
 
-static const struct component_master_ops imx_drm_ops = {
-   .bind = imx_drm_bind,
-   .unbind = imx_drm_unbind,
+static struct aggregate_driver imx_drm_aggregate_driver = {
+   .probe = imx_drm_bind,
+   .remove = imx_drm_unbind,
+   .driver = {
+   .name = "imx_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int imx_drm_platform_probe(struct platform_device *pdev)
 {
-   int ret = drm_of_component_probe(>dev, compare_of, _drm_ops);
+   int ret = drm_of_aggregate_probe(>dev, compare_of, 
_drm_aggregate_driver);
 
if (!ret)
ret = dma_set_coherent_mask(>dev, DMA_BIT_MASK(32));
@@ -298,7 +304,7 @@ static int imx_drm_platform_probe(struct platform_device 
*pdev)
 
 static int imx_drm_platform_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _drm_ops);
+   component_aggregate_unregister(>dev, _drm_aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 10/34] drm/armada: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Russell King 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/armada/armada_drv.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_drv.c 
b/drivers/gpu/drm/armada/armada_drv.c
index 8e3e98f13db4..b3559363ea43 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -60,8 +60,9 @@ static const struct drm_mode_config_funcs 
armada_drm_mode_config_funcs = {
.atomic_commit  = drm_atomic_helper_commit,
 };
 
-static int armada_drm_bind(struct device *dev)
+static int armada_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct armada_private *priv;
struct resource *mem = NULL;
int ret, n;
@@ -159,8 +160,9 @@ static int armada_drm_bind(struct device *dev)
return ret;
 }
 
-static void armada_drm_unbind(struct device *dev)
+static void armada_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
struct armada_private *priv = drm_to_armada_dev(drm);
 
@@ -202,9 +204,13 @@ static void armada_add_endpoints(struct device *dev,
}
 }
 
-static const struct component_master_ops armada_master_ops = {
-   .bind = armada_drm_bind,
-   .unbind = armada_drm_unbind,
+static struct aggregate_driver armada_aggregate_driver = {
+   .probe = armada_drm_bind,
+   .remove = armada_drm_unbind,
+   .driver = {
+   .name = "armada_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int armada_drm_probe(struct platform_device *pdev)
@@ -213,7 +219,7 @@ static int armada_drm_probe(struct platform_device *pdev)
struct device *dev = >dev;
int ret;
 
-   ret = drm_of_component_probe(dev, compare_dev_name, _master_ops);
+   ret = drm_of_aggregate_probe(dev, compare_dev_name, 
_aggregate_driver);
if (ret != -EINVAL)
return ret;
 
@@ -240,13 +246,12 @@ static int armada_drm_probe(struct platform_device *pdev)
}
}
 
-   return component_master_add_with_match(>dev, _master_ops,
-  match);
+   return component_aggregate_register(>dev, 
_aggregate_driver, match);
 }
 
 static int armada_drm_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 13/34] drm/exynos: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index d8f1cf4d6b69..dcb52ec2bd35 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -253,8 +253,9 @@ static struct component_match *exynos_drm_match_add(struct 
device *dev)
return match ?: ERR_PTR(-ENODEV);
 }
 
-static int exynos_drm_bind(struct device *dev)
+static int exynos_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct exynos_drm_private *private;
struct drm_encoder *encoder;
struct drm_device *drm;
@@ -330,8 +331,9 @@ static int exynos_drm_bind(struct device *dev)
return ret;
 }
 
-static void exynos_drm_unbind(struct device *dev)
+static void exynos_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
 
drm_dev_unregister(drm);
@@ -350,9 +352,13 @@ static void exynos_drm_unbind(struct device *dev)
drm_dev_put(drm);
 }
 
-static const struct component_master_ops exynos_drm_ops = {
-   .bind   = exynos_drm_bind,
-   .unbind = exynos_drm_unbind,
+static struct aggregate_driver exynos_drm_aggregate_driver = {
+   .probe  = exynos_drm_bind,
+   .remove = exynos_drm_unbind,
+   .driver = {
+   .name   = "exynos_drm",
+   .owner  = THIS_MODULE,
+   },
 };
 
 static int exynos_drm_platform_probe(struct platform_device *pdev)
@@ -365,13 +371,12 @@ static int exynos_drm_platform_probe(struct 
platform_device *pdev)
if (IS_ERR(match))
return PTR_ERR(match);
 
-   return component_master_add_with_match(>dev, _drm_ops,
-  match);
+   return component_aggregate_register(>dev, 
_drm_aggregate_driver, match);
 }
 
 static int exynos_drm_platform_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _drm_ops);
+   component_aggregate_unregister(>dev, 
_drm_aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 12/34] drm/kirin: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Xinliang Liu 
Cc: Tian Tao 
Cc: John Stultz 
Cc: Xinwei Kong 
Cc: Chen Feng 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c   | 20 ---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c 
b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index 98ae9a48f3fe..00d47c784cbb 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -217,8 +217,9 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev)
return 0;
 }
 
-static int kirin_drm_bind(struct device *dev)
+static int kirin_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct kirin_drm_data *driver_data;
struct drm_device *drm_dev;
int ret;
@@ -253,8 +254,9 @@ static int kirin_drm_bind(struct device *dev)
return ret;
 }
 
-static void kirin_drm_unbind(struct device *dev)
+static void kirin_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm_dev = dev_get_drvdata(dev);
 
drm_dev_unregister(drm_dev);
@@ -262,9 +264,13 @@ static void kirin_drm_unbind(struct device *dev)
drm_dev_put(drm_dev);
 }
 
-static const struct component_master_ops kirin_drm_ops = {
-   .bind = kirin_drm_bind,
-   .unbind = kirin_drm_unbind,
+static struct aggregate_driver kirin_drm_aggregate_driver = {
+   .probe = kirin_drm_bind,
+   .remove = kirin_drm_unbind,
+   .driver = {
+   .name = "kirin_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int kirin_drm_platform_probe(struct platform_device *pdev)
@@ -281,12 +287,12 @@ static int kirin_drm_platform_probe(struct 
platform_device *pdev)
drm_of_component_match_add(dev, , compare_of, remote);
of_node_put(remote);
 
-   return component_master_add_with_match(dev, _drm_ops, match);
+   return component_aggregate_register(dev, _drm_aggregate_driver, 
match);
 }
 
 static int kirin_drm_platform_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _drm_ops);
+   component_aggregate_unregister(>dev, _drm_aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 11/34] drm/etnaviv: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Lucas Stach 
Cc: Russell King 
Cc: Christian Gmeiner 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/etnaviv/etnaviv_drv.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c 
b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 7dcc6392792d..95d1e518ff13 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -494,8 +494,9 @@ static const struct drm_driver etnaviv_drm_driver = {
 /*
  * Platform driver:
  */
-static int etnaviv_bind(struct device *dev)
+static int etnaviv_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct etnaviv_drm_private *priv;
struct drm_device *drm;
int ret;
@@ -552,8 +553,9 @@ static int etnaviv_bind(struct device *dev)
return ret;
 }
 
-static void etnaviv_unbind(struct device *dev)
+static void etnaviv_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
struct etnaviv_drm_private *priv = drm->dev_private;
 
@@ -569,9 +571,13 @@ static void etnaviv_unbind(struct device *dev)
drm_dev_put(drm);
 }
 
-static const struct component_master_ops etnaviv_master_ops = {
-   .bind = etnaviv_bind,
-   .unbind = etnaviv_unbind,
+static struct aggregate_driver etnaviv_aggregate_driver = {
+   .probe = etnaviv_bind,
+   .remove = etnaviv_unbind,
+   .driver = {
+   .name = "etnaviv_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int compare_of(struct device *dev, void *data)
@@ -609,12 +615,12 @@ static int etnaviv_pdev_probe(struct platform_device 
*pdev)
component_match_add(dev, , compare_str, names[i]);
}
 
-   return component_master_add_with_match(dev, _master_ops, match);
+   return component_aggregate_register(dev, _aggregate_driver, 
match);
 }
 
 static int etnaviv_pdev_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
 
return 0;
 }
-- 
https://chromeos.dev



[PATCH v2 07/34] drm/komeda: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: James Qian Wang (Arm Technology China) 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 .../gpu/drm/arm/display/komeda/komeda_drv.c   | 20 ---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
index e7933930a657..0463386a6ed2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
@@ -25,8 +25,9 @@ struct komeda_dev *dev_to_mdev(struct device *dev)
return mdrv ? mdrv->mdev : NULL;
 }
 
-static void komeda_unbind(struct device *dev)
+static void komeda_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct komeda_drv *mdrv = dev_get_drvdata(dev);
 
if (!mdrv)
@@ -45,8 +46,9 @@ static void komeda_unbind(struct device *dev)
devm_kfree(dev, mdrv);
 }
 
-static int komeda_bind(struct device *dev)
+static int komeda_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct komeda_drv *mdrv;
int err;
 
@@ -87,9 +89,13 @@ static int komeda_bind(struct device *dev)
return err;
 }
 
-static const struct component_master_ops komeda_master_ops = {
-   .bind   = komeda_bind,
-   .unbind = komeda_unbind,
+static struct aggregate_driver komeda_aggregate_driver = {
+   .probe  = komeda_bind,
+   .remove = komeda_unbind,
+   .driver = {
+   .name  = "komeda_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int compare_of(struct device *dev, void *data)
@@ -129,12 +135,12 @@ static int komeda_platform_probe(struct platform_device 
*pdev)
komeda_add_slave(dev, , child, KOMEDA_OF_PORT_OUTPUT, 1);
}
 
-   return component_master_add_with_match(dev, _master_ops, match);
+   return component_aggregate_register(dev, _aggregate_driver, 
match);
 }
 
 static int komeda_platform_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 08/34] drm/arm/hdlcd: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

Cc: Liviu Dudau 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 479c2422a2e0..8f3e5924042a 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -270,8 +270,9 @@ static const struct drm_driver hdlcd_driver = {
.minor = 0,
 };
 
-static int hdlcd_drm_bind(struct device *dev)
+static int hdlcd_drm_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm;
struct hdlcd_drm_private *hdlcd;
int ret;
@@ -344,8 +345,9 @@ static int hdlcd_drm_bind(struct device *dev)
return ret;
 }
 
-static void hdlcd_drm_unbind(struct device *dev)
+static void hdlcd_drm_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
struct hdlcd_drm_private *hdlcd = drm->dev_private;
 
@@ -367,9 +369,13 @@ static void hdlcd_drm_unbind(struct device *dev)
drm_dev_put(drm);
 }
 
-static const struct component_master_ops hdlcd_master_ops = {
-   .bind   = hdlcd_drm_bind,
-   .unbind = hdlcd_drm_unbind,
+static struct aggregate_driver hdlcd_aggregate_driver = {
+   .probe  = hdlcd_drm_bind,
+   .remove = hdlcd_drm_unbind,
+   .driver = {
+   .name   = "hdlcd_drm",
+   .owner  = THIS_MODULE,
+   },
 };
 
 static int compare_dev(struct device *dev, void *data)
@@ -390,13 +396,12 @@ static int hdlcd_probe(struct platform_device *pdev)
drm_of_component_match_add(>dev, , compare_dev, port);
of_node_put(port);
 
-   return component_master_add_with_match(>dev, _master_ops,
-  match);
+   return component_aggregate_register(>dev, 
_aggregate_driver, match);
 }
 
 static int hdlcd_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 09/34] drm/malidp: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
Use an aggregate driver instead of component ops so that we can get
proper driver probe ordering of the aggregate device with respect to all
the component devices that make up the aggregate device.

TODO: This can be updated to move the drm helper logic into the
aggregate driver shutdown op.

Cc: Laurent Pinchart 
Cc: Liviu Dudau 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/arm/malidp_drv.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 78d15b04b105..e6ee4d1e3bb8 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -702,8 +702,9 @@ static int malidp_runtime_pm_resume(struct device *dev)
return 0;
 }
 
-static int malidp_bind(struct device *dev)
+static int malidp_bind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct resource *res;
struct drm_device *drm;
struct malidp_drm *malidp;
@@ -894,8 +895,9 @@ static int malidp_bind(struct device *dev)
return ret;
 }
 
-static void malidp_unbind(struct device *dev)
+static void malidp_unbind(struct aggregate_device *adev)
 {
+   struct device *dev = adev->parent;
struct drm_device *drm = dev_get_drvdata(dev);
struct malidp_drm *malidp = drm->dev_private;
struct malidp_hw_device *hwdev = malidp->dev;
@@ -921,9 +923,13 @@ static void malidp_unbind(struct device *dev)
of_reserved_mem_device_release(dev);
 }
 
-static const struct component_master_ops malidp_master_ops = {
-   .bind = malidp_bind,
-   .unbind = malidp_unbind,
+static struct aggregate_driver malidp_aggregate_driver = {
+   .probe = malidp_bind,
+   .remove = malidp_unbind,
+   .driver = {
+   .name = "malidp_drm",
+   .owner = THIS_MODULE,
+   },
 };
 
 static int malidp_compare_dev(struct device *dev, void *data)
@@ -949,13 +955,12 @@ static int malidp_platform_probe(struct platform_device 
*pdev)
drm_of_component_match_add(>dev, , malidp_compare_dev,
   port);
of_node_put(port);
-   return component_master_add_with_match(>dev, _master_ops,
-  match);
+   return component_aggregate_register(>dev, 
_aggregate_driver, match);
 }
 
 static int malidp_platform_remove(struct platform_device *pdev)
 {
-   component_master_del(>dev, _master_ops);
+   component_aggregate_unregister(>dev, _aggregate_driver);
return 0;
 }
 
-- 
https://chromeos.dev



[PATCH v2 03/34] component: Move struct aggregate_device out to header file

2021-10-06 Thread Stephen Boyd
This allows aggregate driver writers to use the device passed to their
probe/remove/shutdown functions properly instead of treating it as an
opaque pointer.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/base/component.c  | 15 ---
 include/linux/component.h | 19 ---
 2 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index d99e99cabb99..f49b48695c8f 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -62,21 +62,6 @@ struct component_match {
struct component_match_array *compare;
 };
 
-struct aggregate_device {
-   const struct component_master_ops *ops;
-   struct device *parent;
-   struct device dev;
-   struct component_match *match;
-   struct aggregate_driver *adrv;
-
-   int id;
-};
-
-static inline struct aggregate_device *to_aggregate_device(struct device *d)
-{
-   return container_of(d, struct aggregate_device, dev);
-}
-
 struct component {
struct list_head node;
struct aggregate_device *adev;
diff --git a/include/linux/component.h b/include/linux/component.h
index 95d1b23ede8a..e99cf8e910f0 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -5,6 +5,8 @@
 #include 
 #include 
 
+struct component_match;
+
 /**
  * struct component_ops - callbacks for component drivers
  *
@@ -39,8 +41,6 @@ void component_del(struct device *, const struct 
component_ops *);
 int component_bind_all(struct device *master, void *master_data);
 void component_unbind_all(struct device *master, void *master_data);
 
-struct aggregate_device;
-
 /**
  * struct component_master_ops - callback for the aggregate driver
  *
@@ -80,7 +80,20 @@ struct component_master_ops {
void (*unbind)(struct device *master);
 };
 
-struct component_match;
+struct aggregate_device {
+   const struct component_master_ops *ops;
+   struct device *parent;
+   struct device dev;
+   struct component_match *match;
+   struct aggregate_driver *adrv;
+
+   int id;
+};
+
+static inline struct aggregate_device *to_aggregate_device(struct device *d)
+{
+   return container_of(d, struct aggregate_device, dev);
+}
 
 /**
  * struct aggregate_driver - Aggregate driver (made up of other drivers)
-- 
https://chromeos.dev



[PATCH v2 04/34] drm/msm: Migrate to aggregate driver

2021-10-06 Thread Stephen Boyd
The device lists are poorly ordered when the component device code is
used. This is because component_master_add_with_match() returns 0
regardless of component devices calling component_add() first. It can
really only fail if an allocation fails, in which case everything is
going bad and we're out of memory. The driver that registers the
aggregate driver, can succeed at probe and put the attached device on
the DPM lists before any of the component devices are probed and put on
the lists.

Within the component device framework this usually isn't that bad
because the real driver work is done at bind time via
component{,master}_ops::bind(). It becomes a problem when the driver
core, or host driver, wants to operate on the component device outside
of the bind/unbind functions, e.g. via 'remove' or 'shutdown'. The
driver core doesn't understand the relationship between the host device
and the component devices and could possibly try to operate on component
devices when they're already removed from the system or shut down.

Normally, device links or probe defer would reorder the lists and put
devices that depend on other devices in the lists at the correct
location, but with component devices this doesn't happen because this
information isn't expressed anywhere. Drivers simply succeed at
registering their component or the aggregate driver with the component
framework and wait for their bind() callback to be called once the other
components are ready. In summary, the drivers that make up the aggregate
driver can probe in any order.

This ordering problem becomes fairly obvious when shutting down the
device with a DSI controller connected to a DSI bridge that is
controlled via i2c. In this case, the msm display driver wants to tear
down the display pipeline on shutdown via msm_pdev_shutdown() by calling
drm_atomic_helper_shutdown(), and it can't do that unless the whole
display chain is still probed and active in the system. When a display
bridge is on i2c, the i2c device for the bridge will be created whenever
the i2c controller probes, which could be before or after the msm
display driver probes. If the i2c controller probes after the display
driver, then the i2c controller will be shutdown before the display
controller during system wide shutdown and thus i2c transactions will
stop working before the display pipeline is shut down. This means we'll
have the display bridge trying to access an i2c bus that's shut down
because drm_atomic_helper_shutdown() is trying to disable the bridge
after the bridge is off.

The solution is to make the aggregate driver into a real struct driver
that is bound to a device when the other component devices have all
probed. Now that the component driver code is a proper bus, we can
simply register an aggregate driver with that bus via
component_aggregate_register() and then attach the shutdown hook to that
driver to be sure that the shutdown for the display pipeline is called
before any of the component device driver shutdown hooks are called.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/msm/msm_drv.c | 46 +++
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 2e6fc185e54d..efbcae6e585f 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1324,19 +1324,35 @@ static int add_gpu_components(struct device *dev,
return 0;
 }
 
-static int msm_drm_bind(struct device *dev)
+static int msm_drm_bind(struct aggregate_device *adev)
 {
-   return msm_drm_init(dev, _driver);
+   return msm_drm_init(adev->parent, _driver);
 }
 
-static void msm_drm_unbind(struct device *dev)
+static void msm_drm_unbind(struct aggregate_device *adev)
 {
-   msm_drm_uninit(dev);
+   msm_drm_uninit(adev->parent);
+}
+
+static void msm_drm_shutdown(struct aggregate_device *adev)
+{
+   struct drm_device *drm = 
platform_get_drvdata(to_platform_device(adev->parent));
+   struct msm_drm_private *priv = drm ? drm->dev_private : NULL;
+
+   if (!priv || !priv->kms)
+   return;
+
+   drm_atomic_helper_shutdown(drm);
 }
 
-static const struct component_master_ops msm_drm_ops = {
-   .bind = msm_drm_bind,
-   .unbind = msm_drm_unbind,
+static struct aggregate_driver msm_drm_aggregate_driver = {
+   .probe = msm_drm_bind,
+   .remove = msm_drm_unbind,
+   .shutdown = msm_drm_shutdown,
+   .driver = {
+   .name   = "msm_drm",
+   .owner  = THIS_MODULE,
+   },
 };
 
 /*
@@ -1365,7 +1381,7 @@ static int msm_pdev_probe(struct platform_device *pdev)
if (ret)
goto fail;
 
-   ret = component_master_add_with_match(>dev, _drm_ops, match);
+   ret = component_aggregate_register(>dev, 
_drm_aggregate_driver, match);
if (ret)
goto 

[PATCH v2 06/34] drm/of: Add a drm_of_aggregate_probe() API

2021-10-06 Thread Stephen Boyd
Similar to drm_of_component_probe() but using the new API that registers
a driver instead of an ops struct. This allows us to migrate the users
of drm_of_component_probe() to the new way of doing things.

Cc: Laurent Pinchart 
Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/gpu/drm/drm_of.c | 85 +++-
 include/drm/drm_of.h | 11 ++
 2 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 997b8827fed2..58db65ad2770 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -99,30 +99,18 @@ void drm_of_component_match_add(struct device *master,
 }
 EXPORT_SYMBOL_GPL(drm_of_component_match_add);
 
-/**
- * drm_of_component_probe - Generic probe function for a component based master
- * @dev: master device containing the OF node
- * @compare_of: compare function used for matching components
- * @m_ops: component master ops to be used
- *
- * Parse the platform device OF node and bind all the components associated
- * with the master. Interface ports are added before the encoders in order to
- * satisfy their .bind requirements
- * See Documentation/devicetree/bindings/graph.txt for the bindings.
- *
- * Returns zero if successful, or one of the standard error codes if it fails.
- */
-int drm_of_component_probe(struct device *dev,
+static int _drm_of_component_probe(struct device *dev,
   int (*compare_of)(struct device *, void *),
-  const struct component_master_ops *m_ops)
+  struct component_match **matchptr)
 {
struct device_node *ep, *port, *remote;
-   struct component_match *match = NULL;
int i;
 
if (!dev->of_node)
return -EINVAL;
 
+   *matchptr = NULL;
+
/*
 * Bind the crtc's ports first, so that drm_of_find_possible_crtcs()
 * called from encoder's .bind callbacks works as expected
@@ -133,7 +121,7 @@ int drm_of_component_probe(struct device *dev,
break;
 
if (of_device_is_available(port->parent))
-   drm_of_component_match_add(dev, , compare_of,
+   drm_of_component_match_add(dev, matchptr, compare_of,
   port);
 
of_node_put(port);
@@ -144,7 +132,7 @@ int drm_of_component_probe(struct device *dev,
return -ENODEV;
}
 
-   if (!match) {
+   if (!*matchptr) {
dev_err(dev, "no available port\n");
return -ENODEV;
}
@@ -174,17 +162,76 @@ int drm_of_component_probe(struct device *dev,
continue;
}
 
-   drm_of_component_match_add(dev, , compare_of,
+   drm_of_component_match_add(dev, matchptr, compare_of,
   remote);
of_node_put(remote);
}
of_node_put(port);
}
 
+   return 0;
+}
+
+/**
+ * drm_of_component_probe - Generic probe function for a component based master
+ * @dev: master device containing the OF node
+ * @compare_of: compare function used for matching components
+ * @m_ops: component master ops to be used
+ *
+ * Parse the platform device OF node and bind all the components associated
+ * with the master. Interface ports are added before the encoders in order to
+ * satisfy their .bind requirements
+ * See Documentation/devicetree/bindings/graph.txt for the bindings.
+ *
+ * Deprecated: Use drm_of_aggregate_probe() instead.
+ *
+ * Returns zero if successful, or one of the standard error codes if it fails.
+ */
+static int drm_of_component_probe(struct device *dev,
+  int (*compare_of)(struct device *, void *),
+  const struct component_master_ops *m_ops)
+{
+
+   struct component_match *match;
+   int ret;
+
+   ret = _drm_of_component_probe(dev, compare_of, );
+   if (ret)
+   return ret;
+
return component_master_add_with_match(dev, m_ops, match);
 }
 EXPORT_SYMBOL(drm_of_component_probe);
 
+
+/**
+ * drm_of_aggregate_probe - Generic probe function for a component based 
aggregate host
+ * @dev: device containing the OF node
+ * @compare_of: compare function used for matching components
+ * @adrv: aggregate driver to be used
+ *
+ * Parse the platform device OF node and bind all the components associated
+ * with the aggregate device. Interface ports are added before the encoders in
+ * order to satisfy their .bind_component requirements
+ * See Documentation/devicetree/bindings/graph.txt for the bindings.
+ *
+ * Returns zero if successful, or one of the standard error codes if it fails.
+ */
+static int drm_of_aggregate_probe(struct 

[PATCH v2 05/34] component: Add {bind, unbind}_component() ops that take aggregate device

2021-10-06 Thread Stephen Boyd
We'd like to get more device model features in the component framework
so let's pass the struct aggregate_device pointer instead of the parent
device pointer to the component binding functions. This will allow
drivers to inspect and control things related to the aggregate device in
case they need it, and they'll always be able to get back to the device
they were using before by using the 'parent' member of the aggregate
device struct.

Suggested-by: Daniel Vetter 
Signed-off-by: Stephen Boyd 
---
 drivers/base/component.c  | 14 +++---
 include/linux/component.h | 22 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index f49b48695c8f..a6dd33d0ddeb 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -707,8 +707,13 @@ static void component_unbind(struct component *component,
 {
WARN_ON(!component->bound);
 
-   if (component->ops && component->ops->unbind)
-   component->ops->unbind(component->dev, adev->parent, data);
+   if (component->ops) {
+   if (component->ops->unbind)
+   component->ops->unbind(component->dev, adev->parent, 
data);
+   else if (component->ops->unbind_component)
+   component->ops->unbind_component(component->dev, adev, 
data);
+   }
+
component->bound = false;
 
/* Release all resources claimed in the binding of this component */
@@ -773,7 +778,10 @@ static int component_bind(struct component *component, 
struct aggregate_device *
dev_dbg(adev->parent, "binding %s (ops %ps)\n",
dev_name(component->dev), component->ops);
 
-   ret = component->ops->bind(component->dev, adev->parent, data);
+   if (component->ops->bind_component)
+   ret = component->ops->bind_component(component->dev, adev, 
data);
+   else
+   ret = component->ops->bind(component->dev, adev->parent, data);
if (!ret) {
component->bound = true;
 
diff --git a/include/linux/component.h b/include/linux/component.h
index e99cf8e910f0..d8dcbf9733da 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -6,6 +6,7 @@
 #include 
 
 struct component_match;
+struct aggregate_device;
 
 /**
  * struct component_ops - callbacks for component drivers
@@ -19,18 +20,39 @@ struct component_ops {
 *
 * Called through component_bind_all() when the aggregate driver is
 * ready to bind the overall driver.
+*
+* Deprecated: Use bind_component() instead.
 */
int (*bind)(struct device *comp, struct device *master,
void *master_data);
+   /**
+* @bind_component:
+*
+* Called through component_bind_all() when the aggregate driver is
+* ready to bind the overall driver.
+*/
+   int (*bind_component)(struct device *comp, struct aggregate_device 
*adev,
+ void *aggregate_data);
/**
 * @unbind:
 *
 * Called through component_unbind_all() when the aggregate driver is
 * ready to bind the overall driver, or when component_bind_all() fails
 * part-ways through and needs to unbind some already bound components.
+*
+* Deprecated: Use unbind_component() instead.
 */
void (*unbind)(struct device *comp, struct device *master,
   void *master_data);
+   /**
+* @unbind_component:
+*
+* Called through component_unbind_all() when the aggregate driver is
+* ready to unbind the overall driver, or when component_bind_all() 
fails
+* part-ways through and needs to unbind some already bound components.
+*/
+   int (*unbind_component)(struct device *comp, struct aggregate_device 
*adev,
+   void *aggregate_data);
 };
 
 int component_add(struct device *, const struct component_ops *);
-- 
https://chromeos.dev



[PATCH v2 02/34] component: Introduce the aggregate bus_type

2021-10-06 Thread Stephen Boyd
The component driver only provides 'bind' and 'unbind' callbacks to tell
the host driver that it is time to assemble the aggregate driver now
that all the components have probed. The component driver model doesn't
attempt to resolve runtime PM or suspend/resume ordering, and explicitly
mentions this in the code. This lack of support leads to some pretty
gnarly usages of the 'prepare' and 'complete' power management hooks in
drivers that host the aggregate device, and it fully breaks down when
faced with ordering shutdown between the various components, the
aggregate driver, and the host driver that registers the whole thing.

In a concrete example, the MSM display driver at drivers/gpu/drm/msm is
using 'prepare' and 'complete' to call the drm helpers
drm_mode_config_helper_suspend() and drm_mode_config_helper_resume()
respectively, so that it can move the aggregate driver suspend/resume
callbacks to be before and after the components that make up the drm
device call any suspend/resume hooks they have. This only works as long
as the component devices don't do anything in their own 'prepare' and
'complete' callbacks. If they did, then the ordering would be incorrect
and we would be doing something in the component drivers before the
aggregate driver could do anything. Yuck!

Similarly, when trying to add shutdown support to the MSM driver we run
across a problem where we're trying to shutdown the drm device via
drm_atomic_helper_shutdown(), but some of the devices in the encoder
chain have already been shutdown. This time, the component devices
aren't the problem (although they could be if they did anything in their
shutdown callbacks), but there's a DSI to eDP bridge in the encoder
chain that has already been shutdown before the driver hosting the
aggregate device runs shutdown. The ordering of driver probe is like
this:

 1. msm_pdev_probe() (host driver)
 2. DSI bridge
 3. aggregate bind

When it comes to shutdown we have this order:

 1. DSI bridge
 2. msm_pdev_shutdown() (host driver)

and so the bridge is already off, but we want to communicate to it to
turn things off on the display during msm_pdev_shutdown(). Double yuck!
Unfortunately, this time we can't split shutdown into multiple phases
and swap msm_pdev_shutdown() with the DSI bridge.

Let's make the component driver into an actual device driver that has
probe/remove/shutdown functions. The driver will only be bound to the
aggregate device once all component drivers have called component_add()
to indicate they're ready to assemble the aggregate driver. This allows
us to attach shutdown logic (and in the future runtime PM logic) to the
aggregate driver so that it runs the hooks in the correct order.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/base/component.c  | 454 +++---
 include/linux/component.h |  62 +-
 2 files changed, 381 insertions(+), 135 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 0a41bbe14981..d99e99cabb99 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -15,6 +15,9 @@
 #include 
 #include 
 #include 
+#include 
+
+#include "base.h"
 
 /**
  * DOC: overview
@@ -38,8 +41,8 @@
  *
  * Aggregate drivers first assemble a component match list of what they need
  * using component_match_add(). This is then registered as an aggregate driver
- * using component_master_add_with_match(), and unregistered using
- * component_master_del().
+ * using component_aggregate_register(), and unregistered using
+ * component_aggregate_unregister().
  */
 
 struct component;
@@ -60,17 +63,20 @@ struct component_match {
 };
 
 struct aggregate_device {
-   struct list_head node;
-   bool bound;
-
const struct component_master_ops *ops;
struct device *parent;
struct device dev;
struct component_match *match;
+   struct aggregate_driver *adrv;
 
int id;
 };
 
+static inline struct aggregate_device *to_aggregate_device(struct device *d)
+{
+   return container_of(d, struct aggregate_device, dev);
+}
+
 struct component {
struct list_head node;
struct aggregate_device *adev;
@@ -79,11 +85,11 @@ struct component {
const struct component_ops *ops;
int subcomponent;
struct device *dev;
+   struct device_link *link;
 };
 
 static DEFINE_MUTEX(component_mutex);
 static LIST_HEAD(component_list);
-static LIST_HEAD(aggregate_devices);
 
 static DEFINE_IDA(aggregate_ida);
 
@@ -101,7 +107,7 @@ static int component_devices_show(struct seq_file *s, void 
*data)
seq_printf(s, "%-40s %20s\n", "aggregate_device name", "status");
seq_puts(s, 
"-\n");
seq_printf(s, "%-40s %20s\n\n",
-  dev_name(m->parent), m->bound ? "bound" : "not bound");
+  dev_name(m->parent), 

[PATCH v2 01/34] component: Introduce struct aggregate_device

2021-10-06 Thread Stephen Boyd
Replace 'struct master' with 'struct aggregate_device' and then rename
'master' to 'adev' everywhere in the code. While we're here, put a
struct device inside the aggregate device so that we can register it
with a bus_type in the next patch.

The diff is large but that's because this is mostly a rename, where
sometimes 'master' is replaced with 'adev' and other times it is
replaced with 'parent' to indicate that the struct device that was being
used is actually the parent of the aggregate device and driver.

Cc: Daniel Vetter 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Saravana Kannan 
Signed-off-by: Stephen Boyd 
---
 drivers/base/component.c  | 250 --
 include/linux/component.h |   2 +-
 2 files changed, 134 insertions(+), 118 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 5e79299f6c3f..0a41bbe14981 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -9,6 +9,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -58,18 +59,21 @@ struct component_match {
struct component_match_array *compare;
 };
 
-struct master {
+struct aggregate_device {
struct list_head node;
bool bound;
 
const struct component_master_ops *ops;
struct device *parent;
+   struct device dev;
struct component_match *match;
+
+   int id;
 };
 
 struct component {
struct list_head node;
-   struct master *master;
+   struct aggregate_device *adev;
bool bound;
 
const struct component_ops *ops;
@@ -79,7 +83,9 @@ struct component {
 
 static DEFINE_MUTEX(component_mutex);
 static LIST_HEAD(component_list);
-static LIST_HEAD(masters);
+static LIST_HEAD(aggregate_devices);
+
+static DEFINE_IDA(aggregate_ida);
 
 #ifdef CONFIG_DEBUG_FS
 
@@ -87,12 +93,12 @@ static struct dentry *component_debugfs_dir;
 
 static int component_devices_show(struct seq_file *s, void *data)
 {
-   struct master *m = s->private;
+   struct aggregate_device *m = s->private;
struct component_match *match = m->match;
size_t i;
 
mutex_lock(_mutex);
-   seq_printf(s, "%-40s %20s\n", "master name", "status");
+   seq_printf(s, "%-40s %20s\n", "aggregate_device name", "status");
seq_puts(s, 
"-\n");
seq_printf(s, "%-40s %20s\n\n",
   dev_name(m->parent), m->bound ? "bound" : "not bound");
@@ -122,46 +128,46 @@ static int __init component_debug_init(void)
 
 core_initcall(component_debug_init);
 
-static void component_master_debugfs_add(struct master *m)
+static void component_master_debugfs_add(struct aggregate_device *m)
 {
debugfs_create_file(dev_name(m->parent), 0444, component_debugfs_dir, m,
_devices_fops);
 }
 
-static void component_master_debugfs_del(struct master *m)
+static void component_master_debugfs_del(struct aggregate_device *m)
 {
debugfs_remove(debugfs_lookup(dev_name(m->parent), 
component_debugfs_dir));
 }
 
 #else
 
-static void component_master_debugfs_add(struct master *m)
+static void component_master_debugfs_add(struct aggregate_device *m)
 { }
 
-static void component_master_debugfs_del(struct master *m)
+static void component_master_debugfs_del(struct aggregate_device *m)
 { }
 
 #endif
 
-static struct master *__master_find(struct device *parent,
+static struct aggregate_device *__aggregate_find(struct device *parent,
const struct component_master_ops *ops)
 {
-   struct master *m;
+   struct aggregate_device *m;
 
-   list_for_each_entry(m, , node)
+   list_for_each_entry(m, _devices, node)
if (m->parent == parent && (!ops || m->ops == ops))
return m;
 
return NULL;
 }
 
-static struct component *find_component(struct master *master,
+static struct component *find_component(struct aggregate_device *adev,
struct component_match_array *mc)
 {
struct component *c;
 
list_for_each_entry(c, _list, node) {
-   if (c->master && c->master != master)
+   if (c->adev && c->adev != adev)
continue;
 
if (mc->compare && mc->compare(c->dev, mc->data))
@@ -175,101 +181,102 @@ static struct component *find_component(struct master 
*master,
return NULL;
 }
 
-static int find_components(struct master *master)
+static int find_components(struct aggregate_device *adev)
 {
-   struct component_match *match = master->match;
+   struct component_match *match = adev->match;
size_t i;
int ret = 0;
 
/*
 * Scan the array of match functions and attach
-* any components which are found to this master.
+* any components which are found to this adev.
 */
for (i = 0; i < match->num; i++) {
struct component_match_array *mc = 

[PATCH v2 00/34] component: Make into an aggregate bus

2021-10-06 Thread Stephen Boyd
This series is from discussion we had on reordering the device lists for
drm shutdown paths[1]. I've introduced an 'aggregate' bus that we put
the aggregate device onto and then we probe the aggregate device once
all the components are probed and call component_add(). The probe/remove
hooks are where the bind/unbind calls go, and then a shutdown hook is
added that can be used to shutdown the drm display pipeline at the right
time.

This works for me on my sc7180 board. I no longer get a warning from i2c
at shutdown that we're trying to make an i2c transaction after the i2c
bus has been shutdown. There's more work to do on the msm drm driver to
extract component device resources like clks, regulators, etc. out of
the component bind function into the driver probe but I wanted to move
everything over now in other component drivers before tackling that
problem.

I'll definitely be sending a v3 so this is partially a request for
testing to shake out any more problems. Tested-by tags would be appreciated,
and Acked-by/Reviewed-by tags too. I sent this to gregkh which may be
incorrect but I don't know what better tree to send it all through.
Maybe drm?

I'll be faster at resending this next time, sorry for the long delay!

Changes since v1 
(https://lore.kernel.org/r/20210520002519.3538432-1-swb...@chromium.org):
 - Use devlink to connect components to the aggregate device
 - Don't set the registering device as a parent of the aggregate device
 - New patch for bind_component/unbind_component ops that takes the
   aggregate device
 - Convert all drivers in the tree to use the aggregate driver approach
 - Allow one aggregate driver to be used for multiple aggregate devices

[1] https://lore.kernel.org/r/20210508074118.1621729-1-swb...@chromium.org

Stephen Boyd (34):
  component: Introduce struct aggregate_device
  component: Introduce the aggregate bus_type
  component: Move struct aggregate_device out to header file
  drm/msm: Migrate to aggregate driver
  component: Add {bind,unbind}_component() ops that take aggregate
device
  drm/of: Add a drm_of_aggregate_probe() API
  drm/komeda: Migrate to aggregate driver
  drm/arm/hdlcd: Migrate to aggregate driver
  drm/malidp: Migrate to aggregate driver
  drm/armada: Migrate to aggregate driver
  drm/etnaviv: Migrate to aggregate driver
  drm/kirin: Migrate to aggregate driver
  drm/exynos: Migrate to aggregate driver
  drm/imx: Migrate to aggregate driver
  drm/ingenic: Migrate to aggregate driver
  drm/mcde: Migrate to aggregate driver
  drm/mediatek: Migrate to aggregate driver
  drm/meson: Migrate to aggregate driver
  drm/omap: Migrate to aggregate driver
  drm/rockchip: Migrate to aggregate driver
  drm/sti: Migrate to aggregate driver
  drm/sun4i: Migrate to aggregate driver
  drm/tilcdc: Migrate to aggregate driver
  drm/vc4: Migrate to aggregate driver
  drm/zte: Migrate to aggregate driver
  iommu/mtk: Migrate to aggregate driver
  mei: Migrate to aggregate driver
  power: supply: ab8500: Migrate to aggregate driver
  fbdev: omap2: Migrate to aggregate driver
  sound: hdac: Migrate to aggregate driver
  ASoC: codecs: wcd938x: Migrate to aggregate driver
  component: Get rid of drm_of_component_probe()
  component: Remove component_master_ops and friends
  component: Remove all references to 'master'

Cc: Arnd Bergmann 
Cc: Benjamin Gaignard 
Cc: Chen Feng 
Cc: Chen-Yu Tsai 
Cc: Christian Gmeiner 
Cc: Chun-Kuang Hu 
Cc: Daniel Vetter 
Cc: Emma Anholt 
Cc: Greg Kroah-Hartman 
Cc: "Heiko Stübner" 
Cc: Inki Dae 
Cc: James Qian Wang (Arm Technology China) 
Cc: Jaroslav Kysela 
Cc: Joerg Roedel 
Cc: John Stultz 
Cc: Joonyoung Shim 
Cc: Jyri Sarha 
Cc: Kai Vehmanen 
Cc: Kyungmin Park 
Cc: Laurent Pinchart 
Cc: 
Cc: 
Cc: 
Cc: Liviu Dudau 
Cc: Lucas Stach 
Cc: Mark Brown 
Cc: Maxime Ripard 
Cc: Neil Armstrong 
Cc: Paul Cercueil 
Cc: Philipp Zabel 
Cc: "Rafael J. Wysocki" 
Cc: Rob Clark 
Cc: Russell King 
Cc: Russell King 
Cc: Russell King 
Cc: Sandy Huang 
Cc: Saravana Kannan 
Cc: Sebastian Reichel 
Cc: Seung-Woo Kim 
Cc: Takashi Iwai 
Cc: Tian Tao 
Cc: Tomas Winkler 
Cc: Tomi Valkeinen 
Cc: Will Deacon 
Cc: Xinliang Liu 
Cc: Xinwei Kong 
Cc: Yong Wu 

 drivers/base/component.c  | 555 +++---
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |  20 +-
 drivers/gpu/drm/arm/hdlcd_drv.c   |  21 +-
 drivers/gpu/drm/arm/malidp_drv.c  |  21 +-
 drivers/gpu/drm/armada/armada_drv.c   |  23 +-
 drivers/gpu/drm/drm_drv.c |   2 +-
 drivers/gpu/drm/drm_of.c  |  20 +-
 drivers/gpu/drm/etnaviv/etnaviv_drv.c |  20 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c   |  21 +-
 .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c   |  20 +-
 drivers/gpu/drm/imx/imx-drm-core.c|  20 +-
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c |  24 +-
 drivers/gpu/drm/mcde/mcde_drv.c   |  23 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|  20 +-
 

Re: [PATCH RFC] drm: introduce DRM_MODE_FB_PERSIST

2021-10-06 Thread Daniel Vetter
On Wed, Oct 6, 2021 at 5:19 PM Simon Ser  wrote:
> This new ADDFB2 flag allows callers to mark a framebuffer as
> "persistent", and no longer have RMFB semantics when the DRM
> file is closed.
>
> [1]: https://lore.kernel.org/dri-devel/YTJypepF1Hpc2YYT@reader/
>
> Signed-off-by: Simon Ser 
> Cc: Hans de Goede 
> Cc: Dennis Filder 
> Cc: Daniel Vetter 
> Cc: Pekka Paalanen 
> ---
>
> I'm not sure this is enough, but posting this to get initial
> feedback and allow to start e.g. Plymouth experiments. I'll
> follow up with an IGT test soon.
>
>  drivers/gpu/drm/drm_framebuffer.c |  6 --
>  include/uapi/drm/drm_mode.h   | 15 +++
>  2 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_framebuffer.c 
> b/drivers/gpu/drm/drm_framebuffer.c
> index 07f5abc875e9..9b398838e1f4 100644
> --- a/drivers/gpu/drm/drm_framebuffer.c
> +++ b/drivers/gpu/drm/drm_framebuffer.c
> @@ -292,7 +292,8 @@ drm_internal_framebuffer_create(struct drm_device *dev,
> struct drm_framebuffer *fb;
> int ret;
>
> -   if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {
> +   if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS |
> +DRM_MODE_FB_PERSIST)) {
> DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
> return ERR_PTR(-EINVAL);
> }
> @@ -789,7 +790,8 @@ void drm_fb_release(struct drm_file *priv)
>  * at it any more.
>  */
> list_for_each_entry_safe(fb, tfb, >fbs, filp_head) {
> -   if (drm_framebuffer_read_refcount(fb) > 1) {
> +   if (drm_framebuffer_read_refcount(fb) > 1 &&
> +   !(fb->flags & DRM_MODE_FB_PERSIST)) {
> list_move_tail(>filp_head, );
> } else {
> list_del_init(>filp_head);
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index e1e351682872..c7a7089ec31e 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -662,6 +662,21 @@ struct drm_mode_fb_cmd {
>
>  #define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */
>  #define DRM_MODE_FB_MODIFIERS  (1<<1) /* enables ->modifer[] */
> +/**
> + * DRM_MODE_FB_PERSIST
> + *
> + * DRM framebuffers are normally implicitly removed when their owner closes 
> the
> + * DRM FD. Passing this flag will make the framebuffer persistent: it will 
> not
> + * be implicitly removed. This is useful to implement flicker-free 
> transitions
> + * between two processes.
> + *
> + * This flag doesn't change the behavior of _IOCTL_MODE_RMFB.
> + *
> + * User-space should ensure the framebuffer doesn't expose any sensitive user
> + * information: persistent framebuffers can be read back by the next DRM
> + * master.

Should probably explain here that the persistent fb stays around for
as long as it's still in use by a plane, but will disappear
automatically when it's no longer in active use.

Also I guess there was some discussion I've missed on why we exclude
rmfb from this (unlike the CLOSEFB thing robclark proposed ages ago).
The nice thing about closefb is that you can give it persistent
semantics retroactively, so don't need to re-wrap an gem_bo and do a
page flip when you quit.
-Daniel

> + */
> +#define DRM_MODE_FB_PERSIST (1 << 2)
>
>  struct drm_mode_fb_cmd2 {
> __u32 fb_id;
> --
> 2.33.0
>
>


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


Re: [RFC 6/8] drm/i915: Make some recently added vfuncs use full scheduling attribute

2021-10-06 Thread Tvrtko Ursulin



On 06/10/2021 18:12, Matthew Brost wrote:

On Mon, Oct 04, 2021 at 03:36:48PM +0100, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Code added in 71ed60112d5d ("drm/i915: Add kick_backend function to
i915_sched_engine") and ee242ca704d3 ("drm/i915/guc: Implement GuC
priority management") introduced some scheduling related vfuncs which
take integer request priority as argument.

Make them instead take struct i915_sched_attr, which is the type
encapsulating this information, so it probably aligns with the design
better. It definitely enables extending the set of scheduling attributes.



Understand the motivation here but the i915_scheduler is going to
disapear when we move to the DRM scheduler or at least its functionality
of priority inheritance will be pushed into the DRM scheduler. I'd be
very careful making any changes here as the priority in the DRM
scheduler is defined as single enum:

/* These are often used as an (initial) index
  * to an array, and as such should start at 0.
  */
enum drm_sched_priority {
 DRM_SCHED_PRIORITY_MIN,
 DRM_SCHED_PRIORITY_NORMAL,
 DRM_SCHED_PRIORITY_HIGH,
 DRM_SCHED_PRIORITY_KERNEL,

 DRM_SCHED_PRIORITY_COUNT,
 DRM_SCHED_PRIORITY_UNSET = -2
};

Adding a field to the i915_sched_attr is fairly easy as we already have
a structure but changing the DRM scheduler might be a tougher sell.
Anyway you can make this work without adding the 'nice' field to
i915_sched_attr? Might be worth exploring so when we move to the DRM
scheduler this feature drops in a little cleaner.


/me rubs a crystal ball.. no idea how that would look. :)

Idea with separate nice in sched attr is that only default priority 
contexts are affected by nice. Thinking being, if i915 aware userspace 
has explicitly requested a different priority, then let it keep that. In 
other words, only if it did not bother and left it at default/normal, 
then we inherit from process nice.


I suppose to keep this idea in some future drm scheduler world it would 
require some work. But in general the concept is of course open to 
discussion.


Implementation wise, not having prio and nice separate opens some other 
problems in how this interacts with GEM context priority, but there are 
probably solutions to those problems as well.


I suppose I could define a "nice range" in the existing priorities and 
nice adjustments would only apply if within that range. That would allow 
max and min user priority to still be undisturbed as requested via the 
i915 uapi.


(min) -1023 - (nice 20) - 0 -- (nice -19) -- +1023 (max)

And I say if some userspace set a priority in the -20 to 19 range then 
it is allowed to adjust it via process nice. That would keep it a single 
int priority as today.


Regards,

Tvrtko



Matt


Signed-off-by: Tvrtko Ursulin 
Cc: Matthew Brost 
Cc: Daniele Ceraolo Spurio 
---
  drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 4 +++-
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c| 3 ++-
  drivers/gpu/drm/i915/i915_scheduler.c| 4 ++--
  drivers/gpu/drm/i915/i915_scheduler_types.h  | 4 ++--
  4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 7147fe80919e..e91d803a6453 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -3216,11 +3216,13 @@ static bool can_preempt(struct intel_engine_cs *engine)
return engine->class != RENDER_CLASS;
  }
  
-static void kick_execlists(const struct i915_request *rq, int prio)

+static void kick_execlists(const struct i915_request *rq,
+  const struct i915_sched_attr *attr)
  {
struct intel_engine_cs *engine = rq->engine;
struct i915_sched_engine *sched_engine = engine->sched_engine;
const struct i915_request *inflight;
+   const int prio = attr->priority;
  
  	/*

 * We only need to kick the tasklet once for the high priority
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ba0de35f6323..b5883a4365ca 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2414,9 +2414,10 @@ static void guc_init_breadcrumbs(struct intel_engine_cs 
*engine)
  }
  
  static void guc_bump_inflight_request_prio(struct i915_request *rq,

-  int prio)
+  const struct i915_sched_attr *attr)
  {
struct intel_context *ce = rq->context;
+   const int prio = attr->priority;
u8 new_guc_prio = map_i915_prio_to_guc_prio(prio);
  
  	/* Short circuit function */

diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index 762127dd56c5..534bab99fcdc 100644
--- 

Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-06 Thread Stephen Boyd
Quoting Bjorn Andersson (2021-10-06 11:05:09)
> On Wed 06 Oct 10:19 PDT 2021, Stephen Boyd wrote:
>
> > Quoting Bjorn Andersson (2021-10-06 10:07:17)
> > > On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:
> > >
> > > > Quoting Bjorn Andersson (2021-10-05 19:37:52)
> > > > > On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:
> > > > >
> > > > > > Quoting Bjorn Andersson (2021-10-05 18:43:16)
> > > > > > > On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:
> > > > > > >
> > > > > > > > Quoting Bjorn Andersson (2021-10-05 16:13:21)
> > > > > > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > > > > > > > > b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > index bdaf227f05dc..674cddfee5b0 100644
> > > > > > > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > @@ -1233,7 +1239,7 @@ static int dp_display_probe(struct 
> > > > > > > > > platform_device *pdev)
> > > > > > > > > if (!dp)
> > > > > > > > > return -ENOMEM;
> > > > > > > > >
> > > > > > > > > -   desc = dp_display_get_desc(pdev);
> > > > > > > > > +   desc = dp_display_get_desc(pdev, >id);
> > > > > > > >
> > > > > > > > I'm sad that dp->id has to match the number in the SoC specific
> > > > > > > > dpu_intf_cfg array in 
> > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > > > > > > > still. Is there any way we can avoid that? Also, notice how 
> > > > > > > > those arrays
> > > > > > > > already have INTF_DP macros, which makes me think that it may 
> > > > > > > > be better
> > > > > > > > to connect this to those arrays instead of making an msm_dp_desc
> > > > > > > > structure and then make sure the 'type' member matches a 
> > > > > > > > connector
> > > > > > > > type number. Otherwise this code is super fragile.
> > > > > > > >
> > > > > > >
> > > > > > > I'm afraid I don't understand what you're proposing. Or which 
> > > > > > > part you
> > > > > > > consider fragile, the indices of the INTF_DP instances aren't 
> > > > > > > going to
> > > > > > > move around...
> > > > > > >
> > > > > > > I have N instances of the DP driver that I need to match to N 
> > > > > > > entries
> > > > > > > from the platform specific intf array, I need some stable 
> > > > > > > reference
> > > > > > > between them. When I started this journey I figured I could rely 
> > > > > > > on the
> > > > > > > of_graph between the DPU and the interface controllers, but the 
> > > > > > > values
> > > > > > > used there today are just bogus, so that was a no go.
> > > > > > >
> > > > > > > We can use whatever, as long as _dpu_kms_initialize_displayport() 
> > > > > > > can
> > > > > > > come up with an identifier to put in h_tile_instance[0] so that
> > > > > > > dpu_encoder_setup_display() can find the relevant INTF.
> > > > > > >
> > > > > >
> > > > > > To make it more concrete we can look at sc7180
> > > > > >
> > > > > > static const struct dpu_intf_cfg sc7180_intf[] = {
> > > > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
> > > > > > INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > > >  ^
> > > > > >  |
> > > > > >
> > > > > > intf0 is irrelevant. Also the address is irrelevant. But here we 
> > > > > > have a
> > > > > > zero, the number after INTF_DP, and that is very relevant. That 
> > > > > > number
> > > > > > needs to match the dp->id. Somewhere we have a match between
> > > > > > controller_id and dp->id in the code.
> > > > >
> > > > > That number (the 0, not INTF_0) is what the code matches against 
> > > > > dp->id
> > > > > in _dpu_kms_initialize_displayport(), in order to figure out that this
> > > > > is INTF_0 in dpu_encoder_setup_display().
> > > > >
> > > > > I.e. look at the sc8180x patch:
> > > > >
> > > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, 
> > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > > INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, 
> > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> > > > > INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, 
> > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> > > > > /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until 
> > > > > this is supported */
> > > > > INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, 
> > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> > > > > INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, 
> > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
> > > > > INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, 
> > > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
> > > > >
> > > > > Where the DP driver defines the 3 controllers with dp->id of 0, 1 and 
> > > > > 2,
> > > > > which the DPU code will match against to INTF_0, INTF_4 and INTF_5.
> > > > >
> > > >
> > > > Yep. I'm saying that having to make that number in this intf 

RE: [PATCH v2] drm/hyperv: Fix double mouse pointers

2021-10-06 Thread Dexuan Cui
> From: Dexuan Cui 
> Sent: Thursday, September 16, 2021 12:37 PM
> To: drawat.fl...@gmail.com; Haiyang Zhang ;
> airl...@linux.ie; dan...@ffwll.ch; tzimmerm...@suse.de;
> dri-devel@lists.freedesktop.org
> Cc: linux-hyp...@vger.kernel.org; linux-ker...@vger.kernel.org; Dexuan Cui
> 
> Subject: [PATCH v2] drm/hyperv: Fix double mouse pointers
> 
> Hyper-V supports a hardware cursor feature. It is not used by Linux VM,
> but the Hyper-V host still draws a point as an extra mouse pointer,
> which is unwanted, especially when Xorg is running.
> 
> The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted pointer.
> When the hyperv_drm driver was developed, the function synthvid_send_ptr()
> was not copied from the hyperv_fb driver. Fix the issue by adding the
> function into hyperv_drm.
> 
> Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video
> device")
> Signed-off-by: Dexuan Cui 
> Reviewed-by: Haiyang Zhang 
> Reviewed-by: Deepak Rawat 
> ---
> 
> Changes in v2:
>   Renamed hyperv_send_ptr() to hyperv_hide_hw_ptr().
>   Improved the comments and the git commit message.
>   Added Reviewed-by's from Haiyang and Deepak.
> 
>  drivers/gpu/drm/hyperv/hyperv_drm.h |  1 +
>  drivers/gpu/drm/hyperv/hyperv_drm_modeset.c |  1 +
>  drivers/gpu/drm/hyperv/hyperv_drm_proto.c   | 54
> -
>  3 files changed, 55 insertions(+), 1 deletion(-)

Hi DRM maintainers,
Could you please take a look at the patch?

Thanks,
-- Dexuan


Re: [Intel-gfx] [RFC 7/8] drm/i915: Inherit process nice for context scheduling priority

2021-10-06 Thread Tvrtko Ursulin



On 06/10/2021 18:24, Matthew Brost wrote:

On Mon, Oct 04, 2021 at 03:36:49PM +0100, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Introduce the concept of context nice value which matches the process
nice.

We do this by extending the struct i915_sched_attr and add a helper
(i915_sched_attr_priority) to be used to convert to effective priority
when used by backend code and for priority sorting.

Context nice is then inherited from the process which creates the GEM
context and utilised secondary to context priority, only when the latter
has been left at the default setting, in order to avoid disturbing any
application made choices of low and high (batch processing and maybe
latency sensitive compositing). In those cases nice value adjusts the
effective priority in the narrow band of -19 to +20 around
I915_CONTEXT_DEFAULT_PRIORITY.

This means that in theory userspace using the context priority uapi
directly has a wider range of possible adjustments (thought to be
beneficial), but in practice that only applies to execlists platforms.
With GuC there are only three priority buckets (less than zero is low
priority, zero is normal and greater than zero is high) which therefore
interact as expected with the nice adjustment. It makes the question of
should the nice be a sub-range of GEM priorities, or stretched across the
whole, a moot one.



Opps, sorry for the double reply to this patch - for some reason I
thinking the below comment would be on the next patch.

The GuC + DRM scheduler actually has 4 priorities with the highest
reserved for the KMD, so 3 user levels which is what I think you mean.
So how would this work with only 3 levels?

>
> The nice value can move a normal priority value to either low or high,
> right?

Yes. I was thinking about three user visible levels. The kernel one is 
reserved for internal stuff so I did not mention it.


Default, nice 0 = normal priority.
Positive nice = low priority.
Negative nice = high priority.

Same as mapping of -1024 to 1023 range works onto those three AFAIU. So 
I think it works.



Normal to low seems fine but would moving to high be an issue?

I thought a high level was reserved for elevated user processes (e.g. a
root user or a compositor)?


Yes, and lowering the nice (negative nice) also needs CAP_SYS_NICE which 
is not available to user processes by default. So that matches i915 
rules with going above default/normal.



Would it be ok for a non-elevated user process to be the same priority
as an elevated process?


Not sure exactly what you have in mind but in principle yes. Same as it 
is okay for all current greater than zero priorities to map to a single 
priority in case of GuC.


Regards,

Tvrtko



Matt


Signed-off-by: Tvrtko Ursulin 
---
  drivers/gpu/drm/i915/gem/i915_gem_context.c|  1 +
  .../gpu/drm/i915/gt/intel_execlists_submission.c   |  4 ++--
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c  |  2 +-
  drivers/gpu/drm/i915/i915_request.c|  2 +-
  drivers/gpu/drm/i915/i915_request.h|  5 +
  drivers/gpu/drm/i915/i915_scheduler.c  | 12 
  drivers/gpu/drm/i915/i915_scheduler.h  | 14 ++
  drivers/gpu/drm/i915/i915_scheduler_types.h|  8 
  8 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 8d4d687ab1d0..fed0733cb652 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -257,6 +257,7 @@ proto_context_create(struct drm_i915_private *i915, 
unsigned int flags)
if (i915->params.enable_hangcheck)
pc->user_flags |= BIT(UCONTEXT_PERSISTENCE);
pc->sched.priority = I915_PRIORITY_NORMAL;
+   pc->sched.nice = task_nice(current);
  
  	if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE) {

if (!HAS_EXECLISTS(i915)) {
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index e91d803a6453..1a02c65823a7 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -250,7 +250,7 @@ static struct i915_priolist *to_priolist(struct rb_node *rb)
  
  static int rq_prio(const struct i915_request *rq)

  {
-   return READ_ONCE(rq->sched.attr.priority);
+   return i915_request_priority(rq);
  }
  
  static int effective_prio(const struct i915_request *rq)

@@ -3221,8 +3221,8 @@ static void kick_execlists(const struct i915_request *rq,
  {
struct intel_engine_cs *engine = rq->engine;
struct i915_sched_engine *sched_engine = engine->sched_engine;
+   const int prio = i915_sched_attr_priority(attr);
const struct i915_request *inflight;
-   const int prio = attr->priority;
  
  	/*

 * We only need to kick the tasklet once for the high priority
diff --git 

Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-06 Thread Bjorn Andersson
On Wed 06 Oct 10:19 PDT 2021, Dmitry Baryshkov wrote:

> On 06/10/2021 20:07, Bjorn Andersson wrote:
> > On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:
> > 
> > > Quoting Bjorn Andersson (2021-10-05 19:37:52)
> > > > On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:
> > > > 
> > > > > Quoting Bjorn Andersson (2021-10-05 18:43:16)
> > > > > > On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:
> > > > > > 
> > > > > > > Quoting Bjorn Andersson (2021-10-05 16:13:21)
> > > > > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > > > > > > > b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > index bdaf227f05dc..674cddfee5b0 100644
> > > > > > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > @@ -1233,7 +1239,7 @@ static int dp_display_probe(struct 
> > > > > > > > platform_device *pdev)
> > > > > > > >  if (!dp)
> > > > > > > >  return -ENOMEM;
> > > > > > > > 
> > > > > > > > -   desc = dp_display_get_desc(pdev);
> > > > > > > > +   desc = dp_display_get_desc(pdev, >id);
> > > > > > > 
> > > > > > > I'm sad that dp->id has to match the number in the SoC specific
> > > > > > > dpu_intf_cfg array in 
> > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > > > > > > still. Is there any way we can avoid that? Also, notice how those 
> > > > > > > arrays
> > > > > > > already have INTF_DP macros, which makes me think that it may be 
> > > > > > > better
> > > > > > > to connect this to those arrays instead of making an msm_dp_desc
> > > > > > > structure and then make sure the 'type' member matches a connector
> > > > > > > type number. Otherwise this code is super fragile.
> > > > > > > 
> > > > > > 
> > > > > > I'm afraid I don't understand what you're proposing. Or which part 
> > > > > > you
> > > > > > consider fragile, the indices of the INTF_DP instances aren't going 
> > > > > > to
> > > > > > move around...
> > > > > > 
> > > > > > I have N instances of the DP driver that I need to match to N 
> > > > > > entries
> > > > > > from the platform specific intf array, I need some stable reference
> > > > > > between them. When I started this journey I figured I could rely on 
> > > > > > the
> > > > > > of_graph between the DPU and the interface controllers, but the 
> > > > > > values
> > > > > > used there today are just bogus, so that was a no go.
> > > > > > 
> > > > > > We can use whatever, as long as _dpu_kms_initialize_displayport() 
> > > > > > can
> > > > > > come up with an identifier to put in h_tile_instance[0] so that
> > > > > > dpu_encoder_setup_display() can find the relevant INTF.
> > > > > > 
> > > > > 
> > > > > To make it more concrete we can look at sc7180
> > > > > 
> > > > > static const struct dpu_intf_cfg sc7180_intf[] = {
> > > > >  INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
> > > > > INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > >   ^
> > > > >   |
> > > > > 
> > > > > intf0 is irrelevant. Also the address is irrelevant. But here we have 
> > > > > a
> > > > > zero, the number after INTF_DP, and that is very relevant. That number
> > > > > needs to match the dp->id. Somewhere we have a match between
> > > > > controller_id and dp->id in the code.
> > > > 
> > > > That number (the 0, not INTF_0) is what the code matches against dp->id
> > > > in _dpu_kms_initialize_displayport(), in order to figure out that this
> > > > is INTF_0 in dpu_encoder_setup_display().
> > > > 
> > > > I.e. look at the sc8180x patch:
> > > > 
> > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 24, 25),
> > > > INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 26, 27),
> > > > INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 28, 29),
> > > > /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until 
> > > > this is supported */
> > > > INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, 
> > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> > > > INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 20, 21),
> > > > INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 22, 23),
> > > > 
> > > > Where the DP driver defines the 3 controllers with dp->id of 0, 1 and 2,
> > > > which the DPU code will match against to INTF_0, INTF_4 and INTF_5.
> > > > 
> > > 
> > > Yep. I'm saying that having to make that number in this intf array match
> > > the order of the register mapping descriptor array is fragile. Why can't
> > > we indicate the interface is DP or eDP with INTF_DP or INTF_EDP and then
> > > map from the descriptor array to this intf array somehow so that the
> > > order of the descriptor array 

Re: [PATCH v1 2/2] drm/tegra: dc: rgb: Allow changing PLLD rate on Tegra30+

2021-10-06 Thread Dmitry Osipenko
06.10.2021 21:13, Thierry Reding пишет:
> On Thu, Sep 30, 2021 at 01:28:05AM +0300, Dmitry Osipenko wrote:
>> Asus Transformer TF700T is a Tegra30 tablet device which uses RGB->DSI
>> bridge that requires a precise clock rate in order to operate properly.
>> Tegra30 has a dedicated PLL for each display controller, hence the PLL
>> rate can be changed freely. Allow PLL rate changes on Tegra30+ for RGB
>> output. Configure the clock rate before display controller is enabled
>> since DC itself may be running off this PLL and it's not okay to change
>> the rate of the active PLL that doesn't support dynamic frequency
>> switching since hardware will hang.
>>
>> Tested-by: Maxim Schwalm  #TF700T
>> Signed-off-by: Dmitry Osipenko 
>> ---
>>  drivers/gpu/drm/tegra/dc.c  | 27 
>>  drivers/gpu/drm/tegra/dc.h  |  1 +
>>  drivers/gpu/drm/tegra/rgb.c | 49 +++--
>>  3 files changed, 65 insertions(+), 12 deletions(-)
> 
> This seems overly complicated. I especially don't like the way how
> clocks are looked up with clk_get_sys() and then used in the comparison.
> Could this not be achieved by using assigned-clocks and friends
> properties in DT?

Assigned-clocks have nothing to do with this patch. We need to check
whether PLLD *is* already pre-assigned as the parent.

Adding properties for describing the clk parents is overly complicated,
clk_get_sys() is a much simpler solution that doesn't involve extra DT
changes.

BTW, assigned-clocks can't be used for display controller  because
controller is usually turned on during boot and reparenting of active DC
will hang machine.


Re: [PATCH v6 6/6] drm/sprd: add Unisoc's drm mipi dsi driver

2021-10-06 Thread Kevin Tang
Sam,
Thanks for your response.

Sam Ravnborg  于2021年9月27日周一 上午12:33写道:
>
> Hi Kevin,
>
> > > > + reg->_0b.bits.out_sel = pll->out_sel;
> > > > + reg->_0b.bits.kint_l = pll->kint & 0xf;
> > > > + reg->_0e.bits.pll_pu_byp = 0;
> > > > + reg->_0e.bits.pll_pu = 0;
> > > > + reg->_0e.bits.stopstate_sel = 1;
> > > > + reg->_0f.bits.det_delay = pll->det_delay;
> > > > +
> > > > + val = (u8 *)
> > > > +
> > > > + for (i = 0; i < sizeof(reg_addr); ++i) {
> > > > + regmap_write(regmap, reg_addr[i], val[i]);
> > > > + DRM_DEBUG("%02x: %02x\n", reg_addr[i], val[i]);
> > > > + }
> > > > +}
> > >
> > > It would be great to also convert this part to a pattern without
> > > structures.
> > I will try it, but our pll registers, all not have official name from
> > aisc design owner.
> > If need to convert it, our pll regiters macro define, it can only be
> > named as reg_01, reg_02...
> IT is better to use the stupid names provided by you asic design owner,
> than just numbers. Add a comment explaining this is due to the asic
> design owner the names are stupid and not your fault.
The chip manual released to us by the asic designer is like this for
many years ago.
As for the specific reason, unable to find out now, i will try use
"stupid names" rather than numbers.
>
> > > > +
> > > > + if (dsi->panel) {
> > > > + drm_panel_prepare(dsi->panel);
> > > > + drm_panel_enable(dsi->panel);
> > > > + }
> > >
> > > Please use the new devm_drm_of_get_bridge helper here, and use the
> > > bridge API instead.
> > We use drm_panel_init and drm_panel_add API to add panel, so here is a
> > panel device, not a bridge.
>
> The new way to do this is to always wrap the panel in a bridge. We will
> start to slowly migrate away from direct use of the panel API, and let
> display drivers always wrap the panles in a bridge.
> So please do as Maxime suggests.
I only found a demo about the use of devm_drm_of_get_bridge in the vc4
dsi driver, i
will try to follow it.
>
> Sam


Re: [PATCH v6 2/3] arm64: tegra: Add NVDEC to Tegra186/194 device trees

2021-10-06 Thread Thierry Reding
On Thu, Sep 16, 2021 at 05:55:16PM +0300, Mikko Perttunen wrote:
> Add a device tree node for NVDEC on Tegra186, and
> device tree nodes for NVDEC and NVDEC1 on Tegra194.
> 
> Signed-off-by: Mikko Perttunen 
> ---
> v5:
> * Change from nvidia,instance to nvidia,host1x-class
> v4:
> * Add dma-coherent markers
> v3:
> * Change read2 to read-1
> v2:
> * Add NVDECSRD1 memory client
> * Add also to T194 (both NVDEC0/1)
> ---
>  arch/arm64/boot/dts/nvidia/tegra186.dtsi | 16 ++
>  arch/arm64/boot/dts/nvidia/tegra194.dtsi | 38 
>  2 files changed, 54 insertions(+)

The driver patch adds support for Tegra210, so could we also add NVDEC
entries for that?

Thierry


signature.asc
Description: PGP signature


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

2021-10-06 Thread Thierry Reding
On Thu, Sep 16, 2021 at 05:55:15PM +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 
> ---
> v6:
> * Elaborated description for nvidia,host1x-class.
> * Added default value for nvidia,host1x-class.
> v5:
> * Changed from nvidia,instance to nvidia,host1x-class optional
>   property.
> * Added dma-coherent
> v4:
> * Fix incorrect compatibility string in 'if' condition
> 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 | 108 ++
>  MAINTAINERS   |   1 +
>  2 files changed, 109 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra210-nvdec.yaml

Applied with the yamllint warning fixed.

Thanks,
Thierry


signature.asc
Description: PGP signature


Re: [PATCH v1 2/2] drm/tegra: dc: rgb: Allow changing PLLD rate on Tegra30+

2021-10-06 Thread Thierry Reding
On Thu, Sep 30, 2021 at 01:28:05AM +0300, Dmitry Osipenko wrote:
> Asus Transformer TF700T is a Tegra30 tablet device which uses RGB->DSI
> bridge that requires a precise clock rate in order to operate properly.
> Tegra30 has a dedicated PLL for each display controller, hence the PLL
> rate can be changed freely. Allow PLL rate changes on Tegra30+ for RGB
> output. Configure the clock rate before display controller is enabled
> since DC itself may be running off this PLL and it's not okay to change
> the rate of the active PLL that doesn't support dynamic frequency
> switching since hardware will hang.
> 
> Tested-by: Maxim Schwalm  #TF700T
> Signed-off-by: Dmitry Osipenko 
> ---
>  drivers/gpu/drm/tegra/dc.c  | 27 
>  drivers/gpu/drm/tegra/dc.h  |  1 +
>  drivers/gpu/drm/tegra/rgb.c | 49 +++--
>  3 files changed, 65 insertions(+), 12 deletions(-)

This seems overly complicated. I especially don't like the way how
clocks are looked up with clk_get_sys() and then used in the comparison.
Could this not be achieved by using assigned-clocks and friends
properties in DT?

Thierry


signature.asc
Description: PGP signature


Re: [PATCH v1 1/2] drm/tegra: dc: rgb: Move PCLK shifter programming to CRTC

2021-10-06 Thread Thierry Reding
On Thu, Sep 30, 2021 at 01:28:04AM +0300, Dmitry Osipenko wrote:
> Asus TF700T tablet uses TC358768 DPI->DSI bridge that sits between Tegra's
> DPI output and display panel input. Bridge requires to have stable PCLK
> output before RGB encoder is enabled because it uses PCLK by itself to
> clock internal logic and bridge is programmed before Tegra's encoder is
> enabled. Hence the PCLK clock shifter must be programmed when CRTC is
> enabled, otherwise clock is unstable and bridge hangs because of it.
> Move the shifter programming from RGB encoder into CRTC.
> 
> Tested-by: Maxim Schwalm  #TF700T
> Signed-off-by: Dmitry Osipenko 
> ---
>  drivers/gpu/drm/tegra/dc.c  | 6 ++
>  drivers/gpu/drm/tegra/rgb.c | 4 
>  2 files changed, 6 insertions(+), 4 deletions(-)

Applied, thanks.

Thierry


signature.asc
Description: PGP signature


Re: [PATCH v6 3/3] drm/tegra: Add NVDEC driver

2021-10-06 Thread Thierry Reding
On Thu, Sep 16, 2021 at 05:55:17PM +0300, Mikko Perttunen wrote:
> Add support for booting and using NVDEC on Tegra210, Tegra186
> and Tegra194 to the Host1x and TegraDRM drivers. Booting in
> secure mode is not currently supported.
> 
> Signed-off-by: Mikko Perttunen 
> ---
> v5:
> * Remove num_instances
> * Change from nvidia,instance to nvidia,host1x-class
> v3:
> * Change num_instances to unsigned int
> * Remove unnecessary '= 0' initializer
> * Populate num_instances data
> * Fix instance number check
> v2:
> * Use devm_platform_get_and_ioremap_resource
> * Remove reset handling, done by power domain code
> * Assume runtime PM is enabled
> ---
>  drivers/gpu/drm/tegra/Makefile |   3 +-
>  drivers/gpu/drm/tegra/drm.c|   4 +
>  drivers/gpu/drm/tegra/drm.h|   1 +
>  drivers/gpu/drm/tegra/nvdec.c  | 464 +
>  drivers/gpu/host1x/dev.c   |  18 ++
>  include/linux/host1x.h |   2 +
>  6 files changed, 491 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/tegra/nvdec.c

Applied, thanks.

Thierry


signature.asc
Description: PGP signature


Re: [PATCH] drm/tegra: Bump VIC/NVDEC clock rates to Fmax

2021-10-06 Thread Thierry Reding
On Thu, Sep 16, 2021 at 06:09:20PM +0300, Mikko Perttunen wrote:
> To get full performance out of these engines, bump their clock rates
> to maximum. In the future we may want something smarter but this
> should be fine for now.
> 
> Signed-off-by: Mikko Perttunen 
> ---
>  drivers/gpu/drm/tegra/nvdec.c | 6 ++
>  drivers/gpu/drm/tegra/vic.c   | 6 ++
>  2 files changed, 12 insertions(+)

Applied, thanks.

Thierry


signature.asc
Description: PGP signature


Re: mmotm 2021-10-05-19-53 uploaded (drivers/gpu/drm/msm/hdmi/hdmi_phy.o)

2021-10-06 Thread Randy Dunlap

On 10/6/21 12:24 AM, Christian König wrote:



Am 06.10.21 um 09:20 schrieb Stephen Rothwell:

Hi Randy,

On Tue, 5 Oct 2021 22:48:03 -0700 Randy Dunlap  wrote:

on i386:

ld: drivers/gpu/drm/msm/hdmi/hdmi_phy.o:(.rodata+0x3f0): undefined reference to 
`msm_hdmi_phy_8996_cfg'


Full randconfig fle is attached.

This would be because CONFIG_DRM_MSM is set but CONFIG_COMMON_CLOCK is
not and has been exposed by commit

   b3ed524f84f5 ("drm/msm: allow compile_test on !ARM")

from the drm-misc tree.


Good point, how about this change:

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 5879f67bc88c..d9879b011fb0 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -5,7 +5,7 @@ config DRM_MSM
     depends on DRM
     depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST
     depends on IOMMU_SUPPORT
-   depends on (OF && COMMON_CLK) || COMPILE_TEST
+   depends on (OF || COMPILE_TEST) && COMMON_CLK
     depends on QCOM_OCMEM || QCOM_OCMEM=n
     depends on QCOM_LLCC || QCOM_LLCC=n
     depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n


WorksForMe. Thanks.
(other than the whitespace damage)

--
~Randy


Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-06 Thread Bjorn Andersson
On Wed 06 Oct 10:19 PDT 2021, Stephen Boyd wrote:

> Quoting Bjorn Andersson (2021-10-06 10:07:17)
> > On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:
> >
> > > Quoting Bjorn Andersson (2021-10-05 19:37:52)
> > > > On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:
> > > >
> > > > > Quoting Bjorn Andersson (2021-10-05 18:43:16)
> > > > > > On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:
> > > > > >
> > > > > > > Quoting Bjorn Andersson (2021-10-05 16:13:21)
> > > > > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > > > > > > > b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > index bdaf227f05dc..674cddfee5b0 100644
> > > > > > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > @@ -1233,7 +1239,7 @@ static int dp_display_probe(struct 
> > > > > > > > platform_device *pdev)
> > > > > > > > if (!dp)
> > > > > > > > return -ENOMEM;
> > > > > > > >
> > > > > > > > -   desc = dp_display_get_desc(pdev);
> > > > > > > > +   desc = dp_display_get_desc(pdev, >id);
> > > > > > >
> > > > > > > I'm sad that dp->id has to match the number in the SoC specific
> > > > > > > dpu_intf_cfg array in 
> > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > > > > > > still. Is there any way we can avoid that? Also, notice how those 
> > > > > > > arrays
> > > > > > > already have INTF_DP macros, which makes me think that it may be 
> > > > > > > better
> > > > > > > to connect this to those arrays instead of making an msm_dp_desc
> > > > > > > structure and then make sure the 'type' member matches a connector
> > > > > > > type number. Otherwise this code is super fragile.
> > > > > > >
> > > > > >
> > > > > > I'm afraid I don't understand what you're proposing. Or which part 
> > > > > > you
> > > > > > consider fragile, the indices of the INTF_DP instances aren't going 
> > > > > > to
> > > > > > move around...
> > > > > >
> > > > > > I have N instances of the DP driver that I need to match to N 
> > > > > > entries
> > > > > > from the platform specific intf array, I need some stable reference
> > > > > > between them. When I started this journey I figured I could rely on 
> > > > > > the
> > > > > > of_graph between the DPU and the interface controllers, but the 
> > > > > > values
> > > > > > used there today are just bogus, so that was a no go.
> > > > > >
> > > > > > We can use whatever, as long as _dpu_kms_initialize_displayport() 
> > > > > > can
> > > > > > come up with an identifier to put in h_tile_instance[0] so that
> > > > > > dpu_encoder_setup_display() can find the relevant INTF.
> > > > > >
> > > > >
> > > > > To make it more concrete we can look at sc7180
> > > > >
> > > > > static const struct dpu_intf_cfg sc7180_intf[] = {
> > > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
> > > > > INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > >  ^
> > > > >  |
> > > > >
> > > > > intf0 is irrelevant. Also the address is irrelevant. But here we have 
> > > > > a
> > > > > zero, the number after INTF_DP, and that is very relevant. That number
> > > > > needs to match the dp->id. Somewhere we have a match between
> > > > > controller_id and dp->id in the code.
> > > >
> > > > That number (the 0, not INTF_0) is what the code matches against dp->id
> > > > in _dpu_kms_initialize_displayport(), in order to figure out that this
> > > > is INTF_0 in dpu_encoder_setup_display().
> > > >
> > > > I.e. look at the sc8180x patch:
> > > >
> > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 24, 25),
> > > > INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 26, 27),
> > > > INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 28, 29),
> > > > /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until 
> > > > this is supported */
> > > > INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, 
> > > > INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> > > > INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 20, 21),
> > > > INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, INTF_SC8180X_MASK, 
> > > > MDP_SSPP_TOP0_INTR, 22, 23),
> > > >
> > > > Where the DP driver defines the 3 controllers with dp->id of 0, 1 and 2,
> > > > which the DPU code will match against to INTF_0, INTF_4 and INTF_5.
> > > >
> > >
> > > Yep. I'm saying that having to make that number in this intf array match
> > > the order of the register mapping descriptor array is fragile. Why can't
> > > we indicate the interface is DP or eDP with INTF_DP or INTF_EDP and then
> > > map from the descriptor array to this intf array somehow so that the
> > > order of the descriptor array doesn't matter? Then we 

Re: [PATCH v6 6/6] drm/sprd: add Unisoc's drm mipi dsi driver

2021-10-06 Thread Kevin Tang
Maxime Ripard  于2021年9月28日周二 下午5:28写道:
>
> On Sun, Sep 26, 2021 at 10:31:53PM +0800, Kevin Tang wrote:
> > Maxime Ripard  于2021年9月17日周五 下午11:40写道:
> > > > +static void sprd_dsi_encoder_mode_set(struct drm_encoder *encoder,
> > > > +  struct drm_display_mode *mode,
> > > > +  struct drm_display_mode *adj_mode)
> > > > +{
> > > > + struct sprd_dsi *dsi = encoder_to_dsi(encoder);
> > > > +
> > > > + drm_dbg(dsi->drm, "%s() set mode: %s\n", __func__, 
> > > > dsi->mode->name);
> > > > +}
> > >
> > > You don't need that function?
> > No need for now. need to delete it?
>
> Yes
>
> > > > +static int sprd_dsi_encoder_atomic_check(struct drm_encoder *encoder,
> > > > + struct drm_crtc_state *crtc_state,
> > > > + struct drm_connector_state 
> > > > *conn_state)
> > > > +{
> > > > + return 0;
> > > > +}
> > >
> > > Ditto
> >
> > No need for now. need to delete it?
>
> Yep
>
> > > > +static int sprd_dsi_find_panel(struct sprd_dsi *dsi)
> > > > +{
> > > > + struct device *dev = dsi->host.dev;
> > > > + struct device_node *child, *lcds_node;
> > > > + struct drm_panel *panel;
> > > > +
> > > > + /* search /lcds child node first */
> > > > + lcds_node = of_find_node_by_path("/lcds");
> > > > + for_each_child_of_node(lcds_node, child) {
> > > > + panel = of_drm_find_panel(child);
> > > > + if (!IS_ERR(panel)) {
> > > > + dsi->panel = panel;
> > > > + return 0;
> > > > + }
> > > > + }
> > > > +
> > > > + /*
> > > > +  * If /lcds child node search failed, we search
> > > > +  * the child of dsi host node.
> > > > +  */
> > > > + for_each_child_of_node(dev->of_node, child) {
> > > > + panel = of_drm_find_panel(child);
> > > > + if (!IS_ERR(panel)) {
> > > > + dsi->panel = panel;
> > > > + return 0;
> > > > + }
> > > > + }
> > > > +
> > > > + drm_err(dsi->drm, "of_drm_find_panel() failed\n");
> > > > + return -ENODEV;
> > > > +}
> > >
> > > Just use devm_drm_of_get_bridge there
> >
> > We use drm_panel_init and drm_panel_add API to add panel, so here is a
> > panel device, not a bridge.
>
> Like Sam said, the panel API is on its way out and is being superseded
> by bridge_panels.
Ok, i will try it.
>
> > > > +static int sprd_dsi_host_init(struct sprd_dsi *dsi, struct device *dev)
> > > > +{
> > > > + int ret;
> > > > +
> > > > + dsi->host.dev = dev;
> > > > + dsi->host.ops = _dsi_host_ops;
> > > > +
> > > > + ret = mipi_dsi_host_register(>host);
> > > > + if (ret)
> > > > + drm_err(dsi->drm, "failed to register dsi host\n");
> > > > +
> > > > + return ret;
> > > > +}
> > > >
> > > > [...]
> > > >
> > > > +static int sprd_dsi_connector_init(struct drm_device *drm, struct 
> > > > sprd_dsi *dsi)
> > > > +{
> > > > + struct drm_encoder *encoder = >encoder;
> > > > + struct drm_connector *connector = >connector;
> > > > + int ret;
> > > > +
> > > > + connector->polled = DRM_CONNECTOR_POLL_HPD;
> > > > +
> > > > + ret = drm_connector_init(drm, connector,
> > > > +  _dsi_atomic_connector_funcs,
> > > > +  DRM_MODE_CONNECTOR_DSI);
> > > > + if (ret) {
> > > > + drm_err(drm, "drm_connector_init() failed\n");
> > > > + return ret;
> > > > + }
> > > > +
> > > > + drm_connector_helper_add(connector,
> > > > +  _dsi_connector_helper_funcs);
> > > > +
> > > > + drm_connector_attach_encoder(connector, encoder);
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static int sprd_dsi_context_init(struct sprd_dsi *dsi,
> > > > + struct device *dev)
> > > > +{
> > > > + struct platform_device *pdev = to_platform_device(dev);
> > > > + struct dsi_context *ctx = >ctx;
> > > > + struct resource *res;
> > > > +
> > > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > > + ctx->base = devm_ioremap(dev, res->start, resource_size(res));
> > > > + if (!ctx->base) {
> > > > + drm_err(dsi->drm, "failed to map dsi host registers\n");
> > > > + return -ENXIO;
> > > > + }
> > > > +
> > > > + ctx->pll = devm_kzalloc(dev, sizeof(*ctx->pll), GFP_KERNEL);
> > > > + if (!ctx->pll)
> > > > + return -ENOMEM;
> > > > +
> > > > + ctx->regmap = devm_regmap_init(dev, _tst_io, dsi, 
> > > > _config);
> > > > + if (IS_ERR(ctx->regmap)) {
> > > > + drm_err(dsi->drm, "dphy regmap init failed\n");
> > > > + return PTR_ERR(ctx->regmap);
> > > > + }
> > > > +
> > > > + ctx->data_hs2lp = 120;
> > > > + ctx->data_lp2hs = 500;
> > > > + ctx->clk_hs2lp = 4;
> > > > + ctx->clk_lp2hs = 15;
> > > > 

Re: [PATCH] drm/msm/dp: Shorten SETUP timeout

2021-10-06 Thread Bjorn Andersson
On Wed 06 Oct 08:37 PDT 2021, khs...@codeaurora.org wrote:

> On 2021-10-05 19:10, Bjorn Andersson wrote:
> > On Tue 05 Oct 16:04 PDT 2021, khs...@codeaurora.org wrote:
> > 
> > > On 2021-10-05 15:36, Stephen Boyd wrote:
> > > > Quoting Bjorn Andersson (2021-10-05 14:40:38)
> > > > > On Tue 05 Oct 11:45 PDT 2021, Stephen Boyd wrote:
> > > > >
> > > > > > Quoting Bjorn Andersson (2021-10-04 19:37:50)
> > > > > > > Found in the middle of a patch from Sankeerth was the reduction 
> > > > > > > of the
> > > > > > > INIT_SETUP timeout from 10s to 100ms. Upon INIT_SETUP timeout the 
> > > > > > > host
> > > > > > > is initalized and HPD interrupt start to be serviced, so in the 
> > > > > > > case of
> > > > > > > eDP this reduction improves the user experience dramatically - 
> > > > > > > i.e.
> > > > > > > removes 9.9s of bland screen time at boot.
> > > > > > >
> > > > > > > Suggested-by: Sankeerth Billakanti 
> > > > > > > Signed-off-by: Bjorn Andersson 
> > > > > > > ---
> > > > > >
> > > > > > Any Fixes tag? BTW, the delay design is pretty convoluted. I had to 
> > > > > > go
> > > > > > re-read the code a couple times to understand that it's waiting 
> > > > > > 100ms
> > > > > > times the 'delay' number. What?
> > > > > >
> > > > >
> > > > > I assume you're happy with the current 10s delay on the current
> > > > > devices, so I don't think we should push for this to be backported.
> > > > > I have no need for it to be backported on my side at least.
> > > > >
> > > >
> > > > Sure. Fixes tag != backported to stable trees but it is close.
> > > >
> > > > > > Reviewed-by: Stephen Boyd 
> > > > >
> > >   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 1); <== to 100ms
> > > 
> > > This patch will prevent usb3 from working due to dp driver
> > > initialize phy
> > > earlier than usb3 which cause timeout error at power up usb3 phy
> > > when both
> > > edp and dp are enabled.
> > 
> > Can you please help me understand what you mean here, I use this on my
> > sc8180x with both eDP and USB-C/DP right now. What is it that doesn't
> > work? Or am I just lucky in some race condition?
> > 
> > Thanks,
> > Bjorn
> > 
> The problem is seen at sc7280.
> Apple dongle have both  hdmi and usb port.
> plug Apple dongle into type-c, then plug DP into apple's hdmi port and usb
> mouse into apple's usb port.
> If edp enabled at this time, then usb mouse will not work due to timeout at
> phy power up.
> 

Okay, so you're saying that if the DP driver invokes phy_power_on()
before the USB driver does, USB initialization fails (or at least USB
doesn't work)?

Sounds like something we need to work out in the QMP phy driver. Do you
have any more details about what's going wrong.


Also, I've seen various references to said "Apple dongle", do you have a
link to the exact one you're testing with so I can pick one up for
testing purposes as well?

Regards,
Bjorn

> > > I had prepared a patch (drm/msm/dp: do not initialize combo phy
> > > until plugin
> > > interrupt) to fix this problem.
> > > Unfortunately, my patch is depend on Bjorn's patch (PATCH v3 3/5]
> > > drm/msm/dp: Support up to 3 DP controllers).
> > > I will submit my patch for review once Bjorn's patches merged in.
> > > Therefore I would think this patch should go after both Bjorn's
> > > patches and
> > > my patch.
> > > 
> > > 
> > > 


Re: [Intel-gfx] [RFC 7/8] drm/i915: Inherit process nice for context scheduling priority

2021-10-06 Thread Matthew Brost
On Mon, Oct 04, 2021 at 03:36:49PM +0100, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> Introduce the concept of context nice value which matches the process
> nice.
> 
> We do this by extending the struct i915_sched_attr and add a helper
> (i915_sched_attr_priority) to be used to convert to effective priority
> when used by backend code and for priority sorting.
> 
> Context nice is then inherited from the process which creates the GEM
> context and utilised secondary to context priority, only when the latter
> has been left at the default setting, in order to avoid disturbing any
> application made choices of low and high (batch processing and maybe
> latency sensitive compositing). In those cases nice value adjusts the
> effective priority in the narrow band of -19 to +20 around
> I915_CONTEXT_DEFAULT_PRIORITY.
> 
> This means that in theory userspace using the context priority uapi
> directly has a wider range of possible adjustments (thought to be
> beneficial), but in practice that only applies to execlists platforms.
> With GuC there are only three priority buckets (less than zero is low
> priority, zero is normal and greater than zero is high) which therefore
> interact as expected with the nice adjustment. It makes the question of
> should the nice be a sub-range of GEM priorities, or stretched across the
> whole, a moot one.
> 

Opps, sorry for the double reply to this patch - for some reason I
thinking the below comment would be on the next patch.

The GuC + DRM scheduler actually has 4 priorities with the highest
reserved for the KMD, so 3 user levels which is what I think you mean.
So how would this work with only 3 levels? 

The nice value can move a normal priority value to either low or high,
right?

Normal to low seems fine but would moving to high be an issue?

I thought a high level was reserved for elevated user processes (e.g. a
root user or a compositor)?

Would it be ok for a non-elevated user process to be the same priority
as an elevated process?

Matt

> Signed-off-by: Tvrtko Ursulin 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c|  1 +
>  .../gpu/drm/i915/gt/intel_execlists_submission.c   |  4 ++--
>  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c  |  2 +-
>  drivers/gpu/drm/i915/i915_request.c|  2 +-
>  drivers/gpu/drm/i915/i915_request.h|  5 +
>  drivers/gpu/drm/i915/i915_scheduler.c  | 12 
>  drivers/gpu/drm/i915/i915_scheduler.h  | 14 ++
>  drivers/gpu/drm/i915/i915_scheduler_types.h|  8 
>  8 files changed, 40 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 8d4d687ab1d0..fed0733cb652 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -257,6 +257,7 @@ proto_context_create(struct drm_i915_private *i915, 
> unsigned int flags)
>   if (i915->params.enable_hangcheck)
>   pc->user_flags |= BIT(UCONTEXT_PERSISTENCE);
>   pc->sched.priority = I915_PRIORITY_NORMAL;
> + pc->sched.nice = task_nice(current);
>  
>   if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE) {
>   if (!HAS_EXECLISTS(i915)) {
> diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
> b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> index e91d803a6453..1a02c65823a7 100644
> --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> @@ -250,7 +250,7 @@ static struct i915_priolist *to_priolist(struct rb_node 
> *rb)
>  
>  static int rq_prio(const struct i915_request *rq)
>  {
> - return READ_ONCE(rq->sched.attr.priority);
> + return i915_request_priority(rq);
>  }
>  
>  static int effective_prio(const struct i915_request *rq)
> @@ -3221,8 +3221,8 @@ static void kick_execlists(const struct i915_request 
> *rq,
>  {
>   struct intel_engine_cs *engine = rq->engine;
>   struct i915_sched_engine *sched_engine = engine->sched_engine;
> + const int prio = i915_sched_attr_priority(attr);
>   const struct i915_request *inflight;
> - const int prio = attr->priority;
>  
>   /*
>* We only need to kick the tasklet once for the high priority
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> index b5883a4365ca..f258607685a2 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> @@ -2417,7 +2417,7 @@ static void guc_bump_inflight_request_prio(struct 
> i915_request *rq,
>  const struct i915_sched_attr *attr)
>  {
>   struct intel_context *ce = rq->context;
> - const int prio = attr->priority;
> + const int prio = i915_sched_attr_priority(attr);
>   u8 new_guc_prio = 

Re: [Intel-gfx] [RFC 7/8] drm/i915: Inherit process nice for context scheduling priority

2021-10-06 Thread Matthew Brost
On Mon, Oct 04, 2021 at 03:36:49PM +0100, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> Introduce the concept of context nice value which matches the process
> nice.
> 
> We do this by extending the struct i915_sched_attr and add a helper
> (i915_sched_attr_priority) to be used to convert to effective priority
> when used by backend code and for priority sorting.
> 
> Context nice is then inherited from the process which creates the GEM
> context and utilised secondary to context priority, only when the latter
> has been left at the default setting, in order to avoid disturbing any
> application made choices of low and high (batch processing and maybe
> latency sensitive compositing). In those cases nice value adjusts the
> effective priority in the narrow band of -19 to +20 around
> I915_CONTEXT_DEFAULT_PRIORITY.
> 
> This means that in theory userspace using the context priority uapi
> directly has a wider range of possible adjustments (thought to be
> beneficial), but in practice that only applies to execlists platforms.
> With GuC there are only three priority buckets (less than zero is low
> priority, zero is normal and greater than zero is high) which therefore
> interact as expected with the nice adjustment. It makes the question of
> should the nice be a sub-range of GEM priorities, or stretched across the
> whole, a moot one.
> 
> Signed-off-by: Tvrtko Ursulin 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c|  1 +
>  .../gpu/drm/i915/gt/intel_execlists_submission.c   |  4 ++--
>  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c  |  2 +-
>  drivers/gpu/drm/i915/i915_request.c|  2 +-
>  drivers/gpu/drm/i915/i915_request.h|  5 +
>  drivers/gpu/drm/i915/i915_scheduler.c  | 12 
>  drivers/gpu/drm/i915/i915_scheduler.h  | 14 ++
>  drivers/gpu/drm/i915/i915_scheduler_types.h|  8 
>  8 files changed, 40 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 8d4d687ab1d0..fed0733cb652 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -257,6 +257,7 @@ proto_context_create(struct drm_i915_private *i915, 
> unsigned int flags)
>   if (i915->params.enable_hangcheck)
>   pc->user_flags |= BIT(UCONTEXT_PERSISTENCE);
>   pc->sched.priority = I915_PRIORITY_NORMAL;
> + pc->sched.nice = task_nice(current);
>  
>   if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE) {
>   if (!HAS_EXECLISTS(i915)) {
> diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
> b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> index e91d803a6453..1a02c65823a7 100644
> --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> @@ -250,7 +250,7 @@ static struct i915_priolist *to_priolist(struct rb_node 
> *rb)
>  
>  static int rq_prio(const struct i915_request *rq)
>  {
> - return READ_ONCE(rq->sched.attr.priority);
> + return i915_request_priority(rq);
>  }
>  
>  static int effective_prio(const struct i915_request *rq)
> @@ -3221,8 +3221,8 @@ static void kick_execlists(const struct i915_request 
> *rq,
>  {
>   struct intel_engine_cs *engine = rq->engine;
>   struct i915_sched_engine *sched_engine = engine->sched_engine;
> + const int prio = i915_sched_attr_priority(attr);
>   const struct i915_request *inflight;
> - const int prio = attr->priority;
>  
>   /*
>* We only need to kick the tasklet once for the high priority
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> index b5883a4365ca..f258607685a2 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> @@ -2417,7 +2417,7 @@ static void guc_bump_inflight_request_prio(struct 
> i915_request *rq,
>  const struct i915_sched_attr *attr)
>  {
>   struct intel_context *ce = rq->context;
> - const int prio = attr->priority;
> + const int prio = i915_sched_attr_priority(attr);
>   u8 new_guc_prio = map_i915_prio_to_guc_prio(prio);
>  
>   /* Short circuit function */
> diff --git a/drivers/gpu/drm/i915/i915_request.c 
> b/drivers/gpu/drm/i915/i915_request.c
> index 79da5eca60af..a8c6f3a64895 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -1930,7 +1930,7 @@ static int print_sched_attr(const struct 
> i915_sched_attr *attr,
>   return x;
>  
>   x += snprintf(buf + x, len - x,
> -   " prio=%d", attr->priority);
> +   " prio=%d nice=%d", attr->priority, attr->nice);
>  
>   return x;
>  }
> diff --git a/drivers/gpu/drm/i915/i915_request.h 
> 

Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-06 Thread Dmitry Baryshkov

On 06/10/2021 20:07, Bjorn Andersson wrote:

On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:


Quoting Bjorn Andersson (2021-10-05 19:37:52)

On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:


Quoting Bjorn Andersson (2021-10-05 18:43:16)

On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:


Quoting Bjorn Andersson (2021-10-05 16:13:21)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index bdaf227f05dc..674cddfee5b0 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1233,7 +1239,7 @@ static int dp_display_probe(struct platform_device *pdev)
 if (!dp)
 return -ENOMEM;

-   desc = dp_display_get_desc(pdev);
+   desc = dp_display_get_desc(pdev, >id);


I'm sad that dp->id has to match the number in the SoC specific
dpu_intf_cfg array in drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
still. Is there any way we can avoid that? Also, notice how those arrays
already have INTF_DP macros, which makes me think that it may be better
to connect this to those arrays instead of making an msm_dp_desc
structure and then make sure the 'type' member matches a connector
type number. Otherwise this code is super fragile.



I'm afraid I don't understand what you're proposing. Or which part you
consider fragile, the indices of the INTF_DP instances aren't going to
move around...

I have N instances of the DP driver that I need to match to N entries
from the platform specific intf array, I need some stable reference
between them. When I started this journey I figured I could rely on the
of_graph between the DPU and the interface controllers, but the values
used there today are just bogus, so that was a no go.

We can use whatever, as long as _dpu_kms_initialize_displayport() can
come up with an identifier to put in h_tile_instance[0] so that
dpu_encoder_setup_display() can find the relevant INTF.



To make it more concrete we can look at sc7180

static const struct dpu_intf_cfg sc7180_intf[] = {
 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
  ^
  |

intf0 is irrelevant. Also the address is irrelevant. But here we have a
zero, the number after INTF_DP, and that is very relevant. That number
needs to match the dp->id. Somewhere we have a match between
controller_id and dp->id in the code.


That number (the 0, not INTF_0) is what the code matches against dp->id
in _dpu_kms_initialize_displayport(), in order to figure out that this
is INTF_0 in dpu_encoder_setup_display().

I.e. look at the sc8180x patch:

INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC8180X_MASK, 
MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC8180X_MASK, 
MDP_SSPP_TOP0_INTR, 26, 27),
INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC8180X_MASK, 
MDP_SSPP_TOP0_INTR, 28, 29),
/* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is 
supported */
INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC8180X_MASK, 
MDP_SSPP_TOP0_INTR, 30, 31),
INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, INTF_SC8180X_MASK, 
MDP_SSPP_TOP0_INTR, 20, 21),
INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, INTF_SC8180X_MASK, 
MDP_SSPP_TOP0_INTR, 22, 23),

Where the DP driver defines the 3 controllers with dp->id of 0, 1 and 2,
which the DPU code will match against to INTF_0, INTF_4 and INTF_5.



Yep. I'm saying that having to make that number in this intf array match
the order of the register mapping descriptor array is fragile. Why can't
we indicate the interface is DP or eDP with INTF_DP or INTF_EDP and then
map from the descriptor array to this intf array somehow so that the
order of the descriptor array doesn't matter? Then we don't have to put
the connector type in the descriptor array, and we don't have to keep
the order of the array a certain way to match this intf descriptor.

Maybe

struct msm_dp_desc {
phys_addr_t io_start;
unsigned int id;


The INTF_ constants are a property of the DPU driver and not
available in the DP driver and the msm_dp struct is a property of the DP
driver and can't be dereferenced in the DPU driver.

The proposed way around this is that the descs array defines the order
in priv->dp[N] and this N is used as controller_id.


So the only thing that I don't find straight forward here is that the
eDP controller is considered just a DP controller, so you have to use
INTF_DP,  for that, and not just INTF_EDP, 0.


Would it be better if we change the DPU driver to handle INTF_EDP too?




};

and then have msm_dp_desc::id equal INTF_ and then look through the
intf from DPU here in the DP driver to find the id and type of connector
that should be used by default? Still sort of fragile because the only
connection is an unsigned int 

Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-06 Thread Stephen Boyd
Quoting Bjorn Andersson (2021-10-06 10:07:17)
> On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:
>
> > Quoting Bjorn Andersson (2021-10-05 19:37:52)
> > > On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:
> > >
> > > > Quoting Bjorn Andersson (2021-10-05 18:43:16)
> > > > > On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:
> > > > >
> > > > > > Quoting Bjorn Andersson (2021-10-05 16:13:21)
> > > > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > > > > > > b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > index bdaf227f05dc..674cddfee5b0 100644
> > > > > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > @@ -1233,7 +1239,7 @@ static int dp_display_probe(struct 
> > > > > > > platform_device *pdev)
> > > > > > > if (!dp)
> > > > > > > return -ENOMEM;
> > > > > > >
> > > > > > > -   desc = dp_display_get_desc(pdev);
> > > > > > > +   desc = dp_display_get_desc(pdev, >id);
> > > > > >
> > > > > > I'm sad that dp->id has to match the number in the SoC specific
> > > > > > dpu_intf_cfg array in drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > > > > > still. Is there any way we can avoid that? Also, notice how those 
> > > > > > arrays
> > > > > > already have INTF_DP macros, which makes me think that it may be 
> > > > > > better
> > > > > > to connect this to those arrays instead of making an msm_dp_desc
> > > > > > structure and then make sure the 'type' member matches a connector
> > > > > > type number. Otherwise this code is super fragile.
> > > > > >
> > > > >
> > > > > I'm afraid I don't understand what you're proposing. Or which part you
> > > > > consider fragile, the indices of the INTF_DP instances aren't going to
> > > > > move around...
> > > > >
> > > > > I have N instances of the DP driver that I need to match to N entries
> > > > > from the platform specific intf array, I need some stable reference
> > > > > between them. When I started this journey I figured I could rely on 
> > > > > the
> > > > > of_graph between the DPU and the interface controllers, but the values
> > > > > used there today are just bogus, so that was a no go.
> > > > >
> > > > > We can use whatever, as long as _dpu_kms_initialize_displayport() can
> > > > > come up with an identifier to put in h_tile_instance[0] so that
> > > > > dpu_encoder_setup_display() can find the relevant INTF.
> > > > >
> > > >
> > > > To make it more concrete we can look at sc7180
> > > >
> > > > static const struct dpu_intf_cfg sc7180_intf[] = {
> > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
> > > > INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > >  ^
> > > >  |
> > > >
> > > > intf0 is irrelevant. Also the address is irrelevant. But here we have a
> > > > zero, the number after INTF_DP, and that is very relevant. That number
> > > > needs to match the dp->id. Somewhere we have a match between
> > > > controller_id and dp->id in the code.
> > >
> > > That number (the 0, not INTF_0) is what the code matches against dp->id
> > > in _dpu_kms_initialize_displayport(), in order to figure out that this
> > > is INTF_0 in dpu_encoder_setup_display().
> > >
> > > I.e. look at the sc8180x patch:
> > >
> > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC8180X_MASK, 
> > > MDP_SSPP_TOP0_INTR, 24, 25),
> > > INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC8180X_MASK, 
> > > MDP_SSPP_TOP0_INTR, 26, 27),
> > > INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC8180X_MASK, 
> > > MDP_SSPP_TOP0_INTR, 28, 29),
> > > /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until 
> > > this is supported */
> > > INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC8180X_MASK, 
> > > MDP_SSPP_TOP0_INTR, 30, 31),
> > > INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, INTF_SC8180X_MASK, 
> > > MDP_SSPP_TOP0_INTR, 20, 21),
> > > INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, INTF_SC8180X_MASK, 
> > > MDP_SSPP_TOP0_INTR, 22, 23),
> > >
> > > Where the DP driver defines the 3 controllers with dp->id of 0, 1 and 2,
> > > which the DPU code will match against to INTF_0, INTF_4 and INTF_5.
> > >
> >
> > Yep. I'm saying that having to make that number in this intf array match
> > the order of the register mapping descriptor array is fragile. Why can't
> > we indicate the interface is DP or eDP with INTF_DP or INTF_EDP and then
> > map from the descriptor array to this intf array somehow so that the
> > order of the descriptor array doesn't matter? Then we don't have to put
> > the connector type in the descriptor array, and we don't have to keep
> > the order of the array a certain way to match this intf descriptor.
> >
> > Maybe
> >
> >   struct msm_dp_desc {
> >   phys_addr_t io_start;
> >   unsigned int id;
>
> The INTF_ constants are a property of 

Re: [RFC 6/8] drm/i915: Make some recently added vfuncs use full scheduling attribute

2021-10-06 Thread Matthew Brost
On Mon, Oct 04, 2021 at 03:36:48PM +0100, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> Code added in 71ed60112d5d ("drm/i915: Add kick_backend function to
> i915_sched_engine") and ee242ca704d3 ("drm/i915/guc: Implement GuC
> priority management") introduced some scheduling related vfuncs which
> take integer request priority as argument.
> 
> Make them instead take struct i915_sched_attr, which is the type
> encapsulating this information, so it probably aligns with the design
> better. It definitely enables extending the set of scheduling attributes.
> 

Understand the motivation here but the i915_scheduler is going to
disapear when we move to the DRM scheduler or at least its functionality
of priority inheritance will be pushed into the DRM scheduler. I'd be
very careful making any changes here as the priority in the DRM
scheduler is defined as single enum:

/* These are often used as an (initial) index
 * to an array, and as such should start at 0.
 */
enum drm_sched_priority {
DRM_SCHED_PRIORITY_MIN,
DRM_SCHED_PRIORITY_NORMAL,
DRM_SCHED_PRIORITY_HIGH,
DRM_SCHED_PRIORITY_KERNEL,

DRM_SCHED_PRIORITY_COUNT,
DRM_SCHED_PRIORITY_UNSET = -2
};

Adding a field to the i915_sched_attr is fairly easy as we already have
a structure but changing the DRM scheduler might be a tougher sell.
Anyway you can make this work without adding the 'nice' field to
i915_sched_attr? Might be worth exploring so when we move to the DRM
scheduler this feature drops in a little cleaner.

Matt

> Signed-off-by: Tvrtko Ursulin 
> Cc: Matthew Brost 
> Cc: Daniele Ceraolo Spurio 
> ---
>  drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 4 +++-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c| 3 ++-
>  drivers/gpu/drm/i915/i915_scheduler.c| 4 ++--
>  drivers/gpu/drm/i915/i915_scheduler_types.h  | 4 ++--
>  4 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
> b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> index 7147fe80919e..e91d803a6453 100644
> --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> @@ -3216,11 +3216,13 @@ static bool can_preempt(struct intel_engine_cs 
> *engine)
>   return engine->class != RENDER_CLASS;
>  }
>  
> -static void kick_execlists(const struct i915_request *rq, int prio)
> +static void kick_execlists(const struct i915_request *rq,
> +const struct i915_sched_attr *attr)
>  {
>   struct intel_engine_cs *engine = rq->engine;
>   struct i915_sched_engine *sched_engine = engine->sched_engine;
>   const struct i915_request *inflight;
> + const int prio = attr->priority;
>  
>   /*
>* We only need to kick the tasklet once for the high priority
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> index ba0de35f6323..b5883a4365ca 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> @@ -2414,9 +2414,10 @@ static void guc_init_breadcrumbs(struct 
> intel_engine_cs *engine)
>  }
>  
>  static void guc_bump_inflight_request_prio(struct i915_request *rq,
> -int prio)
> +const struct i915_sched_attr *attr)
>  {
>   struct intel_context *ce = rq->context;
> + const int prio = attr->priority;
>   u8 new_guc_prio = map_i915_prio_to_guc_prio(prio);
>  
>   /* Short circuit function */
> diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
> b/drivers/gpu/drm/i915/i915_scheduler.c
> index 762127dd56c5..534bab99fcdc 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler.c
> +++ b/drivers/gpu/drm/i915/i915_scheduler.c
> @@ -255,7 +255,7 @@ static void __i915_schedule(struct i915_sched_node *node,
>  
>   /* Must be called before changing the nodes priority */
>   if (sched_engine->bump_inflight_request_prio)
> - sched_engine->bump_inflight_request_prio(from, prio);
> + sched_engine->bump_inflight_request_prio(from, attr);
>  
>   WRITE_ONCE(node->attr.priority, prio);
>  
> @@ -280,7 +280,7 @@ static void __i915_schedule(struct i915_sched_node *node,
>  
>   /* Defer (tasklet) submission until after all of our updates. */
>   if (sched_engine->kick_backend)
> - sched_engine->kick_backend(node_to_request(node), prio);
> + sched_engine->kick_backend(node_to_request(node), attr);
>   }
>  
>   spin_unlock(_engine->lock);
> diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h 
> b/drivers/gpu/drm/i915/i915_scheduler_types.h
> index b0a1b58c7893..24b9ac1c2ce2 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler_types.h
> +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h

Re: [PATCH] drm/i915/pmu: Connect engine busyness stats from GuC to pmu

2021-10-06 Thread Matthew Brost
On Wed, Oct 06, 2021 at 09:22:42AM +0100, Tvrtko Ursulin wrote:
> 
> On 06/10/2021 00:14, Matthew Brost wrote:
> > On Tue, Oct 05, 2021 at 10:47:11AM -0700, Umesh Nerlige Ramappa wrote:
> > > With GuC handling scheduling, i915 is not aware of the time that a
> > > context is scheduled in and out of the engine. Since i915 pmu relies on
> > > this info to provide engine busyness to the user, GuC shares this info
> > > with i915 for all engines using shared memory. For each engine, this
> > > info contains:
> > > 
> > > - total busyness: total time that the context was running (total)
> > > - id: id of the running context (id)
> > > - start timestamp: timestamp when the context started running (start)
> > > 
> > > At the time (now) of sampling the engine busyness, if the id is valid
> > > (!= ~0), and start is non-zero, then the context is considered to be
> > > active and the engine busyness is calculated using the below equation
> > > 
> > >   engine busyness = total + (now - start)
> > > 
> > > All times are obtained from the gt clock base. For inactive contexts,
> > > engine busyness is just equal to the total.
> > > 
> > > The start and total values provided by GuC are 32 bits and wrap around
> > > in a few minutes. Since perf pmu provides busyness as 64 bit
> > > monotonically increasing values, there is a need for this implementation
> > > to account for overflows and extend the time to 64 bits before returning
> > > busyness to the user. In order to do that, a worker runs periodically at
> > > frequency = 1/8th the time it takes for the timestamp to wrap. As an
> > > example, that would be once in 27 seconds for a gt clock frequency of
> > > 19.2 MHz.
> > > 
> > > Opens and wip that are targeted for later patches:
> > > 
> > > 1) On global gt reset the total busyness of engines resets and i915
> > > needs to fix that so that user sees monotonically increasing
> > > busyness.
> > > 2) In runtime suspend mode, the worker may not need to be run. We could
> > > stop the worker on suspend and rerun it on resume provided that the
> > > guc pm timestamp does not tick during suspend.
> > > 
> > > Note:
> > > There might be an overaccounting of busyness due to the fact that GuC
> > > may be updating the total and start values while kmd is reading them.
> > > (i.e kmd may read the updated total and the stale start). In such a
> > > case, user may see higher busyness value followed by smaller ones which
> > > would eventually catch up to the higher value.
> > > 
> > > v2: (Tvrtko)
> > > - Include details in commit message
> > > - Move intel engine busyness function into execlist code
> > > - Use union inside engine->stats
> > > - Use natural type for ping delay jiffies
> > > - Drop active_work condition checks
> > > - Use for_each_engine if iterating all engines
> > > - Drop seq locking, use spinlock at guc level to update engine stats
> > > - Document worker specific details
> > > 
> > > v3: (Tvrtko/Umesh)
> > > - Demarcate guc and execlist stat objects with comments
> > > - Document known over-accounting issue in commit
> > > - Provide a consistent view of guc state
> > > - Add hooks to gt park/unpark for guc busyness
> > > - Stop/start worker in gt park/unpark path
> > > - Drop inline
> > > - Move spinlock and worker inits to guc initialization
> > > - Drop helpers that are called only once
> > > 
> > > Signed-off-by: John Harrison 
> > > Signed-off-by: Umesh Nerlige Ramappa 
> > > ---
> > >   drivers/gpu/drm/i915/gt/intel_engine_cs.c |  26 +-
> > >   drivers/gpu/drm/i915/gt/intel_engine_types.h  |  90 +--
> > >   .../drm/i915/gt/intel_execlists_submission.c  |  32 +++
> > >   drivers/gpu/drm/i915/gt/intel_gt_pm.c |   2 +
> > >   .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   1 +
> > >   drivers/gpu/drm/i915/gt/uc/intel_guc.h|  26 ++
> > >   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  21 ++
> > >   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h|   5 +
> > >   drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  13 +
> > >   .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 227 ++
> > >   .../gpu/drm/i915/gt/uc/intel_guc_submission.h |   2 +
> > >   drivers/gpu/drm/i915/i915_reg.h   |   2 +
> > >   12 files changed, 398 insertions(+), 49 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> > > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > > index 2ae57e4656a3..6fcc70a313d9 100644
> > > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > > @@ -1873,22 +1873,6 @@ void intel_engine_dump(struct intel_engine_cs 
> > > *engine,
> > >   intel_engine_print_breadcrumbs(engine, m);
> > >   }
> > > -static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs 
> > > *engine,
> > > - ktime_t *now)
> > > -{
> > > - ktime_t total = engine->stats.total;
> > > -
> > > - /*
> > > -  * If the engine is executing something 

RE: [PATCH i-g-t 1/1] tests/i915_pxp: Use ioctl_wrapper for DRM_IOCTL_PRIME_HANDLE_TO_FD

2021-10-06 Thread Ruhl, Michael J
>-Original Message-
>From: Teres Alexis, Alan Previn 
>Sent: Wednesday, October 6, 2021 12:52 PM
>To: igt-...@lists.freedesktop.org
>Cc: Teres Alexis, Alan Previn ; dri-
>de...@lists.freedesktop.org; Ruhl; Ruhl, Michael J
>; Vivi, Rodrigo 
>Subject: [PATCH i-g-t 1/1] tests/i915_pxp: Use ioctl_wrapper for
>DRM_IOCTL_PRIME_HANDLE_TO_FD
>
>Replace private helper with call to ioctl_wrapper for
>DRM_IOCTL_PRIME_HANDLE_TO_FD.

Reviewed-by: Michael J. Ruhl 

M

>Signed-off-by: Alan Previn 
>---
> tests/i915/gem_pxp.c | 20 +---
> 1 file changed, 1 insertion(+), 19 deletions(-)
>
>diff --git a/tests/i915/gem_pxp.c b/tests/i915/gem_pxp.c
>index 79040165..0430f4b8 100644
>--- a/tests/i915/gem_pxp.c
>+++ b/tests/i915/gem_pxp.c
>@@ -622,23 +622,6 @@ static void test_render_pxp_protsrc_to_protdest(int
>i915)
>   buf_ops_destroy(bops);
> }
>
>-static int export_handle(int fd, uint32_t handle, int *outfd)
>-{
>-  struct drm_prime_handle args;
>-  int ret;
>-
>-  args.handle = handle;
>-  args.flags = DRM_CLOEXEC;
>-  args.fd = -1;
>-
>-  ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, );
>-  if (ret)
>-  ret = errno;
>-  *outfd = args.fd;
>-
>-  return ret;
>-}
>-
> static void test_pxp_dmabuffshare_refcnt(void)
> {
>   uint32_t ctx[2], sbo[2], dbo[2];
>@@ -659,8 +642,7 @@ static void test_pxp_dmabuffshare_refcnt(void)
>   dbo[0] = alloc_and_fill_dest_buff(fd[0], true,
>TSTSURF_SIZE,
>
>TSTSURF_INITCOLOR1);
>   } else {
>-  ret = export_handle(fd[0], dbo[0], _fd);
>-  igt_assert(ret == 0);
>+  dmabuf_fd = prime_handle_to_fd(fd[0], dbo[0]);
>   dbo[1] = prime_fd_to_handle(fd[1], dmabuf_fd);
>   igt_assert(dbo[1]);
>   }
>--
>2.25.1



Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-06 Thread Bjorn Andersson
On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:

> Quoting Bjorn Andersson (2021-10-05 19:37:52)
> > On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:
> >
> > > Quoting Bjorn Andersson (2021-10-05 18:43:16)
> > > > On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:
> > > >
> > > > > Quoting Bjorn Andersson (2021-10-05 16:13:21)
> > > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > > > > > b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > index bdaf227f05dc..674cddfee5b0 100644
> > > > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > @@ -1233,7 +1239,7 @@ static int dp_display_probe(struct 
> > > > > > platform_device *pdev)
> > > > > > if (!dp)
> > > > > > return -ENOMEM;
> > > > > >
> > > > > > -   desc = dp_display_get_desc(pdev);
> > > > > > +   desc = dp_display_get_desc(pdev, >id);
> > > > >
> > > > > I'm sad that dp->id has to match the number in the SoC specific
> > > > > dpu_intf_cfg array in drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > > > > still. Is there any way we can avoid that? Also, notice how those 
> > > > > arrays
> > > > > already have INTF_DP macros, which makes me think that it may be 
> > > > > better
> > > > > to connect this to those arrays instead of making an msm_dp_desc
> > > > > structure and then make sure the 'type' member matches a connector
> > > > > type number. Otherwise this code is super fragile.
> > > > >
> > > >
> > > > I'm afraid I don't understand what you're proposing. Or which part you
> > > > consider fragile, the indices of the INTF_DP instances aren't going to
> > > > move around...
> > > >
> > > > I have N instances of the DP driver that I need to match to N entries
> > > > from the platform specific intf array, I need some stable reference
> > > > between them. When I started this journey I figured I could rely on the
> > > > of_graph between the DPU and the interface controllers, but the values
> > > > used there today are just bogus, so that was a no go.
> > > >
> > > > We can use whatever, as long as _dpu_kms_initialize_displayport() can
> > > > come up with an identifier to put in h_tile_instance[0] so that
> > > > dpu_encoder_setup_display() can find the relevant INTF.
> > > >
> > >
> > > To make it more concrete we can look at sc7180
> > >
> > > static const struct dpu_intf_cfg sc7180_intf[] = {
> > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
> > > INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > >  ^
> > >  |
> > >
> > > intf0 is irrelevant. Also the address is irrelevant. But here we have a
> > > zero, the number after INTF_DP, and that is very relevant. That number
> > > needs to match the dp->id. Somewhere we have a match between
> > > controller_id and dp->id in the code.
> >
> > That number (the 0, not INTF_0) is what the code matches against dp->id
> > in _dpu_kms_initialize_displayport(), in order to figure out that this
> > is INTF_0 in dpu_encoder_setup_display().
> >
> > I.e. look at the sc8180x patch:
> >
> > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC8180X_MASK, 
> > MDP_SSPP_TOP0_INTR, 24, 25),
> > INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC8180X_MASK, 
> > MDP_SSPP_TOP0_INTR, 26, 27),
> > INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC8180X_MASK, 
> > MDP_SSPP_TOP0_INTR, 28, 29),
> > /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this 
> > is supported */
> > INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC8180X_MASK, 
> > MDP_SSPP_TOP0_INTR, 30, 31),
> > INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, INTF_SC8180X_MASK, 
> > MDP_SSPP_TOP0_INTR, 20, 21),
> > INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, INTF_SC8180X_MASK, 
> > MDP_SSPP_TOP0_INTR, 22, 23),
> >
> > Where the DP driver defines the 3 controllers with dp->id of 0, 1 and 2,
> > which the DPU code will match against to INTF_0, INTF_4 and INTF_5.
> >
> 
> Yep. I'm saying that having to make that number in this intf array match
> the order of the register mapping descriptor array is fragile. Why can't
> we indicate the interface is DP or eDP with INTF_DP or INTF_EDP and then
> map from the descriptor array to this intf array somehow so that the
> order of the descriptor array doesn't matter? Then we don't have to put
> the connector type in the descriptor array, and we don't have to keep
> the order of the array a certain way to match this intf descriptor.
> 
> Maybe
> 
>   struct msm_dp_desc {
>   phys_addr_t io_start;
>   unsigned int id;

The INTF_ constants are a property of the DPU driver and not
available in the DP driver and the msm_dp struct is a property of the DP
driver and can't be dereferenced in the DPU driver.

The proposed way around this is that the descs array defines the order
in priv->dp[N] and this N is used 

[PATCH i-g-t 1/1] tests/i915_pxp: Use ioctl_wrapper for DRM_IOCTL_PRIME_HANDLE_TO_FD

2021-10-06 Thread Alan Previn
Replace private helper with call to ioctl_wrapper for
DRM_IOCTL_PRIME_HANDLE_TO_FD.

Signed-off-by: Alan Previn 
---
 tests/i915/gem_pxp.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/tests/i915/gem_pxp.c b/tests/i915/gem_pxp.c
index 79040165..0430f4b8 100644
--- a/tests/i915/gem_pxp.c
+++ b/tests/i915/gem_pxp.c
@@ -622,23 +622,6 @@ static void test_render_pxp_protsrc_to_protdest(int i915)
buf_ops_destroy(bops);
 }
 
-static int export_handle(int fd, uint32_t handle, int *outfd)
-{
-   struct drm_prime_handle args;
-   int ret;
-
-   args.handle = handle;
-   args.flags = DRM_CLOEXEC;
-   args.fd = -1;
-
-   ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, );
-   if (ret)
-   ret = errno;
-   *outfd = args.fd;
-
-   return ret;
-}
-
 static void test_pxp_dmabuffshare_refcnt(void)
 {
uint32_t ctx[2], sbo[2], dbo[2];
@@ -659,8 +642,7 @@ static void test_pxp_dmabuffshare_refcnt(void)
dbo[0] = alloc_and_fill_dest_buff(fd[0], true, 
TSTSURF_SIZE,
  TSTSURF_INITCOLOR1);
} else {
-   ret = export_handle(fd[0], dbo[0], _fd);
-   igt_assert(ret == 0);
+   dmabuf_fd = prime_handle_to_fd(fd[0], dbo[0]);
dbo[1] = prime_fd_to_handle(fd[1], dmabuf_fd);
igt_assert(dbo[1]);
}
-- 
2.25.1



Re: [PATCH 3/8] drm/i915: Disable tracing points on PREEMPT_RT

2021-10-06 Thread Sebastian Andrzej Siewior
On 2021-10-06 12:15:21 [+0200], To Ville Syrjälä wrote:
> On 2021-10-06 12:34:19 [+0300], Ville Syrjälä wrote:
> > I think the correct answer is to make uncore.lock a raw_spinlock.
> > Without the tracepoints deubgging any of this is stuff pretty much
> > impossible. We also take that lock a lot.
> 
> Let me check if that works.

Turned the uncore.lock into raw_spinlock_t, the debug.lock as well because it
nests inside the former. Also intel_uncore_forcewake_domain::timer fires
now in hardirq since it almost only acquires the uncore.lock.
What worries me a little is the fw_domain_wait_ack_clear() /
wait_ack_clear() which spin-waits up a whole ms.
__gen6_gt_wait_for_thread_c0() has a 5ms limit and wait_ack_clear() has
50ms as upper limit. I know that it does not usually take long and if it
takes that long than it is an error most likely but still...
The full patch at the end of the email.

Now. Before that patch:

| T: 0 ( 1179) P:90 I:250 C: 182450 Min:  2 Act:6 Avg:5 Max:  21
| T: 1 ( 1180) P:90 I:250 C: 182437 Min:  2 Act:6 Avg:5 Max:  22
| T: 2 ( 1181) P:90 I:250 C: 182423 Min:  2 Act:6 Avg:5 Max:  23
| T: 3 ( 1182) P:90 I:250 C: 182401 Min:  2 Act:6 Avg:5 Max:  21
| T: 4 ( 1183) P:90 I:250 C: 182394 Min:  2 Act:7 Avg:5 Max:  27
| T: 5 ( 1184) P:90 I:250 C: 182381 Min:  2 Act:6 Avg:5 Max:  22
| T: 6 ( 1185) P:90 I:250 C: 182368 Min:  3 Act:6 Avg:5 Max:  23
| T: 7 ( 1186) P:90 I:250 C: 182356 Min:  2 Act:8 Avg:5 Max:  22

after:

| T: 0 ( 1183) P:90 I:250 C:1022143 Min:  3 Act:3 Avg:4 Max:  47
| T: 1 ( 1184) P:90 I:250 C:1022125 Min:  2 Act:3 Avg:4 Max:  51
| T: 2 ( 1185) P:90 I:250 C:1022110 Min:  2 Act:5 Avg:4 Max:  52
| T: 3 ( 1186) P:90 I:250 C:1022089 Min:  2 Act:3 Avg:4 Max:  52
| T: 4 ( 1187) P:90 I:250 C:1022083 Min:  2 Act:3 Avg:4 Max:  51
| T: 5 ( 1188) P:90 I:250 C:1022070 Min:  3 Act:3 Avg:4 Max:  50
| T: 6 ( 1189) P:90 I:250 C:1022058 Min:  3 Act:5 Avg:4 Max:  46
| T: 7 ( 1190) P:90 I:250 C:1022045 Min:  2 Act:3 Avg:4 Max:  51

This is cyclictest output. A little explanation:
T: means thread number. There is one thread pinned to each CPU so I have
8 CPUs. This is an i7 SandyBridge so 4 cores + hyperthread with a
built-in i915 (INTEL_SNB_D_GT1_IDS).

Max: is the maximal observed latency in us. The program fires a timer
every 250us and measures the latency between the programmed time and
now. Since it is the thread with the highest priority in the system it
should be scheduled right away. Unless there is a
preempt-disable/IRQ-off section somewhere.

I did the same test in both cases: started a video hoping for some HW
acceleration and skipped forward / backwards in the clip a few times. As
soon as I start jumping in the video the latencies rise. I don't observe
it without the patch.
The system is idle otherwise. If you have other tests in mind which put
more / different load on the system, I'm all yours. I'm mostly curious
how bad can it get. 

Sebastian

diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c 
b/drivers/gpu/drm/i915/display/i9xx_plane.c
index b1439ba78f67b..6f2cab95d8646 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -444,7 +444,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
else
dspaddr_offset = linear_offset;
 
-   spin_lock_irqsave(_priv->uncore.lock, irqflags);
+   raw_spin_lock_irqsave(_priv->uncore.lock, irqflags);
 
intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane),
  plane_state->view.color_plane[0].stride);
@@ -490,7 +490,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
  intel_plane_ggtt_offset(plane_state) + 
dspaddr_offset);
 
-   spin_unlock_irqrestore(_priv->uncore.lock, irqflags);
+   raw_spin_unlock_irqrestore(_priv->uncore.lock, irqflags);
 }
 
 static void i9xx_disable_plane(struct intel_plane *plane,
@@ -513,7 +513,7 @@ static void i9xx_disable_plane(struct intel_plane *plane,
 */
dspcntr = i9xx_plane_ctl_crtc(crtc_state);
 
-   spin_lock_irqsave(_priv->uncore.lock, irqflags);
+   raw_spin_lock_irqsave(_priv->uncore.lock, irqflags);
 
intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
if (DISPLAY_VER(dev_priv) >= 4)
@@ -521,7 +521,7 @@ static void i9xx_disable_plane(struct intel_plane *plane,
else
intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0);
 
-   spin_unlock_irqrestore(_priv->uncore.lock, irqflags);
+   raw_spin_unlock_irqrestore(_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -539,11 +539,11 @@ g4x_primary_async_flip(struct intel_plane *plane,
if 

Re: [Nouveau] [PATCH v3 2/5] drm/nouveau/kms/nv50-: Explicitly check DPCD backlights for aux enable/brightness

2021-10-06 Thread Karol Herbst
On Wed, Oct 6, 2021 at 4:41 AM Lyude Paul  wrote:
>
> Since we don't support hybrid AUX/PWM backlights in nouveau right now,
> let's add some explicit checks so that we don't break nouveau once we
> enable support for these backlights in other drivers.
>
> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/nouveau/nouveau_backlight.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
> b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> index 1cbd71abc80a..ae2f2abc8f5a 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> @@ -308,7 +308,10 @@ nv50_backlight_init(struct nouveau_backlight *bl,
> if (ret < 0)
> return ret;
>
> -   if (drm_edp_backlight_supported(edp_dpcd)) {
> +   /* TODO: Add support for hybrid PWM/DPCD panels */
> +   if (drm_edp_backlight_supported(edp_dpcd) &&
> +   (edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&

where does the DP_EDP_BACKLIGHT_AUX_ENABLE_CAP come from? afaik
drm_edp_backlight_supported checks for
DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP and
DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP so wondering if this was
intentional or a typo

> +   (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) {
> NV_DEBUG(drm, "DPCD backlight controls supported on 
> %s\n",
>  nv_conn->base.name);
>
> --
> 2.31.1
>



[PATCH] drm/msm/dp: do not initialize combo phy until plugin interrupt

2021-10-06 Thread Kuogee Hsieh
Combo phy support both USB3 and DP simultaneously. USB3 is the
master of combo phy so that USB3 should initialize and power on
its phy before DP initialize its phy. At current implementation,
DP driver initialize its phy happen earlier than  USB3 initialize
its phy which cause timeout error at procedure of power up USB3 phy
which prevent USB3 from working. To avoid confliction of phy
initialization between USB3 and DP, this patch have DP driver postpone
phy initialization until plugin interrupt handler. DP driver only enable
regulator, configure its HPD controller and enable interrupt so that it
is able to receive HPD interrupts after completion of the initialization
phase. DP driver will initialize and power up phy at plugin interrupt
handler during normal operation so that both USB3 and DP are work
simultaneously.

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/dp/dp_ctrl.c| 68 ++---
 drivers/gpu/drm/msm/dp/dp_ctrl.h|  9 +++--
 drivers/gpu/drm/msm/dp/dp_display.c | 51 +---
 3 files changed, 84 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 5551a8d..4c5d507 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1378,7 +1378,25 @@ static int dp_ctrl_enable_stream_clocks(struct 
dp_ctrl_private *ctrl)
return ret;
 }
 
-int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset)
+void dp_ctrl_irq_enable(struct dp_ctrl *dp_ctrl, bool flip)
+{
+   struct dp_ctrl_private *ctrl;
+
+   if (!dp_ctrl) {
+   DRM_ERROR("Invalid input data\n");
+   return;
+   }
+
+   ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+
+   ctrl->dp_ctrl.orientation = flip;
+
+   dp_catalog_ctrl_reset(ctrl->catalog);
+
+   dp_catalog_ctrl_enable_irq(ctrl->catalog, true);
+}
+
+void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl)
 {
struct dp_ctrl_private *ctrl;
struct dp_io *dp_io;
@@ -1386,33 +1404,44 @@ int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool 
flip, bool reset)
 
if (!dp_ctrl) {
DRM_ERROR("Invalid input data\n");
-   return -EINVAL;
+   return;
}
 
ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
dp_io = >parser->io;
phy = dp_io->phy;
 
-   ctrl->dp_ctrl.orientation = flip;
-
-   if (reset)
-   dp_catalog_ctrl_reset(ctrl->catalog);
-
dp_catalog_ctrl_phy_reset(ctrl->catalog);
phy_init(phy);
-   dp_catalog_ctrl_enable_irq(ctrl->catalog, true);
+}
 
-   return 0;
+void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl)
+{
+   struct dp_ctrl_private *ctrl;
+   struct dp_io *dp_io;
+   struct phy *phy;
+
+   if (!dp_ctrl) {
+   DRM_ERROR("Invalid input data\n");
+   return;
+   }
+
+   ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+   dp_io = >parser->io;
+   phy = dp_io->phy;
+
+   dp_catalog_ctrl_phy_reset(ctrl->catalog);
+   phy_exit(phy);
 }
 
 /**
- * dp_ctrl_host_deinit() - Uninitialize DP controller
+ * dp_ctrl_irq_phy_exit() - disable dp irq and exit phy
  * @dp_ctrl: Display Port Driver data
  *
  * Perform required steps to uninitialize DP controller
  * and its resources.
  */
-void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl)
+void dp_ctrl_irq_phy_exit(struct dp_ctrl *dp_ctrl)
 {
struct dp_ctrl_private *ctrl;
struct dp_io *dp_io;
@@ -1866,23 +1895,6 @@ int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl)
return ret;
 }
 
-void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl)
-{
-   struct dp_ctrl_private *ctrl;
-   struct dp_io *dp_io;
-   struct phy *phy;
-
-   ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
-   dp_io = >parser->io;
-   phy = dp_io->phy;
-
-   dp_catalog_ctrl_reset(ctrl->catalog);
-
-   phy_exit(phy);
-
-   DRM_DEBUG_DP("DP off phy done\n");
-}
-
 int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
 {
struct dp_ctrl_private *ctrl;
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h
index 2363a2d..c1e4b1b 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
@@ -19,12 +19,9 @@ struct dp_ctrl {
u32 pixel_rate;
 };
 
-int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset);
-void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl);
 int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl);
 int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl);
 int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl);
-void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl);
 int dp_ctrl_off(struct dp_ctrl *dp_ctrl);
 void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl);
 void dp_ctrl_isr(struct dp_ctrl *dp_ctrl);
@@ -34,4 +31,10 @@ struct dp_ctrl *dp_ctrl_get(struct device *dev, struct 
dp_link *link,
struct dp_power 

  1   2   >