Re: [PATCH v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Dmitry Osipenko
30.10.2021 03:47, Dmitry Osipenko пишет:
> 29.10.2021 21:06, Rafael J. Wysocki пишет:
> ...
> I just noticed that RPM core doesn't reset RPM-enable count of a device
> on driver's unbind (pm_runtime_reinit). It was a bad idea to use
> devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
> disabled twice on driver's removal, and thus, RPM will never be enabled
> again.
>
> I'll fix it for PWM and other drivers in this series, in v15.

 Well, for the record, IMV using pm_runtime_force_suspend() is
 generally a questionable idea.

>>>
>>> Please clarify why it's a questionable idea.
>>
>> There are a few reasons.
>>
>> Generally speaking, it makes assumptions that may not be satisfied.
>>
>> For instance, it assumes that the driver will never have to work with
>> the ACPI PM domain, because the ACPI PM domain has a separate set of
>> callbacks for system-wide suspend and resume and they are not the same
>> as its PM-runtime callbacks, so if the driver is combined with the
>> ACPI PM domain, running pm_runtime_force_suspend() may not work as
>> expected.
> 
> ACPI is irrelevant to the drivers touched by this series.
> 
> This series is about older ARM32 Tegra SoCs which either don't have ACPI
> at all or it's unusable by Linux, like a non-standard ACPI of M$ Surface
> tablets.

Although, there are VIC and NVDEC drivers of newer Tegra SoCs touched by
this series. Maybe they could get ACPI support in the future, but this
needs to be clarified. Perhaps Thierry or Mikko could comment on it.

>> Next, it assumes that PM-runtime is actually enabled for the device
>> and the RPM_STATUS of it is valid when it is running.
> 
> Runtime PM presence is mandatory for Tegra and drivers take care of
> enabling it, should be good here.
> 
>> Further, it assumes that the PM-runtime suspend callback of the driver
>> will always be suitable for system-wide suspend which may not be the
>> case if the device can generate wakeup signals and it is not allowed
>> to wake up the system from sleep by user space.
> 
> There are no such 'wakeup' drivers in the context of this patchset.
> 
>> Next, if the driver has to work with a PM domain (other than the ACPI
>> one) or bus type that doesn't take the pm_runtime_force_suspend()
>> explicitly into account, it may end up running the runtime-suspend
>> callback provided by that entity from within its system-wide suspend
>> callback which may not work as expected.
> 
> Only platform bus and generic power domain are relevant for this patchset.
> 
>> I guess I could add a few if I had to.
>>
> 
> So far I can't see any problems.
> 
> If you have a better alternative on yours mind, please share.
> 



Re: [PATCH 2/3] drm/bridge: parade-ps8640: Move real poweroff action to new function

2021-10-29 Thread kernel test robot
Hi AngeloGioacchino,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v5.15-rc7 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/AngeloGioacchino-Del-Regno/drm-bridge-parade-ps8640-Don-t-try-to-enable-VDO-if-poweron-fails/20211029-212903
base:   git://anongit.freedesktop.org/drm/drm drm-next
config: hexagon-buildonly-randconfig-r006-20211028 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
5db7568a6a1fcb408eb8988abdaff2a225a8eb72)
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/a04870beda522c60c8604006667038a096f1cbd4
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
AngeloGioacchino-Del-Regno/drm-bridge-parade-ps8640-Don-t-try-to-enable-VDO-if-poweron-fails/20211029-212903
git checkout a04870beda522c60c8604006667038a096f1cbd4
# 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/gpu/drm/bridge/parade-ps8640.c:304:47: error: variable 'ret' is 
>> uninitialized when used here [-Werror,-Wuninitialized]
   DRM_ERROR("cannot disable regulators %d\n", ret);
   ^~~
   include/drm/drm_print.h:518:19: note: expanded from macro 'DRM_ERROR'
   __drm_err(fmt, ##__VA_ARGS__)
^~~
   drivers/gpu/drm/bridge/parade-ps8640.c:298:9: note: initialize the variable 
'ret' to silence this warning
   int ret;
  ^
   = 0
   1 error generated.


vim +/ret +304 drivers/gpu/drm/bridge/parade-ps8640.c

   295  
   296  static void __ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
   297  {
   298  int ret;
   299  
   300  gpiod_set_value(ps_bridge->gpio_reset, 1);
   301  gpiod_set_value(ps_bridge->gpio_powerdown, 1);
   302  if (regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
   303 ps_bridge->supplies)) {
 > 304  DRM_ERROR("cannot disable regulators %d\n", ret);
   305  }
   306  }
   307  

---
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 v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Dmitry Osipenko
29.10.2021 21:06, Rafael J. Wysocki пишет:
...
 I just noticed that RPM core doesn't reset RPM-enable count of a device
 on driver's unbind (pm_runtime_reinit). It was a bad idea to use
 devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
 disabled twice on driver's removal, and thus, RPM will never be enabled
 again.

 I'll fix it for PWM and other drivers in this series, in v15.
>>>
>>> Well, for the record, IMV using pm_runtime_force_suspend() is
>>> generally a questionable idea.
>>>
>>
>> Please clarify why it's a questionable idea.
> 
> There are a few reasons.
> 
> Generally speaking, it makes assumptions that may not be satisfied.
> 
> For instance, it assumes that the driver will never have to work with
> the ACPI PM domain, because the ACPI PM domain has a separate set of
> callbacks for system-wide suspend and resume and they are not the same
> as its PM-runtime callbacks, so if the driver is combined with the
> ACPI PM domain, running pm_runtime_force_suspend() may not work as
> expected.

ACPI is irrelevant to the drivers touched by this series.

This series is about older ARM32 Tegra SoCs which either don't have ACPI
at all or it's unusable by Linux, like a non-standard ACPI of M$ Surface
tablets.

> Next, it assumes that PM-runtime is actually enabled for the device
> and the RPM_STATUS of it is valid when it is running.

Runtime PM presence is mandatory for Tegra and drivers take care of
enabling it, should be good here.

> Further, it assumes that the PM-runtime suspend callback of the driver
> will always be suitable for system-wide suspend which may not be the
> case if the device can generate wakeup signals and it is not allowed
> to wake up the system from sleep by user space.

There are no such 'wakeup' drivers in the context of this patchset.

> Next, if the driver has to work with a PM domain (other than the ACPI
> one) or bus type that doesn't take the pm_runtime_force_suspend()
> explicitly into account, it may end up running the runtime-suspend
> callback provided by that entity from within its system-wide suspend
> callback which may not work as expected.

Only platform bus and generic power domain are relevant for this patchset.

> I guess I could add a few if I had to.
> 

So far I can't see any problems.

If you have a better alternative on yours mind, please share.


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

2021-10-29 Thread Umesh Nerlige Ramappa

On Tue, Oct 26, 2021 at 05:48:21PM -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.

Note:
There might be an over-accounting 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

v4: (Tvrtko/Matt/Umesh)
- Drop addressed opens from commit message
- Get runtime pm in ping, remove from the park path
- Use cancel_delayed_work_sync in disable_submission path
- Update stats during reset prepare
- Skip ping if reset in progress
- Explicitly name execlists and GuC stats objects
- Since disable_submission is called from many places, move resetting
 stats to intel_guc_submission_reset_prepare

v5: (Tvrtko)
- Add a trylock helper that does not sleep and synchronize PMU event
 callbacks and worker with gt reset

v6: (CI BAT failures)
- DUTs using execlist submission failed to boot since __gt_unpark is
 called during i915 load. This ends up calling the GuC busyness unpark
 hook and results in kick-starting an uninitialized worker. Let
 park/unpark hooks check if GuC submission has been initialized.
- drop cant_sleep() from trylock helper since rcu_read_lock takes care
 of that.

v7: (CI) Fix igt@i915_selftest@live@gt_engines
- For GuC mode of submission the engine busyness is derived from gt time
 domain. Use gt time elapsed as reference in the selftest.
- Increase busyness calculation to 10ms duration to ensure batch runs
 longer and falls within the busyness tolerances in selftest.

v8:
- Use ktime_get in selftest as before
- intel_reset_trylock_no_wait results in a lockdep splat that is not
 trivial to fix since the PMU callback runs in irq context and the
 reset paths are tightly knit into the driver. The test that uncovers
 this is igt@perf_pmu@faulting-read. Drop intel_reset_trylock_no_wait,
 instead use the reset_count to synchronize with gt reset during pmu
 callback. For the ping, continue to use intel_reset_trylock since ping
 is not run in irq context.

- GuC PM timestamp does not tick when GuC is idle. This can potentially
 result in wrong busyness values when a context is active on the
 engine, but GuC is idle. Use the RING TIMESTAMP as GPU timestamp to
 process the GuC busyness stats. This works since both GuC timestamp and
 RING timestamp are synced with the same clock.

- The busyness stats may get updated after the batch starts running.
 This delay causes the busyness reported for 100us duration to fall
 below 95% in the selftest. The only option at this time is to wait for
 GuC busyness to change from idle to active before we sample busyness
 over a 100us period.

Signed-off-by: John Harrison 
Signed-off-by: Umesh Nerlige Ramappa 
Acked-by: Tvrtko Ursulin 
---
drivers/gpu/drm/i915/gt/intel_engine_cs.c |  28 +-
drivers/gpu/drm/i915/gt/

[PATCH v2] drm/bridge: analogix_dp: Make PSR-exit block less

2021-10-29 Thread Brian Norris
Prior to commit 6c836d965bad ("drm/rockchip: Use the helpers for PSR"),
"PSR exit" used non-blocking analogix_dp_send_psr_spd(). The refactor
started using the blocking variant, for a variety of reasons -- quoting
Sean Paul's potentially-faulty memory:

"""
 - To avoid racing a subsequent PSR entry (if exit takes a long time)
 - To avoid racing disable/modeset
 - We're not displaying new content while exiting PSR anyways, so there
   is minimal utility in allowing frames to be submitted
 - We're lying to userspace telling them frames are on the screen when
   we're just dropping them on the floor
"""

However, I'm finding that this blocking transition is causing upwards of
60+ ms of unneeded latency on PSR-exit, to the point that initial cursor
movements when leaving PSR are unbearably jumpy.

It turns out that we need to meet in the middle somewhere: Sean is right
that we were "lying to userspace" with a non-blocking PSR-exit, but the
new blocking behavior is also waiting too long:

According to the eDP specification, the sink device must support PSR
entry transitions from both state 4 (ACTIVE_RESYNC) and state 0
(INACTIVE). It also states that in ACTIVE_RESYNC, "the Sink device must
display the incoming active frames from the Source device with no
visible glitches and/or artifacts."

Thus, for our purposes, we only need to wait for ACTIVE_RESYNC before
moving on; we are ready to display video, and subsequent PSR-entry is
safe.

Tested on a Samsung Chromebook Plus (i.e., Rockchip RK3399 Gru Kevin),
where this saves about 60ms of latency, for PSR-exit that used to
take about 80ms.

Fixes: 6c836d965bad ("drm/rockchip: Use the helpers for PSR")
Cc: 
Cc: Zain Wang 
Cc: Tomasz Figa 
Cc: Heiko Stuebner 
Cc: Sean Paul 
Signed-off-by: Brian Norris 
---
CC list is partially constructed from the commit message of the Fixed
commit

Changes in v2:
 - retitled subject (previous: "drm/bridge: analogix_dp: Make
   PSR-disable non-blocking")
 - instead of completely non-blocking, make this "less"-blocking
 - more background (thanks Sean!)
 - more specification details

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index cab6c8b92efd..f8e119e84ae2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -998,11 +998,21 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device 
*dp,
if (!blocking)
return 0;
 
+   /*
+* db[1]==0: entering PSR, wait for fully active remote frame buffer.
+* db[1]!=0: exiting PSR, wait for either
+*  (a) ACTIVE_RESYNC - the sink "must display the
+*  incoming active frames from the Source device with no visible
+*  glitches and/or artifacts", even though timings may still be
+*  re-synchronizing; or
+*  (b) INACTIVE - the transition is fully complete.
+*/
ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
psr_status >= 0 &&
((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
-   (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
-   DP_TIMEOUT_PSR_LOOP_MS * 1000);
+   (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC ||
+psr_status == DP_PSR_SINK_INACTIVE))),
+   1500, DP_TIMEOUT_PSR_LOOP_MS * 1000);
if (ret) {
dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
return ret;
-- 
2.33.1.1089.g2158813163f-goog



Re: [PATCH] drm/bridge: analogix_dp: Make PSR-disable non-blocking

2021-10-29 Thread Brian Norris
On Wed, Oct 20, 2021 at 06:23:35PM -0700, Brian Norris wrote:
> On Wed, Oct 20, 2021 at 5:40 PM Sean Paul  wrote:
> > The actual latency gains from doing this synchronously are minimal since the
> > panel will display new content as soon as it can regardless of whether the
> > kernel is blocking. There is likely a perceptual difference, but that's only
> > because kernel is lying to userspace and skipping frames without consent.
> 
> Hmm, you might well be right about some of the first points (I'm still
> learning the DRM framework), but I'm a bit skeptical that the
> perceptual difference is "only" because we're cheating in some way.
> I'm not doing science here, and it's certainly not a blinded test, but
> I'm nearly certain this patch cuts out approx 50-80% of the cursor lag
> I see without this patch (relative to the current Chrome OS kernel). I
> don't see how cheating would produce a smoother cursor movement --
> we'd still be dropping frames, and the movement would appear jumpy
> somewhere along the way.

Aha, so I think I found {a,the} reason for some disagreement here:
looking at the eDP PSR spec, I see that while the current implementation
is looking for psr_state==DP_PSR_SINK_INACTIVE to signal PSR-exit
completion, the spec shows an intermediate state
(DP_PSR_SINK_ACTIVE_RESYNC == 4), where among other things, "the Sink
device must display the incoming active frames from the Source device
with no visible glitches and/or artifacts."

And it happens that we move to DP_PSR_SINK_ACTIVE_RESYNC somewhat
quickly (on the order of 20-40ms), while the move to
DP_PSR_SINK_INACTIVE is a good chunk longer (approx 60ms more). So
pre-commit-6c836d965bad might have been cheating a little (we'd claim
we're "done" about 20-40ms too early), but post-commit-6c836d965bad
we're waiting about 60ms too long.

I'll send v2 to make this block for DP_PSR_SINK_ACTIVE_RESYNC ||
DP_PSR_SINK_INACTIVE, which gets much or all of the same latency win,
and I'll try to document the reasons, etc., better.

I'll probably also include a patch to drop the 'blocking' parameter,
since it's unused, and gives the wrong idea about this state machine.

> In any case, I'm absolutely certain that mainline Linux performs much
> much worse with PSR than the current CrOS kernel, but there are some
> other potential reasons for that, such as the lack of an
> input-notifier [1].
...
> [1] This got locked up in "controversy":
> https://patchwork.kernel.org/project/linux-arm-kernel/patch/20180405095000.9756-25-enric.balle...@collabora.com/

While I'm here: I also played with this a bit, and I still haven't
gotten all the details right, but I don't believe this alone will get
the latency wins we'd like. We still need something like the above.

Brian


Re: [RESEND PATCH v3 6/6] drm/ingenic: Attach bridge chain to encoders

2021-10-29 Thread Paul Cercueil

Series applied, thanks!

Cheers,
-Paul


Le ven., oct. 29 2021 at 18:55:50 +0200, Christophe Branchereau 
 a écrit :

Reviewed-by: Christophe Branchereau 

On Tue, Oct 26, 2021 at 8:13 PM Paul Cercueil  
wrote:


 Attach a top-level bridge to each encoder, which will be used for
 negociating the bus format and flags.

 All the bridges are now attached with 
DRM_BRIDGE_ATTACH_NO_CONNECTOR.


 Signed-off-by: Paul Cercueil 
 ---
  drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 92 
+--

  1 file changed, 70 insertions(+), 22 deletions(-)

 diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c

 index a5e2880e07a1..a05a9fa6e115 100644
 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
 +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
 @@ -21,6 +21,7 @@
  #include 
  #include 
  #include 
 +#include 
  #include 
  #include 
  #include 
 @@ -108,6 +109,19 @@ struct ingenic_drm {
 struct drm_private_obj private_obj;
  };

 +struct ingenic_drm_bridge {
 +   struct drm_encoder encoder;
 +   struct drm_bridge bridge, *next_bridge;
 +
 +   struct drm_bus_cfg bus_cfg;
 +};
 +
 +static inline struct ingenic_drm_bridge *
 +to_ingenic_drm_bridge(struct drm_encoder *encoder)
 +{
 +   return container_of(encoder, struct ingenic_drm_bridge, 
encoder);

 +}
 +
  static inline struct ingenic_drm_private_state *
  to_ingenic_drm_priv_state(struct drm_private_state *state)
  {
 @@ -668,11 +682,10 @@ static void 
ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder,

  {
 struct ingenic_drm *priv = 
drm_device_get_priv(encoder->dev);

 struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 -   struct drm_connector *conn = conn_state->connector;
 -   struct drm_display_info *info = &conn->display_info;
 +   struct ingenic_drm_bridge *bridge = 
to_ingenic_drm_bridge(encoder);

 unsigned int cfg, rgbcfg = 0;

 -   priv->panel_is_sharp = info->bus_flags & 
DRM_BUS_FLAG_SHARP_SIGNALS;
 +   priv->panel_is_sharp = bridge->bus_cfg.flags & 
DRM_BUS_FLAG_SHARP_SIGNALS;


 if (priv->panel_is_sharp) {
 cfg = JZ_LCD_CFG_MODE_SPECIAL_TFT_1 | 
JZ_LCD_CFG_REV_POLARITY;
 @@ -685,19 +698,19 @@ static void 
ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder,

 cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
 -   if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
 +   if (bridge->bus_cfg.flags & DRM_BUS_FLAG_DE_LOW)
 cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
 -   if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
 +   if (bridge->bus_cfg.flags & 
DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)

 cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;

 if (!priv->panel_is_sharp) {
 -   if (conn->connector_type == DRM_MODE_CONNECTOR_TV) {
 +   if (conn_state->connector->connector_type == 
DRM_MODE_CONNECTOR_TV) {

 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 cfg |= JZ_LCD_CFG_MODE_TV_OUT_I;
 else
 cfg |= JZ_LCD_CFG_MODE_TV_OUT_P;
 } else {
 -   switch (*info->bus_formats) {
 +   switch (bridge->bus_cfg.format) {
 case MEDIA_BUS_FMT_RGB565_1X16:
 cfg |= 
JZ_LCD_CFG_MODE_GENERIC_16BIT;

 break;
 @@ -723,20 +736,29 @@ static void 
ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder,

 regmap_write(priv->map, JZ_REG_LCD_RGBC, rgbcfg);
  }

 -static int ingenic_drm_encoder_atomic_check(struct drm_encoder 
*encoder,
 -   struct drm_crtc_state 
*crtc_state,
 -   struct 
drm_connector_state *conn_state)

 +static int ingenic_drm_bridge_attach(struct drm_bridge *bridge,
 +enum drm_bridge_attach_flags 
flags)

 +{
 +   struct ingenic_drm_bridge *ib = 
to_ingenic_drm_bridge(bridge->encoder);

 +
 +   return drm_bridge_attach(bridge->encoder, ib->next_bridge,
 +&ib->bridge, flags);
 +}
 +
 +static int ingenic_drm_bridge_atomic_check(struct drm_bridge 
*bridge,
 +  struct drm_bridge_state 
*bridge_state,
 +  struct drm_crtc_state 
*crtc_state,
 +  struct 
drm_connector_state *conn_state)

  {
 -   struct drm_display_info *info = 
&conn_state->connector->display_info;

 struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 +   struct ingenic_drm_bridge *ib = 
to_ingenic_drm_bridge(bridge->encoder);


 -   if (info->num_bus_formats != 1)
 -   return -EINVAL;
 +   

Re: [PATCH 2/3] drm/bridge: parade-ps8640: Move real poweroff action to new function

2021-10-29 Thread kernel test robot
Hi AngeloGioacchino,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm/drm-next]
[also build test WARNING on v5.15-rc7 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/AngeloGioacchino-Del-Regno/drm-bridge-parade-ps8640-Don-t-try-to-enable-VDO-if-poweron-fails/20211029-212903
base:   git://anongit.freedesktop.org/drm/drm drm-next
config: arm-randconfig-r012-20211029 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
5db7568a6a1fcb408eb8988abdaff2a225a8eb72)
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
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# 
https://github.com/0day-ci/linux/commit/a04870beda522c60c8604006667038a096f1cbd4
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
AngeloGioacchino-Del-Regno/drm-bridge-parade-ps8640-Don-t-try-to-enable-VDO-if-poweron-fails/20211029-212903
git checkout a04870beda522c60c8604006667038a096f1cbd4
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 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/drm/bridge/parade-ps8640.c:304:47: warning: variable 'ret' is 
>> uninitialized when used here [-Wuninitialized]
   DRM_ERROR("cannot disable regulators %d\n", ret);
   ^~~
   include/drm/drm_print.h:518:19: note: expanded from macro 'DRM_ERROR'
   __drm_err(fmt, ##__VA_ARGS__)
^~~
   drivers/gpu/drm/bridge/parade-ps8640.c:298:9: note: initialize the variable 
'ret' to silence this warning
   int ret;
  ^
   = 0
   1 warning generated.


vim +/ret +304 drivers/gpu/drm/bridge/parade-ps8640.c

   295  
   296  static void __ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
   297  {
   298  int ret;
   299  
   300  gpiod_set_value(ps_bridge->gpio_reset, 1);
   301  gpiod_set_value(ps_bridge->gpio_powerdown, 1);
   302  if (regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
   303 ps_bridge->supplies)) {
 > 304  DRM_ERROR("cannot disable regulators %d\n", ret);
   305  }
   306  }
   307  

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


.config.gz
Description: application/gzip


Re: [v2] drm/msm/disp/dpu1: set default group ID for CTL.

2021-10-29 Thread Stephen Boyd
Quoting Kalyan Thota (2021-10-29 05:30:19)
> New required programming in CTL for SC7280. Group ID informs
> HW of which VM owns that CTL. Force this group ID to
> default/disabled until virtualization support is enabled in SW.
>
> Changes in v1:
>  - Fix documentation and add descritpion for the change (Stephen)
>
> Signed-off-by: Kalyan Thota 
> ---

Reviewed-by: Stephen Boyd 


Re: [PATCH] drm/rockchip: use generic fbdev setup

2021-10-29 Thread Thomas Zimmermann

Hi

Am 29.10.21 um 13:50 schrieb John Keeping:

The Rockchip fbdev code does not add anything compared to
drm_fbdev_generic_setup(); the one custom function for .fb_mmap does the
same thing as gem_prime_mmap which is called by the helper.

Signed-off-by: John Keeping 
---
  drivers/gpu/drm/rockchip/Makefile |   1 -
  drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |  10 +-
  drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   2 -
  drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 164 --
  drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h |  24 ---
  5 files changed, 2 insertions(+), 199 deletions(-)
  delete mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
  delete mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 17a9e7eb2130..1a56f696558c 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -5,7 +5,6 @@
  
  rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \

rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o
-rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
  
  rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o

  rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 69c699459dce..20d81ae69828 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -26,7 +26,6 @@
  
  #include "rockchip_drm_drv.h"

  #include "rockchip_drm_fb.h"
-#include "rockchip_drm_fbdev.h"
  #include "rockchip_drm_gem.h"
  
  #define DRIVER_NAME	"rockchip"

@@ -159,10 +158,6 @@ static int rockchip_drm_bind(struct device *dev)
  
  	drm_mode_config_reset(drm_dev);
  
-	ret = rockchip_drm_fbdev_init(drm_dev);

-   if (ret)
-   goto err_unbind_all;
-
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(drm_dev);
  
@@ -170,10 +165,11 @@ static int rockchip_drm_bind(struct device *dev)

if (ret)
goto err_kms_helper_poll_fini;
  
+	drm_fbdev_generic_setup(drm_dev, 32);


Please pass 0 for the final argument. The fbdev helpers pick 32 by 
default. Maybe leave a comment if you require 32 here.


For RGB colors, you should rather set 
drm_device.mode_config.preferred_depth to 24 instead.


With these changes:

Acked-by: Thomas Zimmermann 

Best regards
Thomas



+
return 0;
  err_kms_helper_poll_fini:
drm_kms_helper_poll_fini(drm_dev);
-   rockchip_drm_fbdev_fini(drm_dev);
  err_unbind_all:
component_unbind_all(dev, drm_dev);
  err_iommu_cleanup:
@@ -189,7 +185,6 @@ static void rockchip_drm_unbind(struct device *dev)
  
  	drm_dev_unregister(drm_dev);
  
-	rockchip_drm_fbdev_fini(drm_dev);

drm_kms_helper_poll_fini(drm_dev);
  
  	drm_atomic_helper_shutdown(drm_dev);

@@ -203,7 +198,6 @@ DEFINE_DRM_GEM_FOPS(rockchip_drm_driver_fops);
  
  static const struct drm_driver rockchip_drm_driver = {

.driver_features= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
-   .lastclose  = drm_fb_helper_lastclose,
.dumb_create= rockchip_gem_dumb_create,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index aa0909e8edf9..143a48330f84 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -43,8 +43,6 @@ struct rockchip_crtc_state {
   * @mm_lock: protect drm_mm on multi-threads.
   */
  struct rockchip_drm_private {
-   struct drm_fb_helper fbdev_helper;
-   struct drm_gem_object *fbdev_bo;
struct iommu_domain *domain;
struct mutex mm_lock;
struct drm_mm mm;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
deleted file mode 100644
index d8418dd39d0e..
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ /dev/null
@@ -1,164 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
- * Author:Mark Yao 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "rockchip_drm_drv.h"
-#include "rockchip_drm_gem.h"
-#include "rockchip_drm_fb.h"
-#include "rockchip_drm_fbdev.h"
-
-#define PREFERRED_BPP  32
-#define to_drm_private(x) \
-   container_of(x, struct rockchip_drm_private, fbdev_helper)
-
-static int rockchip_fbdev_mmap(struct fb_info *info,
-  struct vm_area_struct *vma)
-{
-   struct drm_fb_helper *helper = info->par;
-   struct rockchip_drm_private *private = to_drm_private(helper);
-
-   return drm_gem_prime_mmap(private->fbdev_bo, vma);
-}
-
-sta

Re: [PATCH v2] drm: import DMA_BUF module namespace

2021-10-29 Thread Thomas Zimmermann

Hi

Am 27.10.21 um 23:25 schrieb Marcel Ziswiler:

From: Marcel Ziswiler 

Today's -next fails building arm64 defconfig as follows:

ERROR: modpost: module drm_cma_helper uses symbol dma_buf_vunmap from
  namespace DMA_BUF, but does not import it.
ERROR: modpost: module drm_cma_helper uses symbol dma_buf_vmap from
  namespace DMA_BUF, but does not import it.

Reported-by: Linux Kernel Functional Testing 
Fixes: commit 4b2b5e142ff4 ("drm: Move GEM memory managers into modules")
Signed-off-by: Marcel Ziswiler 


I added this fix into drm-misc-next. Thanks!

However, I had to import linux-next while doing so. 'Git am' did a 3-way 
merge, which may result in a conflict when the fix reaches linux-next 
again. I also updated the commit description.


Best regards
Thomas



---

Changes in v2:
- After consulting the documentation move it to the bottom of the file
   where the other MODULE statements are as suggested by Thomas.
- Also move it down there for the drm_gem_shmem_helper.c file.

  drivers/gpu/drm/drm_gem_cma_helper.c   | 1 +
  drivers/gpu/drm/drm_gem_shmem_helper.c | 3 +--
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index 6f7b3f8ec04d3..2a34241fee025 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -581,4 +581,5 @@ drm_gem_cma_prime_import_sg_table_vmap(struct drm_device 
*dev,
  EXPORT_SYMBOL(drm_gem_cma_prime_import_sg_table_vmap);
  
  MODULE_DESCRIPTION("DRM CMA memory-management helpers");

+MODULE_IMPORT_NS(DMA_BUF);
  MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index f7324582afe71..a5b743a83ce99 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -22,8 +22,6 @@
  #include 
  #include 
  
-MODULE_IMPORT_NS(DMA_BUF);

-
  /**
   * DOC: overview
   *
@@ -779,4 +777,5 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
  EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
  
  MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");

+MODULE_IMPORT_NS(DMA_BUF);
  MODULE_LICENSE("GPL v2");



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


OpenPGP_signature
Description: OpenPGP digital signature


[pull] amdgpu, amdkfd drm-next-5.16

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

Fixes for 5.16.

The following changes since commit 31fa8cbce4664946a1688898410fee41ad05364d:

  drm: Add R10 and R12 FourCC (2021-10-28 17:20:45 +1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-next-5.16-2021-10-29

for you to fetch changes up to 403475be6d8b122c3e6b8a47e075926d7299e5ef:

  drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits (2021-10-28 14:27:00 -0400)


amd-drm-next-5.16-2021-10-29:

amdgpu:
- RAS fixes
- Fix a potential memory leak in device tear down
- Add a stutter mode quirk
- Misc display fixes
- Further display FP refactoring
- Display USB4 fixes
- Display DP2.0 fixes
- DCN 3.1 fixes
- Display 8 ch audio fix
- Fix DMA mask regression for SI parts
- Aldebaran fixes

amdkfd:
- userptr fix
- BO lifetime fix
- Misc code cleanup

UAPI:
- Minor header cleanup (no functional change)


Ahmad Othman (2):
  drm/amd/display: Add support for USB4 on C20 PHY for DCN3.1
  drm/amd/display: fix a crash on USB4 over C20 PHY

Alex Deucher (6):
  drm/amdgpu/display: add quirk handling for stutter mode
  drm/amdgpu/pm: look up current_level for asics without pm callback
  drm/amdgpu/UAPI: rearrange header to better align related items
  drm/amdgpu/discovery: add UVD/VCN IP instance info for soc15 parts
  drm/amdgpu/discovery: add SDMA IP instance info for soc15 parts
  drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits

Anson Jacob (2):
  drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
  drm/amd/display: Remove unused macros

Anthony Koo (2):
  drm/amd/display: [FW Promotion] Release 0.0.89
  drm/amd/display: [FW Promotion] Release 0.0.90

Aric Cyr (4):
  drm/amd/display: Handle I2C-over-AUX write channel status update
  drm/amd/display: 3.2.158
  drm/amd/display: Fix 3DLUT skipped programming
  drm/amd/display: 3.2.159

Candice Li (1):
  drm/amdgpu: Update TA version output in driver

Dmytro Laktyushkin (3):
  drm/amd/display: clean up dcn31 revision check
  drm/amd/display: restyle dcn31 resource header inline with other asics
  drm/amd/display: allow windowed mpo + odm

George Shen (2):
  drm/amd/display: Implement fixed DP drive settings
  drm/amd/display: Add comment for preferred_training_settings

Guo, Bing (2):
  drm/amd/display: Get ceiling for v_total calc
  drm/amd/display: set Layout properly for 8ch audio at timing validation

Hansen (1):
  drm/amd/display: Set phy_mux_sel bit in dmub scratch register

Jimmy Kizito (1):
  drm/amd/display: Add workaround flag for EDID read on certain docks

Jude Shih (2):
  drm/amd/display: Fix USB4 hot plug crash issue
  drm/amd/display: Enable dpia in dmub only for DCN31 B0

Kent Russell (2):
  drm/amdgpu: Warn when bad pages approaches 90% threshold
  drm/amdgpu: Add kernel parameter support for ignoring bad page threshold

Lang Yu (4):
  drm/amdkfd: Separate pinned BOs destruction from general routine
  drm/amdgpu: fix a potential memory leak in amdgpu_device_fini_sw()
  drm/amdkfd: Add an optional argument into update queue operation(v2)
  drm/amdkfd: Remove cu mask from struct queue_properties(v2)

Lewis Huang (1):
  drm/amd/display: Align bw context with hw config when system resume

Martin Leung (1):
  drm/amd/display: Manually adjust strobe for DCN303

Meenakshikumar Somasundaram (3):
  drm/amd/display: FEC configuration for dpia links
  drm/amd/display: FEC configuration for dpia links in MST mode
  drm/amd/display: MST support for DPIA

Michael Strauss (3):
  drm/amd/display: Set i2c memory to light sleep during hw init
  drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate
  drm/amd/display: Fallback to clocks which meet requested voltage on DCN31

Nicholas Kazlauskas (1):
  drm/amd/display: Fix deadlock when falling back to v2 from v3

Patrik Jakobsson (1):
  drm/amdgpu: Fix even more out of bound writes from debugfs

Philip Yang (1):
  drm/amdkfd: restore userptr ignore bad address error

Qingqing Zhuo (2):
  drm/amd/display: move FPU associated DSC code to DML folder
  drm/amd/display: move FPU associated DCN301 code to DML folder

Robin Chen (1):
  drm/amd/display: dc_link_set_psr_allow_active refactoring

Tao Zhou (2):
  drm/amdgpu: skip GPRs init for some CU settings on ALDEBARAN
  drm/amdgpu: remove GPRs init for ALDEBARAN in gpu reset (v3)

Wenjing Liu (5):
  drm/amd/display: adopt DP2.0 LT SCR revision 8
  drm/amd/display: implement decide lane settings
  drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings
  drm/amd/display: add two lane settings training options
  drm/amd/display: fix link training regression for 1 or 2 lane

 drivers/gpu/drm/amd/amdgpu/amdgpu.h

Re: [PATCH v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Rafael J. Wysocki
On Fri, Oct 29, 2021 at 6:29 PM Dmitry Osipenko  wrote:
>
> 29.10.2021 18:56, Rafael J. Wysocki пишет:
> > On Fri, Oct 29, 2021 at 5:20 PM Dmitry Osipenko  wrote:
> >>
> >> 26.10.2021 01:40, Dmitry Osipenko пишет:
> >>> + ret = devm_pm_runtime_enable(&pdev->dev);
> >>> + if (ret)
> >>> + return ret;
> >>> +
> >>> + ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
> >>> + if (ret)
> >>> + return ret;
> >>> +
> >>> + ret = pm_runtime_resume_and_get(&pdev->dev);
> >>> + if (ret)
> >>> + return ret;
> >>> +
> >>>   /* Set maximum frequency of the IP */
> >>> - ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
> >>> + ret = dev_pm_opp_set_rate(pwm->dev, pwm->soc->max_frequency);
> >>>   if (ret < 0) {
> >>>   dev_err(&pdev->dev, "Failed to set max frequency: %d\n", 
> >>> ret);
> >>> - return ret;
> >>> + goto put_pm;
> >>>   }
> >>>
> >>>   /*
> >>> @@ -278,7 +294,7 @@ static int tegra_pwm_probe(struct platform_device 
> >>> *pdev)
> >>>   if (IS_ERR(pwm->rst)) {
> >>>   ret = PTR_ERR(pwm->rst);
> >>>   dev_err(&pdev->dev, "Reset control is not found: %d\n", 
> >>> ret);
> >>> - return ret;
> >>> + goto put_pm;
> >>>   }
> >>>
> >>>   reset_control_deassert(pwm->rst);
> >>> @@ -291,10 +307,15 @@ static int tegra_pwm_probe(struct platform_device 
> >>> *pdev)
> >>>   if (ret < 0) {
> >>>   dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
> >>>   reset_control_assert(pwm->rst);
> >>> - return ret;
> >>> + goto put_pm;
> >>>   }
> >>>
> >>> + pm_runtime_put(&pdev->dev);
> >>> +
> >>>   return 0;
> >>> +put_pm:
> >>> + pm_runtime_put_sync_suspend(&pdev->dev);
> >>> + return ret;
> >>>  }
> >>>
> >>>  static int tegra_pwm_remove(struct platform_device *pdev)
> >>> @@ -305,20 +326,44 @@ static int tegra_pwm_remove(struct platform_device 
> >>> *pdev)
> >>>
> >>>   reset_control_assert(pc->rst);
> >>>
> >>> + pm_runtime_force_suspend(&pdev->dev);
> >>
> >> I just noticed that RPM core doesn't reset RPM-enable count of a device
> >> on driver's unbind (pm_runtime_reinit). It was a bad idea to use
> >> devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
> >> disabled twice on driver's removal, and thus, RPM will never be enabled
> >> again.
> >>
> >> I'll fix it for PWM and other drivers in this series, in v15.
> >
> > Well, for the record, IMV using pm_runtime_force_suspend() is
> > generally a questionable idea.
> >
>
> Please clarify why it's a questionable idea.

There are a few reasons.

Generally speaking, it makes assumptions that may not be satisfied.

For instance, it assumes that the driver will never have to work with
the ACPI PM domain, because the ACPI PM domain has a separate set of
callbacks for system-wide suspend and resume and they are not the same
as its PM-runtime callbacks, so if the driver is combined with the
ACPI PM domain, running pm_runtime_force_suspend() may not work as
expected.

Next, it assumes that PM-runtime is actually enabled for the device
and the RPM_STATUS of it is valid when it is running.

Further, it assumes that the PM-runtime suspend callback of the driver
will always be suitable for system-wide suspend which may not be the
case if the device can generate wakeup signals and it is not allowed
to wake up the system from sleep by user space.

Next, if the driver has to work with a PM domain (other than the ACPI
one) or bus type that doesn't take the pm_runtime_force_suspend()
explicitly into account, it may end up running the runtime-suspend
callback provided by that entity from within its system-wide suspend
callback which may not work as expected.

I guess I could add a few if I had to.


Re: [PULL] topic/amdgpu-dp2.0-mst

2021-10-29 Thread Lyude Paul
JFYI - the wrapping was because of evolution, sorry about that. Going to make
sure that gets fixed the next time I have to send out a topic branch

On Fri, 2021-10-29 at 13:35 +0300, Jani Nikula wrote:
> On Fri, 29 Oct 2021, Jani Nikula  wrote:
> > On Wed, 27 Oct 2021, Lyude Paul  wrote:
> > > topic/amdgpu-dp2.0-mst-2021-10-27:
> > > UAPI Changes:
> > > Nope!
> > > 
> > > Cross-subsystem Changes:
> > > drm_dp_update_payload_part1() takes a new argument for specifying what
> > > the
> > > VCPI slot start is
> > > 
> > > Core Changes:
> > > Make the DP MST helpers aware of the current starting VCPI slot/VCPI
> > > total
> > > slot count...
> > > 
> > > Driver Changes:
> > > ...and then add support for taking advantage of this for 128b/132b links
> > > on DP
> > > 2.0 for amdgpu
> > > The following changes since commit
> > > 6f2f7c83303d2227f47551423e507d77d9ea01c7:
> > > 
> > >   Merge tag 'drm-intel-gt-next-2021-10-21' of
> > > git://anongit.freedesktop.org/drm/drm-intel into drm-next (2021-10-22
> > > 06:30:34
> > > +1000)
> > > 
> > > are available in the Git repository at:
> > > 
> > >   git://anongit.freedesktop.org/drm/drm-misc tags/topic/amdgpu-dp2.0-
> > > mst-2021-
> > > 10-27
> > 
> > I'm curious, how did you generate and send this pull request? The lines
> > are wrapped with newlines, and you have non-breaking spaces instead of
> > regular spaces there.
> > 
> > So for me this fails with:
> > 
> > Pulling   git://anongit.freedesktop.org/drm/drm-misc tags/topic/amdgpu-
> > dp2.0-mst-2021- 10-27 ...
> > fatal: invalid refspec 'git://anongit.freedesktop.org/drm/drm-misc'
> 
> Fixed manually, but I can't pull this into drm-intel-next directly after
> all, because the baseline is not in drm-intel-next history. The diffstat
> for drm-intel-next is:
> 
> 65 files changed, 3656 insertions(+), 780 deletions(-)
> 
> I asked for this to be a topic branch so I could pull it into
> drm-intel-next. I guess I'll just have to do a drm-next backmerge
> instead.
> 
> BR,
> Jani.
> 
> 
> > 
> > BR,
> > Jani.
> > 
> > 
> > > 
> > > for you to fetch changes up to 00f965e700ef5aa2d889e7e65c7458531d2a4bcf:
> > > 
> > >   drm/amdgpu/display: fix build when CONFIG_DRM_AMD_DC_DCN is not set
> > > (2021-
> > > 10-27 19:50:26 -0400)
> > > 
> > > 
> > > UAPI Changes:
> > > Nope!
> > > 
> > > Cross-subsystem Changes:
> > > drm_dp_update_payload_part1() takes a new argument for specifying what
> > > the
> > > VCPI slot start is
> > > 
> > > Core Changes:
> > > Make the DP MST helpers aware of the current starting VCPI slot/VCPI
> > > total
> > > slot count...
> > > 
> > > Driver Changes:
> > > ...and then add support for taking advantage of this for 128b/132b links
> > > on DP
> > > 2.0 for amdgpu
> > > 
> > > 
> > > Alex Deucher (1):
> > >   drm/amdgpu/display: fix build when CONFIG_DRM_AMD_DC_DCN is not
> > > set
> > > 
> > > Bhawanpreet Lakha (3):
> > >   drm: Remove slot checks in dp mst topology during commit
> > >   drm: Update MST First Link Slot Information Based on Encoding
> > > Format
> > >   drm/amd/display: Add DP 2.0 MST DM Support
> > > 
> > > Fangzhi Zuo (1):
> > >   drm/amd/display: Add DP 2.0 MST DC Support
> > > 
> > >  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  29 ++
> > >  .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c  |   3 +
> > >  .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  |   7 +-
> > >  drivers/gpu/drm/amd/display/dc/core/dc.c   |  14 +
> > >  drivers/gpu/drm/amd/display/dc/core/dc_link.c  | 292
> > > +
> > >  drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |  19 ++
> > >  drivers/gpu/drm/amd/display/dc/dc_link.h   |   7 +
> > >  drivers/gpu/drm/amd/display/dc/dc_stream.h |  13 +
> > >  drivers/gpu/drm/drm_dp_mst_topology.c  |  42 ++-
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.c    |   4 +-
> > >  drivers/gpu/drm/nouveau/dispnv50/disp.c    |   2 +-
> > >  drivers/gpu/drm/radeon/radeon_dp_mst.c |   4 +-
> > >  include/drm/drm_dp_mst_helper.h    |   5 +-
> > >  13 files changed, 425 insertions(+), 16 deletions(-)
> 

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



Re: [PATCH v3 6/6] drm/msm/dp: Remove the hpd init delay for eDP

2021-10-29 Thread khsieh

On 2021-10-27 23:38, Stephen Boyd wrote:

Quoting Sankeerth Billakanti (2021-10-27 18:54:48)

DP driver needs a 10 second delay before phy_init so that
the usb combo phy initializes and sets up the necessary
clocks for usb devices such as keyboard and mouse.

eDP controller uses a standalone phy and need not wait for
phy initialization from any other component. This change
will remove the delay for eDP controller.

Signed-off-by: Sankeerth Billakanti 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c

index 61385d6..de6a1fd 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1438,7 +1439,15 @@ void msm_dp_irq_postinstall(struct msm_dp 
*dp_display)


dp_hpd_event_setup(dp);

-   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
+   if (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP) {
+   /* eDP does not need any delay before phy init */
+   delay = 0;
+   } else {
+   /* DP needs 10 second delay to let usb combo phy 
initialize */


This seems to be a different approach to the patch Kuogee sent a week 
or

two ago. Can we figure out what's wrong with the DP phy starting before
the USB phy? I suppose this patch is OK as a temporary hack to keep
moving with eDP, but we really need to figure out what's wrong with DP
so this delay can be removed entirely. Has any progress been made on
that?


Sankeerth,
Can you drop this patch for now.
Let's discuss more.


+   delay = 100;
+   }
+
+   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, delay);


Re: [RESEND PATCH v3 6/6] drm/ingenic: Attach bridge chain to encoders

2021-10-29 Thread Christophe Branchereau
Reviewed-by: Christophe Branchereau 

On Tue, Oct 26, 2021 at 8:13 PM Paul Cercueil  wrote:
>
> Attach a top-level bridge to each encoder, which will be used for
> negociating the bus format and flags.
>
> All the bridges are now attached with DRM_BRIDGE_ATTACH_NO_CONNECTOR.
>
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 92 +--
>  1 file changed, 70 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
> b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index a5e2880e07a1..a05a9fa6e115 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -21,6 +21,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -108,6 +109,19 @@ struct ingenic_drm {
> struct drm_private_obj private_obj;
>  };
>
> +struct ingenic_drm_bridge {
> +   struct drm_encoder encoder;
> +   struct drm_bridge bridge, *next_bridge;
> +
> +   struct drm_bus_cfg bus_cfg;
> +};
> +
> +static inline struct ingenic_drm_bridge *
> +to_ingenic_drm_bridge(struct drm_encoder *encoder)
> +{
> +   return container_of(encoder, struct ingenic_drm_bridge, encoder);
> +}
> +
>  static inline struct ingenic_drm_private_state *
>  to_ingenic_drm_priv_state(struct drm_private_state *state)
>  {
> @@ -668,11 +682,10 @@ static void ingenic_drm_encoder_atomic_mode_set(struct 
> drm_encoder *encoder,
>  {
> struct ingenic_drm *priv = drm_device_get_priv(encoder->dev);
> struct drm_display_mode *mode = &crtc_state->adjusted_mode;
> -   struct drm_connector *conn = conn_state->connector;
> -   struct drm_display_info *info = &conn->display_info;
> +   struct ingenic_drm_bridge *bridge = to_ingenic_drm_bridge(encoder);
> unsigned int cfg, rgbcfg = 0;
>
> -   priv->panel_is_sharp = info->bus_flags & DRM_BUS_FLAG_SHARP_SIGNALS;
> +   priv->panel_is_sharp = bridge->bus_cfg.flags & 
> DRM_BUS_FLAG_SHARP_SIGNALS;
>
> if (priv->panel_is_sharp) {
> cfg = JZ_LCD_CFG_MODE_SPECIAL_TFT_1 | JZ_LCD_CFG_REV_POLARITY;
> @@ -685,19 +698,19 @@ static void ingenic_drm_encoder_atomic_mode_set(struct 
> drm_encoder *encoder,
> cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
> if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
> -   if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
> +   if (bridge->bus_cfg.flags & DRM_BUS_FLAG_DE_LOW)
> cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
> -   if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
> +   if (bridge->bus_cfg.flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
> cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
>
> if (!priv->panel_is_sharp) {
> -   if (conn->connector_type == DRM_MODE_CONNECTOR_TV) {
> +   if (conn_state->connector->connector_type == 
> DRM_MODE_CONNECTOR_TV) {
> if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> cfg |= JZ_LCD_CFG_MODE_TV_OUT_I;
> else
> cfg |= JZ_LCD_CFG_MODE_TV_OUT_P;
> } else {
> -   switch (*info->bus_formats) {
> +   switch (bridge->bus_cfg.format) {
> case MEDIA_BUS_FMT_RGB565_1X16:
> cfg |= JZ_LCD_CFG_MODE_GENERIC_16BIT;
> break;
> @@ -723,20 +736,29 @@ static void ingenic_drm_encoder_atomic_mode_set(struct 
> drm_encoder *encoder,
> regmap_write(priv->map, JZ_REG_LCD_RGBC, rgbcfg);
>  }
>
> -static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder,
> -   struct drm_crtc_state *crtc_state,
> -   struct drm_connector_state 
> *conn_state)
> +static int ingenic_drm_bridge_attach(struct drm_bridge *bridge,
> +enum drm_bridge_attach_flags flags)
> +{
> +   struct ingenic_drm_bridge *ib = 
> to_ingenic_drm_bridge(bridge->encoder);
> +
> +   return drm_bridge_attach(bridge->encoder, ib->next_bridge,
> +&ib->bridge, flags);
> +}
> +
> +static int ingenic_drm_bridge_atomic_check(struct drm_bridge *bridge,
> +  struct drm_bridge_state 
> *bridge_state,
> +  struct drm_crtc_state *crtc_state,
> +  struct drm_connector_state 
> *conn_state)
>  {
> -   struct drm_display_info *info = &conn_state->connector->display_info;
> struct drm_display_mode *mode = &crtc_state->adjusted_mode;
> +   struct ingenic_drm_bridge *ib = 
> to_ingenic_drm_bridge(bridge->encoder);
>
> -   if (info->num_bus_formats != 1)
> -   return -EINVAL;
> +   ib->bus_cfg = bridge

Re: [RESEND PATCH v3 5/6] drm/ingenic: Upload palette before frame

2021-10-29 Thread Christophe Branchereau
Reviewed-by: Christophe Branchereau 

On Tue, Oct 26, 2021 at 8:13 PM Paul Cercueil  wrote:
>
> When using C8 color mode, make sure that the palette is always uploaded
> before a frame; otherwise the very first frame will have wrong colors.
>
> Do that by changing the link order of the DMA descriptors.
>
> v3: Fix ingenic_drm_get_new_priv_state() called instead of
> ingenic_drm_get_priv_state()
>
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 53 ---
>  1 file changed, 47 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
> b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index cbc76cede99e..a5e2880e07a1 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -66,6 +66,7 @@ struct jz_soc_info {
>
>  struct ingenic_drm_private_state {
> struct drm_private_state base;
> +   bool use_palette;
>  };
>
>  struct ingenic_drm {
> @@ -113,6 +114,30 @@ to_ingenic_drm_priv_state(struct drm_private_state 
> *state)
> return container_of(state, struct ingenic_drm_private_state, base);
>  }
>
> +static struct ingenic_drm_private_state *
> +ingenic_drm_get_priv_state(struct ingenic_drm *priv, struct drm_atomic_state 
> *state)
> +{
> +   struct drm_private_state *priv_state;
> +
> +   priv_state = drm_atomic_get_private_obj_state(state, 
> &priv->private_obj);
> +   if (IS_ERR(priv_state))
> +   return ERR_CAST(priv_state);
> +
> +   return to_ingenic_drm_priv_state(priv_state);
> +}
> +
> +static struct ingenic_drm_private_state *
> +ingenic_drm_get_new_priv_state(struct ingenic_drm *priv, struct 
> drm_atomic_state *state)
> +{
> +   struct drm_private_state *priv_state;
> +
> +   priv_state = drm_atomic_get_new_private_obj_state(state, 
> &priv->private_obj);
> +   if (!priv_state)
> +   return NULL;
> +
> +   return to_ingenic_drm_priv_state(priv_state);
> +}
> +
>  static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg)
>  {
> switch (reg) {
> @@ -183,11 +208,18 @@ static void ingenic_drm_crtc_atomic_enable(struct 
> drm_crtc *crtc,
>struct drm_atomic_state *state)
>  {
> struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
> +   struct ingenic_drm_private_state *priv_state;
> +   unsigned int next_id;
> +
> +   priv_state = ingenic_drm_get_priv_state(priv, state);
> +   if (WARN_ON(IS_ERR(priv_state)))
> +   return;
>
> regmap_write(priv->map, JZ_REG_LCD_STATE, 0);
>
> -   /* Set address of our DMA descriptor chain */
> -   regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, 0));
> +   /* Set addresses of our DMA descriptor chains */
> +   next_id = priv_state->use_palette ? HWDESC_PALETTE : 0;
> +   regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, 
> next_id));
> regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_addr(priv, 1));
>
> regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
> @@ -393,6 +425,7 @@ static int ingenic_drm_plane_atomic_check(struct 
> drm_plane *plane,
> struct drm_plane_state *new_plane_state = 
> drm_atomic_get_new_plane_state(state,
>   
>plane);
> struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
> +   struct ingenic_drm_private_state *priv_state;
> struct drm_crtc_state *crtc_state;
> struct drm_crtc *crtc = new_plane_state->crtc ?: 
> old_plane_state->crtc;
> int ret;
> @@ -405,6 +438,10 @@ static int ingenic_drm_plane_atomic_check(struct 
> drm_plane *plane,
> if (WARN_ON(!crtc_state))
> return -EINVAL;
>
> +   priv_state = ingenic_drm_get_priv_state(priv, state);
> +   if (IS_ERR(priv_state))
> +   return PTR_ERR(priv_state);
> +
> ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
>   DRM_PLANE_HELPER_NO_SCALING,
>   DRM_PLANE_HELPER_NO_SCALING,
> @@ -423,6 +460,9 @@ static int ingenic_drm_plane_atomic_check(struct 
> drm_plane *plane,
>  (new_plane_state->src_h >> 16) != new_plane_state->crtc_h))
> return -EINVAL;
>
> +   priv_state->use_palette = new_plane_state->fb &&
> +   new_plane_state->fb->format->format == DRM_FORMAT_C8;
> +
> /*
>  * Require full modeset if enabling or disabling a plane, or changing
>  * its position, size or depth.
> @@ -583,6 +623,7 @@ static void ingenic_drm_plane_atomic_update(struct 
> drm_plane *plane,
> struct drm_plane_state *newstate = 
> drm_atomic_get_new_plane_state(state, plane);
> struct drm_plane_state *oldstate = 
> drm_atomic_get_old_plane_state(state, plane);
> 

Re: [RESEND PATCH v3 4/6] drm/ingenic: Set DMA descriptor chain register when starting CRTC

2021-10-29 Thread Christophe Branchereau
Reviewed-by: Christophe Branchereau 

On Tue, Oct 26, 2021 at 8:13 PM Paul Cercueil  wrote:
>
> Setting the DMA descriptor chain register in the probe function has been
> fine until now, because we only ever had one descriptor per foreground.
>
> As the driver will soon have real descriptor chains, and the DMA
> descriptor chain register updates itself to point to the current
> descriptor being processed, this register needs to be reset after a full
> modeset to point to the first descriptor of the chain.
>
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
> b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index 5dbeca0f8f37..cbc76cede99e 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -186,6 +186,10 @@ static void ingenic_drm_crtc_atomic_enable(struct 
> drm_crtc *crtc,
>
> regmap_write(priv->map, JZ_REG_LCD_STATE, 0);
>
> +   /* Set address of our DMA descriptor chain */
> +   regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, 0));
> +   regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_addr(priv, 1));
> +
> regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
>JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE,
>JZ_LCD_CTRL_ENABLE);
> --
> 2.33.0
>


Re: [RESEND PATCH v3 3/6] drm/ingenic: Move IPU scale settings to private state

2021-10-29 Thread Christophe Branchereau
Reviewed-by: Christophe Branchereau 

On Tue, Oct 26, 2021 at 8:13 PM Paul Cercueil  wrote:
>
> The IPU scaling information is computed in the plane's ".atomic_check"
> callback, and used in the ".atomic_update" callback. As such, it is
> state-specific, and should be moved to a private state structure.
>
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/ingenic/ingenic-ipu.c | 73 ---
>  1 file changed, 54 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c 
> b/drivers/gpu/drm/ingenic/ingenic-ipu.c
> index c819293b8317..2737fc521e15 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-ipu.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c
> @@ -47,6 +47,8 @@ struct soc_info {
>
>  struct ingenic_ipu_private_state {
> struct drm_private_state base;
> +
> +   unsigned int num_w, num_h, denom_w, denom_h;
>  };
>
>  struct ingenic_ipu {
> @@ -58,8 +60,6 @@ struct ingenic_ipu {
> const struct soc_info *soc_info;
> bool clk_enabled;
>
> -   unsigned int num_w, num_h, denom_w, denom_h;
> -
> dma_addr_t addr_y, addr_u, addr_v;
>
> struct drm_property *sharpness_prop;
> @@ -85,6 +85,30 @@ to_ingenic_ipu_priv_state(struct drm_private_state *state)
> return container_of(state, struct ingenic_ipu_private_state, base);
>  }
>
> +static struct ingenic_ipu_private_state *
> +ingenic_ipu_get_priv_state(struct ingenic_ipu *priv, struct drm_atomic_state 
> *state)
> +{
> +   struct drm_private_state *priv_state;
> +
> +   priv_state = drm_atomic_get_private_obj_state(state, 
> &priv->private_obj);
> +   if (IS_ERR(priv_state))
> +   return ERR_CAST(priv_state);
> +
> +   return to_ingenic_ipu_priv_state(priv_state);
> +}
> +
> +static struct ingenic_ipu_private_state *
> +ingenic_ipu_get_new_priv_state(struct ingenic_ipu *priv, struct 
> drm_atomic_state *state)
> +{
> +   struct drm_private_state *priv_state;
> +
> +   priv_state = drm_atomic_get_new_private_obj_state(state, 
> &priv->private_obj);
> +   if (!priv_state)
> +   return NULL;
> +
> +   return to_ingenic_ipu_priv_state(priv_state);
> +}
> +
>  /*
>   * Apply conventional cubic convolution kernel. Both parameters
>   *  and return value are 15.16 signed fixed-point.
> @@ -305,11 +329,16 @@ static void ingenic_ipu_plane_atomic_update(struct 
> drm_plane *plane,
> const struct drm_format_info *finfo;
> u32 ctrl, stride = 0, coef_index = 0, format = 0;
> bool needs_modeset, upscaling_w, upscaling_h;
> +   struct ingenic_ipu_private_state *ipu_state;
> int err;
>
> if (!newstate || !newstate->fb)
> return;
>
> +   ipu_state = ingenic_ipu_get_new_priv_state(ipu, state);
> +   if (WARN_ON(!ipu_state))
> +   return;
> +
> finfo = drm_format_info(newstate->fb->format->format);
>
> if (!ipu->clk_enabled) {
> @@ -482,27 +511,27 @@ static void ingenic_ipu_plane_atomic_update(struct 
> drm_plane *plane,
> if (ipu->soc_info->has_bicubic)
> ctrl |= JZ_IPU_CTRL_ZOOM_SEL;
>
> -   upscaling_w = ipu->num_w > ipu->denom_w;
> +   upscaling_w = ipu_state->num_w > ipu_state->denom_w;
> if (upscaling_w)
> ctrl |= JZ_IPU_CTRL_HSCALE;
>
> -   if (ipu->num_w != 1 || ipu->denom_w != 1) {
> +   if (ipu_state->num_w != 1 || ipu_state->denom_w != 1) {
> if (!ipu->soc_info->has_bicubic && !upscaling_w)
> -   coef_index |= (ipu->denom_w - 1) << 16;
> +   coef_index |= (ipu_state->denom_w - 1) << 16;
> else
> -   coef_index |= (ipu->num_w - 1) << 16;
> +   coef_index |= (ipu_state->num_w - 1) << 16;
> ctrl |= JZ_IPU_CTRL_HRSZ_EN;
> }
>
> -   upscaling_h = ipu->num_h > ipu->denom_h;
> +   upscaling_h = ipu_state->num_h > ipu_state->denom_h;
> if (upscaling_h)
> ctrl |= JZ_IPU_CTRL_VSCALE;
>
> -   if (ipu->num_h != 1 || ipu->denom_h != 1) {
> +   if (ipu_state->num_h != 1 || ipu_state->denom_h != 1) {
> if (!ipu->soc_info->has_bicubic && !upscaling_h)
> -   coef_index |= ipu->denom_h - 1;
> +   coef_index |= ipu_state->denom_h - 1;
> else
> -   coef_index |= ipu->num_h - 1;
> +   coef_index |= ipu_state->num_h - 1;
> ctrl |= JZ_IPU_CTRL_VRSZ_EN;
> }
>
> @@ -513,13 +542,13 @@ static void ingenic_ipu_plane_atomic_update(struct 
> drm_plane *plane,
> /* Set the LUT index register */
> regmap_write(ipu->map, JZ_REG_IPU_RSZ_COEF_INDEX, coef_index);
>
> -   if (ipu->num_w != 1 || ipu->denom_w != 1)
> +   if (ipu_state->num_w != 1 || ipu_state->denom_w != 1)
> ingenic_ipu_set_coefs(ipu, JZ_REG_IPU_HRSZ_COEF_LUT,
> -   

Re: [RESEND PATCH v3 2/6] drm/ingenic: Add support for private objects

2021-10-29 Thread Christophe Branchereau
Reviewed-by: Christophe Branchereau 

On Tue, Oct 26, 2021 at 8:12 PM Paul Cercueil  wrote:
>
> Until now, the ingenic-drm as well as the ingenic-ipu drivers used to
> put state-specific information in their respective private structure.
>
> Add boilerplate code to support private objects in the two drivers, so
> that state-specific information can be put in the state-specific private
> structure.
>
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 61 +++
>  drivers/gpu/drm/ingenic/ingenic-ipu.c | 54 
>  2 files changed, 115 insertions(+)
>
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
> b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index 95c12c2aba14..5dbeca0f8f37 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -64,6 +64,10 @@ struct jz_soc_info {
> unsigned int num_formats_f0, num_formats_f1;
>  };
>
> +struct ingenic_drm_private_state {
> +   struct drm_private_state base;
> +};
> +
>  struct ingenic_drm {
> struct drm_device drm;
> /*
> @@ -99,8 +103,16 @@ struct ingenic_drm {
> struct mutex clk_mutex;
> bool update_clk_rate;
> struct notifier_block clock_nb;
> +
> +   struct drm_private_obj private_obj;
>  };
>
> +static inline struct ingenic_drm_private_state *
> +to_ingenic_drm_priv_state(struct drm_private_state *state)
> +{
> +   return container_of(state, struct ingenic_drm_private_state, base);
> +}
> +
>  static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg)
>  {
> switch (reg) {
> @@ -766,6 +778,28 @@ ingenic_drm_gem_create_object(struct drm_device *drm, 
> size_t size)
> return &obj->base;
>  }
>
> +static struct drm_private_state *
> +ingenic_drm_duplicate_state(struct drm_private_obj *obj)
> +{
> +   struct ingenic_drm_private_state *state = 
> to_ingenic_drm_priv_state(obj->state);
> +
> +   state = kmemdup(state, sizeof(*state), GFP_KERNEL);
> +   if (!state)
> +   return NULL;
> +
> +   __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
> +
> +   return &state->base;
> +}
> +
> +static void ingenic_drm_destroy_state(struct drm_private_obj *obj,
> + struct drm_private_state *state)
> +{
> +   struct ingenic_drm_private_state *priv_state = 
> to_ingenic_drm_priv_state(state);
> +
> +   kfree(priv_state);
> +}
> +
>  DEFINE_DRM_GEM_CMA_FOPS(ingenic_drm_fops);
>
>  static const struct drm_driver ingenic_drm_driver_data = {
> @@ -836,6 +870,11 @@ static struct drm_mode_config_helper_funcs 
> ingenic_drm_mode_config_helpers = {
> .atomic_commit_tail = drm_atomic_helper_commit_tail,
>  };
>
> +static const struct drm_private_state_funcs ingenic_drm_private_state_funcs 
> = {
> +   .atomic_duplicate_state = ingenic_drm_duplicate_state,
> +   .atomic_destroy_state = ingenic_drm_destroy_state,
> +};
> +
>  static void ingenic_drm_unbind_all(void *d)
>  {
> struct ingenic_drm *priv = d;
> @@ -877,9 +916,15 @@ static void ingenic_drm_configure_hwdesc_plane(struct 
> ingenic_drm *priv,
> ingenic_drm_configure_hwdesc(priv, plane, plane, 0xf0 | plane);
>  }
>
> +static void ingenic_drm_atomic_private_obj_fini(struct drm_device *drm, void 
> *private_obj)
> +{
> +   drm_atomic_private_obj_fini(private_obj);
> +}
> +
>  static int ingenic_drm_bind(struct device *dev, bool has_components)
>  {
> struct platform_device *pdev = to_platform_device(dev);
> +   struct ingenic_drm_private_state *private_state;
> const struct jz_soc_info *soc_info;
> struct ingenic_drm *priv;
> struct clk *parent_clk;
> @@ -1148,6 +1193,20 @@ static int ingenic_drm_bind(struct device *dev, bool 
> has_components)
> goto err_devclk_disable;
> }
>
> +   private_state = kzalloc(sizeof(*private_state), GFP_KERNEL);
> +   if (!private_state) {
> +   ret = -ENOMEM;
> +   goto err_clk_notifier_unregister;
> +   }
> +
> +   drm_atomic_private_obj_init(drm, &priv->private_obj, 
> &private_state->base,
> +   &ingenic_drm_private_state_funcs);
> +
> +   ret = drmm_add_action_or_reset(drm, 
> ingenic_drm_atomic_private_obj_fini,
> +  &priv->private_obj);
> +   if (ret)
> +   goto err_private_state_free;
> +
> ret = drm_dev_register(drm, 0);
> if (ret) {
> dev_err(dev, "Failed to register DRM driver\n");
> @@ -1158,6 +1217,8 @@ static int ingenic_drm_bind(struct device *dev, bool 
> has_components)
>
> return 0;
>
> +err_private_state_free:
> +   kfree(private_state);
>  err_clk_notifier_unregister:
> clk_notifier_unregister(parent_clk, &priv->clock_nb);
>  err_devclk_disable:
> diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c 
>

Re: [RESEND PATCH v3 1/6] drm/ingenic: Simplify code by using hwdescs array

2021-10-29 Thread Christophe Branchereau
Hi Paul,

Reviewed-by: Christophe Branchereau 



On Tue, Oct 26, 2021 at 8:12 PM Paul Cercueil  wrote:
>
> Instead of having one 'hwdesc' variable for the plane #0, one for the
> plane #1 and one for the palette, use a 'hwdesc[3]' array, where the
> DMA hardware descriptors are indexed by the plane's number.
>
> v2: dma_hwdesc_addr() extended to support palette hwdesc. The palette
> hwdesc is now hwdesc[3] to simplify things. Add
> ingenic_drm_configure_hwdesc*() functions to factorize code.
>
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 78 ++-
>  1 file changed, 48 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
> b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index a5df1c8d34cd..95c12c2aba14 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -41,6 +41,8 @@
>  #include 
>  #include 
>
> +#define HWDESC_PALETTE 2
> +
>  struct ingenic_dma_hwdesc {
> u32 next;
> u32 addr;
> @@ -49,9 +51,7 @@ struct ingenic_dma_hwdesc {
>  } __aligned(16);
>
>  struct ingenic_dma_hwdescs {
> -   struct ingenic_dma_hwdesc hwdesc_f0;
> -   struct ingenic_dma_hwdesc hwdesc_f1;
> -   struct ingenic_dma_hwdesc hwdesc_pal;
> +   struct ingenic_dma_hwdesc hwdesc[3];
> u16 palette[256] __aligned(16);
>  };
>
> @@ -141,6 +141,14 @@ static inline struct ingenic_drm *drm_nb_get_priv(struct 
> notifier_block *nb)
> return container_of(nb, struct ingenic_drm, clock_nb);
>  }
>
> +static inline dma_addr_t dma_hwdesc_addr(const struct ingenic_drm *priv,
> +unsigned int idx)
> +{
> +   u32 offset = offsetof(struct ingenic_dma_hwdescs, hwdesc[idx]);
> +
> +   return priv->dma_hwdescs_phys + offset;
> +}
> +
>  static int ingenic_drm_update_pixclk(struct notifier_block *nb,
>  unsigned long action,
>  void *data)
> @@ -558,9 +566,9 @@ static void ingenic_drm_plane_atomic_update(struct 
> drm_plane *plane,
> struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
> struct drm_plane_state *newstate = 
> drm_atomic_get_new_plane_state(state, plane);
> struct drm_plane_state *oldstate = 
> drm_atomic_get_old_plane_state(state, plane);
> +   unsigned int width, height, cpp, next_id, plane_id;
> struct drm_crtc_state *crtc_state;
> struct ingenic_dma_hwdesc *hwdesc;
> -   unsigned int width, height, cpp, offset;
> dma_addr_t addr;
> u32 fourcc;
>
> @@ -569,16 +577,14 @@ static void ingenic_drm_plane_atomic_update(struct 
> drm_plane *plane,
> drm_fb_cma_sync_non_coherent(&priv->drm, oldstate, 
> newstate);
>
> crtc_state = newstate->crtc->state;
> +   plane_id = !!(priv->soc_info->has_osd && plane != &priv->f0);
>
> addr = drm_fb_cma_get_gem_addr(newstate->fb, newstate, 0);
> width = newstate->src_w >> 16;
> height = newstate->src_h >> 16;
> cpp = newstate->fb->format->cpp[0];
>
> -   if (!priv->soc_info->has_osd || plane == &priv->f0)
> -   hwdesc = &priv->dma_hwdescs->hwdesc_f0;
> -   else
> -   hwdesc = &priv->dma_hwdescs->hwdesc_f1;
> +   hwdesc = &priv->dma_hwdescs->hwdesc[plane_id];
>
> hwdesc->addr = addr;
> hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4);
> @@ -588,12 +594,8 @@ static void ingenic_drm_plane_atomic_update(struct 
> drm_plane *plane,
>
> ingenic_drm_plane_config(priv->dev, plane, fourcc);
>
> -   if (fourcc == DRM_FORMAT_C8)
> -   offset = offsetof(struct ingenic_dma_hwdescs, 
> hwdesc_pal);
> -   else
> -   offset = offsetof(struct ingenic_dma_hwdescs, 
> hwdesc_f0);
> -
> -   priv->dma_hwdescs->hwdesc_f0.next = 
> priv->dma_hwdescs_phys + offset;
> +   next_id = fourcc == DRM_FORMAT_C8 ? HWDESC_PALETTE : 
> 0;
> +   priv->dma_hwdescs->hwdesc[0].next = 
> dma_hwdesc_addr(priv, next_id);
>
> crtc_state->color_mgmt_changed = fourcc == 
> DRM_FORMAT_C8;
> }
> @@ -846,6 +848,35 @@ static void __maybe_unused ingenic_drm_release_rmem(void 
> *d)
> of_reserved_mem_device_release(d);
>  }
>
> +static void ingenic_drm_configure_hwdesc(struct ingenic_drm *priv,
> +unsigned int hwdesc,
> +unsigned int next_hwdesc, u32 id)
> +{
> +   struct ingenic_dma_hwdesc *desc = &priv->dma_hwdescs->hwdesc[hwdesc];
> +
> +   desc->next = dma_hwdesc_addr(priv, next_hwdesc);
> +   desc->id = id;
> +}
> +

Re: [PATCH v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Dmitry Osipenko
29.10.2021 18:56, Rafael J. Wysocki пишет:
> On Fri, Oct 29, 2021 at 5:20 PM Dmitry Osipenko  wrote:
>>
>> 26.10.2021 01:40, Dmitry Osipenko пишет:
>>> + ret = devm_pm_runtime_enable(&pdev->dev);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = pm_runtime_resume_and_get(&pdev->dev);
>>> + if (ret)
>>> + return ret;
>>> +
>>>   /* Set maximum frequency of the IP */
>>> - ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
>>> + ret = dev_pm_opp_set_rate(pwm->dev, pwm->soc->max_frequency);
>>>   if (ret < 0) {
>>>   dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
>>> - return ret;
>>> + goto put_pm;
>>>   }
>>>
>>>   /*
>>> @@ -278,7 +294,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
>>>   if (IS_ERR(pwm->rst)) {
>>>   ret = PTR_ERR(pwm->rst);
>>>   dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
>>> - return ret;
>>> + goto put_pm;
>>>   }
>>>
>>>   reset_control_deassert(pwm->rst);
>>> @@ -291,10 +307,15 @@ static int tegra_pwm_probe(struct platform_device 
>>> *pdev)
>>>   if (ret < 0) {
>>>   dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
>>>   reset_control_assert(pwm->rst);
>>> - return ret;
>>> + goto put_pm;
>>>   }
>>>
>>> + pm_runtime_put(&pdev->dev);
>>> +
>>>   return 0;
>>> +put_pm:
>>> + pm_runtime_put_sync_suspend(&pdev->dev);
>>> + return ret;
>>>  }
>>>
>>>  static int tegra_pwm_remove(struct platform_device *pdev)
>>> @@ -305,20 +326,44 @@ static int tegra_pwm_remove(struct platform_device 
>>> *pdev)
>>>
>>>   reset_control_assert(pc->rst);
>>>
>>> + pm_runtime_force_suspend(&pdev->dev);
>>
>> I just noticed that RPM core doesn't reset RPM-enable count of a device
>> on driver's unbind (pm_runtime_reinit). It was a bad idea to use
>> devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
>> disabled twice on driver's removal, and thus, RPM will never be enabled
>> again.
>>
>> I'll fix it for PWM and other drivers in this series, in v15.
> 
> Well, for the record, IMV using pm_runtime_force_suspend() is
> generally a questionable idea.
> 

Please clarify why it's a questionable idea.


Re: [PATCH v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Dmitry Osipenko
29.10.2021 18:28, Ulf Hansson пишет:
> On Fri, 29 Oct 2021 at 17:20, Dmitry Osipenko  wrote:
>>
>> 26.10.2021 01:40, Dmitry Osipenko пишет:
>>> + ret = devm_pm_runtime_enable(&pdev->dev);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = pm_runtime_resume_and_get(&pdev->dev);
>>> + if (ret)
>>> + return ret;
>>> +
>>>   /* Set maximum frequency of the IP */
>>> - ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
>>> + ret = dev_pm_opp_set_rate(pwm->dev, pwm->soc->max_frequency);
>>>   if (ret < 0) {
>>>   dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
>>> - return ret;
>>> + goto put_pm;
>>>   }
>>>
>>>   /*
>>> @@ -278,7 +294,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
>>>   if (IS_ERR(pwm->rst)) {
>>>   ret = PTR_ERR(pwm->rst);
>>>   dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
>>> - return ret;
>>> + goto put_pm;
>>>   }
>>>
>>>   reset_control_deassert(pwm->rst);
>>> @@ -291,10 +307,15 @@ static int tegra_pwm_probe(struct platform_device 
>>> *pdev)
>>>   if (ret < 0) {
>>>   dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
>>>   reset_control_assert(pwm->rst);
>>> - return ret;
>>> + goto put_pm;
>>>   }
>>>
>>> + pm_runtime_put(&pdev->dev);
>>> +
>>>   return 0;
>>> +put_pm:
>>> + pm_runtime_put_sync_suspend(&pdev->dev);
>>> + return ret;
>>>  }
>>>
>>>  static int tegra_pwm_remove(struct platform_device *pdev)
>>> @@ -305,20 +326,44 @@ static int tegra_pwm_remove(struct platform_device 
>>> *pdev)
>>>
>>>   reset_control_assert(pc->rst);
>>>
>>> + pm_runtime_force_suspend(&pdev->dev);
>>
>> I just noticed that RPM core doesn't reset RPM-enable count of a device
>> on driver's unbind (pm_runtime_reinit). It was a bad idea to use
>> devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
>> disabled twice on driver's removal, and thus, RPM will never be enabled
>> again.
>>
>> I'll fix it for PWM and other drivers in this series, in v15.
> 
> Good catch - and sorry for not spotting it while reviewing!
> 
> Maybe devm_pm_runtime_enable() isn't that useful after all? Should we
> suggest to remove it so others don't fall into the same trap?

devm_pm_runtime_enable() was added to the recent v5.15 kernel. It's a
useful helper, if it's used consciously. I'm not going to remove its
usage entirely from this series, for example it still should be good to
use for Tegra FUSE and HDMI drivers.


Re: [PATCH] drm/bridge: Fix the bridge chain order for pre_enable / post_disable

2021-10-29 Thread Andrzej Hajda



On 27.10.2021 01:25, Laurent Pinchart wrote:

Hi Andrzej,

On Mon, Oct 25, 2021 at 10:11:47PM +0200, Andrzej Hajda wrote:

On 25.10.2021 13:21, Laurent Pinchart wrote:

On Mon, Oct 25, 2021 at 01:00:10PM +0200, Andrzej Hajda wrote:

On 21.10.2021 22:21, Sam Ravnborg wrote:

On Thu, Oct 21, 2021 at 12:29:01PM -0700, Douglas Anderson wrote:

Right now, the chaining order of
pre_enable/enable/disable/post_disable looks like this:

pre_enable:   start from connector and move to encoder
enable:   start from encoder and move to connector
disable:  start from connector and move to encoder
post_disable: start from encoder and move to connector

In the above, it can be seen that at least pre_enable() and
post_disable() are opposites of each other and enable() and disable()
are opposites. However, it seems broken that pre_enable() and enable()
would not move in the same direction. In other parts of Linux you can
see that various stages move in the same order. For instance, during
system suspend the "early" calls run in the same order as the normal
calls run in the same order as the "late" calls run in the same order
as the "noirq" calls.

Let fix the above so that it makes more sense. Now we'll have:

pre_enable:   start from encoder and move to connector
enable:   start from encoder and move to connector
disable:  start from connector and move to encoder
post_disable: start from connector and move to encoder

This order is chosen because if there are parent-child relationships
anywhere I would expect that the encoder would be a parent and the
connector a child--not the other way around.

This makes good sense as you describe it. I hope others can add more
useful feedback.
Added Andrzej Hajda  to the mail, as he have
expressed concerns with the chain of bridges before.

Thanks Sam, but I am not sure about useful feedback - when I see bridge
chain issues it automatically triggers "whining mode" in my head :)


This can be important when using the DP AUX bus to instantiate a
panel. The DP AUX bus is likely part of a bridge driver and is a
parent of the panel. We'd like the bridge to be pre_enabled before the
panel and the panel to be post_disabled before the
bridge. Specifically, this allows pm_runtime_put_sync_suspend() in a
bridge driver's post_suspend to work properly even a panel is under
it.

NOTE: it's entirely possible that this change could break someone who
was relying on the old order. Hopefully this isn't the case, but if
this does break someone it seems like it's better to do it sonner
rather than later so we can fix everyone to handle the order that
makes the most sense.

It will break for sure. So the question is: if it is worth changing?

New order seems good for eDP, DSI sinks [1], probably other as well.

Old order is better for example for THC63LVD1024 [2 p. 20], I guess for
many other sinks as well.

I am not even sure if it is protocol specific (LVDS, RGB, HDMI,...), or
it depends on specific hw pairs (source->sink).

This is why I complain about the bridge chain - assumption that one
fixed call order will work for all setups seems to me ridiculous.

Going back to the question - changing the order from fixed one to
another fixed one will not solve general issue.

What can we do then?

1. Configurable call order? Probably doable: every chain element should
expose info if it's call should be before or after source, then some
core helper will create queue of callbacks. Seems quite complicated,
hides the logic from implementer and not fully flexible (for example,
there are protocols which require to perform sth on source, then on
sink, then again on the source).

2. Stop using bridge chain and call sink ops directly from the source
(this is what Exynos and VC4 do): is flexible and straightforward, gives
full control to the source.

And breaks interoperability, because different sources end up calling
operations in different orders. We end up having different sinks that
expect calls in different ways, and divide the world in sink/source
groups that don't interoperate :-(

I have an impression you describe current status :) More seriously, it
is matter of proper specification/documentation/implementations of the
operations. If we really need strict constraints we could try to
implement them on protocol level.

I certainly wouldn't complain if we had better documented operations :-)


3. Use different abstractions to enforce proper initialization order
(like extending mipi_dsi_host_ops): requires existence of transport bus
abstraction (only DSI at the moment(?)).

A real bus seems overkill, but we could have drm_bridge operations
specific to particular hardware interfaces.


... other ideas?

I don't like it because of the amount of work it would require to switch
to such a model, but I'm really starting to think that a variation of
the second option would be best, where the sink controls the source
instead of having the source controlling the sink. It's the sink that
knows about its en

Re: [PATCH v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Rafael J. Wysocki
On Fri, Oct 29, 2021 at 5:20 PM Dmitry Osipenko  wrote:
>
> 26.10.2021 01:40, Dmitry Osipenko пишет:
> > + ret = devm_pm_runtime_enable(&pdev->dev);
> > + if (ret)
> > + return ret;
> > +
> > + ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
> > + if (ret)
> > + return ret;
> > +
> > + ret = pm_runtime_resume_and_get(&pdev->dev);
> > + if (ret)
> > + return ret;
> > +
> >   /* Set maximum frequency of the IP */
> > - ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
> > + ret = dev_pm_opp_set_rate(pwm->dev, pwm->soc->max_frequency);
> >   if (ret < 0) {
> >   dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
> > - return ret;
> > + goto put_pm;
> >   }
> >
> >   /*
> > @@ -278,7 +294,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
> >   if (IS_ERR(pwm->rst)) {
> >   ret = PTR_ERR(pwm->rst);
> >   dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
> > - return ret;
> > + goto put_pm;
> >   }
> >
> >   reset_control_deassert(pwm->rst);
> > @@ -291,10 +307,15 @@ static int tegra_pwm_probe(struct platform_device 
> > *pdev)
> >   if (ret < 0) {
> >   dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
> >   reset_control_assert(pwm->rst);
> > - return ret;
> > + goto put_pm;
> >   }
> >
> > + pm_runtime_put(&pdev->dev);
> > +
> >   return 0;
> > +put_pm:
> > + pm_runtime_put_sync_suspend(&pdev->dev);
> > + return ret;
> >  }
> >
> >  static int tegra_pwm_remove(struct platform_device *pdev)
> > @@ -305,20 +326,44 @@ static int tegra_pwm_remove(struct platform_device 
> > *pdev)
> >
> >   reset_control_assert(pc->rst);
> >
> > + pm_runtime_force_suspend(&pdev->dev);
>
> I just noticed that RPM core doesn't reset RPM-enable count of a device
> on driver's unbind (pm_runtime_reinit). It was a bad idea to use
> devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
> disabled twice on driver's removal, and thus, RPM will never be enabled
> again.
>
> I'll fix it for PWM and other drivers in this series, in v15.

Well, for the record, IMV using pm_runtime_force_suspend() is
generally a questionable idea.


Re: dri/drm/kms question with regards to minor faults

2021-10-29 Thread John Keeping
Hi Bert,

On Tue, Oct 26, 2021 at 05:18:47PM -0700, Bert Schiettecatte wrote:
> I have an application I'm working on where I'm using OpenGLES / EGL
> and dri/drm/kms. The main loop of my application looks like the code
> below. When running htop, I see that the number of minor faults
> (memory) are increasing over time at a rate of about 500 per second,
> due to the code below. Is this normal and something to worry about,
> and is there a way to get rid of the minor faults? I'm on the rockchip
> rk3288 platform. The faults do not come from my OpenGLES code. 

Coincidentally, I've been looking at Panfrost on RK3288 this week as
well!  I'm testing it with a project that has been using the binary blob
driver for several years and unfortunately Panfrost seems to use ~15%
more CPU.

Like you, I see a huge number of minor faults (~500/second compared with
~3/second on libmali).  It seems that Panfrost is mmap'ing and
munmap'ing buffers on every frame which doesn't happen when the same
application is using the binary driver.

I've testing Linux 5.10.76 and 5.15-rc7 along with Mesa 20.3.5, 21.1.8
and main (as of 704340f0f67) and there's no real difference in
performance across any of those.

Panfrost experts, is there a missed opportunity for optimisation here?
Or is there something applications should be doing differently to avoid
repeatedly mapping & unmapping the same buffers?


Thanks,
John


Re: [PATCH v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Ulf Hansson
On Fri, 29 Oct 2021 at 17:20, Dmitry Osipenko  wrote:
>
> 26.10.2021 01:40, Dmitry Osipenko пишет:
> > + ret = devm_pm_runtime_enable(&pdev->dev);
> > + if (ret)
> > + return ret;
> > +
> > + ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
> > + if (ret)
> > + return ret;
> > +
> > + ret = pm_runtime_resume_and_get(&pdev->dev);
> > + if (ret)
> > + return ret;
> > +
> >   /* Set maximum frequency of the IP */
> > - ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
> > + ret = dev_pm_opp_set_rate(pwm->dev, pwm->soc->max_frequency);
> >   if (ret < 0) {
> >   dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
> > - return ret;
> > + goto put_pm;
> >   }
> >
> >   /*
> > @@ -278,7 +294,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
> >   if (IS_ERR(pwm->rst)) {
> >   ret = PTR_ERR(pwm->rst);
> >   dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
> > - return ret;
> > + goto put_pm;
> >   }
> >
> >   reset_control_deassert(pwm->rst);
> > @@ -291,10 +307,15 @@ static int tegra_pwm_probe(struct platform_device 
> > *pdev)
> >   if (ret < 0) {
> >   dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
> >   reset_control_assert(pwm->rst);
> > - return ret;
> > + goto put_pm;
> >   }
> >
> > + pm_runtime_put(&pdev->dev);
> > +
> >   return 0;
> > +put_pm:
> > + pm_runtime_put_sync_suspend(&pdev->dev);
> > + return ret;
> >  }
> >
> >  static int tegra_pwm_remove(struct platform_device *pdev)
> > @@ -305,20 +326,44 @@ static int tegra_pwm_remove(struct platform_device 
> > *pdev)
> >
> >   reset_control_assert(pc->rst);
> >
> > + pm_runtime_force_suspend(&pdev->dev);
>
> I just noticed that RPM core doesn't reset RPM-enable count of a device
> on driver's unbind (pm_runtime_reinit). It was a bad idea to use
> devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
> disabled twice on driver's removal, and thus, RPM will never be enabled
> again.
>
> I'll fix it for PWM and other drivers in this series, in v15.

Good catch - and sorry for not spotting it while reviewing!

Maybe devm_pm_runtime_enable() isn't that useful after all? Should we
suggest to remove it so others don't fall into the same trap?

Kind regards
Uffe


Re: [PATCH v14 20/39] pwm: tegra: Add runtime PM and OPP support

2021-10-29 Thread Dmitry Osipenko
26.10.2021 01:40, Dmitry Osipenko пишет:
> + ret = devm_pm_runtime_enable(&pdev->dev);
> + if (ret)
> + return ret;
> +
> + ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
> + if (ret)
> + return ret;
> +
> + ret = pm_runtime_resume_and_get(&pdev->dev);
> + if (ret)
> + return ret;
> +
>   /* Set maximum frequency of the IP */
> - ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
> + ret = dev_pm_opp_set_rate(pwm->dev, pwm->soc->max_frequency);
>   if (ret < 0) {
>   dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
> - return ret;
> + goto put_pm;
>   }
>  
>   /*
> @@ -278,7 +294,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
>   if (IS_ERR(pwm->rst)) {
>   ret = PTR_ERR(pwm->rst);
>   dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
> - return ret;
> + goto put_pm;
>   }
>  
>   reset_control_deassert(pwm->rst);
> @@ -291,10 +307,15 @@ static int tegra_pwm_probe(struct platform_device *pdev)
>   if (ret < 0) {
>   dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
>   reset_control_assert(pwm->rst);
> - return ret;
> + goto put_pm;
>   }
>  
> + pm_runtime_put(&pdev->dev);
> +
>   return 0;
> +put_pm:
> + pm_runtime_put_sync_suspend(&pdev->dev);
> + return ret;
>  }
>  
>  static int tegra_pwm_remove(struct platform_device *pdev)
> @@ -305,20 +326,44 @@ static int tegra_pwm_remove(struct platform_device 
> *pdev)
>  
>   reset_control_assert(pc->rst);
>  
> + pm_runtime_force_suspend(&pdev->dev);

I just noticed that RPM core doesn't reset RPM-enable count of a device
on driver's unbind (pm_runtime_reinit). It was a bad idea to use
devm_pm_runtime_enable() + pm_runtime_force_suspend() here, since RPM is
disabled twice on driver's removal, and thus, RPM will never be enabled
again.

I'll fix it for PWM and other drivers in this series, in v15.


Re: [PATCH v2] drm/i915/dmabuf: drop the flush on discrete

2021-10-29 Thread Thomas Hellström



On 10/29/21 14:21, Matthew Auld wrote:

We were overzealous here; even though discrete is non-LLC, it should
still be always coherent.

v2(Thomas & Daniel)
   - Be extra cautious and limit to DG1
   - Add some more commentary

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Cc: Daniel Vetter 


Reviewed-by: Thomas Hellström 



---
  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 15 +--
  1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index a45d0ec2c5b6..a2b485a1be8c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -250,8 +250,19 @@ static int i915_gem_object_get_pages_dmabuf(struct 
drm_i915_gem_object *obj)
if (IS_ERR(pages))
return PTR_ERR(pages);
  
-	/* XXX: consider doing a vmap flush or something */

-   if (!HAS_LLC(i915) || i915_gem_object_can_bypass_llc(obj))
+   /*
+* DG1 is special here since it still snoops transactions even with
+* CACHE_NONE. This is not the case with other HAS_SNOOP platforms. We
+* might need to revisit this as we add new discrete platforms.
+*
+* XXX: Consider doing a vmap flush or something, where possible.
+* Currently we just do a heavy handed wbinvd_on_all_cpus() here since
+* the underlying sg_table might not even point to struct pages, so we
+* can't just call drm_clflush_sg or similar, like we do elsewhere in
+* the driver.
+*/
+   if (i915_gem_object_can_bypass_llc(obj) ||
+   (!HAS_LLC(i915) && !IS_DG1(i915)))
wbinvd_on_all_cpus();
  
  	sg_page_sizes = i915_sg_dma_sizes(pages->sgl);


Re: [PATCH v3 12/14] dt-bindings: msm/dp: Add bindings for HDCP registers

2021-10-29 Thread Sean Paul
On Mon, Oct 04, 2021 at 02:58:41PM -0500, Bjorn Andersson wrote:
> On Fri 01 Oct 10:11 CDT 2021, Sean Paul wrote:
> 
> > From: Sean Paul 
> > 
> > This patch adds the bindings for the MSM DisplayPort HDCP registers
> > which are required to write the HDCP key into the display controller as
> > well as the registers to enable HDCP authentication/key
> > exchange/encryption.
> > 
> > We'll use a new compatible string for this since the fields are optional.
> > 
> 
> I don't think you need a new compatible, in particular since I presume
> we should use the hdcp compatible in all platforms? Or is there a reason
> for not picking that one?
> 
> Instead I suggest that you simply do minItems: 1, maxItems: 3 and detect
> which of the two cases you have in the driver.

Thanks for your review, Bjorn! I had done this in v2 (see [1] & [2]), but it was
suggested that a new compatible would be better. I'll change it back to this
method rebased on top of your changes.

Sean

[1]- https://patchwork.freedesktop.org/patch/454066/?series=94712&rev=1
[2]- https://patchwork.freedesktop.org/patch/454068/?series=94712&rev=1


> 
> PS. I hope to get
> https://lore.kernel.org/linux-arm-msm/20211001174400.981707-1-bjorn.anders...@linaro.org/
> landed before we add these new optional regions...
> 
> Regards,
> Bjorn
> 
> > Cc: Rob Herring 
> > Cc: Stephen Boyd 
> > Signed-off-by: Sean Paul 
> > Link: 
> > https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-13-s...@poorly.run
> >  #v1
> > Link: 
> > https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-13-s...@poorly.run
> >  #v2
> > 
> > Changes in v2:
> > -Drop register range names (Stephen)
> > -Fix yaml errors (Rob)
> > Changes in v3:
> > -Add new compatible string for dp-hdcp
> > -Add descriptions to reg
> > -Add minItems/maxItems to reg
> > -Make reg depend on the new hdcp compatible string
> > ---
> > 
> > Disclaimer: I really don't know if this is the right way to approach
> > this. I tried using examples from other bindings, but feedback would be
> > very much welcome on how I could add the optional register ranges.
> > 
> > 
> >  .../bindings/display/msm/dp-controller.yaml   | 34 ---
> >  1 file changed, 30 insertions(+), 4 deletions(-)
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
> > b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
> > index 64d8d9e5e47a..a176f97b2f4c 100644
> > --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
> > +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
> > @@ -17,9 +17,10 @@ properties:
> >compatible:
> >  enum:
> >- qcom,sc7180-dp
> > +  - qcom,sc7180-dp-hdcp
> >  
> > -  reg:
> > -maxItems: 1
> > +  # See compatible-specific constraints below.
> > +  reg: true
> >  
> >interrupts:
> >  maxItems: 1
> > @@ -89,6 +90,29 @@ required:
> >- power-domains
> >- ports
> >  
> > +allOf:
> > +  - if:
> > +  properties:
> > +compatible:
> > +  contains:
> > +const: qcom,sc7180-dp-hdcp
> > +then:
> > +  properties:
> > +reg:
> > +  minItems: 3
> > +  maxItems: 3
> > +  items:
> > +- description: Registers for base DP functionality
> > +- description: (Optional) Registers for HDCP device key 
> > injection
> > +- description: (Optional) Registers for HDCP TrustZone 
> > interaction
> > +else:
> > +  properties:
> > +reg:
> > +  minItems: 1
> > +  maxItems: 1
> > +  items:
> > +- description: Registers for base DP functionality
> > +
> >  additionalProperties: false
> >  
> >  examples:
> > @@ -99,8 +123,10 @@ examples:
> >  #include 
> >  
> >  displayport-controller@ae9 {
> > -compatible = "qcom,sc7180-dp";
> > -reg = <0xae9 0x1400>;
> > +compatible = "qcom,sc7180-dp-hdcp";
> > +reg = <0 0x0ae9 0 0x1400>,
> > +  <0 0x0aed1000 0 0x174>,
> > +  <0 0x0aee1000 0 0x2c>;
> >  interrupt-parent = <&mdss>;
> >  interrupts = <12>;
> >  clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm: check drm_format_info hsub and vsub to avoid divide by zero

2021-10-29 Thread Brian Starkey
Hi,

On Fri, Oct 29, 2021 at 09:15:28AM -0400, George Kennedy wrote:
> 
> Asking if you have any input on how to deal with hsub and vsub = zero?

That's just a straight mistake on those formats - they should
be 1. My bad for not spotting it in review.

On the one hand, having formats in this table is a nice
machine-readable way to describe them. On the other, as drm_fourcc is
being used as the canonical repository for formats, including ones
not used in DRM, we can end up with situations like this.
(R10/R12 being another example of formats not used in DRM:
20211027233140.12268-1-laurent.pinch...@ideasonboard.com)

Thanks,
-Brian


[PATCH] drm/bridge: dw-hdmi: handle ELD when DRM_BRIDGE_ATTACH_NO_CONNECTOR

2021-10-29 Thread Neil Armstrong
The current ELD handling takes the internal connector ELD buffer and
shares it to the I2S and AHB sub-driver.

But with DRM_BRIDGE_ATTACH_NO_CONNECTOR, the connector is created
elsewhere (not not), and an eventual connector is known only
if the bridge chain up to a connector is enabled.

The current dw-hdmi code gets the current connector from
atomic_enable() so use the already stored connector pointer and
replace the buffer pointer with a callback returning the current
connector ELD buffer.

Since a connector is not always available, either pass an empty
ELD to the alsa HDMI driver or don't call snd_pcm_hw_constraint_eld()
in AHB driver.

Reported-by: Martin Blumenstingl 
Signed-off-by: Neil Armstrong 
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 10 +++---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h |  4 ++--
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c |  9 -
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 12 ++--
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index d0db1acf11d7..7d2ed0ed2fe2 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -320,13 +320,17 @@ static int dw_hdmi_open(struct snd_pcm_substream 
*substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dw_hdmi *dw = substream->private_data;
void __iomem *base = dw->data.base;
+   u8 *eld;
int ret;
 
runtime->hw = dw_hdmi_hw;
 
-   ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld);
-   if (ret < 0)
-   return ret;
+   eld = dw->data.get_eld(dw->data.hdmi);
+   if (eld) {
+   ret = snd_pcm_hw_constraint_eld(runtime, eld);
+   if (ret < 0)
+   return ret;
+   }
 
ret = snd_pcm_limit_hw_rates(runtime);
if (ret < 0)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
index cb07dc0da5a7..f72d27208ebe 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
@@ -9,15 +9,15 @@ struct dw_hdmi_audio_data {
void __iomem *base;
int irq;
struct dw_hdmi *hdmi;
-   u8 *eld;
+   u8 *(*get_eld)(struct dw_hdmi *hdmi);
 };
 
 struct dw_hdmi_i2s_audio_data {
struct dw_hdmi *hdmi;
-   u8 *eld;
 
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
u8 (*read)(struct dw_hdmi *hdmi, int offset);
+   u8 *(*get_eld)(struct dw_hdmi *hdmi);
 };
 
 #endif
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index feb04f127b55..f50b47ac11a8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -135,8 +135,15 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void 
*data, uint8_t *buf,
   size_t len)
 {
struct dw_hdmi_i2s_audio_data *audio = data;
+   u8 *eld;
+
+   eld = audio->get_eld(audio->hdmi);
+   if (eld)
+   memcpy(buf, eld, min_t(size_t, MAX_ELD_BYTES, len));
+   else
+   /* Pass en empty ELD if connector not available */
+   memset(buf, 0, len);
 
-   memcpy(buf, audio->eld, min_t(size_t, MAX_ELD_BYTES, len));
return 0;
 }
 
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 62ae63565d3a..54d8fdad395f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -757,6 +757,14 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, 
bool enable)
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 }
 
+static u8 *hdmi_audio_get_eld(struct dw_hdmi *hdmi)
+{
+   if (!hdmi->curr_conn)
+   return NULL;
+
+   return hdmi->curr_conn->eld;
+}
+
 static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
 {
hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
@@ -3432,7 +3440,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device 
*pdev,
audio.base = hdmi->regs;
audio.irq = irq;
audio.hdmi = hdmi;
-   audio.eld = hdmi->connector.eld;
+   audio.get_eld = hdmi_audio_get_eld;
hdmi->enable_audio = dw_hdmi_ahb_audio_enable;
hdmi->disable_audio = dw_hdmi_ahb_audio_disable;
 
@@ -3445,7 +3453,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device 
*pdev,
struct dw_hdmi_i2s_audio_data audio;
 
audio.hdmi  = hdmi;
-   audio.eld   = hdmi->connector.eld;
+   audio.get_eld   = hdmi_audio_get_eld;
audio.write = hdmi_writeb;

Re: [Intel-gfx] [PATCH v3 1/3] drm: Rename lut check functions to lut channel checks

2021-10-29 Thread Harry Wentland



On 2021-10-29 09:43, Sean Paul wrote:
> On Thu, Oct 28, 2021 at 11:03:54PM -0400, Mark Yacoub wrote:
>> On Thu, Oct 28, 2021 at 8:42 PM Sean Paul  wrote:
>>>
>>> On Tue, Oct 26, 2021 at 03:21:00PM -0400, Mark Yacoub wrote:
 From: Mark Yacoub 

 [Why]
 This function and enum do not do generic checking on the luts but they
 test color channels in the LUTs.
>>>
>>> I'm not sure there's anything inherently specific to channels, it seems like
>>> one could add a new test to reflect a HW limitation and it would fit pretty 
>>> well
>>> in the lut check function. I wonder if it would be better to expose the 
>>> types of
>>> tests required by the crtc such that the atomic_check could also do the 
>>> test?
>>>
>> So the tests of the color are pretty unique to intel devices, no other
>> device is using it so I didn't think it adds a lot of benefit adding
>> it to the lut check. However, it's still in DRM because technically it
>> can be supported by any driver. But once it is, the driver will have
>> to expose the tests it wants so we can check it in atomic_check. but
>> given that no one does expose any test but intel, i just left it only
>> used by them.
>>
> 
> Yeah, understood. Regardless of that, the spirit of the function is not 
> specific
> to the color channels in the LUT, so renaming as channels_check is probably 
> not
> the correct fix. I'd probably lean towards stuffing this in i915 as a
> driver-specific check instead of renaming it.
> 

The checks could be generally useful for other drivers. I assume a lot
of HW wants the LUT to be non-decreasing and there might be other HW
out there that implements LUTs with a single channel that applies to
all colors. Since this is only used by i915 at the moment I don't have
a strong opinion about keeping it in DRM core or stuffing it into i915.

I agree with Sean that this function isn't specifically about color
channels. The function seems to be designed as a generic check for LUTs,
which is why the "tests" flag is passed in. DRM_COLOR_LUT_EQUAL_CHANNELS
is checking the channels but DRM_COLOR_LUT_NON_DECREASING doesn't
particularly have anything to do with the channels.

Harry

> Sean
> 
>>> Sean
>>>
 Keeping the name explicit as more generic LUT checks will follow.

 Tested on Eldrid ChromeOS (TGL).

 Signed-off-by: Mark Yacoub 
 ---
  drivers/gpu/drm/drm_color_mgmt.c   | 12 ++--
  drivers/gpu/drm/i915/display/intel_color.c | 10 +-
  include/drm/drm_color_mgmt.h   |  7 ---
  3 files changed, 15 insertions(+), 14 deletions(-)

 diff --git a/drivers/gpu/drm/drm_color_mgmt.c 
 b/drivers/gpu/drm/drm_color_mgmt.c
 index bb14f488c8f6c..6f4e04746d90f 100644
 --- a/drivers/gpu/drm/drm_color_mgmt.c
 +++ b/drivers/gpu/drm/drm_color_mgmt.c
 @@ -585,17 +585,17 @@ int drm_plane_create_color_properties(struct 
 drm_plane *plane,
  EXPORT_SYMBOL(drm_plane_create_color_properties);

  /**
 - * drm_color_lut_check - check validity of lookup table
 + * drm_color_lut_channels_check - check validity of the channels in the 
 lookup table
   * @lut: property blob containing LUT to check
   * @tests: bitmask of tests to run
   *
 - * Helper to check whether a userspace-provided lookup table is valid and
 - * satisfies hardware requirements.  Drivers pass a bitmask indicating 
 which of
 - * the tests in &drm_color_lut_tests should be performed.
 + * Helper to check whether each color channel of userspace-provided 
 lookup table is valid and
 + * satisfies hardware requirements. Drivers pass a bitmask indicating 
 which of in
 + * &drm_color_lut_channels_tests should be performed.
   *
   * Returns 0 on success, -EINVAL on failure.
   */
 -int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)
 +int drm_color_lut_channels_check(const struct drm_property_blob *lut, u32 
 tests)
  {
   const struct drm_color_lut *entry;
   int i;
 @@ -625,4 +625,4 @@ int drm_color_lut_check(const struct drm_property_blob 
 *lut, u32 tests)

   return 0;
  }
 -EXPORT_SYMBOL(drm_color_lut_check);
 +EXPORT_SYMBOL(drm_color_lut_channels_check);
 diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
 b/drivers/gpu/drm/i915/display/intel_color.c
 index dab892d2251ba..4bb1bc76c4de9 100644
 --- a/drivers/gpu/drm/i915/display/intel_color.c
 +++ b/drivers/gpu/drm/i915/display/intel_color.c
 @@ -1285,7 +1285,7 @@ static int check_luts(const struct intel_crtc_state 
 *crtc_state)
   const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
   const struct drm_property_blob *degamma_lut = 
 crtc_state->hw.degamma_lut;
   int gamma_length, degamma_length;
 - u32 gamma_tests, degamma_tests;
 + u32 gamma_channels_tests, degamma_channels_t

Re: [Intel-gfx] [PATCH v3 1/3] drm: Rename lut check functions to lut channel checks

2021-10-29 Thread Sean Paul
On Thu, Oct 28, 2021 at 11:03:54PM -0400, Mark Yacoub wrote:
> On Thu, Oct 28, 2021 at 8:42 PM Sean Paul  wrote:
> >
> > On Tue, Oct 26, 2021 at 03:21:00PM -0400, Mark Yacoub wrote:
> > > From: Mark Yacoub 
> > >
> > > [Why]
> > > This function and enum do not do generic checking on the luts but they
> > > test color channels in the LUTs.
> >
> > I'm not sure there's anything inherently specific to channels, it seems like
> > one could add a new test to reflect a HW limitation and it would fit pretty 
> > well
> > in the lut check function. I wonder if it would be better to expose the 
> > types of
> > tests required by the crtc such that the atomic_check could also do the 
> > test?
> >
> So the tests of the color are pretty unique to intel devices, no other
> device is using it so I didn't think it adds a lot of benefit adding
> it to the lut check. However, it's still in DRM because technically it
> can be supported by any driver. But once it is, the driver will have
> to expose the tests it wants so we can check it in atomic_check. but
> given that no one does expose any test but intel, i just left it only
> used by them.
> 

Yeah, understood. Regardless of that, the spirit of the function is not specific
to the color channels in the LUT, so renaming as channels_check is probably not
the correct fix. I'd probably lean towards stuffing this in i915 as a
driver-specific check instead of renaming it.

Sean

> > Sean
> >
> > > Keeping the name explicit as more generic LUT checks will follow.
> > >
> > > Tested on Eldrid ChromeOS (TGL).
> > >
> > > Signed-off-by: Mark Yacoub 
> > > ---
> > >  drivers/gpu/drm/drm_color_mgmt.c   | 12 ++--
> > >  drivers/gpu/drm/i915/display/intel_color.c | 10 +-
> > >  include/drm/drm_color_mgmt.h   |  7 ---
> > >  3 files changed, 15 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_color_mgmt.c 
> > > b/drivers/gpu/drm/drm_color_mgmt.c
> > > index bb14f488c8f6c..6f4e04746d90f 100644
> > > --- a/drivers/gpu/drm/drm_color_mgmt.c
> > > +++ b/drivers/gpu/drm/drm_color_mgmt.c
> > > @@ -585,17 +585,17 @@ int drm_plane_create_color_properties(struct 
> > > drm_plane *plane,
> > >  EXPORT_SYMBOL(drm_plane_create_color_properties);
> > >
> > >  /**
> > > - * drm_color_lut_check - check validity of lookup table
> > > + * drm_color_lut_channels_check - check validity of the channels in the 
> > > lookup table
> > >   * @lut: property blob containing LUT to check
> > >   * @tests: bitmask of tests to run
> > >   *
> > > - * Helper to check whether a userspace-provided lookup table is valid and
> > > - * satisfies hardware requirements.  Drivers pass a bitmask indicating 
> > > which of
> > > - * the tests in &drm_color_lut_tests should be performed.
> > > + * Helper to check whether each color channel of userspace-provided 
> > > lookup table is valid and
> > > + * satisfies hardware requirements. Drivers pass a bitmask indicating 
> > > which of in
> > > + * &drm_color_lut_channels_tests should be performed.
> > >   *
> > >   * Returns 0 on success, -EINVAL on failure.
> > >   */
> > > -int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)
> > > +int drm_color_lut_channels_check(const struct drm_property_blob *lut, 
> > > u32 tests)
> > >  {
> > >   const struct drm_color_lut *entry;
> > >   int i;
> > > @@ -625,4 +625,4 @@ int drm_color_lut_check(const struct 
> > > drm_property_blob *lut, u32 tests)
> > >
> > >   return 0;
> > >  }
> > > -EXPORT_SYMBOL(drm_color_lut_check);
> > > +EXPORT_SYMBOL(drm_color_lut_channels_check);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
> > > b/drivers/gpu/drm/i915/display/intel_color.c
> > > index dab892d2251ba..4bb1bc76c4de9 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_color.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_color.c
> > > @@ -1285,7 +1285,7 @@ static int check_luts(const struct intel_crtc_state 
> > > *crtc_state)
> > >   const struct drm_property_blob *gamma_lut = 
> > > crtc_state->hw.gamma_lut;
> > >   const struct drm_property_blob *degamma_lut = 
> > > crtc_state->hw.degamma_lut;
> > >   int gamma_length, degamma_length;
> > > - u32 gamma_tests, degamma_tests;
> > > + u32 gamma_channels_tests, degamma_channels_tests;
> > >
> > >   /* Always allow legacy gamma LUT with no further checking. */
> > >   if (crtc_state_is_legacy_gamma(crtc_state))
> > > @@ -1300,15 +1300,15 @@ static int check_luts(const struct 
> > > intel_crtc_state *crtc_state)
> > >
> > >   degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
> > >   gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
> > > - degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
> > > - gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
> > > + degamma_channels_tests = 
> > > INTEL_INFO(dev_priv)->color.degamma_lut_tests;
> > > + gamma_channels_tests = INTEL_INFO(dev_priv)->

[PATCH 3/3] drm/bridge: parade-ps8640: Perform full poweroff if poweron fails

2021-10-29 Thread AngeloGioacchino Del Regno
In function ps8640_bridge_poweron(), in case of a failure not relative
to the regulators enablement, the code was disabling the regulators but
the gpio changes that happened during the poweron sequence were not
being reverted back to a clean poweroff state.

Since it is expected that, when we enter ps8640_bridge_poweron(), the
powerdown and reset GPIOs are both in active state exactly as they were
left in the poweroff function before, we can simply call function
__ps8640_bridge_poweroff() in the failure case, reverting every change
that was done during the power on sequence.

Of course it was chosen to call the poweroff function instead of adding
code to revert the GPIO changes to the poweron one to avoid duplicating
code, as we would be doing exactly what the poweroff function does.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/bridge/parade-ps8640.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 9334217d02c9..8b54b515828a 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -346,7 +346,7 @@ static int ps8640_bridge_poweron(struct ps8640 *ps_bridge)
 
if (ret < 0) {
DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", ret);
-   goto err_regulators_disable;
+   goto err_poweroff;
}
 
msleep(50);
@@ -362,23 +362,22 @@ static int ps8640_bridge_poweron(struct ps8640 *ps_bridge)
ret = regmap_update_bits(map, PAGE2_MCS_EN, MCS_EN, 0);
if (ret < 0) {
DRM_ERROR("failed write PAGE2_MCS_EN: %d\n", ret);
-   goto err_regulators_disable;
+   goto err_poweroff;
}
 
/* Switch access edp panel's edid through i2c */
ret = regmap_write(map, PAGE2_I2C_BYPASS, I2C_BYPASS_EN);
if (ret < 0) {
DRM_ERROR("failed write PAGE2_I2C_BYPASS: %d\n", ret);
-   goto err_regulators_disable;
+   goto err_poweroff;
}
 
ps_bridge->powered = true;
 
return 0;
 
-err_regulators_disable:
-   regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
-  ps_bridge->supplies);
+err_poweroff:
+   __ps8640_bridge_poweroff(ps_bridge);
 
return ret;
 }
-- 
2.33.0



[PATCH 1/3] drm/bridge: parade-ps8640: Don't try to enable VDO if poweron fails

2021-10-29 Thread AngeloGioacchino Del Regno
If the bridge cannot get powered on, there's no reason to try to
communicate with it: change the ps8640_bridge_poweron function to
return an error value to the caller, so that we can avoid calling
ps8640_bridge_vdo_control() in ps8640_pre_enable() if the poweron
sequence fails.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/bridge/parade-ps8640.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 4b36e4dc78f1..8c5402947b3c 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -293,19 +293,19 @@ static int ps8640_bridge_vdo_control(struct ps8640 
*ps_bridge,
return 0;
 }
 
-static void ps8640_bridge_poweron(struct ps8640 *ps_bridge)
+static int ps8640_bridge_poweron(struct ps8640 *ps_bridge)
 {
struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
int ret, status;
 
if (ps_bridge->powered)
-   return;
+   return 0;
 
ret = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies),
ps_bridge->supplies);
if (ret < 0) {
DRM_ERROR("cannot enable regulators %d\n", ret);
-   return;
+   return ret;
}
 
gpiod_set_value(ps_bridge->gpio_powerdown, 0);
@@ -352,11 +352,13 @@ static void ps8640_bridge_poweron(struct ps8640 
*ps_bridge)
 
ps_bridge->powered = true;
 
-   return;
+   return 0;
 
 err_regulators_disable:
regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
   ps_bridge->supplies);
+
+   return ret;
 }
 
 static void ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
@@ -381,7 +383,9 @@ static void ps8640_pre_enable(struct drm_bridge *bridge)
struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
int ret;
 
-   ps8640_bridge_poweron(ps_bridge);
+   ret = ps8640_bridge_poweron(ps_bridge);
+   if (ret)
+   return;
 
ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);
if (ret < 0)
-- 
2.33.0



[PATCH 2/3] drm/bridge: parade-ps8640: Move real poweroff action to new function

2021-10-29 Thread AngeloGioacchino Del Regno
In preparation for varying the poweron error handling in function
ps8640_bridge_poweron(), move function ps8640_bridge_poweroff() up
and also move the actual logic to power off the chip to a new
__ps8640_bridge_poweroff() function.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/bridge/parade-ps8640.c | 39 +++---
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 8c5402947b3c..9334217d02c9 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -293,6 +293,28 @@ static int ps8640_bridge_vdo_control(struct ps8640 
*ps_bridge,
return 0;
 }
 
+static void __ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
+{
+   int ret;
+
+   gpiod_set_value(ps_bridge->gpio_reset, 1);
+   gpiod_set_value(ps_bridge->gpio_powerdown, 1);
+   if (regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
+  ps_bridge->supplies)) {
+   DRM_ERROR("cannot disable regulators %d\n", ret);
+   }
+}
+
+static void ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
+{
+   if (!ps_bridge->powered)
+   return;
+
+   __ps8640_bridge_poweroff(ps_bridge);
+
+   ps_bridge->powered = false;
+}
+
 static int ps8640_bridge_poweron(struct ps8640 *ps_bridge)
 {
struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
@@ -361,23 +383,6 @@ static int ps8640_bridge_poweron(struct ps8640 *ps_bridge)
return ret;
 }
 
-static void ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
-{
-   int ret;
-
-   if (!ps_bridge->powered)
-   return;
-
-   gpiod_set_value(ps_bridge->gpio_reset, 1);
-   gpiod_set_value(ps_bridge->gpio_powerdown, 1);
-   ret = regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
-ps_bridge->supplies);
-   if (ret < 0)
-   DRM_ERROR("cannot disable regulators %d\n", ret);
-
-   ps_bridge->powered = false;
-}
-
 static void ps8640_pre_enable(struct drm_bridge *bridge)
 {
struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
-- 
2.33.0



Re: [PATCH] drm: check drm_format_info hsub and vsub to avoid divide by zero

2021-10-29 Thread George Kennedy



On 10/28/2021 10:04 AM, Ville Syrjälä wrote:

On Thu, Oct 28, 2021 at 08:57:17AM -0500, George Kennedy wrote:

Do a sanity check on struct drm_format_info hsub and vsub values to
avoid divide by zero.

Syzkaller reported a divide error in framebuffer_check() when the
DRM_FORMAT_Q410 or DRM_FORMAT_Q401 pixel_format is passed in via
the DRM_IOCTL_MODE_ADDFB2 ioctl. The drm_format_info struct for
the DRM_FORMAT_Q410 pixel_pattern has ".hsub = 0" and ".vsub = 0".
fb_plane_width() uses hsub as a divisor and fb_plane_height() uses
vsub as a divisor. These divisors need to be sanity checked for
zero before use.

divide error:  [#1] SMP KASAN NOPTI
CPU: 0 PID: 14995 Comm: syz-executor709 Not tainted 5.15.0-rc6-syzk #1
Hardware name: Red Hat KVM, BIOS 1.13.0-2
RIP: 0010:framebuffer_check drivers/gpu/drm/drm_framebuffer.c:199 [inline]
RIP: 0010:drm_internal_framebuffer_create+0x604/0xf90
drivers/gpu/drm/drm_framebuffer.c:317

Call Trace:
  drm_mode_addfb2+0xdc/0x320 drivers/gpu/drm/drm_framebuffer.c:355
  drm_mode_addfb2_ioctl+0x2a/0x40 drivers/gpu/drm/drm_framebuffer.c:391
  drm_ioctl_kernel+0x23a/0x2e0 drivers/gpu/drm/drm_ioctl.c:795
  drm_ioctl+0x589/0xac0 drivers/gpu/drm/drm_ioctl.c:898
  vfs_ioctl fs/ioctl.c:51 [inline]
  __do_sys_ioctl fs/ioctl.c:874 [inline]
  __se_sys_ioctl fs/ioctl.c:860 [inline]
  __x64_sys_ioctl+0x19d/0x220 fs/ioctl.c:860
  do_syscall_x64 arch/x86/entry/common.c:50 [inline]
  do_syscall_64+0x3a/0x80 arch/x86/entry/common.c:80
  entry_SYSCALL_64_after_hwframe+0x44/0xae

Signed-off-by: George Kennedy 
---
  drivers/gpu/drm/drm_framebuffer.c | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index 07f5abc..a146e4b 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -195,6 +195,16 @@ static int framebuffer_check(struct drm_device *dev,
/* now let the driver pick its own format info */
info = drm_get_format_info(dev, r);
  
+	if (info->hsub == 0) {

+   DRM_DEBUG_KMS("bad horizontal chroma subsampling factor %u\n", 
info->hsub);
+   return -EINVAL;
+   }
+
+   if (info->vsub == 0) {
+   DRM_DEBUG_KMS("bad vertical chroma subsampling factor %u\n", 
info->vsub);
+   return -EINVAL;
+   }

Looks like duct tape to me. I think we need to either fix those formats
to have valid format info, or just revert the whole patch that added such
broken things.


Adding the authors and reviewer of the patch in question to CC.

94b292b277343190175d39172c903c0c5fb814f1 drm: drm_fourcc: add NV15, 
Q410, Q401 YUV formats


Asking if you have any input on how to deal with hsub and vsub = zero?

The sanity checks of hsub and vsub in the proposed patch are similar to 
other error checking done in framebuffer_check() preceding the proposed 
patch.


Thank you,
George



+
for (i = 0; i < info->num_planes; i++) {
unsigned int width = fb_plane_width(r->width, info, i);
unsigned int height = fb_plane_height(r->height, info, i);
--
1.8.3.1




[v2] drm/msm/disp/dpu1: set default group ID for CTL.

2021-10-29 Thread Kalyan Thota
New required programming in CTL for SC7280. Group ID informs
HW of which VM owns that CTL. Force this group ID to
default/disabled until virtualization support is enabled in SW.

Changes in v1:
 - Fix documentation and add descritpion for the change (Stephen)

Signed-off-by: Kalyan Thota 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 5 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 8 
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index ce6f32a..283605c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -45,7 +45,7 @@
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
 
 #define CTL_SC7280_MASK \
-   (BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE))
+   (BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | 
BIT(DPU_CTL_VM_CFG))
 
 #define MERGE_3D_SM8150_MASK (0)
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 4ade44b..31af04a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -179,13 +179,16 @@ enum {
 
 /**
  * CTL sub-blocks
- * @DPU_CTL_SPLIT_DISPLAY   CTL supports video mode split display
+ * @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display
+ * @DPU_CTL_FETCH_ACTIVE:  Active CTL for fetch HW (SSPPs)
+ * @DPU_CTL_VM_CFG:CTL config to support multiple VMs
  * @DPU_CTL_MAX
  */
 enum {
DPU_CTL_SPLIT_DISPLAY = 0x1,
DPU_CTL_ACTIVE_CFG,
DPU_CTL_FETCH_ACTIVE,
+   DPU_CTL_VM_CFG,
DPU_CTL_MAX
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 64740ddb..02da9ec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -36,6 +36,7 @@
 #define  MERGE_3D_IDX   23
 #define  INTF_IDX   31
 #define CTL_INVALID_BIT 0x
+#define CTL_DEFAULT_GROUP_ID   0xf
 
 static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19,
CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0,
@@ -498,6 +499,13 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
u32 intf_active = 0;
u32 mode_sel = 0;
 
+   /* CTL_TOP[31:28] carries group_id to collate CTL paths
+* per VM. Explicitly disable it until VM support is
+* added in SW. Power on reset value is not disable.
+*/
+   if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features)))
+   mode_sel = CTL_DEFAULT_GROUP_ID  << 28;
+
if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
mode_sel |= BIT(17);
 
-- 
2.7.4



Re: [v2] drm/msm/disp/dpu1: set default group ID for CTL.

2021-10-29 Thread Dmitry Baryshkov
On Fri, 29 Oct 2021 at 15:30, Kalyan Thota  wrote:
>
> New required programming in CTL for SC7280. Group ID informs
> HW of which VM owns that CTL. Force this group ID to
> default/disabled until virtualization support is enabled in SW.
>
> Changes in v1:
>  - Fix documentation and add descritpion for the change (Stephen)
>
> Signed-off-by: Kalyan Thota 

Reviewed-by: Dmitry Baryshkov 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 5 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 8 
>  3 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> index ce6f32a..283605c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -45,7 +45,7 @@
> (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
>
>  #define CTL_SC7280_MASK \
> -   (BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE))
> +   (BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | 
> BIT(DPU_CTL_VM_CFG))
>
>  #define MERGE_3D_SM8150_MASK (0)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index 4ade44b..31af04a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -179,13 +179,16 @@ enum {
>
>  /**
>   * CTL sub-blocks
> - * @DPU_CTL_SPLIT_DISPLAY   CTL supports video mode split display
> + * @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display
> + * @DPU_CTL_FETCH_ACTIVE:  Active CTL for fetch HW (SSPPs)
> + * @DPU_CTL_VM_CFG:CTL config to support multiple VMs
>   * @DPU_CTL_MAX
>   */
>  enum {
> DPU_CTL_SPLIT_DISPLAY = 0x1,
> DPU_CTL_ACTIVE_CFG,
> DPU_CTL_FETCH_ACTIVE,
> +   DPU_CTL_VM_CFG,
> DPU_CTL_MAX
>  };
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> index 64740ddb..02da9ec 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> @@ -36,6 +36,7 @@
>  #define  MERGE_3D_IDX   23
>  #define  INTF_IDX   31
>  #define CTL_INVALID_BIT 0x
> +#define CTL_DEFAULT_GROUP_ID   0xf
>
>  static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19,
> CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0,
> @@ -498,6 +499,13 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl 
> *ctx,
> u32 intf_active = 0;
> u32 mode_sel = 0;
>
> +   /* CTL_TOP[31:28] carries group_id to collate CTL paths
> +* per VM. Explicitly disable it until VM support is
> +* added in SW. Power on reset value is not disable.
> +*/
> +   if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features)))
> +   mode_sel = CTL_DEFAULT_GROUP_ID  << 28;
> +
> if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
> mode_sel |= BIT(17);
>
> --
> 2.7.4
>


-- 
With best wishes
Dmitry


[PATCH v2] drm/i915/dmabuf: drop the flush on discrete

2021-10-29 Thread Matthew Auld
We were overzealous here; even though discrete is non-LLC, it should
still be always coherent.

v2(Thomas & Daniel)
  - Be extra cautious and limit to DG1
  - Add some more commentary

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Cc: Daniel Vetter 
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index a45d0ec2c5b6..a2b485a1be8c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -250,8 +250,19 @@ static int i915_gem_object_get_pages_dmabuf(struct 
drm_i915_gem_object *obj)
if (IS_ERR(pages))
return PTR_ERR(pages);
 
-   /* XXX: consider doing a vmap flush or something */
-   if (!HAS_LLC(i915) || i915_gem_object_can_bypass_llc(obj))
+   /*
+* DG1 is special here since it still snoops transactions even with
+* CACHE_NONE. This is not the case with other HAS_SNOOP platforms. We
+* might need to revisit this as we add new discrete platforms.
+*
+* XXX: Consider doing a vmap flush or something, where possible.
+* Currently we just do a heavy handed wbinvd_on_all_cpus() here since
+* the underlying sg_table might not even point to struct pages, so we
+* can't just call drm_clflush_sg or similar, like we do elsewhere in
+* the driver.
+*/
+   if (i915_gem_object_can_bypass_llc(obj) ||
+   (!HAS_LLC(i915) && !IS_DG1(i915)))
wbinvd_on_all_cpus();
 
sg_page_sizes = i915_sg_dma_sizes(pages->sgl);
-- 
2.26.3



RE: [PATCH 2/4] drm/dp_mst: Only create connector for connected end device

2021-10-29 Thread Lin, Wayne
[Public]

Thanks Lyude for patiently guiding on this : )
Would like to learn more as following

> -Original Message-
> From: Lyude Paul 
> Sent: Wednesday, October 27, 2021 3:35 AM
> To: Lin, Wayne ; dri-devel@lists.freedesktop.org
> Cc: Kazlauskas, Nicholas ; Wentland, Harry 
> ; Zuo, Jerry
> ; Wu, Hersen ; Juston Li 
> ; Imre Deak ;
> Ville Syrjälä ; Daniel Vetter 
> ; Sean Paul ; Maarten Lankhorst
> ; Maxime Ripard ; 
> Thomas Zimmermann ;
> David Airlie ; Daniel Vetter ; Deucher, 
> Alexander ; Siqueira,
> Rodrigo ; Pillai, Aurabindo 
> ; Bas Nieuwenhuizen
> ; Cornij, Nikola ; Jani 
> Nikula ; Manasi Navare
> ; Ankit Nautiyal ; 
> José Roberto de Souza ; Sean
> Paul ; Ben Skeggs ; 
> sta...@vger.kernel.org
> Subject: Re: [PATCH 2/4] drm/dp_mst: Only create connector for connected end 
> device
>
> Comments below
>
> On Tue, 2021-10-26 at 03:50 +, Lin, Wayne wrote:
> > [Public]
> >
> > Hi Lyude!
> > Apologize for replying late and really thanks for elaborating in such
> > details!
> > Following are some of my thoughts : )
> >
> > > -Original Message-
> > > From: Lyude Paul 
> > > Sent: Saturday, September 18, 2021 1:48 AM
> > > To: Lin, Wayne ; dri-devel@lists.freedesktop.org
> > > Cc: Kazlauskas, Nicholas ; Wentland,
> > > Harry ; Zuo, Jerry ; Wu,
> > > Hersen ; Juston Li ; Imre
> > > Deak ; Ville Syrjälä
> > > ; Daniel Vetter
> > > ; Sean Paul ; Maarten
> > > Lankhorst ; Maxime Ripard
> > > ; Thomas Zimmermann ; David
> > > Airlie ; Daniel Vetter ; Deucher,
> > > Alexander ; Siqueira, Rodrigo
> > > ; Pillai, Aurabindo
> > > ; Bas Nieuwenhuizen
> > > ; Cornij, Nikola ;
> > > Jani Nikula ; Manasi Navare
> > > ; Ankit Nautiyal
> > > ; José Roberto de Souza
> > > ; Sean Paul ; Ben
> > > Skeggs ; sta...@vger.kernel.org
> > > Subject: Re: [PATCH 2/4] drm/dp_mst: Only create connector for
> > > connected end device
> > >
> > > Sorry about the slow response, this week XDC has been going on and
> > > I've been mostly paying attention to that.
> > >
> > > On Tue, 2021-09-14 at 08:46 +, Lin, Wayne wrote:
> > > > [Public]
> > > >
> > > > > -Original Message-
> > > > > From: Lyude Paul 
> > > > > Sent: Thursday, September 2, 2021 6:00 AM
> > > > > To: Lin, Wayne ;
> > > > > dri-devel@lists.freedesktop.org
> > > > > Cc: Kazlauskas, Nicholas ;
> > > > > Wentland, Harry ; Zuo, Jerry
> > > > > ; Wu, Hersen ; Juston Li
> > > > > ; Imre Deak ; Ville
> > > > > Syrjälä ; Daniel Vetter
> > > > > ; Sean Paul ; Maarten
> > > > > Lankhorst ; Maxime Ripard
> > > > > ; Thomas Zimmermann ;
> > > > > David Airlie ; Daniel Vetter
> > > > > ; Deucher, Alexander
> > > > > ; Siqueira, Rodrigo
> > > > > ; Pillai, Aurabindo
> > > > > ; Bas Nieuwenhuizen
> > > > > ; Cornij, Nikola
> > > > > ; Jani Nikula ;
> > > > > Manasi Navare ; Ankit Nautiyal
> > > > > ; José Roberto de Souza
> > > > > ; Sean Paul ; Ben
> > > > > Skeggs ; sta...@vger.kernel.org
> > > > > Subject: Re: [PATCH 2/4] drm/dp_mst: Only create connector for
> > > > > connected end device
> > > > >
> > > > > Actually - did some more thinking, and I think we shouldn't try
> > > > > to make changes like this until we actually know what the
> > > > > problem is here. I could try to figure out what the actual race
> > > > > conditions I was facing before with trying to add/destroy
> > > > > connectors based on PDT, but we still don't even actually have a
> > > > > clear idea of what's broken here.
> > > > > I'd much rather us figure out exactly how this leak is happening
> > > > > before considering making changes like this, because we have no
> > > > > way of knowing if we've properly fixed it or not if we don't
> > > > > know what the problem is in the first place.
> > > > >
> > > > > I'm still happy to write up the topology debugging stuff I
> > > > > mentioned to you if you think that would help you debug this
> > > > > issue - since that would make it a lot easier for you to track
> > > > > down what references are keeping a connector alive (and
> > > > > additkionally, where those references were taken in code. thanks
> > > > > stack_depot!)
> > > > Hi Lyude,
> > > > Sorry for late response. A bit busy on other stuff recently..
> > > >
> > > > Really really thankful for all your help : ) I'm also glad to have
> > > > the debugging tool if it won’t bother you too much. But before
> > > > debugging,
> > >
> > > no problem! I will get to it early next week then
> > >
> > > > I need to have consensus with you about where do we expect to
> > > > release resource allocated for a stream sink when it's reported as
> > > > disconnected. Previous patch suggests releasing resource when
> > > > connector is destroyed which will happen when topology refcount
> > > > reaches zero (i.e. unplug mstb from topology). But when the case
> > > > is receiving CSN notifying connection change, we don't try to
> > > > destroy connector in this case now. And this is not caused by
> > > > topology/malloc refcount leak since I don't expect neither one of
> > > > them g

Re: [PATCH] [RESEND] drm: fb_helper: fix CONFIG_FB dependency

2021-10-29 Thread Arnd Bergmann
On Thu, Oct 28, 2021 at 5:24 PM Daniel Vetter  wrote:
>
> On Wed, Oct 27, 2021 at 03:19:34PM +0200, Javier Martinez Canillas wrote:
> > On 10/27/21 14:18, Arnd Bergmann wrote:
> >
> > [snip]
> >
> > > Right, how about this change on top?
> > >
> > > --- a/drivers/gpu/drm/Kconfig
> > > +++ b/drivers/gpu/drm/Kconfig
> > > @@ -117,9 +117,8 @@ config DRM_DEBUG_MODESET_LOCK
> > >
> > >  config DRM_FBDEV_EMULATION
> > > bool "Enable legacy fbdev support for your modesetting driver"
> > > -   depends on DRM
> > > -   depends on FB=y || FB=DRM
> > > -   select DRM_KMS_HELPER
> > > +   depends on DRM_KMS_HELPER
> > > +   depends on FB=y || FB=DRM_KMS_HELPER
> > > select FB_CFB_FILLRECT
> > > select FB_CFB_COPYAREA
> > > select FB_CFB_IMAGEBLIT
> > >
> > > That would probably make it work for DRM=y, FB=m, DRM_KMS_HELPER=m,
> > > but it needs more randconfig testing, which I can help with.
> >
> > Looks good to me as well.
> >
> > Reviewed-by: Javier Martinez Canillas 
>
> Is the mess I created sorted now, or something for me to do? I'm terribly
> burried in stuff :-/

I have done a few days worth of build testing with that patch applied, and
did not see any other problems. I've written a proper description and
submitted it as
https://lore.kernel.org/all/20211029120307.1407047-1-a...@kernel.org/T

The version you have in linux-next works correctly, but this patch on top
is an improvement.

Arnd


[PATCH] drm: fb_helper: improve CONFIG_FB dependency

2021-10-29 Thread Arnd Bergmann
From: Arnd Bergmann 

My previous patch correctly addressed the possible link failure, but as
Jani points out, the dependency is now stricter than it needs to be.

Change it again, to allow DRM_FBDEV_EMULATION to be used when
DRM_KMS_HELPER and FB are both loadable modules and DRM is linked into
the kernel.

As a side-effect, the option is now only visible when at least one DRM
driver makes use of DRM_KMS_HELPER. This is better, because the option
has no effect otherwise.

Fixes: 606b102876e3 ("drm: fb_helper: fix CONFIG_FB dependency")
Suggested-by: Acked-by: Jani Nikula 
Reviewed-by: Javier Martinez Canillas 
Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/Kconfig | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index c08860db2520..d2e6d8ce5000 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -117,9 +117,8 @@ config DRM_DEBUG_MODESET_LOCK
 
 config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
-   depends on DRM
-   depends on FB=y || FB=DRM
-   select DRM_KMS_HELPER
+   depends on DRM_KMS_HELPER
+   depends on FB=y || FB=DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
-- 
2.29.2



[PATCH] drm/rockchip: use generic fbdev setup

2021-10-29 Thread John Keeping
The Rockchip fbdev code does not add anything compared to
drm_fbdev_generic_setup(); the one custom function for .fb_mmap does the
same thing as gem_prime_mmap which is called by the helper.

Signed-off-by: John Keeping 
---
 drivers/gpu/drm/rockchip/Makefile |   1 -
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |  10 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   2 -
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 164 --
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h |  24 ---
 5 files changed, 2 insertions(+), 199 deletions(-)
 delete mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
 delete mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 17a9e7eb2130..1a56f696558c 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -5,7 +5,6 @@
 
 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o
-rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
 
 rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 69c699459dce..20d81ae69828 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -26,7 +26,6 @@
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_fb.h"
-#include "rockchip_drm_fbdev.h"
 #include "rockchip_drm_gem.h"
 
 #define DRIVER_NAME"rockchip"
@@ -159,10 +158,6 @@ static int rockchip_drm_bind(struct device *dev)
 
drm_mode_config_reset(drm_dev);
 
-   ret = rockchip_drm_fbdev_init(drm_dev);
-   if (ret)
-   goto err_unbind_all;
-
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(drm_dev);
 
@@ -170,10 +165,11 @@ static int rockchip_drm_bind(struct device *dev)
if (ret)
goto err_kms_helper_poll_fini;
 
+   drm_fbdev_generic_setup(drm_dev, 32);
+
return 0;
 err_kms_helper_poll_fini:
drm_kms_helper_poll_fini(drm_dev);
-   rockchip_drm_fbdev_fini(drm_dev);
 err_unbind_all:
component_unbind_all(dev, drm_dev);
 err_iommu_cleanup:
@@ -189,7 +185,6 @@ static void rockchip_drm_unbind(struct device *dev)
 
drm_dev_unregister(drm_dev);
 
-   rockchip_drm_fbdev_fini(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
 
drm_atomic_helper_shutdown(drm_dev);
@@ -203,7 +198,6 @@ DEFINE_DRM_GEM_FOPS(rockchip_drm_driver_fops);
 
 static const struct drm_driver rockchip_drm_driver = {
.driver_features= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
-   .lastclose  = drm_fb_helper_lastclose,
.dumb_create= rockchip_gem_dumb_create,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index aa0909e8edf9..143a48330f84 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -43,8 +43,6 @@ struct rockchip_crtc_state {
  * @mm_lock: protect drm_mm on multi-threads.
  */
 struct rockchip_drm_private {
-   struct drm_fb_helper fbdev_helper;
-   struct drm_gem_object *fbdev_bo;
struct iommu_domain *domain;
struct mutex mm_lock;
struct drm_mm mm;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
deleted file mode 100644
index d8418dd39d0e..
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ /dev/null
@@ -1,164 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
- * Author:Mark Yao 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "rockchip_drm_drv.h"
-#include "rockchip_drm_gem.h"
-#include "rockchip_drm_fb.h"
-#include "rockchip_drm_fbdev.h"
-
-#define PREFERRED_BPP  32
-#define to_drm_private(x) \
-   container_of(x, struct rockchip_drm_private, fbdev_helper)
-
-static int rockchip_fbdev_mmap(struct fb_info *info,
-  struct vm_area_struct *vma)
-{
-   struct drm_fb_helper *helper = info->par;
-   struct rockchip_drm_private *private = to_drm_private(helper);
-
-   return drm_gem_prime_mmap(private->fbdev_bo, vma);
-}
-
-static const struct fb_ops rockchip_drm_fbdev_ops = {
-   .owner  = THIS_MODULE,
-   DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_mmap= rockchip_fbdev_mmap,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
-};
-
-static int

Re: [PATCH v8, 07/17] dt-bindings: media: mtk-vcodec: Separate video encoder and decoder dt-bindings

2021-10-29 Thread Dafna Hirschfeld




On 29.10.21 05:55, Yunfei Dong wrote:

Decoder will use component framework to manage hardware, it is big
difference with encoder.

Reviewed-by: Rob Herring
Signed-off-by: Yunfei Dong 
---
  .../media/mediatek,vcodec-decoder.yaml| 176 +
  .../media/mediatek,vcodec-encoder.yaml| 187 ++
  .../bindings/media/mediatek-vcodec.txt| 131 
  3 files changed, 363 insertions(+), 131 deletions(-)
  create mode 100644 
Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
  create mode 100644 
Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
  delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt

diff --git 
a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml 
b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
new file mode 100644
index ..5de37065fbce
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -0,0 +1,176 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong 
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8173-vcodec-dec
+  - mediatek,mt8183-vcodec-dec
+
+  reg:
+maxItems: 12
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+maxItems: 8
+
+  clock-names:
+items:
+  - const: vcodecpll
+  - const: univpll_d2
+  - const: clk_cci400_sel
+  - const: vdec_sel
+  - const: vdecpll
+  - const: vencpll
+  - const: venc_lt_sel
+  - const: vdec_bus_clk_src
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  assigned-clock-rates: true
+
+  power-domains:
+maxItems: 1
+
+  iommus:
+minItems: 1
+maxItems: 32
+description: |
+  List of the hardware port in respective IOMMU block for current Socs.
+  Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+maxItems: 1
+description: |
+  Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+$ref: /schemas/types.yaml#/definitions/phandle
+maxItems: 1
+description: |
+  Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+$ref: /schemas/types.yaml#/definitions/phandle
+maxItems: 1
+description:
+  Describes point to vpu.
+
+  mediatek,scp:
+$ref: /schemas/types.yaml#/definitions/phandle
+maxItems: 1
+description:
+  Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - mediatek,mt8183-vcodec-dec
+
+then:
+  required:
+- mediatek,scp
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - mediatek,mt8173-vcodec-dec
+
+then:
+  required:
+- mediatek,vpu
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+#include 
+#include 
+
+vcodec_dec: vcodec@1600 {
+  compatible = "mediatek,mt8173-vcodec-dec";
+  reg = <0x1600 0x100>,   /*VDEC_SYS*/
+  <0x1602 0x1000>,  /*VDEC_MISC*/
+  <0x16021000 0x800>,   /*VDEC_LD*/
+  <0x16021800 0x800>,   /*VDEC_TOP*/
+  <0x16022000 0x1000>,  /*VDEC_CM*/
+  <0x16023000 0x1000>,  /*VDEC_AD*/
+  <0x16024000 0x1000>,  /*VDEC_AV*/
+  <0x16025000 0x1000>,  /*VDEC_PP*/
+  <0x16026800 0x800>,   /*VP8_VD*/
+  <0x16027000 0x800>,   /*VP6_VD*/
+  <0x16027800 0x800>,   /*VP8_VL*/
+  <0x16028400 0x400>;   /*VP9_VD*/
+  interrupts = ;
+  mediatek,larb = <&larb1>;
+  iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
+  mediatek,vpu = <&vpu>;
+  power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+  clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
+ <&topckgen CLK_TOP_UNIVPLL_D2>,
+ <&topckgen CLK_TOP_CCI400_SEL>,
+ <&topckgen CLK_TOP_VDEC_SEL>,
+ <&topckgen CLK_TOP_VCODECPLL>,
+ <&apmixedsys CLK_APMIXED_VENCPLL>,
+ <&topckgen CLK_TOP_VENC_LT_

Re: [PATCH v8, 04/17] media: mtk-vcodec: Build decoder pm file as module

2021-10-29 Thread Dafna Hirschfeld




On 29.10.21 05:55, Yunfei Dong wrote:

Need to build decoder pm file as module for master and comp
use the same pm interface.


Do you still use the component framework in this patchset?
In the cover letter you write: "- Use of_platform_populate to manage multi hardware, 
not component framework for patch 4/15"
If that frameworks is not used anymore you should also change the commit log, 
and maybe this patch is not needed anymore?

Thanks,
Dafna


Signed-off-by: Yunfei Dong 
---
v8: add new patch to build pm file as module
---
  drivers/media/platform/mtk-vcodec/Makefile| 6 --
  drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 9 +
  2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/Makefile 
b/drivers/media/platform/mtk-vcodec/Makefile
index ca8e9e7a9c4e..5d36e05535d7 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -2,7 +2,8 @@
  
  obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \

   mtk-vcodec-enc.o \
-  mtk-vcodec-common.o
+  mtk-vcodec-common.o \
+  mtk-vcodec-dec-common.o
  
  mtk-vcodec-dec-y := vdec/vdec_h264_if.o \

vdec/vdec_vp8_if.o \
@@ -14,7 +15,8 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
mtk_vcodec_dec.o \
mtk_vcodec_dec_stateful.o \
mtk_vcodec_dec_stateless.o \
-   mtk_vcodec_dec_pm.o \
+
+mtk-vcodec-dec-common-y := mtk_vcodec_dec_pm.o
  
  mtk-vcodec-enc-y := venc/venc_vp8_if.o \

venc/venc_h264_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 20bd157a855c..09a281e3065a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -77,12 +77,14 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
put_device(pm->larbvdec);
return ret;
  }
+EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_pm);
  
  void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)

  {
pm_runtime_disable(pm->dev);
put_device(pm->larbvdec);
  }
+EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
  
  int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)

  {
@@ -94,6 +96,7 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
  
  	return ret;

  }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
  
  void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)

  {
@@ -103,6 +106,7 @@ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
if (ret)
mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
  }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
  
  void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)

  {
@@ -129,6 +133,7 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
for (i -= 1; i >= 0; i--)
clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
  }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
  
  void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)

  {
@@ -139,3 +144,7 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
for (i = dec_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
  }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediatek video decoder driver");



Re: [PATCH v8, 03/17] media: mtk-vcodec: Refactor vcodec pm interface

2021-10-29 Thread Dafna Hirschfeld




On 29.10.21 05:55, Yunfei Dong wrote:

Using the needed param for pm init/release function and remove unused
param mtkdev in 'struct mtk_vcodec_pm'.

Reviewed-by: Tzung-Bi Shih 
Reviewed-By: AngeloGioacchino Del Regno 

Signed-off-by: Yunfei Dong 


Hi,
I already commented on v7 that since the pm implementation for dec and enc is 
identical,
you should better do the same refactor to enc and dec or better remove the code 
duplication.

Thanks,
Dafna


---
  .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
  .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 22 ---
  .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 +++--
  .../platform/mtk-vcodec/mtk_vcodec_drv.h  |  1 -
  .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
  5 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 055d50e52720..3ac4c3935e4e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -249,7 +249,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
if (IS_ERR(dev->fw_handler))
return PTR_ERR(dev->fw_handler);
  
-	ret = mtk_vcodec_init_dec_pm(dev);

+   ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
goto err_dec_pm;
@@ -378,7 +378,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
  err_dec_alloc:
v4l2_device_unregister(&dev->v4l2_dev);
  err_res:
-   mtk_vcodec_release_dec_pm(dev);
+   mtk_vcodec_release_dec_pm(&dev->pm);
  err_dec_pm:
mtk_vcodec_fw_release(dev->fw_handler);
return ret;
@@ -418,7 +418,7 @@ static int mtk_vcodec_dec_remove(struct platform_device 
*pdev)
video_unregister_device(dev->vfd_dec);
  
  	v4l2_device_unregister(&dev->v4l2_dev);

-   mtk_vcodec_release_dec_pm(dev);
+   mtk_vcodec_release_dec_pm(&dev->pm);
mtk_vcodec_fw_release(dev->fw_handler);
return 0;
  }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 6038db96f71c..20bd157a855c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -13,18 +13,15 @@
  #include "mtk_vcodec_dec_pm.h"
  #include "mtk_vcodec_util.h"
  
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)

+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+   struct mtk_vcodec_pm *pm)
  {
struct device_node *node;
-   struct platform_device *pdev;
-   struct mtk_vcodec_pm *pm;
+   struct platform_device *larb_pdev;
struct mtk_vcodec_clk *dec_clk;
struct mtk_vcodec_clk_info *clk_info;
int i = 0, ret = 0;
  
-	pdev = mtkdev->plat_dev;

-   pm = &mtkdev->pm;
-   pm->mtkdev = mtkdev;
dec_clk = &pm->vdec_clk;
node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
if (!node) {
@@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
return -1;
}
  
-	pdev = of_find_device_by_node(node);

+   larb_pdev = of_find_device_by_node(node);
of_node_put(node);
-   if (WARN_ON(!pdev)) {
+   if (WARN_ON(!larb_pdev)) {
return -1;
}
-   pm->larbvdec = &pdev->dev;
-   pdev = mtkdev->plat_dev;
+   pm->larbvdec = &larb_pdev->dev;
pm->dev = &pdev->dev;
  
  	dec_clk->clk_num =

@@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
return ret;
  }
  
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)

+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
  {
-   pm_runtime_disable(dev->pm.dev);
-   put_device(dev->pm.larbvdec);
+   pm_runtime_disable(pm->dev);
+   put_device(pm->larbvdec);
  }
  
  int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 280aeaefdb65..a3df6aef6cb9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,8 +9,9 @@
  
  #include "mtk_vcodec_drv.h"
  
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);

-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+   struct mtk_vcodec_pm *pm);
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
  
  int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);

  void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 1d2370608d0d..0fa9d85114b9 100644
--- a/dri

[PATCH] drm/armada: Fix off-by-one error in armada_overlay_get_property()

2021-10-29 Thread Geert Uytterhoeven
As ffs() returns one more than the index of the first bit set (zero
means no bits set), the color key mode value is shifted one position too
much.

Fix this by using FIELD_GET() instead.

Fixes: c96103b6c49ff9a8 ("drm/armada: move colorkey properties into overlay 
plane state")
Signed-off-by: Geert Uytterhoeven 
---
Compile-tested only.
---
 drivers/gpu/drm/armada/armada_overlay.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 424250535fed9e87..0383deb97003 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -4,6 +4,8 @@
  *  Rewritten from the dovefb driver, and Armada510 manuals.
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -451,8 +453,8 @@ static int armada_overlay_get_property(struct drm_plane 
*plane,
 drm_to_overlay_state(state)->colorkey_ug,
 drm_to_overlay_state(state)->colorkey_vb, 0);
} else if (property == priv->colorkey_mode_prop) {
-   *val = (drm_to_overlay_state(state)->colorkey_mode &
-   CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK);
+   *val = FIELD_GET(CFG_CKMODE_MASK,
+drm_to_overlay_state(state)->colorkey_mode);
} else if (property == priv->brightness_prop) {
*val = drm_to_overlay_state(state)->brightness + 256;
} else if (property == priv->contrast_prop) {
-- 
2.25.1



[PATCH v3 8/8] drm/i915: Require object lock when freeing pages during destruction

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

TTM already requires this, and we require it for delayed destroy.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 55b0f1df3192..6e5412e2b5ad 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -257,6 +257,8 @@ static void __i915_gem_object_free_mmaps(struct 
drm_i915_gem_object *obj)
  */
 void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
 {
+   assert_object_held(obj);
+
if (!list_empty(&obj->vma.list)) {
struct i915_vma *vma;
 
@@ -323,7 +325,10 @@ static void __i915_gem_free_objects(struct 
drm_i915_private *i915,
obj->ops->delayed_free(obj);
continue;
}
+
+   i915_gem_object_lock(obj, NULL);
__i915_gem_object_pages_fini(obj);
+   i915_gem_object_unlock(obj);
__i915_gem_free_object(obj);
 
/* But keep the pointer alive for RCU-protected lookups */
-- 
2.26.3



[PATCH v3 7/8] drm/i915: Drain the ttm delayed workqueue too

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

Lets be thorough here. Users of the TTM backend would likely expect this
behaviour.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 57f2f8da931e..1dc30ee26771 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1818,6 +1818,7 @@ static inline void i915_gem_drain_freed_objects(struct 
drm_i915_private *i915)
 */
while (atomic_read(&i915->mm.free_count)) {
flush_work(&i915->mm.free_work);
+   flush_delayed_work(&i915->bdev.wq);
rcu_barrier();
}
 }
-- 
2.26.3



[PATCH v3 6/8] drm/i915: Rework context handling in hugepages selftests

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

In the next commit, we don't evict when refcount = 0, so we need to
call drain freed objects, because we want to pin new bo's in the same
place, causing a test failure.

Furthermore, since each subtest is separated, it's a lot better to use
i915_live_selftests, so each subtest starts with a clean slate, and a
clean address space.

v2:
  - Make hugepage_ctx static. Reported-by: kernel test robot 

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 .../gpu/drm/i915/gem/selftests/huge_pages.c   | 128 +++---
 1 file changed, 80 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index b2003133deaf..257588b68adc 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -22,6 +22,22 @@
 #include "selftests/mock_region.h"
 #include "selftests/i915_random.h"
 
+static struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915,
+struct file *file)
+{
+   struct i915_gem_context *ctx = live_context(i915, file);
+   struct i915_address_space *vm;
+
+   if (IS_ERR(ctx))
+   return ctx;
+
+   vm = ctx->vm;
+   if (vm)
+   WRITE_ONCE(vm->scrub_64K, true);
+
+   return ctx;
+}
+
 static const unsigned int page_sizes[] = {
I915_GTT_PAGE_SIZE_2M,
I915_GTT_PAGE_SIZE_64K,
@@ -959,6 +975,8 @@ static int igt_mock_ppgtt_64K(void *arg)
__i915_gem_object_put_pages(obj);
i915_gem_object_unlock(obj);
i915_gem_object_put(obj);
+
+   i915_gem_drain_freed_objects(i915);
}
}
 
@@ -1080,10 +1098,6 @@ static int __igt_write_huge(struct intel_context *ce,
if (IS_ERR(vma))
return PTR_ERR(vma);
 
-   err = i915_vma_unbind(vma);
-   if (err)
-   return err;
-
err = i915_vma_pin(vma, size, 0, flags | offset);
if (err) {
/*
@@ -1117,7 +1131,7 @@ static int __igt_write_huge(struct intel_context *ce,
return err;
 }
 
-static int igt_write_huge(struct i915_gem_context *ctx,
+static int igt_write_huge(struct drm_i915_private *i915,
  struct drm_i915_gem_object *obj)
 {
struct i915_gem_engines *engines;
@@ -1127,6 +1141,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
IGT_TIMEOUT(end_time);
unsigned int max_page_size;
unsigned int count;
+   struct i915_gem_context *ctx;
+   struct file *file;
u64 max;
u64 num;
u64 size;
@@ -1134,6 +1150,16 @@ static int igt_write_huge(struct i915_gem_context *ctx,
int i, n;
int err = 0;
 
+   file = mock_file(i915);
+   if (IS_ERR(file))
+   return PTR_ERR(file);
+
+   ctx = hugepage_ctx(i915, file);
+   if (IS_ERR(ctx)) {
+   err = PTR_ERR(ctx);
+   goto out;
+   }
+
GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
 
size = obj->base.size;
@@ -1153,7 +1179,7 @@ static int igt_write_huge(struct i915_gem_context *ctx,
}
i915_gem_context_unlock_engines(ctx);
if (!n)
-   return 0;
+   goto out;
 
/*
 * To keep things interesting when alternating between engines in our
@@ -1215,6 +1241,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 
kfree(order);
 
+out:
+   fput(file);
return err;
 }
 
@@ -1277,8 +1305,7 @@ static u32 igt_random_size(struct rnd_state *prng,
 
 static int igt_ppgtt_smoke_huge(void *arg)
 {
-   struct i915_gem_context *ctx = arg;
-   struct drm_i915_private *i915 = ctx->i915;
+   struct drm_i915_private *i915 = arg;
struct drm_i915_gem_object *obj;
I915_RND_STATE(prng);
struct {
@@ -1302,6 +1329,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
u32 min = backends[i].min;
u32 max = backends[i].max;
u32 size = max;
+
 try_again:
size = igt_random_size(&prng, min, rounddown_pow_of_two(size));
 
@@ -1336,7 +1364,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
goto out_unpin;
}
 
-   err = igt_write_huge(ctx, obj);
+   err = igt_write_huge(i915, obj);
if (err) {
pr_err("%s write-huge failed with size=%u, i=%d\n",
   __func__, size, i);
@@ -1363,8 +1391,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 
 static int igt_ppgtt_sanity_check(void *arg)
 {
-   struct i915_gem_context *ctx = arg;
-   struct drm_i915_private *i915 = ctx->i915;
+   struct drm_i915_private *i915 = arg;
unsigned int supported = INTEL_INFO(i915)->page_sizes;

[PATCH v3 5/8] drm/i915: Remove resv from i915_vma

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

It's just an alias to vma->obj->base.resv, no need to duplicate it.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Niranjana Vishwanathapura 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 4 ++--
 drivers/gpu/drm/i915/i915_vma.c| 9 -
 drivers/gpu/drm/i915/i915_vma.h| 6 +++---
 drivers/gpu/drm/i915/i915_vma_types.h  | 1 -
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index ea5b7b2a4d70..9f7c6ecadb90 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1001,7 +1001,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
}
 
if (!(ev->flags & EXEC_OBJECT_WRITE)) {
-   err = dma_resv_reserve_shared(vma->resv, 1);
+   err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
if (err)
return err;
}
@@ -2175,7 +2175,7 @@ static int eb_parse(struct i915_execbuffer *eb)
goto err_trampoline;
}
 
-   err = dma_resv_reserve_shared(shadow->resv, 1);
+   err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
if (err)
goto err_trampoline;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 656152daabbe..2e43d9511b28 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -116,7 +116,6 @@ vma_create(struct drm_i915_gem_object *obj,
vma->vm = i915_vm_get(vm);
vma->ops = &vm->vma_ops;
vma->obj = obj;
-   vma->resv = obj->base.resv;
vma->size = obj->base.size;
vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
 
@@ -1032,7 +1031,7 @@ int i915_ggtt_pin(struct i915_vma *vma, struct 
i915_gem_ww_ctx *ww,
GEM_BUG_ON(!i915_vma_is_ggtt(vma));
 
 #ifdef CONFIG_LOCKDEP
-   WARN_ON(!ww && dma_resv_held(vma->resv));
+   WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
 #endif
 
do {
@@ -1251,19 +1250,19 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
}
 
if (fence) {
-   dma_resv_add_excl_fence(vma->resv, fence);
+   dma_resv_add_excl_fence(vma->obj->base.resv, fence);
obj->write_domain = I915_GEM_DOMAIN_RENDER;
obj->read_domains = 0;
}
} else {
if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-   err = dma_resv_reserve_shared(vma->resv, 1);
+   err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
if (unlikely(err))
return err;
}
 
if (fence) {
-   dma_resv_add_shared_fence(vma->resv, fence);
+   dma_resv_add_shared_fence(vma->obj->base.resv, fence);
obj->write_domain = 0;
}
}
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 312933c06017..4033aa08d5e4 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -234,16 +234,16 @@ static inline void __i915_vma_put(struct i915_vma *vma)
kref_put(&vma->ref, i915_vma_release);
 }
 
-#define assert_vma_held(vma) dma_resv_assert_held((vma)->resv)
+#define assert_vma_held(vma) dma_resv_assert_held((vma)->obj->base.resv)
 
 static inline void i915_vma_lock(struct i915_vma *vma)
 {
-   dma_resv_lock(vma->resv, NULL);
+   dma_resv_lock(vma->obj->base.resv, NULL);
 }
 
 static inline void i915_vma_unlock(struct i915_vma *vma)
 {
-   dma_resv_unlock(vma->resv);
+   dma_resv_unlock(vma->obj->base.resv);
 }
 
 int __must_check
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h 
b/drivers/gpu/drm/i915/i915_vma_types.h
index 80e93bf00f2e..8a0decb19bcc 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -178,7 +178,6 @@ struct i915_vma {
const struct i915_vma_ops *ops;
 
struct drm_i915_gem_object *obj;
-   struct dma_resv *resv; /** Alias of obj->resv */
 
struct sg_table *pages;
void __iomem *iomap;
-- 
2.26.3



[PATCH v3 2/8] drm/i915: Create a dummy object for gen6 ppgtt

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

We currently have to special case vma->obj being NULL because
of gen6 ppgtt and mock_engine. Fix gen6 ppgtt, so we may soon
be able to remove a few checks. As the object only exists as
a fake object pointing to ggtt, we have no backing storage,
so no real object is created. It just has to look real enough.

Also kill pin_mutex, it's not compatible with ww locking,
and we can use the vm lock instead.

v2:
  - Drop IS_SHRINKABLE and shorten overly long line
v3:
  - Checkpatch fix for alignment

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c |  44 ---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 123 +++
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h |   1 -
 drivers/gpu/drm/i915/i915_drv.h  |   4 +
 4 files changed, 100 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c 
b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index a57a6b7013c2..c5150a1ee3d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -145,24 +145,10 @@ static const struct drm_i915_gem_object_ops 
i915_gem_object_internal_ops = {
.put_pages = i915_gem_object_put_pages_internal,
 };
 
-/**
- * i915_gem_object_create_internal: create an object with volatile pages
- * @i915: the i915 device
- * @size: the size in bytes of backing storage to allocate for the object
- *
- * Creates a new object that wraps some internal memory for private use.
- * This object is not backed by swappable storage, and as such its contents
- * are volatile and only valid whilst pinned. If the object is reaped by the
- * shrinker, its pages and data will be discarded. Equally, it is not a full
- * GEM object and so not valid for access from userspace. This makes it useful
- * for hardware interfaces like ringbuffers (which are pinned from the time
- * the request is written to the time the hardware stops accessing it), but
- * not for contexts (which need to be preserved when not active for later
- * reuse). Note that it is not cleared upon allocation.
- */
 struct drm_i915_gem_object *
-i915_gem_object_create_internal(struct drm_i915_private *i915,
-   phys_addr_t size)
+__i915_gem_object_create_internal(struct drm_i915_private *i915,
+ const struct drm_i915_gem_object_ops *ops,
+ phys_addr_t size)
 {
static struct lock_class_key lock_class;
struct drm_i915_gem_object *obj;
@@ -179,7 +165,7 @@ i915_gem_object_create_internal(struct drm_i915_private 
*i915,
return ERR_PTR(-ENOMEM);
 
drm_gem_private_object_init(&i915->drm, &obj->base, size);
-   i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class, 
0);
+   i915_gem_object_init(obj, ops, &lock_class, 0);
obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
 
/*
@@ -199,3 +185,25 @@ i915_gem_object_create_internal(struct drm_i915_private 
*i915,
 
return obj;
 }
+
+/**
+ * i915_gem_object_create_internal: create an object with volatile pages
+ * @i915: the i915 device
+ * @size: the size in bytes of backing storage to allocate for the object
+ *
+ * Creates a new object that wraps some internal memory for private use.
+ * This object is not backed by swappable storage, and as such its contents
+ * are volatile and only valid whilst pinned. If the object is reaped by the
+ * shrinker, its pages and data will be discarded. Equally, it is not a full
+ * GEM object and so not valid for access from userspace. This makes it useful
+ * for hardware interfaces like ringbuffers (which are pinned from the time
+ * the request is written to the time the hardware stops accessing it), but
+ * not for contexts (which need to be preserved when not active for later
+ * reuse). Note that it is not cleared upon allocation.
+ */
+struct drm_i915_gem_object *
+i915_gem_object_create_internal(struct drm_i915_private *i915,
+   phys_addr_t size)
+{
+   return __i915_gem_object_create_internal(i915, 
&i915_gem_object_internal_ops, size);
+}
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c 
b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index ae693bf88ef0..4a166d25fe60 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -261,13 +261,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space 
*vm)
 {
struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
 
-   __i915_vma_put(ppgtt->vma);
-
gen6_ppgtt_free_pd(ppgtt);
free_scratch(vm);
 
mutex_destroy(&ppgtt->flush);
-   mutex_destroy(&ppgtt->pin_mutex);
 
free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 }
@@ -330,37 +327,6 @@ static const struct i915_vma_ops pd_vma_ops = {
.unbind_vma = pd_vma_unbind,
 };
 
-static struct i915_vma *pd_vma_create

[PATCH v3 4/8] drm/i915: vma is always backed by an object.

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

vma->obj and vma->resv are now never NULL, and some checks can be removed.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  2 +-
 .../gpu/drm/i915/gt/intel_ring_submission.c   |  2 +-
 drivers/gpu/drm/i915/i915_vma.c   | 48 ---
 drivers/gpu/drm/i915/i915_vma.h   |  3 --
 4 files changed, 22 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 5634d14052bc..e0220ac0e9b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -219,7 +219,7 @@ int __intel_context_do_pin_ww(struct intel_context *ce,
 */
 
err = i915_gem_object_lock(ce->timeline->hwsp_ggtt->obj, ww);
-   if (!err && ce->ring->vma->obj)
+   if (!err)
err = i915_gem_object_lock(ce->ring->vma->obj, ww);
if (!err && ce->state)
err = i915_gem_object_lock(ce->state->obj, ww);
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 586dca1731ce..3e6fac0340ef 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -1357,7 +1357,7 @@ int intel_ring_submission_setup(struct intel_engine_cs 
*engine)
err = i915_gem_object_lock(timeline->hwsp_ggtt->obj, &ww);
if (!err && gen7_wa_vma)
err = i915_gem_object_lock(gen7_wa_vma->obj, &ww);
-   if (!err && engine->legacy.ring->vma->obj)
+   if (!err)
err = i915_gem_object_lock(engine->legacy.ring->vma->obj, &ww);
if (!err)
err = intel_timeline_pin(timeline, &ww);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 90546fa58fc1..656152daabbe 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -40,12 +40,12 @@
 
 static struct kmem_cache *slab_vmas;
 
-struct i915_vma *i915_vma_alloc(void)
+static struct i915_vma *i915_vma_alloc(void)
 {
return kmem_cache_zalloc(slab_vmas, GFP_KERNEL);
 }
 
-void i915_vma_free(struct i915_vma *vma)
+static void i915_vma_free(struct i915_vma *vma)
 {
return kmem_cache_free(slab_vmas, vma);
 }
@@ -426,10 +426,8 @@ int i915_vma_bind(struct i915_vma *vma,
 
work->base.dma.error = 0; /* enable the queue_work() */
 
-   if (vma->obj) {
-   __i915_gem_object_pin_pages(vma->obj);
-   work->pinned = i915_gem_object_get(vma->obj);
-   }
+   __i915_gem_object_pin_pages(vma->obj);
+   work->pinned = i915_gem_object_get(vma->obj);
} else {
vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags);
}
@@ -670,7 +668,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 
alignment, u64 flags)
}
 
color = 0;
-   if (vma->obj && i915_vm_has_cache_coloring(vma->vm))
+   if (i915_vm_has_cache_coloring(vma->vm))
color = vma->obj->cache_level;
 
if (flags & PIN_OFFSET_FIXED) {
@@ -795,17 +793,14 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned 
int flags)
 static int vma_get_pages(struct i915_vma *vma)
 {
int err = 0;
-   bool pinned_pages = false;
+   bool pinned_pages = true;
 
if (atomic_add_unless(&vma->pages_count, 1, 0))
return 0;
 
-   if (vma->obj) {
-   err = i915_gem_object_pin_pages(vma->obj);
-   if (err)
-   return err;
-   pinned_pages = true;
-   }
+   err = i915_gem_object_pin_pages(vma->obj);
+   if (err)
+   return err;
 
/* Allocations ahoy! */
if (mutex_lock_interruptible(&vma->pages_mutex)) {
@@ -838,8 +833,8 @@ static void __vma_put_pages(struct i915_vma *vma, unsigned 
int count)
if (atomic_sub_return(count, &vma->pages_count) == 0) {
vma->ops->clear_pages(vma);
GEM_BUG_ON(vma->pages);
-   if (vma->obj)
-   i915_gem_object_unpin_pages(vma->obj);
+
+   i915_gem_object_unpin_pages(vma->obj);
}
mutex_unlock(&vma->pages_mutex);
 }
@@ -875,7 +870,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct 
i915_gem_ww_ctx *ww,
int err;
 
 #ifdef CONFIG_PROVE_LOCKING
-   if (debug_locks && !WARN_ON(!ww) && vma->resv)
+   if (debug_locks && !WARN_ON(!ww))
assert_vma_held(vma);
 #endif
 
@@ -983,7 +978,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct 
i915_gem_ww_ctx *ww,
 
GEM_BUG_ON(!vma->pages);
err = i915_vma_bind(vma,
-   vma->obj ? vma->obj->cache_level : 0,
+   vma->obj->cache_level,
flags, work);
   

[PATCH v3 3/8] drm/i915: Create a full object for mock_ring, v2.

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

This allows us to finally get rid of all the assumptions that vma->obj
is NULL.

Changes since v1:
- Ensure the mock_ring vma is pinned to prevent a fault.
- Pin it high to avoid failure in evict_for_vma selftest.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/mock_engine.c | 38 ---
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c 
b/drivers/gpu/drm/i915/gt/mock_engine.c
index 8b89215afe46..bb99fc03f503 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
atomic_dec(&tl->pin_count);
 }
 
+static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
+{
+   struct i915_address_space *vm = &ggtt->vm;
+   struct drm_i915_private *i915 = vm->i915;
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+
+   obj = i915_gem_object_create_internal(i915, size);
+   if (IS_ERR(obj))
+   return ERR_CAST(obj);
+
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (IS_ERR(vma))
+   goto err;
+
+   return vma;
+
+err:
+   i915_gem_object_put(obj);
+   return vma;
+}
+
 static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 {
-   const unsigned long sz = PAGE_SIZE / 2;
+   const unsigned long sz = PAGE_SIZE;
struct intel_ring *ring;
 
ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
@@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs 
*engine)
ring->vaddr = (void *)(ring + 1);
atomic_set(&ring->pin_count, 1);
 
-   ring->vma = i915_vma_alloc();
-   if (!ring->vma) {
+   ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
+   if (IS_ERR(ring->vma)) {
kfree(ring);
return NULL;
}
-   i915_active_init(&ring->vma->active, NULL, NULL, 0);
-   __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
-   __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
-   ring->vma->node.size = sz;
 
intel_ring_update_space(ring);
 
@@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs 
*engine)
 
 static void mock_ring_free(struct intel_ring *ring)
 {
-   i915_active_fini(&ring->vma->active);
-   i915_vma_free(ring->vma);
+   i915_vma_put(ring->vma);
 
kfree(ring);
 }
@@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
 
 static void mock_context_post_unpin(struct intel_context *ce)
 {
+   i915_vma_unpin(ce->ring->vma);
 }
 
 static void mock_context_destroy(struct kref *ref)
@@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
 static int mock_context_pre_pin(struct intel_context *ce,
struct i915_gem_ww_ctx *ww, void **unused)
 {
-   return 0;
+   return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
 }
 
 static int mock_context_pin(struct intel_context *ce, void *unused)
-- 
2.26.3



[PATCH v3 1/8] drm/i915: Remove gen6_ppgtt_unpin_all

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

gen6_ppgtt_unpin_all is unused, kill it.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 11 ---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c 
b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index baea9770200a..ae693bf88ef0 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -404,17 +404,6 @@ void gen6_ppgtt_unpin(struct i915_ppgtt *base)
i915_vma_unpin(ppgtt->vma);
 }
 
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base)
-{
-   struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
-
-   if (!atomic_read(&ppgtt->pin_count))
-   return;
-
-   i915_vma_unpin(ppgtt->vma);
-   atomic_set(&ppgtt->pin_count, 0);
-}
-
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 {
struct i915_ggtt * const ggtt = gt->ggtt;
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h 
b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
index 6a61a5c3a85a..ab0eecb086dd 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
@@ -71,7 +71,6 @@ static inline struct gen6_ppgtt *to_gen6_ppgtt(struct 
i915_ppgtt *base)
 
 int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww);
 void gen6_ppgtt_unpin(struct i915_ppgtt *base);
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base);
 void gen6_ppgtt_enable(struct intel_gt *gt);
 void gen7_ppgtt_enable(struct intel_gt *gt);
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt);
-- 
2.26.3



Re: [PULL] topic/amdgpu-dp2.0-mst

2021-10-29 Thread Jani Nikula
On Fri, 29 Oct 2021, Jani Nikula  wrote:
> On Wed, 27 Oct 2021, Lyude Paul  wrote:
>> topic/amdgpu-dp2.0-mst-2021-10-27:
>> UAPI Changes:
>> Nope!
>>
>> Cross-subsystem Changes:
>> drm_dp_update_payload_part1() takes a new argument for specifying what the
>> VCPI slot start is
>>
>> Core Changes:
>> Make the DP MST helpers aware of the current starting VCPI slot/VCPI total
>> slot count...
>>
>> Driver Changes:
>> ...and then add support for taking advantage of this for 128b/132b links on 
>> DP
>> 2.0 for amdgpu
>> The following changes since commit 6f2f7c83303d2227f47551423e507d77d9ea01c7:
>>
>>   Merge tag 'drm-intel-gt-next-2021-10-21' of
>> git://anongit.freedesktop.org/drm/drm-intel into drm-next (2021-10-22 
>> 06:30:34
>> +1000)
>>
>> are available in the Git repository at:
>>
>>   git://anongit.freedesktop.org/drm/drm-misc 
>> tags/topic/amdgpu-dp2.0-mst-2021-
>> 10-27
>
> I'm curious, how did you generate and send this pull request? The lines
> are wrapped with newlines, and you have non-breaking spaces instead of
> regular spaces there.
>
> So for me this fails with:
>
> Pulling   git://anongit.freedesktop.org/drm/drm-misc 
> tags/topic/amdgpu-dp2.0-mst-2021- 10-27 ...
> fatal: invalid refspec 'git://anongit.freedesktop.org/drm/drm-misc'

Fixed manually, but I can't pull this into drm-intel-next directly after
all, because the baseline is not in drm-intel-next history. The diffstat
for drm-intel-next is:

65 files changed, 3656 insertions(+), 780 deletions(-)

I asked for this to be a topic branch so I could pull it into
drm-intel-next. I guess I'll just have to do a drm-next backmerge
instead.

BR,
Jani.


>
> BR,
> Jani.
>
>
>>
>> for you to fetch changes up to 00f965e700ef5aa2d889e7e65c7458531d2a4bcf:
>>
>>   drm/amdgpu/display: fix build when CONFIG_DRM_AMD_DC_DCN is not set (2021-
>> 10-27 19:50:26 -0400)
>>
>> 
>> UAPI Changes:
>> Nope!
>>
>> Cross-subsystem Changes:
>> drm_dp_update_payload_part1() takes a new argument for specifying what the
>> VCPI slot start is
>>
>> Core Changes:
>> Make the DP MST helpers aware of the current starting VCPI slot/VCPI total
>> slot count...
>>
>> Driver Changes:
>> ...and then add support for taking advantage of this for 128b/132b links on 
>> DP
>> 2.0 for amdgpu
>>
>> 
>> Alex Deucher (1):
>>   drm/amdgpu/display: fix build when CONFIG_DRM_AMD_DC_DCN is not set
>>
>> Bhawanpreet Lakha (3):
>>   drm: Remove slot checks in dp mst topology during commit
>>   drm: Update MST First Link Slot Information Based on Encoding Format
>>   drm/amd/display: Add DP 2.0 MST DM Support
>>
>> Fangzhi Zuo (1):
>>   drm/amd/display: Add DP 2.0 MST DC Support
>>
>>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  29 ++
>>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c  |   3 +
>>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  |   7 +-
>>  drivers/gpu/drm/amd/display/dc/core/dc.c   |  14 +
>>  drivers/gpu/drm/amd/display/dc/core/dc_link.c  | 292
>> +
>>  drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |  19 ++
>>  drivers/gpu/drm/amd/display/dc/dc_link.h   |   7 +
>>  drivers/gpu/drm/amd/display/dc/dc_stream.h |  13 +
>>  drivers/gpu/drm/drm_dp_mst_topology.c  |  42 ++-
>>  drivers/gpu/drm/i915/display/intel_dp_mst.c    |   4 +-
>>  drivers/gpu/drm/nouveau/dispnv50/disp.c    |   2 +-
>>  drivers/gpu/drm/radeon/radeon_dp_mst.c |   4 +-
>>  include/drm/drm_dp_mst_helper.h    |   5 +-
>>  13 files changed, 425 insertions(+), 16 deletions(-)

-- 
Jani Nikula, Intel Open Source Graphics Center


Re: [PULL] topic/amdgpu-dp2.0-mst

2021-10-29 Thread Jani Nikula
On Wed, 27 Oct 2021, Lyude Paul  wrote:
> topic/amdgpu-dp2.0-mst-2021-10-27:
> UAPI Changes:
> Nope!
>
> Cross-subsystem Changes:
> drm_dp_update_payload_part1() takes a new argument for specifying what the
> VCPI slot start is
>
> Core Changes:
> Make the DP MST helpers aware of the current starting VCPI slot/VCPI total
> slot count...
>
> Driver Changes:
> ...and then add support for taking advantage of this for 128b/132b links on DP
> 2.0 for amdgpu
> The following changes since commit 6f2f7c83303d2227f47551423e507d77d9ea01c7:
>
>   Merge tag 'drm-intel-gt-next-2021-10-21' of
> git://anongit.freedesktop.org/drm/drm-intel into drm-next (2021-10-22 06:30:34
> +1000)
>
> are available in the Git repository at:
>
>   git://anongit.freedesktop.org/drm/drm-misc tags/topic/amdgpu-dp2.0-mst-2021-
> 10-27

I'm curious, how did you generate and send this pull request? The lines
are wrapped with newlines, and you have non-breaking spaces instead of
regular spaces there.

So for me this fails with:

Pulling   git://anongit.freedesktop.org/drm/drm-misc 
tags/topic/amdgpu-dp2.0-mst-2021- 10-27 ...
fatal: invalid refspec 'git://anongit.freedesktop.org/drm/drm-misc'

BR,
Jani.


>
> for you to fetch changes up to 00f965e700ef5aa2d889e7e65c7458531d2a4bcf:
>
>   drm/amdgpu/display: fix build when CONFIG_DRM_AMD_DC_DCN is not set (2021-
> 10-27 19:50:26 -0400)
>
> 
> UAPI Changes:
> Nope!
>
> Cross-subsystem Changes:
> drm_dp_update_payload_part1() takes a new argument for specifying what the
> VCPI slot start is
>
> Core Changes:
> Make the DP MST helpers aware of the current starting VCPI slot/VCPI total
> slot count...
>
> Driver Changes:
> ...and then add support for taking advantage of this for 128b/132b links on DP
> 2.0 for amdgpu
>
> 
> Alex Deucher (1):
>   drm/amdgpu/display: fix build when CONFIG_DRM_AMD_DC_DCN is not set
>
> Bhawanpreet Lakha (3):
>   drm: Remove slot checks in dp mst topology during commit
>   drm: Update MST First Link Slot Information Based on Encoding Format
>   drm/amd/display: Add DP 2.0 MST DM Support
>
> Fangzhi Zuo (1):
>   drm/amd/display: Add DP 2.0 MST DC Support
>
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  29 ++
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c  |   3 +
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  |   7 +-
>  drivers/gpu/drm/amd/display/dc/core/dc.c   |  14 +
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c  | 292
> +
>  drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |  19 ++
>  drivers/gpu/drm/amd/display/dc/dc_link.h   |   7 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h |  13 +
>  drivers/gpu/drm/drm_dp_mst_topology.c  |  42 ++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c    |   4 +-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c    |   2 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c |   4 +-
>  include/drm/drm_dp_mst_helper.h    |   5 +-
>  13 files changed, 425 insertions(+), 16 deletions(-)

-- 
Jani Nikula, Intel Open Source Graphics Center


Re: [PATCH 3/3] [RFC] dt-bindings: display: bridge: nxp,tda998x: Convert to json-schema

2021-10-29 Thread Russell King (Oracle)
On Fri, Oct 29, 2021 at 11:40:26AM +0200, Geert Uytterhoeven wrote:
> Hi Russell,
> 
> On Fri, Oct 29, 2021 at 11:33 AM Russell King (Oracle)
>  wrote:
> > On Fri, Oct 29, 2021 at 10:28:22AM +0200, Geert Uytterhoeven wrote:
> > > No, you can still use port:
> > >
> > > +oneOf:
> > > +  - required:
> > > +  - port
> > > +  - required:
> > > +  - ports
> > >
> > > When using ports, no further requirements are set, but perhaps port@0
> > > should be made required in that case?
> >
> > Maybe I don't understand the binding description then, but to me it
> > looks like you require both port@0 and port@1.
> 
> "make dtbs_check" disagrees.
> 
> > The reality of the driver is that it makes almost no use of the graph
> > itself, except via drm_of_find_possible_crtcs() to find the connected
> > CRTCs. If it is connected to an I2S source, then it probably needs a
> > port specification for that. If someone wants to describe the HDMI
> > connector (which I don't see any point in) then they likely need a
> 
> I can't comment on the point of describing the HDMI connector.
> 
> > port specification for that too. However, the driver itself doesn't
> > care about any of those.
> 
> DT describes hardware, not software limitations.

Sigh. There's no point discussing this further, my replies seem to be
interpreted out of context.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


[PATCH v1] media: mtk-vcodec: Align width and height to 64

2021-10-29 Thread Yunfei Dong
User get width and height are 64 align when set format. Need to make
sure all is 64 align when use width and height to calculate buffer size.

Signed-off-by: Yunfei Dong 
---
 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c 
b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 946c23088308..28c17204f9a1 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -562,8 +562,8 @@ static void get_pic_info(struct vdec_h264_slice_inst *inst,
 {
struct mtk_vcodec_ctx *ctx = inst->ctx;
 
-   ctx->picinfo.buf_w = (ctx->picinfo.pic_w + 15) & 0xFFF0;
-   ctx->picinfo.buf_h = (ctx->picinfo.pic_h + 31) & 0xFFE0;
+   ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+   ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
ctx->picinfo.fb_sz[0] = ctx->picinfo.buf_w * ctx->picinfo.buf_h;
ctx->picinfo.fb_sz[1] = ctx->picinfo.fb_sz[0] >> 1;
inst->vsi_ctx.dec.cap_num_planes =
-- 
2.25.1



Re: [PATCH 3/3] [RFC] dt-bindings: display: bridge: nxp,tda998x: Convert to json-schema

2021-10-29 Thread Geert Uytterhoeven
Hi Russell,

On Fri, Oct 29, 2021 at 11:33 AM Russell King (Oracle)
 wrote:
> On Fri, Oct 29, 2021 at 10:28:22AM +0200, Geert Uytterhoeven wrote:
> > No, you can still use port:
> >
> > +oneOf:
> > +  - required:
> > +  - port
> > +  - required:
> > +  - ports
> >
> > When using ports, no further requirements are set, but perhaps port@0
> > should be made required in that case?
>
> Maybe I don't understand the binding description then, but to me it
> looks like you require both port@0 and port@1.

"make dtbs_check" disagrees.

> The reality of the driver is that it makes almost no use of the graph
> itself, except via drm_of_find_possible_crtcs() to find the connected
> CRTCs. If it is connected to an I2S source, then it probably needs a
> port specification for that. If someone wants to describe the HDMI
> connector (which I don't see any point in) then they likely need a

I can't comment on the point of describing the HDMI connector.

> port specification for that too. However, the driver itself doesn't
> care about any of those.

DT describes hardware, not software limitations.

> So, describing the port nodes makes no sense.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH 3/3] [RFC] dt-bindings: display: bridge: nxp,tda998x: Convert to json-schema

2021-10-29 Thread Russell King (Oracle)
On Fri, Oct 29, 2021 at 10:28:22AM +0200, Geert Uytterhoeven wrote:
> Hi Russell,
> 
> Thanks for your comments!
> 
> No, you can still use port:
> 
> +oneOf:
> +  - required:
> +  - port
> +  - required:
> +  - ports
> 
> When using ports, no further requirements are set, but perhaps port@0
> should be made required in that case?

Maybe I don't understand the binding description then, but to me it
looks like you require both port@0 and port@1.

The reality of the driver is that it makes almost no use of the graph
itself, except via drm_of_find_possible_crtcs() to find the connected
CRTCs. If it is connected to an I2S source, then it probably needs a
port specification for that. If someone wants to describe the HDMI
connector (which I don't see any point in) then they likely need a
port specification for that too. However, the driver itself doesn't
care about any of those.

So, describing the port nodes makes no sense.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


Re: [PATCH 1/4] dma-buf: add dma_fence_describe and dma_resv_describe

2021-10-29 Thread kernel test robot
Hi "Christian,

I love your patch! Yet something to improve:

[auto build test ERROR on drm-tip/drm-tip]
[also build test ERROR on next-20211028]
[cannot apply to drm/drm-next drm-intel/for-linux-next 
drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master 
airlied/drm-next v5.15-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Christian-K-nig/dma-buf-add-dma_fence_describe-and-dma_resv_describe/20211028-171805
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: m68k-allyesconfig (attached as .config)
compiler: m68k-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/80ae7cf414dbdb7fa9f48a46cc1bfa25b0a4fda7
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Christian-K-nig/dma-buf-add-dma_fence_describe-and-dma_resv_describe/20211028-171805
git checkout 80ae7cf414dbdb7fa9f48a46cc1bfa25b0a4fda7
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross 
ARCH=m68k 

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

All errors (new ones prefixed by >>):

   drivers/dma-buf/dma-fence.c: In function 'dma_fence_describe':
>> drivers/dma-buf/dma-fence.c:919:9: error: implicit declaration of function 
>> 'seq_printf'; did you mean 'bstr_printf'? 
>> [-Werror=implicit-function-declaration]
 919 | seq_printf(seq, "%s %s seq %llu %ssignalled\n",
 | ^~
 | bstr_printf
   cc1: all warnings being treated as errors


vim +919 drivers/dma-buf/dma-fence.c

   909  
   910  /**
   911   * dma_fence_describe - Dump fence describtion into seq_file
   912   * @fence: the 6fence to describe
   913   * @seq: the seq_file to put the textual description into
   914   *
   915   * Dump a textual description of the fence and it's state into the 
seq_file.
   916   */
   917  void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq)
   918  {
 > 919  seq_printf(seq, "%s %s seq %llu %ssignalled\n",
   920 fence->ops->get_driver_name(fence),
   921 fence->ops->get_timeline_name(fence), fence->seqno,
   922 dma_fence_is_signaled(fence) ? "" : "un");
   923  }
   924  EXPORT_SYMBOL(dma_fence_describe);
   925  

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


.config.gz
Description: application/gzip


Re: [v6,02/21] drm/bridge: adv7511: Register and attach our DSI device at probe

2021-10-29 Thread Maxime Ripard
On Fri, Oct 29, 2021 at 10:36:00AM +0200, Marek Szyprowski wrote:
> Hi Mexime,
> 
> On 29.10.2021 10:05, Maxime Ripard wrote:
> > On Fri, Oct 29, 2021 at 08:23:45AM +0200, Marek Szyprowski wrote:
> >> On 25.10.2021 17:15, Maxime Ripard wrote:
> >>> In order to avoid any probe ordering issue, the best practice is to move
> >>> the secondary MIPI-DSI device registration and attachment to the
> >>> MIPI-DSI host at probe time. Let's do this.
> >>>
> >>> Acked-by: Sam Ravnborg 
> >>> Tested-by: John Stultz 
> >>> Signed-off-by: Maxime Ripard 
> >> This patch landed in linux-next as commit 864c49a31d6b ("drm/bridge:
> >> adv7511: Register and attach our DSI device at probe"). Sadly it causes
> >> endless probe-fail-defer loop on DragonBoard 410c board
> >> (arch/arm64/boot/dts/qcom/apq8016-sbc.dts):
> > I'm sorry to hear that (but would have been surprised if it didn't occur)
> >
> > This is supposed to be fixed by 8f59ee9a570c ("drm/msm/dsi: Adjust probe
> > order"). Do you have that patch applied?
> 
> Yes, I did my test directly on linux next-20211028, which also contains 
> it. What might be important in my case, my DragonBoard 410c doesn't have 
> any display attached.
> 
> I've also noticed the following error during boot:
> 
> [   23.847651] msm_mdp 1a01000.mdp: Adding to iommu group 3
> [   23.866044] msm_mdp 1a01000.mdp: No interconnect support may cause 
> display underflows!
> [   23.957949] irq: no irq domain found for mdss@1a0 !
> [   23.958014] msm_dsi 1a98000.dsi: failed to request IRQ0: -22
> [   23.962229] msm_dsi: probe of 1a98000.dsi failed with error -22
> 
> The above errors appeared in next-20211028 for the first time. I assume 
> that they are related.

Yeah, it's likely that the DSI host cannot probe anymore, and the DSI
bridge thus cannot find its DSI host. Rob, do you know what could be
going on?

Maxime


signature.asc
Description: PGP signature


Re: [v6,02/21] drm/bridge: adv7511: Register and attach our DSI device at probe

2021-10-29 Thread Marek Szyprowski
Hi Mexime,

On 29.10.2021 10:05, Maxime Ripard wrote:
> On Fri, Oct 29, 2021 at 08:23:45AM +0200, Marek Szyprowski wrote:
>> On 25.10.2021 17:15, Maxime Ripard wrote:
>>> In order to avoid any probe ordering issue, the best practice is to move
>>> the secondary MIPI-DSI device registration and attachment to the
>>> MIPI-DSI host at probe time. Let's do this.
>>>
>>> Acked-by: Sam Ravnborg 
>>> Tested-by: John Stultz 
>>> Signed-off-by: Maxime Ripard 
>> This patch landed in linux-next as commit 864c49a31d6b ("drm/bridge:
>> adv7511: Register and attach our DSI device at probe"). Sadly it causes
>> endless probe-fail-defer loop on DragonBoard 410c board
>> (arch/arm64/boot/dts/qcom/apq8016-sbc.dts):
> I'm sorry to hear that (but would have been surprised if it didn't occur)
>
> This is supposed to be fixed by 8f59ee9a570c ("drm/msm/dsi: Adjust probe
> order"). Do you have that patch applied?

Yes, I did my test directly on linux next-20211028, which also contains 
it. What might be important in my case, my DragonBoard 410c doesn't have 
any display attached.

I've also noticed the following error during boot:

[   23.847651] msm_mdp 1a01000.mdp: Adding to iommu group 3
[   23.866044] msm_mdp 1a01000.mdp: No interconnect support may cause 
display underflows!
[   23.957949] irq: no irq domain found for mdss@1a0 !
[   23.958014] msm_dsi 1a98000.dsi: failed to request IRQ0: -22
[   23.962229] msm_dsi: probe of 1a98000.dsi failed with error -22

The above errors appeared in next-20211028 for the first time. I assume 
that they are related.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



[PATCH v2 10/10] drm/i915: Require object lock when freeing pages during destruction

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

TTM already requires this, and we require it for delayed destroy.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 55b0f1df3192..6e5412e2b5ad 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -257,6 +257,8 @@ static void __i915_gem_object_free_mmaps(struct 
drm_i915_gem_object *obj)
  */
 void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
 {
+   assert_object_held(obj);
+
if (!list_empty(&obj->vma.list)) {
struct i915_vma *vma;
 
@@ -323,7 +325,10 @@ static void __i915_gem_free_objects(struct 
drm_i915_private *i915,
obj->ops->delayed_free(obj);
continue;
}
+
+   i915_gem_object_lock(obj, NULL);
__i915_gem_object_pages_fini(obj);
+   i915_gem_object_unlock(obj);
__i915_gem_free_object(obj);
 
/* But keep the pointer alive for RCU-protected lookups */
-- 
2.26.3



[PATCH v2 07/10] drm/i915: Remove resv from i915_vma

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

It's just an alias to vma->obj->base.resv, no need to duplicate it.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Niranjana Vishwanathapura 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 4 ++--
 drivers/gpu/drm/i915/i915_vma.c| 9 -
 drivers/gpu/drm/i915/i915_vma.h| 6 +++---
 drivers/gpu/drm/i915/i915_vma_types.h  | 1 -
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index ea5b7b2a4d70..9f7c6ecadb90 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1001,7 +1001,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
}
 
if (!(ev->flags & EXEC_OBJECT_WRITE)) {
-   err = dma_resv_reserve_shared(vma->resv, 1);
+   err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
if (err)
return err;
}
@@ -2175,7 +2175,7 @@ static int eb_parse(struct i915_execbuffer *eb)
goto err_trampoline;
}
 
-   err = dma_resv_reserve_shared(shadow->resv, 1);
+   err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
if (err)
goto err_trampoline;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index aebfc232b58b..ac09b685678a 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -116,7 +116,6 @@ vma_create(struct drm_i915_gem_object *obj,
vma->vm = i915_vm_get(vm);
vma->ops = &vm->vma_ops;
vma->obj = obj;
-   vma->resv = obj->base.resv;
vma->size = obj->base.size;
vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
 
@@ -1032,7 +1031,7 @@ int i915_ggtt_pin(struct i915_vma *vma, struct 
i915_gem_ww_ctx *ww,
GEM_BUG_ON(!i915_vma_is_ggtt(vma));
 
 #ifdef CONFIG_LOCKDEP
-   WARN_ON(!ww && dma_resv_held(vma->resv));
+   WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
 #endif
 
do {
@@ -1251,19 +1250,19 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
}
 
if (fence) {
-   dma_resv_add_excl_fence(vma->resv, fence);
+   dma_resv_add_excl_fence(vma->obj->base.resv, fence);
obj->write_domain = I915_GEM_DOMAIN_RENDER;
obj->read_domains = 0;
}
} else {
if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-   err = dma_resv_reserve_shared(vma->resv, 1);
+   err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
if (unlikely(err))
return err;
}
 
if (fence) {
-   dma_resv_add_shared_fence(vma->resv, fence);
+   dma_resv_add_shared_fence(vma->obj->base.resv, fence);
obj->write_domain = 0;
}
}
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 423e0df81c87..9a931ecb09e5 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -232,16 +232,16 @@ static inline void __i915_vma_put(struct i915_vma *vma)
kref_put(&vma->ref, i915_vma_release);
 }
 
-#define assert_vma_held(vma) dma_resv_assert_held((vma)->resv)
+#define assert_vma_held(vma) dma_resv_assert_held((vma)->obj->base.resv)
 
 static inline void i915_vma_lock(struct i915_vma *vma)
 {
-   dma_resv_lock(vma->resv, NULL);
+   dma_resv_lock(vma->obj->base.resv, NULL);
 }
 
 static inline void i915_vma_unlock(struct i915_vma *vma)
 {
-   dma_resv_unlock(vma->resv);
+   dma_resv_unlock(vma->obj->base.resv);
 }
 
 int __must_check
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h 
b/drivers/gpu/drm/i915/i915_vma_types.h
index 80e93bf00f2e..8a0decb19bcc 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -178,7 +178,6 @@ struct i915_vma {
const struct i915_vma_ops *ops;
 
struct drm_i915_gem_object *obj;
-   struct dma_resv *resv; /** Alias of obj->resv */
 
struct sg_table *pages;
void __iomem *iomap;
-- 
2.26.3



[PATCH v2 08/10] drm/i915: Rework context handling in hugepages selftests

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

In the next commit, we don't evict when refcount = 0, so we need to
call drain freed objects, because we want to pin new bo's in the same
place, causing a test failure.

Furthermore, since each subtest is separated, it's a lot better to use
i915_live_selftests, so each subtest starts with a clean slate, and a
clean address space.

v2:
  - Make hugepage_ctx static. Reported-by: kernel test robot 

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 .../gpu/drm/i915/gem/selftests/huge_pages.c   | 128 +++---
 1 file changed, 80 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index b2003133deaf..257588b68adc 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -22,6 +22,22 @@
 #include "selftests/mock_region.h"
 #include "selftests/i915_random.h"
 
+static struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915,
+struct file *file)
+{
+   struct i915_gem_context *ctx = live_context(i915, file);
+   struct i915_address_space *vm;
+
+   if (IS_ERR(ctx))
+   return ctx;
+
+   vm = ctx->vm;
+   if (vm)
+   WRITE_ONCE(vm->scrub_64K, true);
+
+   return ctx;
+}
+
 static const unsigned int page_sizes[] = {
I915_GTT_PAGE_SIZE_2M,
I915_GTT_PAGE_SIZE_64K,
@@ -959,6 +975,8 @@ static int igt_mock_ppgtt_64K(void *arg)
__i915_gem_object_put_pages(obj);
i915_gem_object_unlock(obj);
i915_gem_object_put(obj);
+
+   i915_gem_drain_freed_objects(i915);
}
}
 
@@ -1080,10 +1098,6 @@ static int __igt_write_huge(struct intel_context *ce,
if (IS_ERR(vma))
return PTR_ERR(vma);
 
-   err = i915_vma_unbind(vma);
-   if (err)
-   return err;
-
err = i915_vma_pin(vma, size, 0, flags | offset);
if (err) {
/*
@@ -1117,7 +1131,7 @@ static int __igt_write_huge(struct intel_context *ce,
return err;
 }
 
-static int igt_write_huge(struct i915_gem_context *ctx,
+static int igt_write_huge(struct drm_i915_private *i915,
  struct drm_i915_gem_object *obj)
 {
struct i915_gem_engines *engines;
@@ -1127,6 +1141,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
IGT_TIMEOUT(end_time);
unsigned int max_page_size;
unsigned int count;
+   struct i915_gem_context *ctx;
+   struct file *file;
u64 max;
u64 num;
u64 size;
@@ -1134,6 +1150,16 @@ static int igt_write_huge(struct i915_gem_context *ctx,
int i, n;
int err = 0;
 
+   file = mock_file(i915);
+   if (IS_ERR(file))
+   return PTR_ERR(file);
+
+   ctx = hugepage_ctx(i915, file);
+   if (IS_ERR(ctx)) {
+   err = PTR_ERR(ctx);
+   goto out;
+   }
+
GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
 
size = obj->base.size;
@@ -1153,7 +1179,7 @@ static int igt_write_huge(struct i915_gem_context *ctx,
}
i915_gem_context_unlock_engines(ctx);
if (!n)
-   return 0;
+   goto out;
 
/*
 * To keep things interesting when alternating between engines in our
@@ -1215,6 +1241,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 
kfree(order);
 
+out:
+   fput(file);
return err;
 }
 
@@ -1277,8 +1305,7 @@ static u32 igt_random_size(struct rnd_state *prng,
 
 static int igt_ppgtt_smoke_huge(void *arg)
 {
-   struct i915_gem_context *ctx = arg;
-   struct drm_i915_private *i915 = ctx->i915;
+   struct drm_i915_private *i915 = arg;
struct drm_i915_gem_object *obj;
I915_RND_STATE(prng);
struct {
@@ -1302,6 +1329,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
u32 min = backends[i].min;
u32 max = backends[i].max;
u32 size = max;
+
 try_again:
size = igt_random_size(&prng, min, rounddown_pow_of_two(size));
 
@@ -1336,7 +1364,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
goto out_unpin;
}
 
-   err = igt_write_huge(ctx, obj);
+   err = igt_write_huge(i915, obj);
if (err) {
pr_err("%s write-huge failed with size=%u, i=%d\n",
   __func__, size, i);
@@ -1363,8 +1391,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 
 static int igt_ppgtt_sanity_check(void *arg)
 {
-   struct i915_gem_context *ctx = arg;
-   struct drm_i915_private *i915 = ctx->i915;
+   struct drm_i915_private *i915 = arg;
unsigned int supported = INTEL_INFO(i915)->page_sizes;

[PATCH v2 09/10] drm/i915: Drain the ttm delayed workqueue too

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

Lets be thorough here. Users of the TTM backend would likely expect this
behaviour.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 57f2f8da931e..1dc30ee26771 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1818,6 +1818,7 @@ static inline void i915_gem_drain_freed_objects(struct 
drm_i915_private *i915)
 */
while (atomic_read(&i915->mm.free_count)) {
flush_work(&i915->mm.free_work);
+   flush_delayed_work(&i915->bdev.wq);
rcu_barrier();
}
 }
-- 
2.26.3



[PATCH v2 06/10] drm/i915/pm: Move CONTEXT_VALID_BIT check

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

Resetting will clear the CONTEXT_VALID_BIT, so wait until after that to
test.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Niranjana Vishwanathapura 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/intel_engine_pm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index a1334b48dde7..849fbb229bd3 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -52,8 +52,6 @@ static int __engine_unpark(struct intel_wakeref *wf)
/* Discard stale context state from across idling */
ce = engine->kernel_context;
if (ce) {
-   GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
-
/* Flush all pending HW writes before we touch the context */
while (unlikely(intel_context_inflight(ce)))
intel_engine_flush_submission(engine);
@@ -68,6 +66,9 @@ static int __engine_unpark(struct intel_wakeref *wf)
 ce->timeline->seqno,
 READ_ONCE(*ce->timeline->hwsp_seqno),
 ce->ring->emit);
+
+   GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
+
GEM_BUG_ON(ce->timeline->seqno !=
   READ_ONCE(*ce->timeline->hwsp_seqno));
}
-- 
2.26.3



[PATCH v2 05/10] drm/i915: vma is always backed by an object.

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

vma->obj and vma->resv are now never NULL, and some checks can be removed.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  2 +-
 .../gpu/drm/i915/gt/intel_ring_submission.c   |  2 +-
 drivers/gpu/drm/i915/i915_vma.c   | 48 ---
 drivers/gpu/drm/i915/i915_vma.h   |  3 --
 4 files changed, 22 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 5634d14052bc..e0220ac0e9b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -219,7 +219,7 @@ int __intel_context_do_pin_ww(struct intel_context *ce,
 */
 
err = i915_gem_object_lock(ce->timeline->hwsp_ggtt->obj, ww);
-   if (!err && ce->ring->vma->obj)
+   if (!err)
err = i915_gem_object_lock(ce->ring->vma->obj, ww);
if (!err && ce->state)
err = i915_gem_object_lock(ce->state->obj, ww);
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 586dca1731ce..3e6fac0340ef 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -1357,7 +1357,7 @@ int intel_ring_submission_setup(struct intel_engine_cs 
*engine)
err = i915_gem_object_lock(timeline->hwsp_ggtt->obj, &ww);
if (!err && gen7_wa_vma)
err = i915_gem_object_lock(gen7_wa_vma->obj, &ww);
-   if (!err && engine->legacy.ring->vma->obj)
+   if (!err)
err = i915_gem_object_lock(engine->legacy.ring->vma->obj, &ww);
if (!err)
err = intel_timeline_pin(timeline, &ww);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 1187f1956c20..aebfc232b58b 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -40,12 +40,12 @@
 
 static struct kmem_cache *slab_vmas;
 
-struct i915_vma *i915_vma_alloc(void)
+static struct i915_vma *i915_vma_alloc(void)
 {
return kmem_cache_zalloc(slab_vmas, GFP_KERNEL);
 }
 
-void i915_vma_free(struct i915_vma *vma)
+static void i915_vma_free(struct i915_vma *vma)
 {
return kmem_cache_free(slab_vmas, vma);
 }
@@ -426,10 +426,8 @@ int i915_vma_bind(struct i915_vma *vma,
 
work->base.dma.error = 0; /* enable the queue_work() */
 
-   if (vma->obj) {
-   __i915_gem_object_pin_pages(vma->obj);
-   work->pinned = i915_gem_object_get(vma->obj);
-   }
+   __i915_gem_object_pin_pages(vma->obj);
+   work->pinned = i915_gem_object_get(vma->obj);
} else {
vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags);
}
@@ -670,7 +668,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 
alignment, u64 flags)
}
 
color = 0;
-   if (vma->obj && i915_vm_has_cache_coloring(vma->vm))
+   if (i915_vm_has_cache_coloring(vma->vm))
color = vma->obj->cache_level;
 
if (flags & PIN_OFFSET_FIXED) {
@@ -795,17 +793,14 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned 
int flags)
 static int vma_get_pages(struct i915_vma *vma)
 {
int err = 0;
-   bool pinned_pages = false;
+   bool pinned_pages = true;
 
if (atomic_add_unless(&vma->pages_count, 1, 0))
return 0;
 
-   if (vma->obj) {
-   err = i915_gem_object_pin_pages(vma->obj);
-   if (err)
-   return err;
-   pinned_pages = true;
-   }
+   err = i915_gem_object_pin_pages(vma->obj);
+   if (err)
+   return err;
 
/* Allocations ahoy! */
if (mutex_lock_interruptible(&vma->pages_mutex)) {
@@ -838,8 +833,8 @@ static void __vma_put_pages(struct i915_vma *vma, unsigned 
int count)
if (atomic_sub_return(count, &vma->pages_count) == 0) {
vma->ops->clear_pages(vma);
GEM_BUG_ON(vma->pages);
-   if (vma->obj)
-   i915_gem_object_unpin_pages(vma->obj);
+
+   i915_gem_object_unpin_pages(vma->obj);
}
mutex_unlock(&vma->pages_mutex);
 }
@@ -875,7 +870,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct 
i915_gem_ww_ctx *ww,
int err;
 
 #ifdef CONFIG_PROVE_LOCKING
-   if (debug_locks && !WARN_ON(!ww) && vma->resv)
+   if (debug_locks && !WARN_ON(!ww))
assert_vma_held(vma);
 #endif
 
@@ -983,7 +978,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct 
i915_gem_ww_ctx *ww,
 
GEM_BUG_ON(!vma->pages);
err = i915_vma_bind(vma,
-   vma->obj ? vma->obj->cache_level : 0,
+   vma->obj->cache_level,
flags, work);
   

[PATCH v2 04/10] drm/i915: Create a full object for mock_ring, v2.

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

This allows us to finally get rid of all the assumptions that vma->obj
is NULL.

Changes since v1:
- Ensure the mock_ring vma is pinned to prevent a fault.
- Pin it high to avoid failure in evict_for_vma selftest.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/mock_engine.c | 38 ---
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c 
b/drivers/gpu/drm/i915/gt/mock_engine.c
index 8b89215afe46..bb99fc03f503 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
atomic_dec(&tl->pin_count);
 }
 
+static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
+{
+   struct i915_address_space *vm = &ggtt->vm;
+   struct drm_i915_private *i915 = vm->i915;
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+
+   obj = i915_gem_object_create_internal(i915, size);
+   if (IS_ERR(obj))
+   return ERR_CAST(obj);
+
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (IS_ERR(vma))
+   goto err;
+
+   return vma;
+
+err:
+   i915_gem_object_put(obj);
+   return vma;
+}
+
 static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 {
-   const unsigned long sz = PAGE_SIZE / 2;
+   const unsigned long sz = PAGE_SIZE;
struct intel_ring *ring;
 
ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
@@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs 
*engine)
ring->vaddr = (void *)(ring + 1);
atomic_set(&ring->pin_count, 1);
 
-   ring->vma = i915_vma_alloc();
-   if (!ring->vma) {
+   ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
+   if (IS_ERR(ring->vma)) {
kfree(ring);
return NULL;
}
-   i915_active_init(&ring->vma->active, NULL, NULL, 0);
-   __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
-   __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
-   ring->vma->node.size = sz;
 
intel_ring_update_space(ring);
 
@@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs 
*engine)
 
 static void mock_ring_free(struct intel_ring *ring)
 {
-   i915_active_fini(&ring->vma->active);
-   i915_vma_free(ring->vma);
+   i915_vma_put(ring->vma);
 
kfree(ring);
 }
@@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
 
 static void mock_context_post_unpin(struct intel_context *ce)
 {
+   i915_vma_unpin(ce->ring->vma);
 }
 
 static void mock_context_destroy(struct kref *ref)
@@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
 static int mock_context_pre_pin(struct intel_context *ce,
struct i915_gem_ww_ctx *ww, void **unused)
 {
-   return 0;
+   return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
 }
 
 static int mock_context_pin(struct intel_context *ce, void *unused)
-- 
2.26.3



[PATCH v2 03/10] drm/i915: Create a dummy object for gen6 ppgtt

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

We currently have to special case vma->obj being NULL because
of gen6 ppgtt and mock_engine. Fix gen6 ppgtt, so we may soon
be able to remove a few checks. As the object only exists as
a fake object pointing to ggtt, we have no backing storage,
so no real object is created. It just has to look real enough.

Also kill pin_mutex, it's not compatible with ww locking,
and we can use the vm lock instead.

v2:
  - Drop IS_SHRINKABLE and shorten overly long line
v3:
  - Checkpatch fix for alignment

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c |  44 ---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 123 +++
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h |   1 -
 drivers/gpu/drm/i915/i915_drv.h  |   4 +
 4 files changed, 100 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c 
b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index a57a6b7013c2..c5150a1ee3d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -145,24 +145,10 @@ static const struct drm_i915_gem_object_ops 
i915_gem_object_internal_ops = {
.put_pages = i915_gem_object_put_pages_internal,
 };
 
-/**
- * i915_gem_object_create_internal: create an object with volatile pages
- * @i915: the i915 device
- * @size: the size in bytes of backing storage to allocate for the object
- *
- * Creates a new object that wraps some internal memory for private use.
- * This object is not backed by swappable storage, and as such its contents
- * are volatile and only valid whilst pinned. If the object is reaped by the
- * shrinker, its pages and data will be discarded. Equally, it is not a full
- * GEM object and so not valid for access from userspace. This makes it useful
- * for hardware interfaces like ringbuffers (which are pinned from the time
- * the request is written to the time the hardware stops accessing it), but
- * not for contexts (which need to be preserved when not active for later
- * reuse). Note that it is not cleared upon allocation.
- */
 struct drm_i915_gem_object *
-i915_gem_object_create_internal(struct drm_i915_private *i915,
-   phys_addr_t size)
+__i915_gem_object_create_internal(struct drm_i915_private *i915,
+ const struct drm_i915_gem_object_ops *ops,
+ phys_addr_t size)
 {
static struct lock_class_key lock_class;
struct drm_i915_gem_object *obj;
@@ -179,7 +165,7 @@ i915_gem_object_create_internal(struct drm_i915_private 
*i915,
return ERR_PTR(-ENOMEM);
 
drm_gem_private_object_init(&i915->drm, &obj->base, size);
-   i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class, 
0);
+   i915_gem_object_init(obj, ops, &lock_class, 0);
obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
 
/*
@@ -199,3 +185,25 @@ i915_gem_object_create_internal(struct drm_i915_private 
*i915,
 
return obj;
 }
+
+/**
+ * i915_gem_object_create_internal: create an object with volatile pages
+ * @i915: the i915 device
+ * @size: the size in bytes of backing storage to allocate for the object
+ *
+ * Creates a new object that wraps some internal memory for private use.
+ * This object is not backed by swappable storage, and as such its contents
+ * are volatile and only valid whilst pinned. If the object is reaped by the
+ * shrinker, its pages and data will be discarded. Equally, it is not a full
+ * GEM object and so not valid for access from userspace. This makes it useful
+ * for hardware interfaces like ringbuffers (which are pinned from the time
+ * the request is written to the time the hardware stops accessing it), but
+ * not for contexts (which need to be preserved when not active for later
+ * reuse). Note that it is not cleared upon allocation.
+ */
+struct drm_i915_gem_object *
+i915_gem_object_create_internal(struct drm_i915_private *i915,
+   phys_addr_t size)
+{
+   return __i915_gem_object_create_internal(i915, 
&i915_gem_object_internal_ops, size);
+}
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c 
b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index ae693bf88ef0..4a166d25fe60 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -261,13 +261,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space 
*vm)
 {
struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
 
-   __i915_vma_put(ppgtt->vma);
-
gen6_ppgtt_free_pd(ppgtt);
free_scratch(vm);
 
mutex_destroy(&ppgtt->flush);
-   mutex_destroy(&ppgtt->pin_mutex);
 
free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 }
@@ -330,37 +327,6 @@ static const struct i915_vma_ops pd_vma_ops = {
.unbind_vma = pd_vma_unbind,
 };
 
-static struct i915_vma *pd_vma_create

[PATCH v2 02/10] drm/i915: Remove gen6_ppgtt_unpin_all

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

gen6_ppgtt_unpin_all is unused, kill it.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 11 ---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c 
b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index baea9770200a..ae693bf88ef0 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -404,17 +404,6 @@ void gen6_ppgtt_unpin(struct i915_ppgtt *base)
i915_vma_unpin(ppgtt->vma);
 }
 
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base)
-{
-   struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
-
-   if (!atomic_read(&ppgtt->pin_count))
-   return;
-
-   i915_vma_unpin(ppgtt->vma);
-   atomic_set(&ppgtt->pin_count, 0);
-}
-
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 {
struct i915_ggtt * const ggtt = gt->ggtt;
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h 
b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
index 6a61a5c3a85a..ab0eecb086dd 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
@@ -71,7 +71,6 @@ static inline struct gen6_ppgtt *to_gen6_ppgtt(struct 
i915_ppgtt *base)
 
 int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww);
 void gen6_ppgtt_unpin(struct i915_ppgtt *base);
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base);
 void gen6_ppgtt_enable(struct intel_gt *gt);
 void gen7_ppgtt_enable(struct intel_gt *gt);
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt);
-- 
2.26.3



[PATCH v2 01/10] drm/i915: Remove unused bits of i915_vma/active api

2021-10-29 Thread Matthew Auld
From: Maarten Lankhorst 

When reworking the code to move the eviction fence to the object,
the best code is removed code.

Remove some functions that are unused, and change the function definition
if it's only used in 1 place.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Niranjana Vishwanathapura 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_active.c | 28 +++-
 drivers/gpu/drm/i915/i915_active.h | 17 +
 drivers/gpu/drm/i915/i915_vma.c|  2 +-
 drivers/gpu/drm/i915/i915_vma.h|  2 --
 4 files changed, 5 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c 
b/drivers/gpu/drm/i915/i915_active.c
index 3103c1e1fd14..ee2b3a375362 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -426,8 +426,9 @@ replace_barrier(struct i915_active *ref, struct 
i915_active_fence *active)
return true;
 }
 
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
 {
+   struct dma_fence *fence = &rq->fence;
struct i915_active_fence *active;
int err;
 
@@ -436,7 +437,7 @@ int i915_active_ref(struct i915_active *ref, u64 idx, 
struct dma_fence *fence)
if (err)
return err;
 
-   active = active_instance(ref, idx);
+   active = active_instance(ref, i915_request_timeline(rq)->fence_context);
if (!active) {
err = -ENOMEM;
goto out;
@@ -477,29 +478,6 @@ __i915_active_set_fence(struct i915_active *ref,
return prev;
 }
 
-static struct i915_active_fence *
-__active_fence(struct i915_active *ref, u64 idx)
-{
-   struct active_node *it;
-
-   it = __active_lookup(ref, idx);
-   if (unlikely(!it)) { /* Contention with parallel tree builders! */
-   spin_lock_irq(&ref->tree_lock);
-   it = __active_lookup(ref, idx);
-   spin_unlock_irq(&ref->tree_lock);
-   }
-   GEM_BUG_ON(!it); /* slot must be preallocated */
-
-   return &it->base;
-}
-
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
-{
-   /* Only valid while active, see i915_active_acquire_for_context() */
-   return __i915_active_set_fence(ref, __active_fence(ref, idx), fence);
-}
-
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f)
 {
diff --git a/drivers/gpu/drm/i915/i915_active.h 
b/drivers/gpu/drm/i915/i915_active.h
index 5fcdb0e2bc9e..7eb44132183a 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -164,26 +164,11 @@ void __i915_active_init(struct i915_active *ref,
__i915_active_init(ref, active, retire, flags, &__mkey, &__wkey);   
\
 } while (0)
 
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-
-static inline int
-i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
-{
-   return i915_active_ref(ref,
-  i915_request_timeline(rq)->fence_context,
-  &rq->fence);
-}
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq);
 
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f);
 
-static inline bool i915_active_has_exclusive(struct i915_active *ref)
-{
-   return rcu_access_pointer(ref->excl.fence);
-}
-
 int __i915_active_wait(struct i915_active *ref, int state);
 static inline int i915_active_wait(struct i915_active *ref)
 {
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 90546fa58fc1..1187f1956c20 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1220,7 +1220,7 @@ __i915_request_await_bind(struct i915_request *rq, struct 
i915_vma *vma)
return __i915_request_await_exclusive(rq, &vma->active);
 }
 
-int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq)
+static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request 
*rq)
 {
int err;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 648dbe744c96..b882fd7b5f99 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -55,8 +55,6 @@ static inline bool i915_vma_is_active(const struct i915_vma 
*vma)
 /* do not reserve memory to prevent deadlocks */
 #define __EXEC_OBJECT_NO_RESERVE BIT(31)
 
-int __must_check __i915_vma_move_to_active(struct i915_vma *vma,
-  struct i915_request *rq);
 int __must_check _i915_vma_move_to_active(struct i915_vma *vma,
  struct i915_request *rq,
  struct dma_fence *fence,
-- 
2.

Re: [PATCH 3/3] [RFC] dt-bindings: display: bridge: nxp,tda998x: Convert to json-schema

2021-10-29 Thread Geert Uytterhoeven
Hi Russell,

Thanks for your comments!

On Fri, Oct 29, 2021 at 10:08 AM Russell King (Oracle)
 wrote:
> On Thu, Oct 28, 2021 at 08:04:48PM -0500, Rob Herring wrote:
> > On Thu, Oct 21, 2021 at 03:18:53PM +0200, Geert Uytterhoeven wrote:
> > > +properties:
> > > +  port@0:
> > > +type: object
> > > +description: FIXME
> >
> > Looks like the input from the example
> >
> > > +
> > > +  port@1:
> > > +type: object
> > > +description: FIXME
> >
> > Presumably the output to connector or another bridge.
>
> This is changing the binding. The original had:
>
> Required node:
>   - port: Input port node with endpoint definition, as described
> in Documentation/devicetree/bindings/graph.txt

Indeed, cfr. "Add ports hierarchy, as an alternative to port." in the
patch description. Some users use port, other use ports with one or
two port subnodes.

> The above change appears to require that tda998x now has two ports.

No, you can still use port:

+oneOf:
+  - required:
+  - port
+  - required:
+  - ports

When using ports, no further requirements are set, but perhaps port@0
should be made required in that case?

> This goes against current usage in DT and the example.

The original example didn't even have the original required input
port node, so it was incomplete.

arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts has two port subnodes.
Is that wrong?

Thanks!

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


[PATCH v4 1/4] drm/i915: Introduce refcounted sg-tables

2021-10-29 Thread Thomas Hellström
As we start to introduce asynchronous failsafe object migration,
where we update the object state and then submit asynchronous
commands we need to record what memory resources are actually used
by various part of the command stream. Initially for three purposes:

1) Error capture.
2) Asynchronous migration error recovery.
3) Asynchronous vma bind.

At the time where these happens, the object state may have been updated
to be several migrations ahead and object sg-tables discarded.

In order to make it possible to keep sg-tables with memory resource
information for these operations, introduce refcounted sg-tables that
aren't freed until the last user is done with them.

The alternative would be to reference information sitting on the
corresponding ttm_resources which typically have the same lifetime as
these refcountes sg_tables, but that leads to other awkward constructs:
Due to the design direction chosen for ttm resource managers that would
lead to diamond-style inheritance, the LMEM resources may sometimes be
prematurely freed, and finally the subclassed struct ttm_resource would
have to bleed into the asynchronous vma bind code.

v3:
- Address a number of style issues (Matthew Auld)
v4:
- Dont check for st->sgl being NULL in i915_ttm_tt__shmem_unpopulate(),
  that should never happen. (Matthew Auld)

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h|  12 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   3 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c |  49 +++--
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   | 186 ++
 drivers/gpu/drm/i915/i915_scatterlist.c   |  62 --
 drivers/gpu/drm/i915/i915_scatterlist.h   |  76 ++-
 drivers/gpu/drm/i915/intel_region_ttm.c   |  15 +-
 drivers/gpu/drm/i915/intel_region_ttm.h   |   5 +-
 drivers/gpu/drm/i915/selftests/mock_region.c  |  12 +-
 9 files changed, 276 insertions(+), 144 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index a5479ac7a4ad..ba224598ed69 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -620,12 +620,12 @@ int i915_gem_object_wait_migration(struct 
drm_i915_gem_object *obj,
 bool i915_gem_object_placement_possible(struct drm_i915_gem_object *obj,
enum intel_memory_type type);
 
-struct sg_table *shmem_alloc_st(struct drm_i915_private *i915,
-   size_t size, struct intel_memory_region *mr,
-   struct address_space *mapping,
-   unsigned int max_segment);
-void shmem_free_st(struct sg_table *st, struct address_space *mapping,
-  bool dirty, bool backup);
+int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
+size_t size, struct intel_memory_region *mr,
+struct address_space *mapping,
+unsigned int max_segment);
+void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
+bool dirty, bool backup);
 void __shmem_writeback(size_t size, struct address_space *mapping);
 
 #ifdef CONFIG_MMU_NOTIFIER
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index a4b69a43b898..604ed5ad77f5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -544,6 +544,7 @@ struct drm_i915_gem_object {
 */
struct list_head region_link;
 
+   struct i915_refct_sgt *rsgt;
struct sg_table *pages;
void *mapping;
 
@@ -597,7 +598,7 @@ struct drm_i915_gem_object {
} mm;
 
struct {
-   struct sg_table *cached_io_st;
+   struct i915_refct_sgt *cached_io_rsgt;
struct i915_gem_object_page_iter get_io_page;
struct drm_i915_gem_object *backup;
bool created:1;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 01f332d8dbde..e09141031a5e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -25,8 +25,8 @@ static void check_release_pagevec(struct pagevec *pvec)
cond_resched();
 }
 
-void shmem_free_st(struct sg_table *st, struct address_space *mapping,
-  bool dirty, bool backup)
+void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
+bool dirty, bool backup)
 {
struct sgt_iter sgt_iter;
struct pagevec pvec;
@@ -49,17 +49,15 @@ void shmem_free_st(struct sg_table *st, struct 
address_space *mapping,
check_release_pagevec(&pvec);
 
sg_free_table(st);
-   kfree(st);
 }
 
-struct sg_table *shmem_alloc_st(struct

[PATCH v4 2/4] drm/i915: Update error capture code to avoid using the current vma state

2021-10-29 Thread Thomas Hellström
With asynchronous migrations, the vma state may be several migrations
ahead of the state that matches the request we're capturing.
Address that by introducing an i915_vma_snapshot structure that
can be used to snapshot relevant state at request submission.
In order to make sure we access the correct memory, the snapshots take
references on relevant sg-tables and memory regions.

Also move the capture list allocation out of the fence signaling
critical path and use the CONFIG_DRM_I915_CAPTURE_ERROR define to
avoid compiling in members and functions used for error capture
when they're not used.

Finally, Introducing lockdep annotation means we will be start seeing
lockdep splats in the capture code. This is because typically the
capture code runs in the fence signalling critical path. These splats
and the associated deadlocks will be worked around in an upcoming patch.

Splats look like these:

[  234.842048] WARNING: possible circular locking dependency detected
[  234.842050] 5.15.0-rc7+ #20 Tainted: G U  W
[  234.842052] --
[  234.842054] gem_exec_captur/1180 is trying to acquire lock:
[  234.842056] a3e51c00 (fs_reclaim){+.+.}-{0:0}, at: 
__kmalloc+0x4d/0x330
[  234.842063]
   but task is already holding lock:
[  234.842064] a3f57620 (dma_fence_map){}-{0:0}, at: 
i915_vma_snapshot_resource_pin+0x27/0x30 [i915]
[  234.842138]
   which lock already depends on the new lock.

[  234.842140]
   the existing dependency chain (in reverse order) is:
[  234.842142]
   -> #2 (dma_fence_map){}-{0:0}:
[  234.842145]__dma_fence_might_wait+0x41/0xa0
[  234.842149]dma_resv_lockdep+0x1dc/0x28f
[  234.842151]do_one_initcall+0x58/0x2d0
[  234.842154]kernel_init_freeable+0x273/0x2bf
[  234.842157]kernel_init+0x16/0x120
[  234.842160]ret_from_fork+0x1f/0x30
[  234.842163]
   -> #1 (mmu_notifier_invalidate_range_start){+.+.}-{0:0}:
[  234.842166]fs_reclaim_acquire+0x6d/0xd0
[  234.842168]__kmalloc_node+0x51/0x3a0
[  234.842171]alloc_cpumask_var_node+0x1b/0x30
[  234.842174]native_smp_prepare_cpus+0xc7/0x292
[  234.842177]kernel_init_freeable+0x160/0x2bf
[  234.842179]kernel_init+0x16/0x120
[  234.842181]ret_from_fork+0x1f/0x30
[  234.842184]
   -> #0 (fs_reclaim){+.+.}-{0:0}:
[  234.842186]__lock_acquire+0x1161/0x1dc0
[  234.842189]lock_acquire+0xb5/0x2b0
[  234.842192]fs_reclaim_acquire+0xa1/0xd0
[  234.842193]__kmalloc+0x4d/0x330
[  234.842196]i915_vma_coredump_create+0x78/0x5b0 [i915]
[  234.842253]intel_engine_coredump_add_vma+0x36/0xe0 [i915]
[  234.842307]__i915_gpu_coredump+0x290/0x5e0 [i915]
[  234.842365]i915_capture_error_state+0x57/0xa0 [i915]
[  234.842415]intel_gt_handle_error+0x348/0x3e0 [i915]
[  234.842462]intel_gt_debugfs_reset_store+0x3c/0x90 [i915]
[  234.842504]simple_attr_write+0xc1/0xe0
[  234.842507]full_proxy_write+0x53/0x80
[  234.842509]vfs_write+0xbc/0x350
[  234.842513]ksys_write+0x58/0xd0
[  234.842514]do_syscall_64+0x38/0x90
[  234.842516]entry_SYSCALL_64_after_hwframe+0x44/0xae
[  234.842519]
   other info that might help us debug this:

[  234.842521] Chain exists of:
 fs_reclaim --> mmu_notifier_invalidate_range_start --> 
dma_fence_map

[  234.842526]  Possible unsafe locking scenario:

[  234.842528]CPU0CPU1
[  234.842529]
[  234.842531]   lock(dma_fence_map);
[  234.842532]
lock(mmu_notifier_invalidate_range_start);
[  234.842535]lock(dma_fence_map);
[  234.842537]   lock(fs_reclaim);
[  234.842539]
*** DEADLOCK ***

[  234.842540] 4 locks held by gem_exec_captur/1180:
[  234.842543]  #0: 9007812d9460 (sb_writers#17){.+.+}-{0:0}, at: 
ksys_write+0x58/0xd0
[  234.842547]  #1: 900781d9ecb8 (&attr->mutex){+.+.}-{3:3}, at: 
simple_attr_write+0x3a/0xe0
[  234.842552]  #2: c11913a8 (capture_mutex){+.+.}-{3:3}, at: 
i915_capture_error_state+0x1a/0xa0 [i915]
[  234.842602]  #3: a3f57620 (dma_fence_map){}-{0:0}, at: 
i915_vma_snapshot_resource_pin+0x27/0x30 [i915]
[  234.842656]
   stack backtrace:
[  234.842658] CPU: 0 PID: 1180 Comm: gem_exec_captur Tainted: G U  W   
  5.15.0-rc7+ #20
[  234.842661] Hardware name: ASUS System Product Name/PRIME B560M-A AC, BIOS 
0403 01/26/2021
[  234.842664] Call Trace:
[  234.842666]  dump_stack_lvl+0x57/0x72
[  234.842669]  check_noncircular+0xde/0x100
[  234.842672]  ? __lock_acquire+0x3bf/0x1dc0
[  234.842675]  __lock_acquire+0x1161/0x1dc0
[  234.842678]  lock_acquire+0xb5/0x2b0
[  234.842680]  ? __kmalloc+0x4d/0x330
[  234.842683]  ? finish_task_switch.isra.0+0xf2

[PATCH v4 3/4] drm/i915: Use GFP_NOWAIT in the capture code

2021-10-29 Thread Thomas Hellström
The capture code is typically run entirely in the fence signalling
critical path. Recently added lockdep annotation reveals a lockdep splat
similar to the below one.

Fix the splats and the associated potential deadlocks using GFP_NOWAIT
rather than GFP_KERNEL for memory allocation in the capture path. This
has the potential drawback that capture might fail in situations with
memory pressure.

Reliably being able to use GFP_KERNEL allocations during capture might
require that we pin all relevant vmas first, then reset and retire the
request, and finally capture and unpin.

[  234.842048] WARNING: possible circular locking dependency detected
[  234.842050] 5.15.0-rc7+ #20 Tainted: G U  W
[  234.842052] --
[  234.842054] gem_exec_captur/1180 is trying to acquire lock:
[  234.842056] a3e51c00 (fs_reclaim){+.+.}-{0:0}, at: 
__kmalloc+0x4d/0x330
[  234.842063]
   but task is already holding lock:
[  234.842064] a3f57620 (dma_fence_map){}-{0:0}, at: 
i915_vma_snapshot_resource_pin+0x27/0x30 [i915]
[  234.842138]
   which lock already depends on the new lock.

[  234.842140]
   the existing dependency chain (in reverse order) is:
[  234.842142]
   -> #2 (dma_fence_map){}-{0:0}:
[  234.842145]__dma_fence_might_wait+0x41/0xa0
[  234.842149]dma_resv_lockdep+0x1dc/0x28f
[  234.842151]do_one_initcall+0x58/0x2d0
[  234.842154]kernel_init_freeable+0x273/0x2bf
[  234.842157]kernel_init+0x16/0x120
[  234.842160]ret_from_fork+0x1f/0x30
[  234.842163]
   -> #1 (mmu_notifier_invalidate_range_start){+.+.}-{0:0}:
[  234.842166]fs_reclaim_acquire+0x6d/0xd0
[  234.842168]__kmalloc_node+0x51/0x3a0
[  234.842171]alloc_cpumask_var_node+0x1b/0x30
[  234.842174]native_smp_prepare_cpus+0xc7/0x292
[  234.842177]kernel_init_freeable+0x160/0x2bf
[  234.842179]kernel_init+0x16/0x120
[  234.842181]ret_from_fork+0x1f/0x30
[  234.842184]
   -> #0 (fs_reclaim){+.+.}-{0:0}:
[  234.842186]__lock_acquire+0x1161/0x1dc0
[  234.842189]lock_acquire+0xb5/0x2b0
[  234.842192]fs_reclaim_acquire+0xa1/0xd0
[  234.842193]__kmalloc+0x4d/0x330
[  234.842196]i915_vma_coredump_create+0x78/0x5b0 [i915]
[  234.842253]intel_engine_coredump_add_vma+0x36/0xe0 [i915]
[  234.842307]__i915_gpu_coredump+0x290/0x5e0 [i915]
[  234.842365]i915_capture_error_state+0x57/0xa0 [i915]
[  234.842415]intel_gt_handle_error+0x348/0x3e0 [i915]
[  234.842462]intel_gt_debugfs_reset_store+0x3c/0x90 [i915]
[  234.842504]simple_attr_write+0xc1/0xe0
[  234.842507]full_proxy_write+0x53/0x80
[  234.842509]vfs_write+0xbc/0x350
[  234.842513]ksys_write+0x58/0xd0
[  234.842514]do_syscall_64+0x38/0x90
[  234.842516]entry_SYSCALL_64_after_hwframe+0x44/0xae
[  234.842519]
   other info that might help us debug this:

[  234.842521] Chain exists of:
 fs_reclaim --> mmu_notifier_invalidate_range_start --> 
dma_fence_map

[  234.842526]  Possible unsafe locking scenario:

[  234.842528]CPU0CPU1
[  234.842529]
[  234.842531]   lock(dma_fence_map);
[  234.842532]
lock(mmu_notifier_invalidate_range_start);
[  234.842535]lock(dma_fence_map);
[  234.842537]   lock(fs_reclaim);
[  234.842539]
*** DEADLOCK ***

[  234.842540] 4 locks held by gem_exec_captur/1180:
[  234.842543]  #0: 9007812d9460 (sb_writers#17){.+.+}-{0:0}, at: 
ksys_write+0x58/0xd0
[  234.842547]  #1: 900781d9ecb8 (&attr->mutex){+.+.}-{3:3}, at: 
simple_attr_write+0x3a/0xe0
[  234.842552]  #2: c11913a8 (capture_mutex){+.+.}-{3:3}, at: 
i915_capture_error_state+0x1a/0xa0 [i915]
[  234.842602]  #3: a3f57620 (dma_fence_map){}-{0:0}, at: 
i915_vma_snapshot_resource_pin+0x27/0x30 [i915]
[  234.842656]
   stack backtrace:
[  234.842658] CPU: 0 PID: 1180 Comm: gem_exec_captur Tainted: G U  W   
  5.15.0-rc7+ #20
[  234.842661] Hardware name: ASUS System Product Name/PRIME B560M-A AC, BIOS 
0403 01/26/2021
[  234.842664] Call Trace:
[  234.842666]  dump_stack_lvl+0x57/0x72
[  234.842669]  check_noncircular+0xde/0x100
[  234.842672]  ? __lock_acquire+0x3bf/0x1dc0
[  234.842675]  __lock_acquire+0x1161/0x1dc0
[  234.842678]  lock_acquire+0xb5/0x2b0
[  234.842680]  ? __kmalloc+0x4d/0x330
[  234.842683]  ? finish_task_switch.isra.0+0xf2/0x360
[  234.842686]  ? i915_vma_coredump_create+0x78/0x5b0 [i915]
[  234.842734]  fs_reclaim_acquire+0xa1/0xd0
[  234.842737]  ? __kmalloc+0x4d/0x330
[  234.842739]  __kmalloc+0x4d/0x330
[  234.842742]  i915_vma_coredump_create+0x78/0x5b0 [i915]
[  234.842793]  ? capture_vma+0xbe/0x110 [i915]
[  234.842844]  intel_engine_c

[PATCH v4 0/4] Prepare error capture for asynchronous migration

2021-10-29 Thread Thomas Hellström
This patch series prepares error capture for asynchronous migration,
where the vma pages may not reflect the pages the GPU is currently
executing from but may be several migrations ahead.

The first patch deals with refcounting sg-list so that they don't
disappear under the capture code, which typically otherwise happens at
put_pages() time.

The second patch introduces vma state snapshots that record the vma state
at request submission time.
It also takes additional measures to make sure that
the capture list and request is not disappearing from under us while
capturing. The latter may otherwise happen if a heartbeat triggered parallel
capture is running during a manual reset which retires the request.

The third patch changes the allocation mode during capture to reflect that
capturing is typically done in the fence signalling critical path. More
details on the patch itself.

Finally the last patch is more of a POC patch and not strictly needed yet,
but will be (or at least something very similar) soon for async unbinding.
It will make sure that unbinding doesn't complete or signal completion
before capture is done. Async reuse of memory can't happen until unbinding
signals complete and without waiting for capture done, we might capture
contents of reused memory.
Before the last patch the vma active is instead still keeping the vma alive,
but that will not work with async unbinding anymore, and also it is still
not clear how we guarantee keeping the vma alive long enough to even
grab an active reference during capture.

v2:
- Mostly Fixes for selftests and rebinding. See patch 3. 
v3:
- Honor the unbind fence also when evicting for suspend on gen6.
- Cleanups on patch 1
- Minor cleanups on patch 3.
v4:
- Break out patch 3 from patch 2.
- Move a fix from patch 4 to patch 1.

Thomas Hellström (4):
  drm/i915: Introduce refcounted sg-tables
  drm/i915: Update error capture code to avoid using the current vma
state
  drm/i915: Use GFP_NOWAIT in the capture code
  drm/i915: Initial introduction of vma resources

 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 137 ++--
 drivers/gpu/drm/i915/gem/i915_gem_object.h|  12 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   3 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c |  49 ++---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   | 186 +---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |   8 +-
 .../drm/i915/gt/intel_execlists_submission.c  |   2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c | 180 ++-
 drivers/gpu/drm/i915/i915_request.c   |  63 --
 drivers/gpu/drm/i915/i915_request.h   |  18 +-
 drivers/gpu/drm/i915/i915_scatterlist.c   |  62 --
 drivers/gpu/drm/i915/i915_scatterlist.h   |  76 ++-
 drivers/gpu/drm/i915/i915_vma.c   | 206 +-
 drivers/gpu/drm/i915/i915_vma.h   |  20 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.c  | 131 +++
 drivers/gpu/drm/i915/i915_vma_snapshot.h  | 112 ++
 drivers/gpu/drm/i915/i915_vma_types.h |   5 +
 drivers/gpu/drm/i915/intel_region_ttm.c   |  15 +-
 drivers/gpu/drm/i915/intel_region_ttm.h   |   5 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  98 +
 drivers/gpu/drm/i915/selftests/mock_region.c  |  12 +-
 22 files changed,  insertions(+), 290 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.c
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.h

-- 
2.31.1



[PATCH v4 4/4] drm/i915: Initial introduction of vma resources

2021-10-29 Thread Thomas Hellström
From: Thomas Hellström 

The vma resource are needed for asynchronous bind management and are
similar to TTM resources. They contain the data needed for
asynchronous unbinding (typically the vm range, any backend
private information and a means to do refcounting and to hold
the unbinding for error capture).

When a vma is bound, a vma resource is created and attached to the
vma, and on async unbinding it is detached from the vma, and instead
the vm records the fence marking unbind complete. This fence needs to
be waited on before we can bind the same region again, so either
the fence can be recorded for this particular range only, using an
interval tree, or as a simpler approach, for the whole vm. The latter
means no binding can take place on a vm until all detached vma
resources scheduled for unbind are signaled. With an interval tree
fence recording, the interval tree needs to be searched for fences
to be signaled before binding can take place.

But most of that is for later, this patch only introduces stub vma
resources without unbind capability and the fences of which are waited
for sync during unbinding. At this point we're interested in the hold
capability as a POC for error capture. Note that the current sync waiting
at unbind time is done uninterruptible, but that's OK since we're
only ever waiting during error capture, and in that case there's very
little gpu activity (if any) that can stall.

v2:
- Fix the mock gtt selftest to bind with vma resources.
- Update a code comment.
- Account for rebinding the same vma with different I915_VMA_*_BIND flags
v3:
- Some style fixups.
- Move the sync fence wait to __i915_vma_evict instead of __i915_vma_unbind
  to catch also the evict case on suspend.
v4:
- Remove a minor fix that incorrectly landed in this patch.

Signed-off-by: Thomas Hellström 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|   2 +-
 drivers/gpu/drm/i915/i915_vma.c   | 206 +-
 drivers/gpu/drm/i915/i915_vma.h   |  20 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.c  |  14 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.h  |   2 +-
 drivers/gpu/drm/i915/i915_vma_types.h |   5 +
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  98 +
 7 files changed, 288 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 301eb58bebd1..69915c00ce18 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1376,7 +1376,7 @@ eb_relocate_entry(struct i915_execbuffer *eb,
GRAPHICS_VER(eb->i915) == 6) {
err = i915_vma_bind(target->vma,
target->vma->obj->cache_level,
-   PIN_GLOBAL, NULL);
+   PIN_GLOBAL, NULL, NULL);
if (err)
return err;
}
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 90546fa58fc1..ff125cbea45c 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -38,7 +38,35 @@
 #include "i915_trace.h"
 #include "i915_vma.h"
 
+/**
+ * struct i915_vma_resource - Snapshotted unbind information.
+ * @unbind_fence: Fence to mark unbinding complete. Note that this fence
+ * is not considered published until unbind is scheduled, and as such it
+ * is illegal to access this fence before scheduled unbind other than
+ * for refcounting.
+ * @lock: The @unbind_fence lock. We're also using it to protect the weak
+ * pointer to the struct i915_vma, @vma during lookup and takedown.
+ * @vma: Weak back-pointer to the parent vma struct. This pointer is
+ * protected by @lock, and a reference on @vma needs to be taken
+ * using kref_get_unless_zero.
+ * @hold_count: Number of holders blocking the fence from finishing.
+ * The vma itself is keeping a hold, which is released when unbind
+ * is scheduled.
+ */
+struct i915_vma_resource {
+   struct dma_fence unbind_fence;
+   /* See above for description of the lock. */
+   spinlock_t lock;
+   struct i915_vma *vma;
+   refcount_t hold_count;
+};
+
 static struct kmem_cache *slab_vmas;
+static struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource 
*vma_res);
+#ifndef CONFIG_DRM_I915_SELFTEST
+static void i915_vma_resource_init(struct i915_vma_resource *vma_res,
+  struct i915_vma *vma);
+#endif
 
 struct i915_vma *i915_vma_alloc(void)
 {
@@ -363,6 +391,8 @@ int i915_vma_wait_for_bind(struct i915_vma *vma)
  * @cache_level: mapping cache level
  * @flags: flags like global or local mapping
  * @work: preallocated worker for allocating and binding the PTE
+ * @vma_res: pointer to a preallocated vma resource. The resource is either
+ * consumed or freed.
  *
  * DMA addresses are taken from the scatter

Re: [PATCH 3/3] [RFC] dt-bindings: display: bridge: nxp,tda998x: Convert to json-schema

2021-10-29 Thread Russell King (Oracle)
On Thu, Oct 28, 2021 at 08:04:48PM -0500, Rob Herring wrote:
> On Thu, Oct 21, 2021 at 03:18:53PM +0200, Geert Uytterhoeven wrote:
> > +properties:
> > +  port@0:
> > +type: object
> > +description: FIXME
> 
> Looks like the input from the example
> 
> > +
> > +  port@1:
> > +type: object
> > +description: FIXME
> 
> Presumably the output to connector or another bridge.

This is changing the binding. The original had:

Required node:
  - port: Input port node with endpoint definition, as described
in Documentation/devicetree/bindings/graph.txt

The above change appears to require that tda998x now has two ports.
This goes against current usage in DT and the example.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


Re: [v6,02/21] drm/bridge: adv7511: Register and attach our DSI device at probe

2021-10-29 Thread Maxime Ripard
Hi Marek,

On Fri, Oct 29, 2021 at 08:23:45AM +0200, Marek Szyprowski wrote:
> Hi,
> 
> On 25.10.2021 17:15, Maxime Ripard wrote:
> > In order to avoid any probe ordering issue, the best practice is to move
> > the secondary MIPI-DSI device registration and attachment to the
> > MIPI-DSI host at probe time. Let's do this.
> >
> > Acked-by: Sam Ravnborg 
> > Tested-by: John Stultz 
> > Signed-off-by: Maxime Ripard 
>
> This patch landed in linux-next as commit 864c49a31d6b ("drm/bridge:
> adv7511: Register and attach our DSI device at probe"). Sadly it causes
> endless probe-fail-defer loop on DragonBoard 410c board
> (arch/arm64/boot/dts/qcom/apq8016-sbc.dts):

I'm sorry to hear that (but would have been surprised if it didn't occur)

This is supposed to be fixed by 8f59ee9a570c ("drm/msm/dsi: Adjust probe
order"). Do you have that patch applied?

Maxime


signature.asc
Description: PGP signature


Re: linux-next: manual merge of the char-misc tree with the drm-intel tree

2021-10-29 Thread Greg KH
On Thu, Oct 28, 2021 at 06:27:53PM +1100, Stephen Rothwell wrote:
> Hi all,
> 
> Today's linux-next merge of the char-misc tree got a conflict in:
> 
>   drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> 
> between commit:
> 
>   5740211ea442 ("drm/i915/dmabuf: fix broken build")
> 
> from the drm-intel tree and commit:
> 
>   16b0314aa746 ("dma-buf: move dma-buf symbols into the DMA_BUF module 
> namespace")
> 
> from the char-misc tree.
> 
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.
> 
> -- 
> Cheers,
> Stephen Rothwell
> 
> diff --cc drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> index a45d0ec2c5b6,abb854281347..
> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> @@@ -12,13 -13,8 +13,15 @@@
>   #include "i915_gem_object.h"
>   #include "i915_scatterlist.h"
>   
>  +#if defined(CONFIG_X86)
>  +#include 
>  +#else
>  +#define wbinvd_on_all_cpus() \
>  +pr_warn(DRIVER_NAME ": Missing cache flush in %s\n", __func__)
>  +#endif
>  +
> + MODULE_IMPORT_NS(DMA_BUF);
> + 
>   I915_SELFTEST_DECLARE(static bool force_different_devices;)
>   
>   static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)



Fix looks good, thanks!


[PATCH v7 08/20] soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195 vdosys1

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

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

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

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 545a9cee8b7b..868df83eb57d 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -88,6 +88,7 @@ struct mtk_mmsys {
const struct mtk_mmsys_driver_data *data;
spinlock_t lock; /* protects mmsys_sw_rst_b reg */
struct reset_controller_dev rcdev;
+   struct cmdq_client_reg cmdq_base;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -180,7 +181,7 @@ static const struct reset_control_ops mtk_mmsys_reset_ops = 
{
 };
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type 
config,
- u32 id, u32 val)
+ u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
@@ -188,7 +189,6 @@ void mtk_mmsys_ddp_config(struct device *dev, enum 
mtk_mmsys_config_type config,
u32 mask;
u32 offset;
int i;
-   u32 tmp;
 
if (!mmsys->data->num_configs)
return;
@@ -204,10 +204,20 @@ void mtk_mmsys_ddp_config(struct device *dev, enum 
mtk_mmsys_config_type config,
mask = mmsys_config[i].mask;
reg_val = val << mmsys_config[i].shift;
 
-   tmp = readl(mmsys->regs + offset);
-
-   tmp = (tmp & ~mask) | reg_val;
-   writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   if (cmdq_pkt && mmsys->cmdq_base.size) {
+   cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+   mmsys->cmdq_base.offset + offset, reg_val,
+   mask);
+   } else {
+#endif
+   u32 tmp = readl(mmsys->regs + offset);
+
+   tmp = (tmp & ~mask) | reg_val;
+   writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   }
+#endif
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
@@ -243,6 +253,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
}
 
mmsys->data = of_device_get_match_data(&pdev->dev);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
+   if (ret)
+   dev_dbg(dev, "No mediatek,gce-client-reg!\n");
+#endif
+
platform_set_drvdata(pdev, mmsys);
 
clks = platform_device_register_data(&pdev->dev, 
mmsys->data->clk_driver,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h 
b/include/linux/soc/mediatek/mtk-mmsys.h
index b2d2310d7e7a..3e998bfb795a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -6,6 +6,10 @@
 #ifndef __MTK_MMSYS_H
 #define __MTK_MMSYS_H
 
+#include 
+#include 
+#include 
+
 enum mtk_ddp_comp_id;
 struct device;
 
@@ -78,6 +82,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
  enum mtk_ddp_comp_id next);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type 
config,
- u32 id, u32 val);
+ u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
 
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



[PATCH v7 06/20] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1

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

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

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

[PATCH v7 09/20] soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1

2021-10-29 Thread Nancy . Lin
MT8195 vdosys1 has more than 32 reset bits and a different reset base
than other chips. Modify mmsys for support 64 bit and different reset
base.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mt8195-mmsys.h |  1 +
 drivers/soc/mediatek/mtk-mmsys.c| 21 -
 drivers/soc/mediatek/mtk-mmsys.h|  2 ++
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h 
b/drivers/soc/mediatek/mt8195-mmsys.h
index 11ba79e3275e..628098260f61 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -229,6 +229,7 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN  0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER   0
 
+#define MT8195_VDO1_SW0_RST_B  0x1d0
 #define MT8195_VDO1_MERGE0_ASYNC_CFG_WD0xe30
 #define MT8195_VDO1_MERGE1_ASYNC_CFG_WD0xe40
 #define MT8195_VDO1_MERGE2_ASYNC_CFG_WD0xe50
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 868df83eb57d..362609bd244b 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -19,6 +19,8 @@
 #include "mt8192-mmsys.h"
 #include "mt8195-mmsys.h"
 
+#define MMSYS_SW_RESET_PER_REG 32
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
.clk_driver = "clk-mt2701-mm",
.routes = mmsys_default_routing_table,
@@ -49,12 +51,16 @@ static const struct mtk_mmsys_driver_data 
mt8173_mmsys_driver_data = {
.clk_driver = "clk-mt8173-mm",
.routes = mmsys_default_routing_table,
.num_routes = ARRAY_SIZE(mmsys_default_routing_table),
+   .sw_reset_start = MMSYS_SW0_RST_B,
+   .num_resets = 32,
 };
 
 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
.clk_driver = "clk-mt8183-mm",
.routes = mmsys_mt8183_routing_table,
.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
+   .sw_reset_start = MMSYS_SW0_RST_B,
+   .num_resets = 32,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -75,6 +81,8 @@ static const struct mtk_mmsys_driver_data 
mt8195_vdosys1_driver_data = {
.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
.config = mmsys_mt8195_config_table,
.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
+   .sw_reset_start = MT8195_VDO1_SW0_RST_B,
+   .num_resets = 64,
 };
 
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
@@ -133,18 +141,22 @@ static int mtk_mmsys_reset_update(struct 
reset_controller_dev *rcdev, unsigned l
 {
struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
unsigned long flags;
+   u32 offset;
u32 reg;
 
+   offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32);
+   id = id % MMSYS_SW_RESET_PER_REG;
+
spin_lock_irqsave(&mmsys->lock, flags);
 
-   reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B);
+   reg = readl_relaxed(mmsys->regs + mmsys->data->sw_reset_start + offset);
 
if (assert)
reg &= ~BIT(id);
else
reg |= BIT(id);
 
-   writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B);
+   writel_relaxed(reg, mmsys->regs + mmsys->data->sw_reset_start + offset);
 
spin_unlock_irqrestore(&mmsys->lock, flags);
 
@@ -240,10 +252,11 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
return ret;
}
 
+   mmsys->data = of_device_get_match_data(&pdev->dev);
spin_lock_init(&mmsys->lock);
 
mmsys->rcdev.owner = THIS_MODULE;
-   mmsys->rcdev.nr_resets = 32;
+   mmsys->rcdev.nr_resets = mmsys->data->num_resets;
mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
mmsys->rcdev.of_node = pdev->dev.of_node;
ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
@@ -252,8 +265,6 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
return ret;
}
 
-   mmsys->data = of_device_get_match_data(&pdev->dev);
-
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
if (ret)
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 2694021435d2..4842102cd451 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -102,6 +102,8 @@ struct mtk_mmsys_driver_data {
const unsigned int num_routes;
const struct mtk_mmsys_config *config;
const unsigned int num_configs;
+   u32 sw_reset_start;
+   u32 num_resets;
 };
 
 /*
-- 
2.18.0



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

2021-10-29 Thread Nancy . Lin
Add vdosys1 RDMA definition.

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

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



[PATCH v7 20/20] drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

2021-10-29 Thread Nancy . Lin
Add driver data of mt8195 vdosys1 to mediatek-drm and the sub driver.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 13 ++---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 +--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 56 -
 5 files changed, 78 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index dff2797a2f68..d64846c38fe1 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "mtk_drm_ddp_comp.h"
@@ -79,6 +80,9 @@ void mtk_merge_stop(struct device *dev)
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
mtk_merge_stop_cmdq(dev, NULL);
+
+   if (priv->async_clk)
+   device_reset_optional(dev);
 }
 
 void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 25580106a2c4..d41bd8201371 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -876,15 +876,10 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
node = priv->comp_node[comp_id];
comp = &priv->ddp_comp[comp_id];
 
-   if (!node) {
-   dev_info(dev,
-"Not creating crtc %d because component %d is 
disabled or missing\n",
-crtc_i, comp_id);
-   return 0;
-   }
-
-   if (!comp->dev) {
-   dev_err(dev, "Component %pOF not initialized\n", node);
+   if (!node && !comp->dev) {
+   dev_err(dev,
+   "Not creating crtc %d because component %d is 
disabled, missing or not initialized\n",
+   crtc_i, comp_id);
return -ENODEV;
}
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index eb9835102d79..279087ae889b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -385,6 +385,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
.start = mtk_ufoe_start,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
+   .clk_enable = mtk_ovl_adaptor_clk_enable,
+   .clk_disable = mtk_ovl_adaptor_clk_disable,
+   .config = mtk_ovl_adaptor_config,
+   .start = mtk_ovl_adaptor_start,
+   .stop = mtk_ovl_adaptor_stop,
+   .layer_nr = mtk_ovl_adaptor_layer_nr,
+   .layer_config = mtk_ovl_adaptor_layer_config,
+   .enable_vblank = mtk_ovl_adaptor_enable_vblank,
+   .disable_vblank = mtk_ovl_adaptor_disable_vblank,
+};
+
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
[MTK_DISP_AAL] = "aal",
[MTK_DISP_BLS] = "bls",
@@ -398,6 +410,7 @@ static const char * const 
mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
[MTK_DISP_OD] = "od",
[MTK_DISP_OVL] = "ovl",
[MTK_DISP_OVL_2L] = "ovl-2l",
+   [MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
[MTK_DISP_POSTMASK] = "postmask",
[MTK_DISP_PWM] = "pwm",
[MTK_DISP_RDMA] = "rdma",
@@ -443,6 +456,7 @@ static const struct mtk_ddp_comp_match 
mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L,0, &ddp_ovl },
[DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L,1, &ddp_ovl },
[DDP_COMPONENT_OVL_2L2] = { MTK_DISP_OVL_2L,2, &ddp_ovl },
+   [DDP_COMPONENT_OVL_ADAPTOR] = { MTK_DISP_OVL_ADAPTOR,   0, 
&ddp_ovl_adaptor },
[DDP_COMPONENT_POSTMASK0]   = { MTK_DISP_POSTMASK,  0, 
&ddp_postmask },
[DDP_COMPONENT_PWM0]= { MTK_DISP_PWM,   0, NULL },
[DDP_COMPONENT_PWM1]= { MTK_DISP_PWM,   1, NULL },
@@ -548,12 +562,17 @@ int mtk_ddp_comp_init(struct device_node *node, struct 
mtk_ddp_comp *comp,
 
comp->id = comp_id;
comp->funcs = mtk_ddp_matches[comp_id].funcs;
-   comp_pdev = of_find_device_by_node(node);
-   if (!comp_pdev) {
-   DRM_INFO("Waiting for device %s\n", node->full_name);
-   return -EPROBE_DEFER;
+   /* Not all drm components have a DTS device node, such as ovl_adaptor,
+* which is the drm bring up sub driver
+*/
+   if (node) {
+   comp_pdev = of_find_device_by_node(node);
+   if (!comp_pdev) {
+   DRM_INFO("Waiting for device %s\n", node->full_name);
+   return -EPROBE_DEFER;
+   }
+  

[PATCH v7 00/20] Add MediaTek SoC DRM (vdosys1) support for mt8195

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

Add DRM and these modules support by the patches below:

Changes in v7:
- rebase on vdosys0 series v12 (ref[5])
- add dma description in ethdr binding document.
- refine vdosys1 bit definition of mmsys routing table.
- separate merge modification into 3 pathces.
- separate mutex modification into 2 patches.
- add plane color coding for mdp_rdma csc.
- move mdp_rdma pm control to ovl_adaptor.
- fix reviewer comment in v6.

Changes in v6:
- rebase on kernel-5.15-rc1.
- change mbox label to gce0 for dts node of vdosys1.
- modify mmsys reset num for mt8195.
- rebase on vdosys0 series v10. (ref [5])
- use drm to bring up ovl_adaptor driver.
- move drm iommu/mutex check from kms init to drm bind.
- modify rdma binding doc location. (Documentation/devicetree/bindings/arm/)
- modify for reviewer's comment in v5.

Changes in v5:
- add mmsys reset controller reference.

Changes in v4:
- use merge common driver for merge1~4.
- refine ovl_adaptor rdma driver.
- use ovl_adaptor ddp_comp function instead of ethdr.
- modify for reviewer's comment in v3.

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

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

Signed-off-by: Nancy.Lin 

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

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

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

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

https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-christine@mediatek.com/
[7] [v3,2/7] dt-bindings: mediatek: Add #reset-cells to mmsys system controller

https://patchwork.kernel.org/project/linux-mediatek/patch/20210825122613.v3.2.I3f7f1c9a8e46be07d1757ddf4e0097535f3a7d41@changeid/
[8] [v4,6/7] soc: mediatek: mmsys: Add reset controller support

https://patchwork.kernel.org/project/linux-mediatek/patch/20210930103105.v4.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid/

Nancy.Lin (20):
  dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
  dt-bindings: mediatek: add vdosys1 MERGE property for mt8195
  dt-bindings: mediatek: add ethdr definition for mt8195
  dt-bindings: reset: mt8195: add vdosys1 reset control bit
  arm64: dts: mt8195: add display node for vdosys1
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
  soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
  soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195
vdosys1
  soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1
  soc: mediatek: change the mutex defines and the mutex_mod type
  soc: mediatek: add mtk-mutex support for mt8195 vdosys1
  drm/mediatek: add display MDP RDMA support for MT8195
  drm/mediatek: add display merge advance config API for MT8195
  drm/mediatek: add display merge start/stop API for cmdq support
  drm/mediatek: add display merge mute/unmute support for MT8195
  drm/mediatek: add ETHDR support for MT8195
  drm/mediatek: add mediatek-drm plane color encoding info
  drm/mediatek: add ovl_adaptor support for MT8195
  drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support
  drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

 .../arm/mediatek/mediatek,mdp-rdma.yaml   |  77 
 .../display/mediatek/mediatek,ethdr.yaml  | 147 ++
 .../display/mediatek/mediatek,merge.yaml  |   4 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi  | 222 +
 drivers/gpu/drm/mediatek/Makefile |   5 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  28 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c |  99 +++-
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 436 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c   |  35 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h   |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  30 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c| 339 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|  10 +-
 drivers/gpu/d

[PATCH v7 14/20] drm/mediatek: add display merge start/stop API for cmdq support

2021-10-29 Thread Nancy . Lin
Add merge start/stop API for cmdq support. The ovl_adaptor merges
are configured with each drm plane update. Need to enable/disable
merge with cmdq making sure all the settings taken effect in the
same vblank.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  2 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 20 +---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index c2de53a5892e..224a710bb537 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -66,6 +66,8 @@ void mtk_merge_stop(struct device *dev);
 void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned 
int r_w,
  unsigned int h, unsigned int vrefresh, unsigned 
int bpc,
  struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 558e0cb2a297..92c81ce24a49 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -67,17 +67,31 @@ struct mtk_disp_merge {
 };
 
 void mtk_merge_start(struct device *dev)
+{
+   mtk_merge_start_cmdq(dev, NULL);
+}
+
+void mtk_merge_stop(struct device *dev)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-   writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+   mtk_merge_stop_cmdq(dev, NULL);
 }
 
-void mtk_merge_stop(struct device *dev)
+void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+   struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+   mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-   writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+   mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_CTRL);
 }
 
 static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
-- 
2.18.0



[PATCH v7 05/20] arm64: dts: mt8195: add display node for vdosys1

2021-10-29 Thread Nancy . Lin
Add display node for vdosys1.

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

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

[PATCH v7 15/20] drm/mediatek: add display merge mute/unmute support for MT8195

2021-10-29 Thread Nancy . Lin
Add merge mute/unmute setting for MT8195.
MT8195 Vdosys1 merge1~merge4 support HW mute function.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 92c81ce24a49..dff2797a2f68 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -58,12 +58,15 @@
 #define FLD_PREULTRA_TH_LOWGENMASK(15, 0)
 #define FLD_PREULTRA_TH_HIGH   GENMASK(31, 16)
 
+#define DISP_REG_MERGE_MUTE_0  0xf00
+
 struct mtk_disp_merge {
-   void __iomem *regs;
-   struct clk *clk;
-   struct clk *async_clk;
-   struct cmdq_client_reg  cmdq_reg;
-   boolfifo_en;
+   void __iomem*regs;
+   struct clk  *clk;
+   struct clk  *async_clk;
+   struct cmdq_client_reg  cmdq_reg;
+   boolfifo_en;
+   boolmute_support;
 };
 
 void mtk_merge_start(struct device *dev)
@@ -82,6 +85,10 @@ void mtk_merge_start_cmdq(struct device *dev, struct 
cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
+   if (priv->mute_support)
+   mtk_ddp_write(cmdq_pkt, 0x0, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_MUTE_0);
+
mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CTRL);
 }
@@ -90,6 +97,10 @@ void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt 
*cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
+   if (priv->mute_support)
+   mtk_ddp_write(cmdq_pkt, 0x1, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_MUTE_0);
+
mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CTRL);
 }
@@ -264,6 +275,8 @@ static int mtk_disp_merge_probe(struct platform_device 
*pdev)
priv->fifo_en = of_property_read_bool(dev->of_node,
  "mediatek,merge-fifo-en");
 
+   priv->mute_support = of_property_read_bool(dev->of_node,
+  "mediatek,merge-mute");
platform_set_drvdata(pdev, priv);
 
ret = component_add(dev, &mtk_disp_merge_component_ops);
-- 
2.18.0



[PATCH v7 07/20] soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1

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

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

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

[PATCH v7 13/20] drm/mediatek: add display merge advance config API for MT8195

2021-10-29 Thread Nancy . Lin
Add merge new advance config API. The original merge API is
mtk_ddp_comp_funcs function prototype. The API interface parameters
cannot be modified, so add a new config API for extension. This is
the preparation for ovl_adaptor merge control.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  3 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 52 ---
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index b3a372cab0bd..c2de53a5892e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -63,6 +63,9 @@ void mtk_merge_config(struct device *dev, unsigned int width,
  unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
 void mtk_merge_start(struct device *dev);
 void mtk_merge_stop(struct device *dev);
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned 
int r_w,
+ unsigned int h, unsigned int vrefresh, unsigned 
int bpc,
+ struct cmdq_pkt *cmdq_pkt);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 470ebc4b5296..558e0cb2a297 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -17,6 +17,7 @@
 #define DISP_REG_MERGE_CTRL0x000
 #define MERGE_EN   1
 #define DISP_REG_MERGE_CFG_0   0x010
+#define DISP_REG_MERGE_CFG_1   0x014
 #define DISP_REG_MERGE_CFG_4   0x020
 #define DISP_REG_MERGE_CFG_10  0x038
 /* no swap */
@@ -25,9 +26,12 @@
 #define DISP_REG_MERGE_CFG_12  0x040
 #define CFG_10_10_1PI_2PO_BUF_MODE 6
 #define CFG_10_10_2PI_2PO_BUF_MODE 8
+#define CFG_11_10_1PI_2PO_MERGE18
 #define FLD_CFG_MERGE_MODE GENMASK(4, 0)
 #define DISP_REG_MERGE_CFG_24  0x070
 #define DISP_REG_MERGE_CFG_25  0x074
+#define DISP_REG_MERGE_CFG_26  0x078
+#define DISP_REG_MERGE_CFG_27  0x07c
 #define DISP_REG_MERGE_CFG_36  0x0a0
 #define ULTRA_EN   BIT(0)
 #define PREULTRA_ENBIT(4)
@@ -98,12 +102,19 @@ static void mtk_merge_fifo_setting(struct mtk_disp_merge 
*priv,
 void mtk_merge_config(struct device *dev, unsigned int w,
  unsigned int h, unsigned int vrefresh,
  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+   mtk_merge_advance_config(dev, w, 0, h, vrefresh, bpc, cmdq_pkt);
+}
+
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned 
int r_w,
+ unsigned int h, unsigned int vrefresh, unsigned 
int bpc,
+ struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
 
-   if (!h || !w) {
-   dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", 
__func__, w, h);
+   if (!h || !l_w) {
+   dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", 
__func__, l_w, h);
return;
}
 
@@ -112,14 +123,41 @@ void mtk_merge_config(struct device *dev, unsigned int w,
mode = CFG_10_10_2PI_2PO_BUF_MODE;
}
 
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+   if (r_w)
+   mode = CFG_11_10_1PI_2PO_MERGE;
+
+   mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CFG_0);
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+   mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_CFG_1);
+   mtk_ddp_write(cmdq_pkt, h << 16 | (l_w + r_w), &priv->cmdq_reg, 
priv->regs,
  DISP_REG_MERGE_CFG_4);
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+   /*
+* DISP_REG_MERGE_CFG_24 is merge SRAM0 w/h
+* DISP_REG_MERGE_CFG_25 is merge SRAM1 w/h.
+* If r_w > 0, the merge is in merge mode (input0 and input1 merge 
together),
+* the input0 goes to SRAM0, and input1 goes to SRAM1.
+* If r_w = 0, the merge is in buffer mode, the input goes through 
SRAM0 and
+* then to SRAM1. Both SRAM0 and SRAM1 are set to the same size.
+*/
+   mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CFG_24);
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
- DISP_REG_MERGE_CFG_25);
+   if (r_w)
+   mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, 
priv->regs,
+

[PATCH v7 12/20] drm/mediatek: add display MDP RDMA support for MT8195

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

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

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index a38e88e82d12..6e604a933ed0 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_aal.o \
  mtk_drm_gem.o \
  mtk_drm_plane.o \
  mtk_dsi.o \
- mtk_dpi.o
+ mtk_dpi.o \
+ mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index a33b13fe2b6e..b3a372cab0bd 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -8,6 +8,7 @@
 
 #include 
 #include "mtk_drm_plane.h"
+#include "mtk_mdp_rdma.h"
 
 int mtk_aal_clk_enable(struct device *dev);
 void mtk_aal_clk_disable(struct device *dev);
@@ -106,4 +107,10 @@ void mtk_rdma_enable_vblank(struct device *dev,
void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_mdp_rdma_clk_enable(struct device *dev);
+void mtk_mdp_rdma_clk_disable(struct device *dev);
+void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
+struct cmdq_pkt *cmdq_pkt);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c 
b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
new file mode 100644
index ..d7926e43e77e
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_drv.h"
+#include "mtk_mdp_rdma.h"
+
+#define MDP_RDMA_EN0x000
+#define FLD_ROT_ENABLE BIT(0)
+#define MDP_RDMA_RESET 0x008
+#define MDP_RDMA_CON   0x020
+#define FLD_OUTPUT_10B BIT(5)
+#define FLD_SIMPLE_MODEBIT(4)
+#define MDP_RDMA_GMCIF_CON 0x028
+#define FLD_COMMAND_DIVBIT(0)
+#define FLD_EXT_PREULTRA_ENBIT(3)
+#define FLD_RD_REQ_TYPEGENMASK(7, 4)
+#define VAL_RD_REQ_TYPE_BURST_8_ACCESS 7
+#define FLD_ULTRA_EN   GENMASK(13, 12)
+#define VAL_ULTRA_EN_ENABLE1
+#define FLD_PRE_ULTRA_EN   GENMASK(17, 16)
+#define VAL_PRE_ULTRA_EN_ENABLE1
+#define FLD_EXT_ULTRA_EN   BIT(18)
+#define MDP_RDMA_SRC_CON   0x030
+#define FLD_OUTPUT_ARGBBIT(25)
+#define FLD_BIT_NUMBER GENMASK(19, 18)
+#define FLD_SWAP   BIT(14)
+#define FLD_UNIFORM_CONFIG BIT(17)
+#define RDMA_INPUT_10BIT   BIT(18)
+#define FLD_SRC_FORMAT GENMASK(3, 0)
+#define MDP_RDMA_COMP_CON  0x038
+#define FLD_AFBC_ENBIT(22)
+#define FLD_AFBC_YUV_TRANSFORM BIT(21)
+#define FLD_UFBDC_EN   BIT(12)
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE  0x060
+#define FLD_MF_BKGD_WB GENMASK(22, 0)
+#define MDP_RDMA_MF_SRC_SIZE   0x070
+#define FLD_MF_SRC_H   GENMASK(30, 16)
+#define FLD_MF_SRC_W   GENMASK(14, 0)
+#define MDP_RDMA_MF_CLIP_SIZE  0x078
+#define FLD_MF_CLIP_H  GENMASK(30, 16)
+#define FLD_MF_CLIP_W  GENMASK(14, 0)
+#define MDP_RDMA_SRC_OFFSET_0  0x118
+#define FLD_SRC_OFFSET_0   GENMASK(31, 0)
+#define MDP_RDMA_TRANSFORM_0   0x200
+#define FLD_INT_MATRIX_SEL GENMASK(27, 23)
+#define FLD_TRANS_EN   BIT(16)
+#define MDP_RDMA_SRC_BASE_00xf00
+#define FLD_SRC_BASE_0 GENMASK(31, 0)
+
+#define RDMA_CSC_FULL709_TO_RGB5
+#define RDMA_CSC_BT601_TO_RGB  6
+
+enum rdma_format {
+   RDMA_INPUT_FORMAT_RGB565 = 0,
+   RDMA_INPUT_FO

[PATCH v7 17/20] drm/mediatek: add mediatek-drm plane color encoding info

2021-10-29 Thread Nancy . Lin
Add plane color encoding information for color space conversion.
It's a preparation for adding support for mt8195 ovl_adaptor mdp_rdma
csc control.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 1 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c 
b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 734a1fb052df..81bd5d6e8df5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -137,6 +137,7 @@ static void mtk_plane_update_new_state(struct 
drm_plane_state *new_state,
mtk_plane_state->pending.width = drm_rect_width(&new_state->dst);
mtk_plane_state->pending.height = drm_rect_height(&new_state->dst);
mtk_plane_state->pending.rotation = new_state->rotation;
+   mtk_plane_state->pending.color_encoding = new_state->color_encoding;
 }
 
 static void mtk_plane_atomic_async_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h 
b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
index d454bece9535..2d5ec66e3df1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
@@ -24,6 +24,7 @@ struct mtk_plane_pending_state {
booldirty;
boolasync_dirty;
boolasync_config;
+   enum drm_color_encoding color_encoding;
 };
 
 struct mtk_plane_state {
-- 
2.18.0



[PATCH v7 10/20] soc: mediatek: change the mutex defines and the mutex_mod type

2021-10-29 Thread Nancy . Lin
This is a preparation for adding support for mt8195 vdosys1 mutex.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements,
so change it to support multi-bit control.

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

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 36502b27fe20..ff2f74668e8a 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -29,113 +29,113 @@
 
 #define INT_MUTEX  BIT(1)
 
-#define MT8167_MUTEX_MOD_DISP_PWM  1
-#define MT8167_MUTEX_MOD_DISP_OVL0 6
-#define MT8167_MUTEX_MOD_DISP_OVL1 7
-#define MT8167_MUTEX_MOD_DISP_RDMA08
-#define MT8167_MUTEX_MOD_DISP_RDMA19
-#define MT8167_MUTEX_MOD_DISP_WDMA010
-#define MT8167_MUTEX_MOD_DISP_CCORR11
-#define MT8167_MUTEX_MOD_DISP_COLOR12
-#define MT8167_MUTEX_MOD_DISP_AAL  13
-#define MT8167_MUTEX_MOD_DISP_GAMMA14
-#define MT8167_MUTEX_MOD_DISP_DITHER   15
-#define MT8167_MUTEX_MOD_DISP_UFOE 16
-
-#define MT8192_MUTEX_MOD_DISP_OVL0 0
-#define MT8192_MUTEX_MOD_DISP_OVL0_2L  1
-#define MT8192_MUTEX_MOD_DISP_RDMA02
-#define MT8192_MUTEX_MOD_DISP_COLOR0   4
-#define MT8192_MUTEX_MOD_DISP_CCORR0   5
-#define MT8192_MUTEX_MOD_DISP_AAL0 6
-#define MT8192_MUTEX_MOD_DISP_GAMMA0   7
-#define MT8192_MUTEX_MOD_DISP_POSTMASK08
-#define MT8192_MUTEX_MOD_DISP_DITHER0  9
-#define MT8192_MUTEX_MOD_DISP_OVL2_2L  16
-#define MT8192_MUTEX_MOD_DISP_RDMA417
-
-#define MT8183_MUTEX_MOD_DISP_RDMA00
-#define MT8183_MUTEX_MOD_DISP_RDMA11
-#define MT8183_MUTEX_MOD_DISP_OVL0 9
-#define MT8183_MUTEX_MOD_DISP_OVL0_2L  10
-#define MT8183_MUTEX_MOD_DISP_OVL1_2L  11
-#define MT8183_MUTEX_MOD_DISP_WDMA012
-#define MT8183_MUTEX_MOD_DISP_COLOR0   13
-#define MT8183_MUTEX_MOD_DISP_CCORR0   14
-#define MT8183_MUTEX_MOD_DISP_AAL0 15
-#define MT8183_MUTEX_MOD_DISP_GAMMA0   16
-#define MT8183_MUTEX_MOD_DISP_DITHER0  17
-
-#define MT8173_MUTEX_MOD_DISP_OVL0 11
-#define MT8173_MUTEX_MOD_DISP_OVL1 12
-#define MT8173_MUTEX_MOD_DISP_RDMA013
-#define MT8173_MUTEX_MOD_DISP_RDMA114
-#define MT8173_MUTEX_MOD_DISP_RDMA215
-#define MT8173_MUTEX_MOD_DISP_WDMA016
-#define MT8173_MUTEX_MOD_DISP_WDMA117
-#define MT8173_MUTEX_MOD_DISP_COLOR0   18
-#define MT8173_MUTEX_MOD_DISP_COLOR1   19
-#define MT8173_MUTEX_MOD_DISP_AAL  20
-#define MT8173_MUTEX_MOD_DISP_GAMMA21
-#define MT8173_MUTEX_MOD_DISP_UFOE 22
-#define MT8173_MUTEX_MOD_DISP_PWM0 23
-#define MT8173_MUTEX_MOD_DISP_PWM1 24
-#define MT8173_MUTEX_MOD_DISP_OD   25
-
-#define MT8195_MUTEX_MOD_DISP_OVL0 0
-#define MT8195_MUTEX_MOD_DISP_WDMA01
-#define MT8195_MUTEX_MOD_DISP_RDMA02
-#define MT8195_MUTEX_MOD_DISP_COLOR0   3
-#define MT8195_MUTEX_MOD_DISP_CCORR0   4
-#define MT8195_MUTEX_MOD_DISP_AAL0 5
-#define MT8195_MUTEX_MOD_DISP_GAMMA0   6
-#define MT8195_MUTEX_MOD_DISP_DITHER0  7
-#define MT8195_MUTEX_MOD_DISP_DSI0 8
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0  9
-#define MT8195_MUTEX_MOD_DISP_OVL1 10
-#define MT8195_MUTEX_MOD_DISP_WDMA111
-#define MT8195_MUTEX_MOD_DISP_RDMA112
-#define MT8195_MUTEX_MOD_DISP_COLOR1   13
-#define MT8195_MUTEX_MOD_DISP_CCORR1   14
-#define MT8195_MUTEX_MOD_DISP_AAL1 15
-#define MT8195_MUTEX_MOD_DISP_GAMMA1   16
-#define MT8195_MUTEX_MOD_DISP_DITHER1  17
-#define MT8195_MUTEX_MOD_DISP_DSI1 18
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1  19
-#define MT8195_MUTEX_MOD_DISP_VPP_MERGE20
-#define MT8195_MUTEX_MOD_DISP_DP_INTF0 21
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0   22
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1   23
-#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2   24
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3   25
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4   26
-#define MT8195_MUTEX_MOD_DISP_PWM0 27
-#define MT8195_MUTEX_MOD_DISP_PWM1 28
-
-#define MT2712_MUTEX_MOD_DISP_PWM2 10
-#define MT2712_MUTEX_MOD_DISP_OVL0 11
-#define MT2712_MUTEX_MOD_DISP_OVL1 12
-#define MT2712_MUTEX_MOD_DISP_RDMA013
-#define MT2712_MUTEX_MOD_DISP_RDMA114
-#define MT2712_MUTEX_MOD_DISP_RDMA215
-#define MT2712_MUTEX_MOD_DISP_WDMA01

[PATCH v7 18/20] drm/mediatek: add ovl_adaptor support for MT8195

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

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/Makefile |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  16 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 436 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|   1 +
 4 files changed, 454 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index fb158a1e7f06..3abd27d7c91d 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -6,6 +6,7 @@ mediatek-drm-y := mtk_disp_aal.o \
  mtk_disp_gamma.o \
  mtk_disp_merge.o \
  mtk_disp_ovl.o \
+ mtk_disp_ovl_adaptor.o \
  mtk_disp_rdma.o \
  mtk_drm_crtc.o \
  mtk_drm_ddp_comp.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 224a710bb537..cd9827402626 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -112,6 +112,22 @@ void mtk_rdma_enable_vblank(struct device *dev,
void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_ovl_adaptor_clk_enable(struct device *dev);
+void mtk_ovl_adaptor_clk_disable(struct device *dev);
+void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
+   unsigned int h, unsigned int vrefresh,
+   unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *state,
+ struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_enable_vblank(struct device *dev,
+  void (*vblank_cb)(void *),
+  void *vblank_cb_data);
+void mtk_ovl_adaptor_disable_vblank(struct device *dev);
+void mtk_ovl_adaptor_start(struct device *dev);
+void mtk_ovl_adaptor_stop(struct device *dev);
+unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
+
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
 void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
new file mode 100644
index ..148322597fa8
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_ethdr.h"
+
+#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
+#define MTK_OVL_ADAPTOR_LAYER_NUM 4
+
+enum mtk_ovl_adaptor_comp_type {
+   OVL_ADAPTOR_TYPE_RDMA = 0,
+   OVL_ADAPTOR_TYPE_MERGE,
+   OVL_ADAPTOR_TYPE_ETHDR,
+   OVL_ADAPTOR_TYPE_NUM,
+};
+
+enum mtk_ovl_adaptor_comp_id {
+   OVL_ADAPTOR_MDP_RDMA0,
+   OVL_ADAPTOR_MDP_RDMA1,
+   OVL_ADAPTOR_MDP_RDMA2,
+   OVL_ADAPTOR_MDP_RDMA3,
+   OVL_ADAPTOR_MDP_RDMA4,
+   OVL_ADAPTOR_MDP_RDMA5,
+   OVL_ADAPTOR_MDP_RDMA6,
+   OVL_ADAPTOR_MDP_RDMA7,
+   OVL_ADAPTOR_MERGE0,
+   OVL_ADAPTOR_MERGE1,
+   OVL_ADAPTOR_MERGE2,
+   OVL_ADAPTOR_MERGE3,
+   OVL_ADAPTOR_ETHDR0,
+   OVL_ADAPTOR_ID_MAX
+};
+
+struct ovl_adaptor_comp_match {
+   enum mtk_ovl_adaptor_comp_type type;
+   int alias_id;
+};
+
+struct mtk_disp_ovl_adaptor {
+   struct device *ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
+   struct device *mmsys_dev;
+};
+
+static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
+   [OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma",
+   [OVL_ADAPTOR_TYPE_MERGE]= "merge",
+   [OVL_ADAPTOR_TYPE_ETHDR]= "ethdr",
+};
+
+static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
+   [OVL_ADAPTOR_MDP_RDMA0] = { OVL_ADAPTOR_TYPE_RDMA, 0 },
+   [OVL_ADAPTOR_MDP_RDMA1] = { OVL_ADAPTOR_TYPE_RDMA, 1 },
+   [OVL_ADAPTOR_MDP_RDMA2] = { OVL_ADAPTOR_TYPE_RDMA, 2 },
+   [OVL_ADAPTOR_MDP_RDMA3] = { OVL_ADAPTOR_TYPE_RDMA, 3 },
+   [OVL_ADAPTOR_MDP_RDMA4] = { OVL_ADAPTOR_TYPE_RDMA, 4 },
+   [OVL_ADAPTOR_MDP_RDMA5] = { OVL_ADAPTOR_TYPE_RDMA, 5 },
+   [OVL_ADAPTOR_MDP_RDMA6] = { OVL_ADAPTOR_TYPE_RDMA, 6 },
+   [OVL_ADAPTOR_MDP_RDMA7] = { OVL_ADAPTOR_TYPE_RDMA, 7 },
+   [O

  1   2   >