[BUG 5.15-rc3] kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!

2021-10-01 Thread Steven Rostedt
When I tried to test patches applied to v5.15-rc3, I hit this bug (and
hence can not test my code), on 32 bit x86.

[ cut here ]
kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!
invalid opcode:  [#1] SMP PTI
CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc1-test+ #456
Hardware name: MSI MS-7823/CSM-H87M-G43 (MS-7823), BIOS V1.6 02/22/2014
EIP: __i915_sw_fence_init+0x15/0x38
Code: 2b 3d 58 98 88 c1 74 05 e8 60 d9 58 00 8d 65 f4 5b 5e 5f 5d c3 3e
8d 74 26 00 55 89 e5 56 89 d6 53 85 d2 74 05 f6 c2 03 74 02 <0f> 0b 89
ca 8b 4d 08 89 c3 e8 48 94 ab ff 89 73 34 c7 43 38 01 00
EAX: c2508260 EBX: c2508000 ECX: c143de1e EDX: c09dfadd
ESI: c09dfadd EDI: c45e7200 EBP: c26c9c68 ESP: c26c9c60
DS: 007b ES: 007b FS: 00d8 GS:  SS: 0068 EFLAGS: 00010202
CR0: 80050033 CR2:  CR3: 019e2000 CR4: 001506f0
Call Trace:
 intel_context_init+0x112/0x145
 intel_context_create+0x29/0x37
 intel_ring_submission_setup+0x3cb/0x5a8
 ? kfree+0x135/0x1c6
 ? wa_init_finish+0x32/0x59
 ? wa_init_finish+0x4f/0x59
 ? intel_engine_init_ctx_wa+0x39a/0x3b3
 intel_engines_init+0x2dd/0x4d0
 ? gen6_bsd_submit_request+0x97/0x97
 intel_gt_init+0x122/0x20d
 i915_gem_init+0x80/0xef
 i915_driver_probe+0x880/0xa90
 ? i915_pci_remove+0x27/0x27
 i915_pci_probe+0xdd/0xf6
 ? __pm_runtime_resume+0x63/0x6b
 ? i915_pci_remove+0x27/0x27
 pci_device_probe+0xbc/0x11e
 really_probe+0x13e/0x328
 __driver_probe_device+0x140/0x176
 driver_probe_device+0x1f/0x71
 __driver_attach+0xf6/0x109
 ? __device_attach_driver+0xbd/0xbd
 bus_for_each_dev+0x5b/0x88
 driver_attach+0x19/0x1b
 ? __device_attach_driver+0xbd/0xbd
 bus_add_driver+0xf2/0x199
 driver_register+0x8c/0xbe
 __pci_register_driver+0x5b/0x60
 i915_register_pci_driver+0x19/0x1b
 i915_init+0x15/0x67
 ? radeon_module_init+0x6a/0x6a
 do_one_initcall+0xce/0x21c
 ? rcu_read_lock_sched_held+0x35/0x6d
 ? trace_initcall_level+0x5f/0x99
 kernel_init_freeable+0x1fb/0x247
 ? rest_init+0x129/0x129
 kernel_init+0x17/0xfd
 ret_from_fork+0x1c/0x28
Modules linked in:
---[ end trace 791dc89810d853da ]---
EIP: __i915_sw_fence_init+0x15/0x38
Code: 2b 3d 58 98 88 c1 74 05 e8 60 d9 58 00 8d 65 f4 5b 5e 5f 5d c3 3e
8d 74 26 00 55 89 e5 56 89 d6 53 85 d2 74 05 f6 c2 03 74 02 <0f> 0b 89
ca 8b 4d 08 89 c3 e8 48 94 ab ff 89 73 34 c7 43 38 01 00
EAX: c2508260 EBX: c2508000 ECX: c143de1e EDX: c09dfadd
ESI: c09dfadd EDI: c45e7200 EBP: c26c9c68 ESP: c26c9c60
DS: 007b ES: 007b FS: 00d8 GS:  SS: 0068 EFLAGS: 00010202
CR0: 80050033 CR2:  CR3: 019e2000 CR4: 001506f0
Kernel panic - not syncing: Attempted to kill init! exitcode=0x000b
Kernel Offset: disabled
---[ end Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x000b ]---

Attached is the dmesg and the config.

I bisected it down to this commit:

3ffe82d701a4 ("drm/i915/xehp: handle new steering options")

-- Steve


mitest-config.gz
Description: application/gzip


mitest-dmesg.gz
Description: application/gzip


Re: [PATCH] drm/i915: remove IS_ACTIVE

2021-10-01 Thread kernel test robot
Hi Lucas,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on drm-tip/drm-tip drm-exynos/exynos-drm-next 
tegra-drm/drm/tegra/for-next v5.15-rc3 next-20210823]
[cannot apply to airlied/drm-next]
[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/Lucas-De-Marchi/drm-i915-remove-IS_ACTIVE/20211001-154226
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: i386-randconfig-r024-20211001 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
962e503cc8bc411f7523cc393acae8aae425b1c4)
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/50006042f1d264599bd1be1942f9958112e15c01
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Lucas-De-Marchi/drm-i915-remove-IS_ACTIVE/20211001-154226
git checkout 50006042f1d264599bd1be1942f9958112e15c01
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
ARCH=i386 

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/i915/i915_config.c:11:14: error: use of logical '&&' with 
>> constant operand [-Werror,-Wconstant-logical-operand]
   if (context && CONFIG_DRM_I915_FENCE_TIMEOUT)
   ^  ~
   drivers/gpu/drm/i915/i915_config.c:11:14: note: use '&' for a bitwise 
operation
   if (context && CONFIG_DRM_I915_FENCE_TIMEOUT)
   ^~
   &
   drivers/gpu/drm/i915/i915_config.c:11:14: note: remove constant to silence 
this warning
   if (context && CONFIG_DRM_I915_FENCE_TIMEOUT)
  ~^~~~
   1 error generated.


vim +11 drivers/gpu/drm/i915/i915_config.c

 7  
 8  unsigned long
 9  i915_fence_context_timeout(const struct drm_i915_private *i915, u64 
context)
10  {
  > 11  if (context && CONFIG_DRM_I915_FENCE_TIMEOUT)

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


.config.gz
Description: application/gzip


Re: [Intel-gfx] [PATCH v2 00/17] drm: cleanup: Use DRM_MODESET_LOCK_ALL_* helpers where possible

2021-10-01 Thread Ville Syrjälä
On Sat, Oct 02, 2021 at 01:05:47AM +0300, Ville Syrjälä wrote:
> On Fri, Oct 01, 2021 at 04:48:15PM -0400, Sean Paul wrote:
> > On Fri, Oct 01, 2021 at 10:00:50PM +0300, Ville Syrjälä wrote:
> > > On Fri, Oct 01, 2021 at 02:36:55PM -0400, Sean Paul wrote:
> > > > On Fri, Sep 24, 2021 at 08:43:07AM +0200, Fernando Ramos wrote:
> > > > > Hi all,
> > > > > 
> > > > > One of the things in the DRM TODO list ("Documentation/gpu/todo.rst") 
> > > > > was to
> > > > > "use DRM_MODESET_LOCAL_ALL_* helpers instead of boilerplate". That's 
> > > > > what this
> > > > > patch series is about.
> > > > > 
> > > > > You will find two types of changes here:
> > > > > 
> > > > >   - Replacing "drm_modeset_lock_all_ctx()" (and surrounding 
> > > > > boilerplate) with
> > > > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()" in the remaining places (as 
> > > > > it has
> > > > > already been done in previous commits such as b7ea04d2)
> > > > > 
> > > > >   - Replacing "drm_modeset_lock_all()" with 
> > > > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()"
> > > > > in the remaining places (as it has already been done in previous 
> > > > > commits
> > > > > such as 57037094)
> > > > > 
> > > > > Most of the changes are straight forward, except for a few cases in 
> > > > > the "amd"
> > > > > and "i915" drivers where some extra dancing was needed to overcome the
> > > > > limitation that the DRM_MODESET_LOCK_ALL_BEGIN()/END() macros can 
> > > > > only be used
> > > > > once inside the same function (the reason being that the macro 
> > > > > expansion
> > > > > includes *labels*, and you can not have two labels named the same 
> > > > > inside one
> > > > > function)
> > > > > 
> > > > > Notice that, even after this patch series, some places remain where
> > > > > "drm_modeset_lock_all()" and "drm_modeset_lock_all_ctx()" are still 
> > > > > present,
> > > > > all inside drm core (which makes sense), except for two (in "amd" and 
> > > > > "i915")
> > > > > which cannot be replaced due to the way they are being used.
> > > > > 
> > > > > Changes in v2:
> > > > > 
> > > > >   - Fix commit message typo
> > > > >   - Use the value returned by DRM_MODESET_LOCK_ALL_END when possible
> > > > >   - Split drm/i915 patch into two simpler ones
> > > > >   - Remove drm_modeset_(un)lock_all()
> > > > >   - Fix build problems in non-x86 platforms
> > > > > 
> > > > > Fernando Ramos (17):
> > > > >   drm: cleanup: drm_modeset_lock_all_ctx() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/i915: cleanup: drm_modeset_lock_all_ctx() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/msm: cleanup: drm_modeset_lock_all_ctx() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN() drm/vmwgfx: cleanup: 
> > > > > drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/tegra: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/shmobile: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/radeon: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/omapdrm: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/nouveau: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/msm: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/i915: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/i915: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN() part 2
> > > > >   drm/gma500: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm/amd: cleanup: drm_modeset_lock_all() --> 
> > > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > > >   drm: cleanup: remove drm_modeset_(un)lock_all()
> > > > >   doc: drm: remove TODO entry regarding DRM_MODSET_LOCK_ALL cleanup
> > > > > 
> > > > 
> > > > Thank you for revising, Fernando! I've pushed the set to drm-misc-next 
> > > > (along
> > > > with the necessary drm-tip conflict resolutions).
> > > 
> > > Ugh. Did anyone actually review the locking changes this does?
> > > I shot the previous i915 stuff down because the commit messages
> > > did not address any of it.
> > 
> > I reviewed the set on 9/17, I didn't see your feedback on that thread.
> 
> It was much earlir than that.
> https://lists.freedesktop.org/archives/dri-devel/2021-June/313193.html
> 
> And I think I might have also shot down a similar thing earlier.
> 
> I was actually half considering sending a patch to nuke that
> misleading TODO item. I don't think anything which changes
> which locks are taken should be considred a starter level task.
> And the commit messages here don't seem to address any of it.

And i915 is now broken :(

https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10680/fi-bwr-2160/boot.html

-- 
Ville

Re: [Freedreno] [PATCH v3] drm/msm/dsi: do not enable irq handler before powering up the host

2021-10-01 Thread abhinavk

On 2021-10-01 18:08, Dmitry Baryshkov wrote:

The DSI host might be left in some state by the bootloader. If this
state generates an IRQ, it might hang the system by holding the
interrupt line before the driver sets up the DSI host to the known
state.

Move the request_irq into msm_dsi_host_init and pass IRQF_NO_AUTOEN to
it. Call enable/disable_irq after msm_dsi_host_power_on/_off()
functions, so that we can be sure that the interrupt is delivered when
the host is in the known state.

It is not possible to defer the interrupt enablement to a later point,
because drm_panel_prepare might need to communicate with the panel over
the DSI link and that requires working interrupt.

Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/dsi/dsi.h |  2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c| 48 +--
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 16 +
 3 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h 
b/drivers/gpu/drm/msm/dsi/dsi.h

index b50db91cb8a7..569c8ff062ba 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -107,6 +107,8 @@ void msm_dsi_host_cmd_xfer_commit(struct
mipi_dsi_host *host,
u32 dma_base, u32 len);
 int msm_dsi_host_enable(struct mipi_dsi_host *host);
 int msm_dsi_host_disable(struct mipi_dsi_host *host);
+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host);
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host);
 int msm_dsi_host_power_on(struct mipi_dsi_host *host,
struct msm_dsi_phy_shared_timings *phy_shared_timings,
bool is_bonded_dsi, struct msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..ce26eb78cb6c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1898,6 +1898,23 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
return ret;
}

+   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+   if (msm_host->irq < 0) {
+   ret = msm_host->irq;
+   dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
+   return ret;
+   }
+
+   /* do not autoenable, will be enabled later */
+   ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+   "dsi_isr", msm_host);
+   if (ret < 0) {
+   dev_err(&pdev->dev, "failed to request IRQ%u: %d\n",
+   msm_host->irq, ret);
+   return ret;
+   }
+
init_completion(&msm_host->dma_comp);
init_completion(&msm_host->video_comp);
mutex_init(&msm_host->dev_mutex);
@@ -1941,25 +1958,8 @@ int msm_dsi_host_modeset_init(struct 
mipi_dsi_host *host,

 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-   struct platform_device *pdev = msm_host->pdev;
int ret;

-   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
-   if (msm_host->irq < 0) {
-   ret = msm_host->irq;
-   DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret);
-   return ret;
-   }
-
-   ret = devm_request_irq(&pdev->dev, msm_host->irq,
-   dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-   "dsi_isr", msm_host);
-   if (ret < 0) {
-   DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n",
-   msm_host->irq, ret);
-   return ret;
-   }
-
msm_host->dev = dev;
ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
if (ret) {
@@ -2315,6 +2315,20 @@ void msm_dsi_host_get_phy_clk_req(struct
mipi_dsi_host *host,
clk_req->escclk_rate = msm_host->esc_clk_rate;
 }

+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   enable_irq(msm_host->irq);
+}
+
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   disable_irq(msm_host->irq);
+}
+
 int msm_dsi_host_enable(struct mipi_dsi_host *host)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index c41d39f5b7cf..fb4ccffdcfe1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -377,6 +377,14 @@ static void dsi_mgr_bridge_pre_enable(struct
drm_bridge *bridge)
}
}

+   /*
+* Enable before preparing the panel, disable after unpreparing, so
+* that th

[PATCH] drm/msm/dsi: use bulk clk API

2021-10-01 Thread Dmitry Baryshkov
Use clk_bulk_* API instead of hand-coding them. Note, this drops support
for legacy clk naming (e.g. "iface_clk" instead of just "iface"),
however all in-kernel device trees were converted long long ago. The
warning is present there since 2017.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 59 ++
 1 file changed, 12 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..3b81f40bba2e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -106,7 +106,8 @@ struct msm_dsi_host {
phys_addr_t ctrl_size;
struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX];
 
-   struct clk *bus_clks[DSI_BUS_CLK_MAX];
+   int num_bus_clks;
+   struct clk_bulk_data bus_clks[DSI_BUS_CLK_MAX];
 
struct clk *byte_clk;
struct clk *esc_clk;
@@ -374,15 +375,14 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host)
int i, ret = 0;
 
/* get bus clocks */
-   for (i = 0; i < cfg->num_bus_clks; i++) {
-   msm_host->bus_clks[i] = msm_clk_get(pdev,
-   cfg->bus_clk_names[i]);
-   if (IS_ERR(msm_host->bus_clks[i])) {
-   ret = PTR_ERR(msm_host->bus_clks[i]);
-   pr_err("%s: Unable to get %s clock, ret = %d\n",
-   __func__, cfg->bus_clk_names[i], ret);
-   goto exit;
-   }
+   for (i = 0; i < cfg->num_bus_clks; i++)
+   msm_host->bus_clks[i].id = cfg->bus_clk_names[i];
+   msm_host->num_bus_clks = cfg->num_bus_clks;
+
+   ret = devm_clk_bulk_get(&pdev->dev, msm_host->num_bus_clks, 
msm_host->bus_clks);
+   if (ret < 0) {
+   dev_err(&pdev->dev, "Unable to get clocks, ret = %d\n", ret);
+   goto exit;
}
 
/* get link and source clocks */
@@ -433,41 +433,6 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host)
return ret;
 }
 
-static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host)
-{
-   const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
-   int i, ret;
-
-   DBG("id=%d", msm_host->id);
-
-   for (i = 0; i < cfg->num_bus_clks; i++) {
-   ret = clk_prepare_enable(msm_host->bus_clks[i]);
-   if (ret) {
-   pr_err("%s: failed to enable bus clock %d ret %d\n",
-   __func__, i, ret);
-   goto err;
-   }
-   }
-
-   return 0;
-err:
-   for (; i > 0; i--)
-   clk_disable_unprepare(msm_host->bus_clks[i]);
-
-   return ret;
-}
-
-static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host)
-{
-   const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
-   int i;
-
-   DBG("");
-
-   for (i = cfg->num_bus_clks - 1; i >= 0; i--)
-   clk_disable_unprepare(msm_host->bus_clks[i]);
-}
-
 int msm_dsi_runtime_suspend(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
@@ -478,7 +443,7 @@ int msm_dsi_runtime_suspend(struct device *dev)
if (!msm_host->cfg_hnd)
return 0;
 
-   dsi_bus_clk_disable(msm_host);
+   clk_bulk_disable_unprepare(msm_host->num_bus_clks, msm_host->bus_clks);
 
return 0;
 }
@@ -493,7 +458,7 @@ int msm_dsi_runtime_resume(struct device *dev)
if (!msm_host->cfg_hnd)
return 0;
 
-   return dsi_bus_clk_enable(msm_host);
+   return clk_bulk_prepare_enable(msm_host->num_bus_clks, 
msm_host->bus_clks);
 }
 
 int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
-- 
2.33.0



Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-10-01 Thread Dmitry Baryshkov

On 28/09/2021 04:40, Dmitry Baryshkov wrote:

On 28/09/2021 04:33, abhin...@codeaurora.org wrote:

On 2021-09-27 18:29, Dmitry Baryshkov wrote:

On 28/09/2021 04:19, abhin...@codeaurora.org wrote:

On 2021-09-27 18:06, Dmitry Baryshkov wrote:

On Tue, 28 Sept 2021 at 03:22,  wrote:


On 2021-09-25 12:43, Dmitry Baryshkov wrote:
> On 21/09/2021 23:52, abhin...@codeaurora.org wrote:
>> On 2021-09-21 10:47, Dmitry Baryshkov wrote:
>>> Hi,
>>>
>>> On Tue, 21 Sept 2021 at 20:01,  wrote:

 On 2021-09-21 09:22, Dmitry Baryshkov wrote:
 > The DSI host might be left in some state by the bootloader. 
If this
 > state generates an IRQ, it might hang the system by holding 
the
 > interrupt line before the driver sets up the DSI host to 
the known

 > state.
 >
 > Move the request/free_irq calls into 
msm_dsi_host_power_on/_off calls,
 > so that we can be sure that the interrupt is delivered when 
the host is

 > in the known state.
 >
 > Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector 
support")

 > Signed-off-by: Dmitry Baryshkov 

 This is a valid change and we have seen interrupt storms in
 downstream
 happening
 when like you said the bootloader leaves the DSI host in unknown
 state.
 Just one question below.

 > ---
 >  drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
 >  1 file changed, 12 insertions(+), 9 deletions(-)
 >
 > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
 > b/drivers/gpu/drm/msm/dsi/dsi_host.c
 > index e269df285136..cd842347a6b1 100644
 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
 > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
 > @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct
 > mipi_dsi_host *host,
 >   return ret;
 >   }
 >
 > - ret = devm_request_irq(&pdev->dev, msm_host->irq,
 > - dsi_host_irq, IRQF_TRIGGER_HIGH | 
IRQF_ONESHOT,

 > - "dsi_isr", msm_host);
 > - if (ret < 0) {
 > - DRM_DEV_ERROR(&pdev->dev, "failed to request 
IRQ%u: %d\n",

 > - msm_host->irq, ret);
 > - return ret;
 > - }
 > -
 >   msm_host->dev = dev;
 >   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
 >   if (ret) {
 > @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct 
mipi_dsi_host

 > *host,
 >   if (msm_host->disp_en_gpio)
 >   gpiod_set_value(msm_host->disp_en_gpio, 1);
 >
 > + ret = devm_request_irq(&msm_host->pdev->dev, 
msm_host->irq,
 > + dsi_host_irq, IRQF_TRIGGER_HIGH | 
IRQF_ONESHOT,

 > + "dsi_isr", msm_host);
 > + if (ret < 0) {
 > + DRM_DEV_ERROR(&msm_host->pdev->dev, "failed 
to request IRQ%u: %d\n",

 > + msm_host->irq, ret);
 > + return ret;
 > + }
 > +
 > +

 Do you want to move this to msm_dsi_host_enable()?
 So without the controller being enabled it is still in unknown
 state?
>>>
>>> msm_dsi_host_power_on() reconfigures the host registers, so 
the state

>>> is known at the end of the power_on().
>>>
 Also do you want to do this after dsi0 and dsi1 are 
initialized to

 account for
 dual dsi cases?
>>>
>>> I don't think this should matter. The host won't generate 'extra'
>>> interrupts in such case, will it?
>>>
>> We have seen cases where misconfiguration has caused interrupts to
>> storm only
>> on one DSI in some cases. So yes, I would prefer this is done 
after

>> both are
>> configured.
>
> I've checked. The power_on is called from 
dsi_mgr_bridge_pre_enable()

> when both DSI hosts should be bound.

DSI being bound is enough? I thought the issue we are trying to 
address

is that
we need to have called msm_dsi_host_power_on() for both the hosts so
that both are
put in the known state before requesting the irq.

OR in other words move the irq_enable() to below location.

341 static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
342 {

364 ret = msm_dsi_host_power_on(host, &phy_shared_timings[id],
is_bonded_dsi, msm_dsi->phy);
365 if (ret) {
366 pr_err("%s: power on host %d failed, %d\n", 
__func__, id, ret);

367 goto host_on_fail;
368 }
369
370 if (is_bonded_dsi && msm_dsi1) {
371 ret = msm_dsi_host_power_on(msm_dsi1->host,
372 &phy_shared_timings[DSI_1], 
is_bonded_dsi, msm_dsi1->phy);

373 if (ret) {
374 pr_err("%s: power on host1 failed, %d\n",
375 __func__, 
ret);

376 goto host1_on_fail;
377 }
378 }

< move the irq enable here >
**


Ah, I see your point. Wha

Re: [PATCH 1/3] mfd: qcom-pm8xxx: switch away from using chained IRQ handlers

2021-10-01 Thread Dmitry Baryshkov

On 02/10/2021 04:08, Dmitry Baryshkov wrote:

PM8xxx PMIC family uses GPIO as parent IRQ. Using it together with the
irq_set_chained_handler_and_data() results in warnings from the GPIOLIB
as in this path the IRQ resources are not allocated (and thus the
corresponding GPIO is not marked as used for the IRQ. Use request_irq so
that the IRQ resources are proprely setup.

Signed-off-by: Dmitry Baryshkov 


Please ignore this duplicate, it was sent by mistake.


--
With best wishes
Dmitry


[PATCH v3] drm/msm/dsi: do not enable irq handler before powering up the host

2021-10-01 Thread Dmitry Baryshkov
The DSI host might be left in some state by the bootloader. If this
state generates an IRQ, it might hang the system by holding the
interrupt line before the driver sets up the DSI host to the known
state.

Move the request_irq into msm_dsi_host_init and pass IRQF_NO_AUTOEN to
it. Call enable/disable_irq after msm_dsi_host_power_on/_off()
functions, so that we can be sure that the interrupt is delivered when
the host is in the known state.

It is not possible to defer the interrupt enablement to a later point,
because drm_panel_prepare might need to communicate with the panel over
the DSI link and that requires working interrupt.

Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/dsi.h |  2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c| 48 +--
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 16 +
 3 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index b50db91cb8a7..569c8ff062ba 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -107,6 +107,8 @@ void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host 
*host,
u32 dma_base, u32 len);
 int msm_dsi_host_enable(struct mipi_dsi_host *host);
 int msm_dsi_host_disable(struct mipi_dsi_host *host);
+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host);
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host);
 int msm_dsi_host_power_on(struct mipi_dsi_host *host,
struct msm_dsi_phy_shared_timings *phy_shared_timings,
bool is_bonded_dsi, struct msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..ce26eb78cb6c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1898,6 +1898,23 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
return ret;
}
 
+   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+   if (msm_host->irq < 0) {
+   ret = msm_host->irq;
+   dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
+   return ret;
+   }
+
+   /* do not autoenable, will be enabled later */
+   ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+   "dsi_isr", msm_host);
+   if (ret < 0) {
+   dev_err(&pdev->dev, "failed to request IRQ%u: %d\n",
+   msm_host->irq, ret);
+   return ret;
+   }
+
init_completion(&msm_host->dma_comp);
init_completion(&msm_host->video_comp);
mutex_init(&msm_host->dev_mutex);
@@ -1941,25 +1958,8 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-   struct platform_device *pdev = msm_host->pdev;
int ret;
 
-   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
-   if (msm_host->irq < 0) {
-   ret = msm_host->irq;
-   DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret);
-   return ret;
-   }
-
-   ret = devm_request_irq(&pdev->dev, msm_host->irq,
-   dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-   "dsi_isr", msm_host);
-   if (ret < 0) {
-   DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n",
-   msm_host->irq, ret);
-   return ret;
-   }
-
msm_host->dev = dev;
ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
if (ret) {
@@ -2315,6 +2315,20 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host 
*host,
clk_req->escclk_rate = msm_host->esc_clk_rate;
 }
 
+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   enable_irq(msm_host->irq);
+}
+
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   disable_irq(msm_host->irq);
+}
+
 int msm_dsi_host_enable(struct mipi_dsi_host *host)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index c41d39f5b7cf..fb4ccffdcfe1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -377,6 +377,14 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge 
*bridge)
}
}
 
+   /*
+* Enable before preparing the panel, disable after unpreparing, so
+* that the panel can communicate over the DSI link.
+*/
+   msm_dsi_h

[PATCH 1/3] mfd: qcom-pm8xxx: switch away from using chained IRQ handlers

2021-10-01 Thread Dmitry Baryshkov
PM8xxx PMIC family uses GPIO as parent IRQ. Using it together with the
irq_set_chained_handler_and_data() results in warnings from the GPIOLIB
as in this path the IRQ resources are not allocated (and thus the
corresponding GPIO is not marked as used for the IRQ. Use request_irq so
that the IRQ resources are proprely setup.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/mfd/qcom-pm8xxx.c | 39 ---
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/drivers/mfd/qcom-pm8xxx.c b/drivers/mfd/qcom-pm8xxx.c
index ec18a04de355..2f2734ba5273 100644
--- a/drivers/mfd/qcom-pm8xxx.c
+++ b/drivers/mfd/qcom-pm8xxx.c
@@ -65,7 +65,7 @@
 struct pm_irq_data {
int num_irqs;
struct irq_chip *irq_chip;
-   void (*irq_handler)(struct irq_desc *desc);
+   irq_handler_t irq_handler;
 };
 
 struct pm_irq_chip {
@@ -169,19 +169,16 @@ static int pm8xxx_irq_master_handler(struct pm_irq_chip 
*chip, int master)
return ret;
 }
 
-static void pm8xxx_irq_handler(struct irq_desc *desc)
+static irqreturn_t pm8xxx_irq_handler(int irq, void *data)
 {
-   struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
-   struct irq_chip *irq_chip = irq_desc_get_chip(desc);
+   struct pm_irq_chip *chip = data;
unsigned int root;
int i, ret, masters = 0;
 
-   chained_irq_enter(irq_chip, desc);
-
ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root);
if (ret) {
pr_err("Can't read root status ret=%d\n", ret);
-   return;
+   return IRQ_NONE;
}
 
/* on pm8xxx series masters start from bit 1 of the root */
@@ -192,7 +189,7 @@ static void pm8xxx_irq_handler(struct irq_desc *desc)
if (masters & (1 << i))
pm8xxx_irq_master_handler(chip, i);
 
-   chained_irq_exit(irq_chip, desc);
+   return IRQ_HANDLED;
 }
 
 static void pm8821_irq_block_handler(struct pm_irq_chip *chip,
@@ -230,19 +227,17 @@ static inline void pm8821_irq_master_handler(struct 
pm_irq_chip *chip,
pm8821_irq_block_handler(chip, master, block);
 }
 
-static void pm8821_irq_handler(struct irq_desc *desc)
+static irqreturn_t pm8821_irq_handler(int irq, void *data)
 {
-   struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
-   struct irq_chip *irq_chip = irq_desc_get_chip(desc);
+   struct pm_irq_chip *chip = data;
unsigned int master;
int ret;
 
-   chained_irq_enter(irq_chip, desc);
ret = regmap_read(chip->regmap,
  PM8821_SSBI_REG_ADDR_IRQ_MASTER0, &master);
if (ret) {
pr_err("Failed to read master 0 ret=%d\n", ret);
-   goto done;
+   return IRQ_NONE;
}
 
/* bits 1 through 7 marks the first 7 blocks in master 0 */
@@ -251,19 +246,18 @@ static void pm8821_irq_handler(struct irq_desc *desc)
 
/* bit 0 marks if master 1 contains any bits */
if (!(master & BIT(0)))
-   goto done;
+   return IRQ_NONE;
 
ret = regmap_read(chip->regmap,
  PM8821_SSBI_REG_ADDR_IRQ_MASTER1, &master);
if (ret) {
pr_err("Failed to read master 1 ret=%d\n", ret);
-   goto done;
+   return IRQ_NONE;
}
 
pm8821_irq_master_handler(chip, 1, master);
 
-done:
-   chained_irq_exit(irq_chip, desc);
+   return IRQ_HANDLED;
 }
 
 static void pm8xxx_irq_mask_ack(struct irq_data *d)
@@ -574,14 +568,15 @@ static int pm8xxx_probe(struct platform_device *pdev)
if (!chip->irqdomain)
return -ENODEV;
 
-   irq_set_chained_handler_and_data(irq, data->irq_handler, chip);
+   rc = devm_request_irq(&pdev->dev, irq, data->irq_handler, 0, 
dev_name(&pdev->dev), chip);
+   if (rc)
+   return rc;
+
irq_set_irq_wake(irq, 1);
 
rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-   if (rc) {
-   irq_set_chained_handler_and_data(irq, NULL, NULL);
+   if (rc)
irq_domain_remove(chip->irqdomain);
-   }
 
return rc;
 }
@@ -594,11 +589,9 @@ static int pm8xxx_remove_child(struct device *dev, void 
*unused)
 
 static int pm8xxx_remove(struct platform_device *pdev)
 {
-   int irq = platform_get_irq(pdev, 0);
struct pm_irq_chip *chip = platform_get_drvdata(pdev);
 
device_for_each_child(&pdev->dev, NULL, pm8xxx_remove_child);
-   irq_set_chained_handler_and_data(irq, NULL, NULL);
irq_domain_remove(chip->irqdomain);
 
return 0;
-- 
2.33.0



Re: [PATCH 3/3] drm/msm/dsi: fix signedness bug in msm_dsi_host_cmd_rx()

2021-10-01 Thread Dmitry Baryshkov

On 01/10/2021 15:36, Dan Carpenter wrote:

The "msg->tx_len" variable is type size_t so if dsi_cmds2buf_tx()
returns a negative error code that it type promoted to a high positive
value and treat as a success.  The second problem with this code is
that it can return meaningless positive values on error.


It looks to me that this piece of code is not fully correct at all.
dsi_cmds2bus_tx would return the size of DSI packet, not the size of the 
DSI buffer.


Could you please be more specific, which 'meaningless positive values' 
were you receiving?




Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Signed-off-by: Dan Carpenter 
---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index c86b5090fae6..42073a562072 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2133,8 +2133,10 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
}
  
  		ret = dsi_cmds2buf_tx(msm_host, msg);

-   if (ret < msg->tx_len) {
+   if (ret < 0 || ret < msg->tx_len) {
pr_err("%s: Read cmd Tx failed, %d\n", __func__, ret);
+   if (ret >= 0)
+   ret = -EIO;
return ret;
}
  




--
With best wishes
Dmitry


[PATCH v2 4/4] drm/i915: Clarify probing order in intel_dp_aux_init_backlight_funcs()

2021-10-01 Thread Lyude Paul
Hooray! We've managed to hit enough bugs upstream that I've been able to
come up with a pretty solid explanation for how backlight controls are
actually supposed to be detected and used these days. As well, having the
rest of the PWM bits in VESA's backlight interface implemented seems to
have fixed all of the problematic brightness controls laptop panels that
we've hit so far.

So, let's actually document this instead of just calling the laptop panels
liars. As well, I would like to formally apologize to all of the laptop
panels I called liars. I'm sorry laptop panels, hopefully you can all
forgive me and we can move past this~

Signed-off-by: Lyude Paul 
---
 .../drm/i915/display/intel_dp_aux_backlight.c| 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 91daf9ab50e8..04a52d6a74ed 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -455,11 +455,17 @@ int intel_dp_aux_init_backlight_funcs(struct 
intel_connector *connector)
}
 
/*
-* A lot of eDP panels in the wild will report supporting both the
-* Intel proprietary backlight control interface, and the VESA
-* backlight control interface. Many of these panels are liars though,
-* and will only work with the Intel interface. So, always probe for
-* that first.
+* Since Intel has their own backlight control interface, the majority 
of machines out there
+* using DPCD backlight controls with Intel GPUs will be using this 
interface as opposed to
+* the VESA interface. However, other GPUs (such as Nvidia's) will 
always use the VESA
+* interface. This means that there's quite a number of panels out 
there that will advertise
+* support for both interfaces, primarily systems with Intel/Nvidia 
hybrid GPU setups.
+*
+* There's a catch to this though: on many panels that advertise 
support for both
+* interfaces, the VESA backlight interface will stop working once 
we've programmed the
+* panel with Intel's OUI - which is also required for us to be able to 
detect Intel's
+* backlight interface at all. This means that the only sensible way 
for us to detect both
+* interfaces is to probe for Intel's first, and VESA's second.
 */
if (try_intel_interface && 
intel_dp_aux_supports_hdr_backlight(connector)) {
drm_dbg_kms(dev, "Using Intel proprietary eDP backlight 
controls\n");
-- 
2.31.1



[PATCH v2 3/4] drm/dp, drm/i915: Add support for VESA backlights using PWM for brightness control

2021-10-01 Thread Lyude Paul
Now that we've added support to i915 for controlling panel backlights that
need PWM to be enabled/disabled, let's finalize this and add support for
controlling brightness levels via PWM as well. This should hopefully put us
towards the path of supporting _ALL_ backlights via VESA's DPCD interface
which would allow us to finally start trusting the DPCD again.

Note however that we still don't enable using this by default on i915 when
it's not needed, primarily because I haven't yet had a chance to confirm if
it's safe to do this on the one machine in Intel's CI that had an issue
with this: samus-fi-bdw. I have done basic testing of this on other
machines though, by manually patching i915 to force it into PWM-only mode
on some of my laptops.

v2:
* Correct documentation (thanks Doug!)
* Get rid of backlight caps

Signed-off-by: Lyude Paul 
Cc: Rajeev Nandan 
Cc: Doug Anderson 
Cc: Satadru Pramanik 
---
 drivers/gpu/drm/drm_dp_helper.c   | 75 +--
 .../drm/i915/display/intel_dp_aux_backlight.c | 48 +---
 include/drm/drm_dp_helper.h   |  7 +-
 3 files changed, 93 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 4d0d1e8e51fa..f350e17a80e7 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -3173,6 +3173,10 @@ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, 
const struct drm_edp_bac
int ret;
u8 buf[2] = { 0 };
 
+   /* The panel uses the PWM for controlling brightness levels */
+   if (!bl->aux_set)
+   return 0;
+
if (bl->lsb_reg_used) {
buf[0] = (level & 0xff00) >> 8;
buf[1] = (level & 0x00ff);
@@ -3199,7 +3203,7 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, 
const struct drm_edp_backli
int ret;
u8 buf;
 
-   /* The panel uses something other then DPCD for enabling its backlight 
*/
+   /* This panel uses the EDP_BL_PWR GPIO for enablement */
if (!bl->aux_enable)
return 0;
 
@@ -3234,11 +3238,11 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, 
const struct drm_edp_backli
  * restoring any important backlight state such as the given backlight level, 
the brightness byte
  * count, backlight frequency, etc.
  *
- * Note that certain panels, while supporting brightness level controls over 
DPCD, may not support
- * having their backlights enabled via the standard 
%DP_EDP_DISPLAY_CONTROL_REGISTER. On such panels
- * &drm_edp_backlight_info.aux_enable will be set to %false, this function 
will skip the step of
- * programming the %DP_EDP_DISPLAY_CONTROL_REGISTER, and the driver must 
perform the required
- * implementation specific step for enabling the backlight after calling this 
function.
+ * Note that certain panels do not support being enabled or disabled via DPCD, 
but instead require
+ * that the driver handle enabling/disabling the panel through 
implementation-specific means using
+ * the EDP_BL_PWR GPIO. For such panels, &drm_edp_backlight_info.aux_enable 
will be set to %false,
+ * this function becomes a no-op, and the driver is expected to handle 
powering the panel on using
+ * the EDP_BL_PWR GPIO.
  *
  * Returns: %0 on success, negative error code on failure.
  */
@@ -3246,7 +3250,7 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, 
const struct drm_edp_backli
 const u16 level)
 {
int ret;
-   u8 dpcd_buf, new_dpcd_buf;
+   u8 dpcd_buf, new_dpcd_buf, new_mode;
 
ret = drm_dp_dpcd_readb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, 
&dpcd_buf);
if (ret != 1) {
@@ -3256,10 +3260,14 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, 
const struct drm_edp_backli
}
 
new_dpcd_buf = dpcd_buf;
+   if (bl->aux_set)
+   new_mode = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
+   else
+   new_mode = DP_EDP_BACKLIGHT_CONTROL_MODE_PWM;
 
-   if ((dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) != 
DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
+   if ((dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) != new_mode) {
new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
-   new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
+   new_dpcd_buf |= new_mode;
 
if (bl->pwmgen_bit_count) {
ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, 
bl->pwmgen_bit_count);
@@ -3304,12 +3312,13 @@ EXPORT_SYMBOL(drm_edp_backlight_enable);
  * @aux: The DP AUX channel to use
  * @bl: Backlight capability info from drm_edp_backlight_init()
  *
- * This function handles disabling DPCD backlight controls on a panel over 
AUX. Note that some
- * panels have backlights that are enabled/disabled by other means, despite 
having their brightness
- * values controlled through DPCD. On such panels 
&drm_edp_backlight_info.aux_enable will be set to
- * %false, th

[PATCH v2 1/4] drm/i915: Add support for panels with VESA backlights with PWM enable/disable

2021-10-01 Thread Lyude Paul
This simply adds proper support for panel backlights that can be controlled
via VESA's backlight control protocol, but which also require that we
enable and disable the backlight via PWM instead of via the DPCD interface.
We also enable this by default, in order to fix some people's backlights
that were broken by not having this enabled.

For reference, backlights that require this and use VESA's backlight
interface tend to be laptops with hybrid GPUs, but this very well may
change in the future.

Signed-off-by: Lyude Paul 
Link: https://gitlab.freedesktop.org/drm/intel/-/issues/3680
Fixes: fe7d52bccab6 ("drm/i915/dp: Don't use DPCD backlights that need PWM 
enable/disable")
Cc:  # v5.12+
---
 .../drm/i915/display/intel_dp_aux_backlight.c | 24 ++-
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 569d17b4d00f..594fdc7453ca 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -293,6 +293,10 @@ intel_dp_aux_vesa_enable_backlight(const struct 
intel_crtc_state *crtc_state,
struct intel_panel *panel = &connector->panel;
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
 
+   if (!panel->backlight.edp.vesa.info.aux_enable)
+   panel->backlight.pwm_funcs->enable(crtc_state, conn_state,
+  
panel->backlight.pwm_level_max);
+
drm_edp_backlight_enable(&intel_dp->aux, 
&panel->backlight.edp.vesa.info, level);
 }
 
@@ -304,6 +308,10 @@ static void intel_dp_aux_vesa_disable_backlight(const 
struct drm_connector_state
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
 
drm_edp_backlight_disable(&intel_dp->aux, 
&panel->backlight.edp.vesa.info);
+
+   if (!panel->backlight.edp.vesa.info.aux_enable)
+   panel->backlight.pwm_funcs->disable(old_conn_state,
+   
intel_backlight_invert_pwm_level(connector, 0));
 }
 
 static int intel_dp_aux_vesa_setup_backlight(struct intel_connector 
*connector, enum pipe pipe)
@@ -321,6 +329,15 @@ static int intel_dp_aux_vesa_setup_backlight(struct 
intel_connector *connector,
if (ret < 0)
return ret;
 
+   if (!panel->backlight.edp.vesa.info.aux_enable) {
+   ret = panel->backlight.pwm_funcs->setup(connector, pipe);
+   if (ret < 0) {
+   drm_err(&i915->drm,
+   "Failed to setup PWM backlight controls for eDP 
backlight: %d\n",
+   ret);
+   return ret;
+   }
+   }
panel->backlight.max = panel->backlight.edp.vesa.info.max;
panel->backlight.min = 0;
if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
@@ -340,12 +357,7 @@ intel_dp_aux_supports_vesa_backlight(struct 
intel_connector *connector)
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 
-   /* TODO: We currently only support AUX only backlight configurations, 
not backlights which
-* require a mix of PWM and AUX controls to work. In the mean time, 
these machines typically
-* work just fine using normal PWM controls anyway.
-*/
-   if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
-   drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
+   if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
return true;
}
-- 
2.31.1



[PATCH v2 2/4] drm/nouveau/kms/nv50-: Explicitly check DPCD backlights for aux enable/brightness

2021-10-01 Thread Lyude Paul
Since we don't support hybrid AUX/PWM backlights in nouveau right now,
let's add some explicit checks so that we don't break nouveau once we
enable support for these backlights in other drivers.

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nouveau_backlight.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index 1cbd71abc80a..ae2f2abc8f5a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -308,7 +308,10 @@ nv50_backlight_init(struct nouveau_backlight *bl,
if (ret < 0)
return ret;
 
-   if (drm_edp_backlight_supported(edp_dpcd)) {
+   /* TODO: Add support for hybrid PWM/DPCD panels */
+   if (drm_edp_backlight_supported(edp_dpcd) &&
+   (edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
+   (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) {
NV_DEBUG(drm, "DPCD backlight controls supported on 
%s\n",
 nv_conn->base.name);
 
-- 
2.31.1



[PATCH v2 0/4] drm/dp, drm/i915: Finish basic PWM support for VESA backlight helpers

2021-10-01 Thread Lyude Paul
When I originally moved all of the VESA backlight code in i915 into DRM
helpers, one of the things I didn't have the hardware or time for
testing was machines that used a combination of PWM and DPCD in order to
control their backlights. This has since then caused some breakages and
resulted in us disabling DPCD backlight support on such machines. This
works fine, unless you have a machine that actually needs this
functionality for backlight controls to work at all. Additionally, we
will need to support PWM for when we start adding support for VESA's
product (as in the product of multiplication) control mode for better
brightness ranges.

So - let's finally finish up implementing basic support for these types
of backlights to solve these problems in our DP helpers, along with
implementing support for this in i915. And since digging into this issue
solved the last questions we really had about probing backlights in i915
for the most part, let's update some of the comments around that as
well!

Changes:
* Fixup docs
* Add patch to stop us from breaking nouveau

Lyude Paul (4):
  drm/i915: Add support for panels with VESA backlights with PWM
enable/disable
  drm/nouveau/kms/nv50-: Explicitly check DPCD backlights for aux
enable/brightness
  drm/dp, drm/i915: Add support for VESA backlights using PWM for
brightness control
  drm/i915: Clarify probing order in intel_dp_aux_init_backlight_funcs()

 drivers/gpu/drm/drm_dp_helper.c   | 75 +++--
 .../drm/i915/display/intel_dp_aux_backlight.c | 80 ++-
 drivers/gpu/drm/nouveau/nouveau_backlight.c   |  5 +-
 include/drm/drm_dp_helper.h   |  7 +-
 4 files changed, 122 insertions(+), 45 deletions(-)

-- 
2.31.1



Re: [PATCH 2/3] drm/msm/dsi: fix off by one in dsi_bus_clk_enable error handling

2021-10-01 Thread Dmitry Baryshkov

On 01/10/2021 15:34, Dan Carpenter wrote:

This disables a lock which wasn't enabled and it does not disable
the first lock in the array.

Fixes: 6e0eb52eba9e ("drm/msm/dsi: Parse bus clocks from a list")
Signed-off-by: Dan Carpenter 


Reviewed-by: Dmitry Baryshkov 

We should probably switch this to bulk clk api.


---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..c86b5090fae6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -451,7 +451,7 @@ static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host)
  
  	return 0;

  err:
-   for (; i > 0; i--)
+   while (--i >= 0)
clk_disable_unprepare(msm_host->bus_clks[i]);
  
  	return ret;





--
With best wishes
Dmitry


Re: [PATCH 1/3] drm/msm/dsi: Fix an error code in msm_dsi_modeset_init()

2021-10-01 Thread Dmitry Baryshkov

On 01/10/2021 15:33, Dan Carpenter wrote:

Return an error code if msm_dsi_manager_validate_current_config().
Don't return success.

Fixes: 8b03ad30e314 ("drm/msm/dsi: Use one connector for dual DSI mode")
Signed-off-by: Dan Carpenter 


Reviewed-by: Dmitry Baryshkov 



---
  drivers/gpu/drm/msm/dsi/dsi.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 614dc7f26f2c..75ae3008b68f 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -215,8 +215,10 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct 
drm_device *dev,
goto fail;
}
  
-	if (!msm_dsi_manager_validate_current_config(msm_dsi->id))

+   if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) {
+   ret = -EINVAL;
goto fail;
+   }
  
  	msm_dsi->encoder = encoder;
  




--
With best wishes
Dmitry


Re: [PATCH] drm/msm/dsi: prevent unintentional integer overflow in dsi_pll_28nm_clk_recalc_rate()

2021-10-01 Thread Dmitry Baryshkov

On 29/09/2021 20:51, Tim Gardner wrote:

Coverity warns of an unintentional integer overflow

CID 120715 (#1 of 1): Unintentional integer overflow (OVERFLOW_BEFORE_WIDEN)
overflow_before_widen: Potentially overflowing expression ref_clk * sdm_byp_div
   with type unsigned int (32 bits, unsigned) is evaluated using 32-bit 
arithmetic,
   and then used in a context that expects an expression of type unsigned long
   (64 bits, unsigned).
To avoid overflow, cast either ref_clk or sdm_byp_div to type unsigned long.
263vco_rate = ref_clk * sdm_byp_div;

Fix this and another possible overflow by casting ref_clk to unsigned long.


Changing ref_clk from u32 to unsigned long would be a more simple and 
elegant way of fixing this issue. Could you please update your patch?




Cc: Rob Clark 
Cc: Sean Paul 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Dmitry Baryshkov 
Cc: Abhinav Kumar 
Cc: linux-arm-...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: freedr...@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Tim Gardner 
---
  drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c 
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
index 2da673a2add6..cfe4b30eb96d 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
@@ -260,7 +260,7 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct 
clk_hw *hw,
sdm_byp_div = FIELD(
dsi_phy_read(base + 
REG_DSI_28nm_PHY_PLL_SDM_CFG0),
DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1;
-   vco_rate = ref_clk * sdm_byp_div;
+   vco_rate = (unsigned long)ref_clk * sdm_byp_div;
} else {
/* sdm mode */
sdm_dc_off = FIELD(
@@ -274,7 +274,7 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct 
clk_hw *hw,
sdm_freq_seed = (sdm3 << 8) | sdm2;
DBG("sdm_freq_seed = %d", sdm_freq_seed);
  
-		vco_rate = (ref_clk * (sdm_dc_off + 1)) +

+   vco_rate = ((unsigned long)ref_clk * (sdm_dc_off + 1)) +
mult_frac(ref_clk, sdm_freq_seed, BIT(16));
DBG("vco rate = %lu", vco_rate);
}




--
With best wishes
Dmitry


Re: [PATCH] drm/msm: prevent NULL dereference in msm_gpu_crashstate_capture()

2021-10-01 Thread Dmitry Baryshkov

On 29/09/2021 19:25, Tim Gardner wrote:

Coverity complains of a possible NULL dereference:

CID 120718 (#1 of 1): Dereference null return value (NULL_RETURNS)
23. dereference: Dereferencing a pointer that might be NULL state->bos when
 calling msm_gpu_crashstate_get_bo. [show details]
301msm_gpu_crashstate_get_bo(state, submit->bos[i].obj,
302submit->bos[i].iova, submit->bos[i].flags);

Fix this by employing the same state->bos NULL check as is used in the next
for loop.

Cc: Rob Clark 
Cc: Sean Paul 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: linux-arm-...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: freedr...@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Tim Gardner 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/msm_gpu.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 8a3a592da3a4..2c46cd968ac4 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -296,7 +296,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
state->bos = kcalloc(nr,
sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
  
-		for (i = 0; i < submit->nr_bos; i++) {

+   for (i = 0; state->bos && i < submit->nr_bos; i++) {
if (should_dump(submit, i)) {
msm_gpu_crashstate_get_bo(state, 
submit->bos[i].obj,
submit->bos[i].iova, 
submit->bos[i].flags);




--
With best wishes
Dmitry


Re: [PATCH v2] drm: msm: adreno_gpu.c: Add and use pr_fmt(fmt)

2021-10-01 Thread Dmitry Baryshkov

On 26/08/2021 05:23, zhaoxiao wrote:

Use a more common logging style.

Signed-off-by: zhaoxiao 


Your subject tells about pr_fmt(), while the patch itself changs 
printk()s to pr_info(). Could you please fix the commit subject and 
expand/correct commit message?



---
v2:Remove the line: #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
drivers/gpu/drm/msm/adreno/adreno_gpu.c:23:9: warning: 'pr_fmt' macro 
redefined [-Wmacro-redefined]
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^
include/linux/printk.h:348:9: note: previous definition is here
#define pr_fmt(fmt) fmt

  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 12 ++--
  1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 9f5a30234b33..f10e9e04c13b 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -753,7 +753,7 @@ void adreno_dump_info(struct msm_gpu *gpu)
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
int i;
  
-	printk("revision: %d (%d.%d.%d.%d)\n",

+   pr_info("revision: %d (%d.%d.%d.%d)\n",
adreno_gpu->info->revn, adreno_gpu->rev.core,
adreno_gpu->rev.major, adreno_gpu->rev.minor,
adreno_gpu->rev.patchid);
@@ -761,12 +761,12 @@ void adreno_dump_info(struct msm_gpu *gpu)
for (i = 0; i < gpu->nr_rings; i++) {
struct msm_ringbuffer *ring = gpu->rb[i];
  
-		printk("rb %d: fence:%d/%d\n", i,

+   pr_info("rb %d: fence:%d/%d\n", i,
ring->memptrs->fence,
ring->seqno);
  
-		printk("rptr: %d\n", get_rptr(adreno_gpu, ring));

-   printk("rb wptr:  %d\n", get_wptr(ring));
+   pr_info("rptr: %d\n", get_rptr(adreno_gpu, ring));
+   pr_info("rb wptr:  %d\n", get_wptr(ring));
}
  }
  
@@ -780,7 +780,7 @@ void adreno_dump(struct msm_gpu *gpu)

return;
  
  	/* dump these out in a form that can be parsed by demsm: */

-   printk("IO:region %s  0002\n", gpu->name);
+   pr_info("IO:region %s  0002\n", gpu->name);
for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
uint32_t start = adreno_gpu->registers[i];
uint32_t end   = adreno_gpu->registers[i+1];
@@ -788,7 +788,7 @@ void adreno_dump(struct msm_gpu *gpu)
  
  		for (addr = start; addr <= end; addr++) {

uint32_t val = gpu_read(gpu, addr);
-   printk("IO:R %08x %08x\n", addr<<2, val);
+   pr_info("IO:R %08x %08x\n", addr<<2, val);
}
}
  }




--
With best wishes
Dmitry


Re: [PATCH v2 2/2] drm/msm/dpu: Fix timeout issues on command mode panels

2021-10-01 Thread Dmitry Baryshkov

On 11/09/2021 19:39, AngeloGioacchino Del Regno wrote:

In function dpu_encoder_phys_cmd_wait_for_commit_done we are always
checking if the relative CTL is started by waiting for an interrupt
to fire: it is fine to do that, but then sometimes we call this
function while the CTL is up and has never been put down, but that
interrupt gets raised only when the CTL gets a state change from
0 to 1 (disabled to enabled), so we're going to wait for something
that will never happen on its own.

Solving this while avoiding to restart the CTL is actually possible
and can be done by just checking if it is already up and running
when the wait_for_commit_done function is called: in this case, so,
if the CTL was already running, we can say that the commit is done
if the command transmission is complete (in other terms, if the
interface has been flushed).


I've compared this with the MDP5 driver, where we always wait for 
PP_DONE interrupt. Would it be enough to always wait for it (= always 
call dpu_encoder_phys_cmd_wait_for_tx_complete())?




Signed-off-by: AngeloGioacchino Del Regno 

---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index aa01698d6b25..aa5d3b3cef15 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -682,6 +682,9 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done(
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
return 0;
  
+	if (phys_enc->hw_ctl->ops.is_started(phys_enc->hw_ctl))

+   return dpu_encoder_phys_cmd_wait_for_tx_complete(phys_enc);
+
return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
  }
  




--
With best wishes
Dmitry


Re: [PATCH v2 00/17] drm: cleanup: Use DRM_MODESET_LOCK_ALL_* helpers where possible

2021-10-01 Thread Ville Syrjälä
On Fri, Oct 01, 2021 at 04:48:15PM -0400, Sean Paul wrote:
> On Fri, Oct 01, 2021 at 10:00:50PM +0300, Ville Syrjälä wrote:
> > On Fri, Oct 01, 2021 at 02:36:55PM -0400, Sean Paul wrote:
> > > On Fri, Sep 24, 2021 at 08:43:07AM +0200, Fernando Ramos wrote:
> > > > Hi all,
> > > > 
> > > > One of the things in the DRM TODO list ("Documentation/gpu/todo.rst") 
> > > > was to
> > > > "use DRM_MODESET_LOCAL_ALL_* helpers instead of boilerplate". That's 
> > > > what this
> > > > patch series is about.
> > > > 
> > > > You will find two types of changes here:
> > > > 
> > > >   - Replacing "drm_modeset_lock_all_ctx()" (and surrounding 
> > > > boilerplate) with
> > > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()" in the remaining places (as it 
> > > > has
> > > > already been done in previous commits such as b7ea04d2)
> > > > 
> > > >   - Replacing "drm_modeset_lock_all()" with 
> > > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()"
> > > > in the remaining places (as it has already been done in previous 
> > > > commits
> > > > such as 57037094)
> > > > 
> > > > Most of the changes are straight forward, except for a few cases in the 
> > > > "amd"
> > > > and "i915" drivers where some extra dancing was needed to overcome the
> > > > limitation that the DRM_MODESET_LOCK_ALL_BEGIN()/END() macros can only 
> > > > be used
> > > > once inside the same function (the reason being that the macro expansion
> > > > includes *labels*, and you can not have two labels named the same 
> > > > inside one
> > > > function)
> > > > 
> > > > Notice that, even after this patch series, some places remain where
> > > > "drm_modeset_lock_all()" and "drm_modeset_lock_all_ctx()" are still 
> > > > present,
> > > > all inside drm core (which makes sense), except for two (in "amd" and 
> > > > "i915")
> > > > which cannot be replaced due to the way they are being used.
> > > > 
> > > > Changes in v2:
> > > > 
> > > >   - Fix commit message typo
> > > >   - Use the value returned by DRM_MODESET_LOCK_ALL_END when possible
> > > >   - Split drm/i915 patch into two simpler ones
> > > >   - Remove drm_modeset_(un)lock_all()
> > > >   - Fix build problems in non-x86 platforms
> > > > 
> > > > Fernando Ramos (17):
> > > >   drm: cleanup: drm_modeset_lock_all_ctx() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/i915: cleanup: drm_modeset_lock_all_ctx() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/msm: cleanup: drm_modeset_lock_all_ctx() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN() 
> > > > drm/vmwgfx: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/tegra: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/shmobile: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/radeon: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/omapdrm: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/nouveau: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/msm: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/i915: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/i915: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN() part 2
> > > >   drm/gma500: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm/amd: cleanup: drm_modeset_lock_all() --> 
> > > > DRM_MODESET_LOCK_ALL_BEGIN()
> > > >   drm: cleanup: remove drm_modeset_(un)lock_all()
> > > >   doc: drm: remove TODO entry regarding DRM_MODSET_LOCK_ALL cleanup
> > > > 
> > > 
> > > Thank you for revising, Fernando! I've pushed the set to drm-misc-next 
> > > (along
> > > with the necessary drm-tip conflict resolutions).
> > 
> > Ugh. Did anyone actually review the locking changes this does?
> > I shot the previous i915 stuff down because the commit messages
> > did not address any of it.
> 
> I reviewed the set on 9/17, I didn't see your feedback on that thread.

It was much earlir than that.
https://lists.freedesktop.org/archives/dri-devel/2021-June/313193.html

And I think I might have also shot down a similar thing earlier.

I was actually half considering sending a patch to nuke that
misleading TODO item. I don't think anything which changes
which locks are taken should be considred a starter level task.
And the commit messages here don't seem to address any of it.

-- 
Ville Syrjälä
Intel


[PATCH v2] drm/bridge: analogix_dp: Grab runtime PM reference for DP-AUX

2021-10-01 Thread Brian Norris
If the display is not enable()d, then we aren't holding a runtime PM
reference here. Thus, it's easy to accidentally cause a hang, if user
space is poking around at /dev/drm_dp_aux0 at the "wrong" time.

Let's get the panel and PM state right before trying to talk AUX.

Fixes: 0d97ad03f422 ("drm/bridge: analogix_dp: Remove duplicated code")
Cc: 
Cc: Tomeu Vizoso 
Signed-off-by: Brian Norris 
---

Changes in v2:
- Fix spelling in Subject
- DRM_DEV_ERROR() -> drm_err()
- Propagate errors from un-analogix_dp_prepare_panel()

 .../drm/bridge/analogix/analogix_dp_core.c| 21 ++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index b7d2e4449cfa..6fc46ac93ef8 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1632,8 +1632,27 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux 
*aux,
   struct drm_dp_aux_msg *msg)
 {
struct analogix_dp_device *dp = to_dp(aux);
+   int ret, ret2;
 
-   return analogix_dp_transfer(dp, msg);
+   ret = analogix_dp_prepare_panel(dp, true, false);
+   if (ret) {
+   drm_err(dp->drm_dev, "Failed to prepare panel (%d)\n", ret);
+   return ret;
+   }
+
+   pm_runtime_get_sync(dp->dev);
+   ret = analogix_dp_transfer(dp, msg);
+   pm_runtime_put(dp->dev);
+
+   ret2 = analogix_dp_prepare_panel(dp, false, false);
+   if (ret2) {
+   drm_err(dp->drm_dev, "Failed to unprepare panel (%d)\n", ret2);
+   /* Prefer the analogix_dp_transfer() error, if it exists. */
+   if (!ret)
+   ret = ret2;
+   }
+
+   return ret;
 }
 
 struct analogix_dp_device *
-- 
2.33.0.800.g4c38ced690-goog



Re: [PATCH][V2] drm/msm: Fix potential integer overflow on 32 bit multiply

2021-10-01 Thread Dmitry Baryshkov

On 29/09/2021 14:53, Colin King wrote:

From: Colin Ian King 

In the case where clock is 2147485 or greater the 32 bit multiplication
by 1000 will cause an integer overflow. Fix this by making the constant
1000 an unsigned long to ensure a long multiply occurs to avoid the


You are talking about 'unsigned long' here, however in the patch you've 
used just 'unsigned' suffix. So, which one should be used?


I suspect that wanted to use UL here, since mode->clock is int, so it is 
int * unsigned.


Also I'd suggest to define a helper function macro in the drm_modes.h(?) 
that would take struct drm_display_mode pointer and return proper clock. 
See icc_units_to_bps() for the inspiration.




overflow before assigning the result to the long result in variable
requested.  Most probably a theoretical overflow issue, but worth fixing
to clear up static analysis warnings.

Addresses-Coverity: ("Unintentional integer overflow")
Fixes: c8afe684c95c ("drm/msm: basic KMS driver for snapdragon")
Fixes: 3e87599b68e7 ("drm/msm/mdp4: add LVDS panel support")
Fixes: 937f941ca06f ("drm/msm/dp: Use qmp phy for DP PLL and PHY")
Fixes: ab5b0107ccf3 ("drm/msm: Initial add eDP support in msm drm driver (v5)")
Fixes: a3376e3ec81c ("drm/msm: convert to drm_bridge")

Signed-off-by: Colin Ian King 
---
V2: Find and fix all unintentional integer overflows that match this
 overflow pattern.
---
  drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c| 2 +-
  drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c   | 2 +-
  drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c | 2 +-
  drivers/gpu/drm/msm/dp/dp_ctrl.c| 4 ++--
  drivers/gpu/drm/msm/edp/edp_connector.c | 2 +-
  drivers/gpu/drm/msm/hdmi/hdmi_bridge.c  | 2 +-
  drivers/gpu/drm/msm/hdmi/hdmi_connector.c   | 2 +-
  7 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c
index 88645dbc3785..83140066441e 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c
@@ -50,7 +50,7 @@ static void mdp4_dtv_encoder_mode_set(struct drm_encoder 
*encoder,
  
  	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
  
-	mdp4_dtv_encoder->pixclock = mode->clock * 1000;

+   mdp4_dtv_encoder->pixclock = mode->clock * 1000U;
  
  	DBG("pixclock=%lu", mdp4_dtv_encoder->pixclock);
  
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c

index 10eb3e5b218e..d90dc0a39855 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
@@ -225,7 +225,7 @@ static void mdp4_lcdc_encoder_mode_set(struct drm_encoder 
*encoder,
  
  	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
  
-	mdp4_lcdc_encoder->pixclock = mode->clock * 1000;

+   mdp4_lcdc_encoder->pixclock = mode->clock * 1000U;
  
  	DBG("pixclock=%lu", mdp4_lcdc_encoder->pixclock);
  
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c

index 7288041dd86a..a965e7962a7f 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
@@ -64,7 +64,7 @@ static int mdp4_lvds_connector_mode_valid(struct 
drm_connector *connector,
struct drm_encoder *encoder = mdp4_lvds_connector->encoder;
long actual, requested;
  
-	requested = 1000 * mode->clock;

+   requested = 1000U * mode->clock;
actual = mdp4_lcdc_round_pixclk(encoder, requested);
  
  	DBG("requested=%ld, actual=%ld", requested, actual);

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 62e75dc8afc6..6babeb79aeb0 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1316,7 +1316,7 @@ static int dp_ctrl_enable_mainlink_clocks(struct 
dp_ctrl_private *ctrl)
opts_dp->lanes = ctrl->link->link_params.num_lanes;
opts_dp->link_rate = ctrl->link->link_params.rate / 100;
dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
-   ctrl->link->link_params.rate * 1000);
+   ctrl->link->link_params.rate * 1000U);
  
  	phy_configure(phy, &dp_io->phy_opts);

phy_power_on(phy);
@@ -1336,7 +1336,7 @@ static int dp_ctrl_enable_stream_clocks(struct 
dp_ctrl_private *ctrl)
int ret = 0;
  
  	dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel",

-   ctrl->dp_ctrl.pixel_rate * 1000);
+   ctrl->dp_ctrl.pixel_rate * 1000U);
  
  	ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true);

if (ret)
diff --git a/drivers/gpu/drm/msm/edp/edp_connector.c 
b/drivers/gpu/drm/msm/edp/edp_connector.c
index 73cb5fd97a5a..837e7873141f 100644
--- a/drivers/gpu/drm/msm/

Re: [PATCH v13 14/35] drm/tegra: gr3d: Support generic power domain and runtime PM

2021-10-01 Thread Dmitry Osipenko
01.10.2021 17:06, Ulf Hansson пишет:
> On Mon, 27 Sept 2021 at 00:42, Dmitry Osipenko  wrote:
>> Add runtime power management and support generic power domains.
>>
>> Tested-by: Peter Geis  # Ouya T30
>> Tested-by: Paul Fertser  # PAZ00 T20
>> Tested-by: Nicolas Chauvet  # PAZ00 T20 and TK1 T124
>> Tested-by: Matt Merhar  # Ouya T30
>> Signed-off-by: Dmitry Osipenko 
>> ---
>>  drivers/gpu/drm/tegra/gr3d.c | 388 ++-
> [...]

> 
> I was looking for a call to dev_pm_opp_set_rate(), but couldn't find
> it. Isn't that needed when changing the rate of the clock?

That is another good catch! Previous versions of this patch were
changing the rate, while the current version not. So the
set_opp_helper() isn't needed for this patch anymore. It may become
needed sometime later, but not for this series. I'll remove it in the
next version, thanks!


Re: [PATCH] drm/brdige: analogix_dp: Grab runtime PM reference for DP-AUX

2021-10-01 Thread Brian Norris
On Fri, Oct 1, 2021 at 1:37 PM Sean Paul  wrote:
> On Wed, Sep 29, 2021 at 02:41:03PM -0700, Brian Norris wrote:
> > --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> > +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> > @@ -1632,8 +1632,23 @@ static ssize_t analogix_dpaux_transfer(struct 
> > drm_dp_aux *aux,
> >  struct drm_dp_aux_msg *msg)
> >  {
> >   struct analogix_dp_device *dp = to_dp(aux);
> > + int ret, ret2;
> >
> > - return analogix_dp_transfer(dp, msg);
> > + ret = analogix_dp_prepare_panel(dp, true, false);
> > + if (ret) {
> > + DRM_DEV_ERROR(dp->dev, "Failed to prepare panel (%d)\n", ret);
>
> s/DRM_DEV_ERROR/drm_err/

Sure. Now that I'm looking a second time, I see the header recommends this.

> > + return ret;
> > + }
> > +
> > + pm_runtime_get_sync(dp->dev);
> > + ret = analogix_dp_transfer(dp, msg);
> > + pm_runtime_put(dp->dev);
> > +
> > + ret2 = analogix_dp_prepare_panel(dp, false, false);
> > + if (ret2)
> > + DRM_DEV_ERROR(dp->dev, "Failed to unprepare panel (%d)\n", 
> > ret2);
>
> What's the reasoning for not propagating unprepare failures? I feel like that
> should be fair game.

I suppose the underlying reason is laziness, sorry. But a related
reason is the we probably should prefer propagating the
analogix_dp_transfer() error, if it's non-zero, rather than the
unprepare error. That's not too hard to do though, even if it's
slightly more awkward.

> > +
> > + return ret;
> >  }
> >
> >  struct analogix_dp_device *

v2 coming.

Regards,
Brian


Re: [PATCH v3 3/3] drm/msm/mdp5: Add configuration for MDP v1.16

2021-10-01 Thread Dmitry Baryshkov

On 28/09/2021 16:19, Sireesh Kodali wrote:

From: Vladimir Lypak 

MDP version v1.16 is almost identical to v1.15 with most significant
difference being presence of second DSI interface. MDP v1.16 is found on
SoCs such as MSM8x53, SDM450, SDM632 (All with Adreno 506).

Signed-off-by: Vladimir Lypak 
Signed-off-by: Sireesh Kodali 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 89 
  1 file changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
index 9741544ffc35..0d28c8ff4009 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
@@ -752,6 +752,94 @@ const struct mdp5_cfg_hw msm8x76_config = {
.max_clk = 36000,
  };
  
+static const struct mdp5_cfg_hw msm8x53_config = {

+   .name = "msm8x53",
+   .mdp = {
+   .count = 1,
+   .caps = MDP_CAP_CDM |
+   MDP_CAP_SRC_SPLIT,
+   },
+   .ctl = {
+   .count = 3,
+   .base = { 0x01000, 0x01200, 0x01400 },
+   .flush_hw_mask = 0x,
+   },
+   .pipe_vig = {
+   .count = 1,
+   .base = { 0x04000 },
+   .caps = MDP_PIPE_CAP_HFLIP  |
+   MDP_PIPE_CAP_VFLIP  |
+   MDP_PIPE_CAP_SCALE  |
+   MDP_PIPE_CAP_CSC|
+   MDP_PIPE_CAP_DECIMATION |
+   MDP_PIPE_CAP_SW_PIX_EXT |
+   0,
+   },
+   .pipe_rgb = {
+   .count = 2,
+   .base = { 0x14000, 0x16000 },
+   .caps = MDP_PIPE_CAP_HFLIP  |
+   MDP_PIPE_CAP_VFLIP  |
+   MDP_PIPE_CAP_DECIMATION |
+   MDP_PIPE_CAP_SW_PIX_EXT |
+   0,
+   },
+   .pipe_dma = {
+   .count = 1,
+   .base = { 0x24000 },
+   .caps = MDP_PIPE_CAP_HFLIP  |
+   MDP_PIPE_CAP_VFLIP  |
+   MDP_PIPE_CAP_SW_PIX_EXT |
+   0,
+   },
+   .pipe_cursor = {
+   .count = 1,
+   .base = { 0x34000 },
+   .caps = MDP_PIPE_CAP_HFLIP  |
+   MDP_PIPE_CAP_VFLIP  |
+   MDP_PIPE_CAP_SW_PIX_EXT |
+   MDP_PIPE_CAP_CURSOR |
+   0,
+   },
+
+   .lm = {
+   .count = 3,
+   .base = { 0x44000, 0x45000 },
+   .instances = {
+   { .id = 0, .pp = 0, .dspp = 0,
+ .caps = MDP_LM_CAP_DISPLAY |
+ MDP_LM_CAP_PAIR },
+   { .id = 1, .pp = 1, .dspp = -1,
+ .caps = MDP_LM_CAP_DISPLAY },
+},
+   .nb_stages = 5,
+   .max_width = 2048,
+   .max_height = 0x,
+   },
+   .dspp = {
+   .count = 1,
+   .base = { 0x54000 },
+
+   },
+   .pp = {
+   .count = 2,
+   .base = { 0x7, 0x70800 },
+   },
+   .cdm = {
+   .count = 1,
+   .base = { 0x79200 },
+   },
+   .intf = {
+   .base = { 0x6a000, 0x6a800, 0x6b000 },
+   .connect = {
+   [0] = INTF_DISABLED,
+   [1] = INTF_DSI,
+   [2] = INTF_DSI,
+   },
+   },
+   .max_clk = 4,
+};
+
  static const struct mdp5_cfg_hw msm8917_config = {
.name = "msm8917",
.mdp = {
@@ -1151,6 +1239,7 @@ static const struct mdp5_cfg_handler cfg_handlers_v1[] = {
{ .revision = 7, .config = { .hw = &msm8x96_config } },
{ .revision = 11, .config = { .hw = &msm8x76_config } },
{ .revision = 15, .config = { .hw = &msm8917_config } },
+   { .revision = 16, .config = { .hw = &msm8x53_config } },
  };
  
  static const struct mdp5_cfg_handler cfg_handlers_v3[] = {





--
With best wishes
Dmitry


Re: [RFC] drm/msm/dp: Allow attaching a drm_panel

2021-10-01 Thread Bjorn Andersson
On Fri 27 Aug 13:52 PDT 2021, Doug Anderson wrote:

> Hi,
> 
> On Mon, Jul 26, 2021 at 4:15 PM Bjorn Andersson
>  wrote:
> >
> > +static int dp_parser_find_panel(struct dp_parser *parser)
> > +{
> > +   struct device_node *np = parser->pdev->dev.of_node;
> > +   int rc;
> > +
> > +   rc = drm_of_find_panel_or_bridge(np, 2, 0, &parser->drm_panel, 
> > NULL);
> 
> Why port 2? Shouldn't this just be port 1 always? The yaml says that
> port 1 is "Output endpoint of the controller". We should just use port
> 1 here, right?
> 

Finally got back to this, changed it to 1 and figured out why I left it
at 2.

drm_of_find_panel_or_bridge() on a DP controller will find the of_graph
reference to the USB-C controller, scan through the registered panels
and conclude that the of_node of the USB-C controller isn't a registered
panel and return -EPROBE_DEFER.

So I picked 2, because I'm not able to figure out a way to distinguish
between a not yet probed panel and the USB-C controller...

Any suggestions?

Regards,
Bjorn


Re: [PATCH v2 00/17] drm: cleanup: Use DRM_MODESET_LOCK_ALL_* helpers where possible

2021-10-01 Thread Sean Paul
On Fri, Oct 01, 2021 at 10:00:50PM +0300, Ville Syrjälä wrote:
> On Fri, Oct 01, 2021 at 02:36:55PM -0400, Sean Paul wrote:
> > On Fri, Sep 24, 2021 at 08:43:07AM +0200, Fernando Ramos wrote:
> > > Hi all,
> > > 
> > > One of the things in the DRM TODO list ("Documentation/gpu/todo.rst") was 
> > > to
> > > "use DRM_MODESET_LOCAL_ALL_* helpers instead of boilerplate". That's what 
> > > this
> > > patch series is about.
> > > 
> > > You will find two types of changes here:
> > > 
> > >   - Replacing "drm_modeset_lock_all_ctx()" (and surrounding boilerplate) 
> > > with
> > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()" in the remaining places (as it 
> > > has
> > > already been done in previous commits such as b7ea04d2)
> > > 
> > >   - Replacing "drm_modeset_lock_all()" with 
> > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()"
> > > in the remaining places (as it has already been done in previous 
> > > commits
> > > such as 57037094)
> > > 
> > > Most of the changes are straight forward, except for a few cases in the 
> > > "amd"
> > > and "i915" drivers where some extra dancing was needed to overcome the
> > > limitation that the DRM_MODESET_LOCK_ALL_BEGIN()/END() macros can only be 
> > > used
> > > once inside the same function (the reason being that the macro expansion
> > > includes *labels*, and you can not have two labels named the same inside 
> > > one
> > > function)
> > > 
> > > Notice that, even after this patch series, some places remain where
> > > "drm_modeset_lock_all()" and "drm_modeset_lock_all_ctx()" are still 
> > > present,
> > > all inside drm core (which makes sense), except for two (in "amd" and 
> > > "i915")
> > > which cannot be replaced due to the way they are being used.
> > > 
> > > Changes in v2:
> > > 
> > >   - Fix commit message typo
> > >   - Use the value returned by DRM_MODESET_LOCK_ALL_END when possible
> > >   - Split drm/i915 patch into two simpler ones
> > >   - Remove drm_modeset_(un)lock_all()
> > >   - Fix build problems in non-x86 platforms
> > > 
> > > Fernando Ramos (17):
> > >   drm: cleanup: drm_modeset_lock_all_ctx() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/i915: cleanup: drm_modeset_lock_all_ctx() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/msm: cleanup: drm_modeset_lock_all_ctx() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN() 
> > > drm/vmwgfx: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/tegra: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/shmobile: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/radeon: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/omapdrm: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/nouveau: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/msm: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/i915: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/i915: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN() part 2
> > >   drm/gma500: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm/amd: cleanup: drm_modeset_lock_all() --> 
> > > DRM_MODESET_LOCK_ALL_BEGIN()
> > >   drm: cleanup: remove drm_modeset_(un)lock_all()
> > >   doc: drm: remove TODO entry regarding DRM_MODSET_LOCK_ALL cleanup
> > > 
> > 
> > Thank you for revising, Fernando! I've pushed the set to drm-misc-next 
> > (along
> > with the necessary drm-tip conflict resolutions).
> 
> Ugh. Did anyone actually review the locking changes this does?
> I shot the previous i915 stuff down because the commit messages
> did not address any of it.

I reviewed the set on 9/17, I didn't see your feedback on that thread.

Sean

> 
> -- 
> Ville Syrjälä
> Intel

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


Re: [PATCH] drm/brdige: analogix_dp: Grab runtime PM reference for DP-AUX

2021-10-01 Thread Sean Paul
On Wed, Sep 29, 2021 at 02:41:03PM -0700, Brian Norris wrote:
> If the display is not enable()d, then we aren't holding a runtime PM
> reference here. Thus, it's easy to accidentally cause a hang, if user
> space is poking around at /dev/drm_dp_aux0 at the "wrong" time.
> 
> Let's get the panel and PM state right before trying to talk AUX.
> 
> Fixes: 0d97ad03f422 ("drm/bridge: analogix_dp: Remove duplicated code")
> Cc: 
> Cc: Tomeu Vizoso 
> Signed-off-by: Brian Norris 
> ---
> 
>  .../gpu/drm/bridge/analogix/analogix_dp_core.c  | 17 -
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
> b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index b7d2e4449cfa..a1b553904b85 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -1632,8 +1632,23 @@ static ssize_t analogix_dpaux_transfer(struct 
> drm_dp_aux *aux,
>  struct drm_dp_aux_msg *msg)
>  {
>   struct analogix_dp_device *dp = to_dp(aux);
> + int ret, ret2;
>  
> - return analogix_dp_transfer(dp, msg);
> + ret = analogix_dp_prepare_panel(dp, true, false);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev, "Failed to prepare panel (%d)\n", ret);

s/DRM_DEV_ERROR/drm_err/

> + return ret;
> + }
> +
> + pm_runtime_get_sync(dp->dev);
> + ret = analogix_dp_transfer(dp, msg);
> + pm_runtime_put(dp->dev);
> +
> + ret2 = analogix_dp_prepare_panel(dp, false, false);
> + if (ret2)
> + DRM_DEV_ERROR(dp->dev, "Failed to unprepare panel (%d)\n", 
> ret2);

What's the reasoning for not propagating unprepare failures? I feel like that
should be fair game.

> +
> + return ret;
>  }
>  
>  struct analogix_dp_device *
> -- 
> 2.33.0.685.g46640cef36-goog
> 

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


Re: [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-01 Thread Sean Paul
On Wed, Sep 29, 2021 at 03:39:25PM -0400, Mark Yacoub wrote:
> From: Mark Yacoub 
> 
> [Why]
> 1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
> or Degamma props in the new CRTC state, allowing any invalid size to
> be passed on.
> 2. Each driver has its own LUT size, which could also be different for
> legacy users.
> 
> [How]
> 1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
> assigned by the driver when it's initializing its color and CTM
> management.
> 2. Create drm_atomic_helper_check_crtc which is called by
> drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
> they match the sizes in the new CRTC state.
> 

Did you consider extending drm_color_lut_check() with the size checks?

> Fixes: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
> Tested on Zork(amdgpu) and Jacuzzi(mediatek)
> 
> Signed-off-by: Mark Yacoub

nit: missing a space between name and email


> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 56 +
>  drivers/gpu/drm/drm_color_mgmt.c|  2 ++
>  include/drm/drm_atomic_helper.h |  1 +
>  include/drm/drm_crtc.h  | 11 ++
>  4 files changed, 70 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index 2c0c6ec928200..265b9747250d1 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -930,6 +930,58 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_check_planes);
>  
> +/**
> + * drm_atomic_helper_check_planes - validate state object for CRTC changes

Ctrl+c/Ctrl+v error here

> + * @state: the driver state object
> + *
> + * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the new

Are there missing words between "object" and "such"?

> + * state holds them.
> + *
> + * RETURNS:
> + * Zero for success or -errno
> + */
> +int drm_atomic_helper_check_crtc(struct drm_atomic_state *state)

drm_atomic_helper_check_crtcs to be consistent with
drm_atomic_helper_check_planes

> +{
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *new_crtc_state;
> + int i;
> +
> + for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {

no space before (

> + if (new_crtc_state->gamma_lut) {

Perhaps gate these with a check of state->color_mgmt_changed first?

> + uint64_t supported_lut_size = crtc->gamma_lut_size;
> + uint32_t supported_legacy_lut_size = crtc->gamma_size;
> + uint32_t new_state_lut_size =
> + drm_color_lut_size(new_crtc_state->gamma_lut);

nit: new_state_lut_size and supported_lut_size can be pulled out to top level 
scope
to avoid re-instantiation on each iteration

> +
> + if (new_state_lut_size != supported_lut_size &&
> + new_state_lut_size != supported_legacy_lut_size) {

According to the docbook, "If drivers support multiple LUT sizes then they
should publish the largest size, and sub-sample smaller sized LUTs". So
should this check be > instead of != ?

> + DRM_DEBUG_DRIVER(

drm_dbg_state() is probably more appropriate

> + "Invalid Gamma LUT size. Should be %u 
> (or %u for legacy) but got %u.\n",
> + supported_lut_size,
> + supported_legacy_lut_size,
> + new_state_lut_size);
> + return -EINVAL;
> + }
> + }
> +
> + if (new_crtc_state->degamma_lut) {
> + uint32_t new_state_lut_size =
> + drm_color_lut_size(new_crtc_state->degamma_lut);
> + uint64_t supported_lut_size = crtc->degamma_lut_size;
> +
> + if (new_state_lut_size != supported_lut_size) {
> + DRM_DEBUG_DRIVER(

drm_dbg_state()

> + "Invalid Degamma LUT size. Should be %u 
> but got %u.\n",
> + supported_lut_size, new_state_lut_size);
> + return -EINVAL;
> + }
> + }
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_check_crtc);
> +
>  /**
>   * drm_atomic_helper_check - validate state object
>   * @dev: DRM device
> @@ -975,6 +1027,10 @@ int drm_atomic_helper_check(struct drm_device *dev,
>   if (ret)
>   return ret;
>  
> + ret = drm_atomic_helper_check_crtc(state);
> + if (ret)
> + return ret;
> +
>   if (state->legacy_cursor_update)
>   state->async_update = !drm_atomic_helper_async_check(dev, 
> state);
>  
> diff --git a/drivers/gpu/drm/drm_color_mgmt.c 
> b/drivers/gpu/drm/drm_color_mgmt.c
> index bb14f488c8f6c..72a1b

Re: [PATCH 2/2] amd/amdgpu_dm: Verify Gamma and Degamma LUT sizes using DRM Core check

2021-10-01 Thread Sean Paul
On Wed, Sep 29, 2021 at 03:39:26PM -0400, Mark Yacoub wrote:
> From: Mark Yacoub 
> 
> [Why]
> drm_atomic_helper_check_crtc now verifies both legacy and non-legacy LUT
> sizes. There is no need to check it within amdgpu_dm_atomic_check.
> 
> [How]
> Remove the local call to verify LUT sizes and use DRM Core function
> instead.
> 
> Tested on ChromeOS Zork.
> 
> Signed-off-by: Mark Yacoub 
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 07adac1a8c42b..96a1d006b777e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10683,6 +10683,10 @@ static int amdgpu_dm_atomic_check(struct drm_device 
> *dev,
>   }
>   }
>  #endif
> + ret = drm_atomic_helper_check_crtc(state);
> + if (ret)
> + return ret;
> +
>   for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
> new_crtc_state, i) {
>   dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
>  
> @@ -10692,10 +10696,6 @@ static int amdgpu_dm_atomic_check(struct drm_device 
> *dev,
>   dm_old_crtc_state->dsc_force_changed == false)
>   continue;
>  
> - ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);

>From a quick glance, I think you can now delete this function. It's called from
amdgpu_dm_update_crtc_color_mgmt() which is part of the commit, so the lut sizes
should have already been checked.

If the call from amdgpu_dm_update_crtc_color_mgmt() is not possible to remove,
you could replace it with a call to the new helper function. And if _that_ is
not possible, please make amdgpu_dm_verify_lut_sizes() static :-)

Sean

> - if (ret)
> - goto fail;
> -
>   if (!new_crtc_state->enable)
>   continue;
>  
> -- 
> 2.33.0.685.g46640cef36-goog
> 

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


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

2021-10-01 Thread Dmitry Osipenko
01.10.2021 15:32, Ulf Hansson пишет:
>> +static int tegra_clock_sync_pd_state(struct tegra_clk_device *clk_dev)
>> +{
>> +   unsigned long rate;
>> +   int ret = 0;
>> +
>> +   mutex_lock(&clk_dev->lock);
>> +
>> +   if (!pm_runtime_status_suspended(clk_dev->dev)) {
>> +   rate = clk_hw_get_rate(clk_dev->hw);
>> +   ret = tegra_clock_set_pd_state(clk_dev, rate);
> Don't we need to sync the performance state even when the device is
> runtime suspended?
> 
> Perhaps the clock, via a child-clock for example, can get
> prepared/enabled (hence its device gets runtime resumed) before there
> is a clock rate update for it. Then there is no performance state set
> for it, right? Or maybe that isn't a problem?
> 

Good catch! Older versions of this patch had a special handling for clk
enable/disable. I just forgot to update this function, it's now not a
problem to change performance state of a suspended device and it
actually needs to be done. I'll correct it, thanks!


[PATCH] drm/msm/a6xx: Serialize GMU communication

2021-10-01 Thread Rob Clark
From: Rob Clark 

I've seen some crashes in our crash reporting that *look* like multiple
threads stomping on each other while communicating with GMU.  So wrap
all those paths in a lock.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  6 
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  3 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 40 +++
 3 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index a7c58018959f..8b73f70766a4 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -296,6 +296,8 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
u32 val;
int request, ack;
 
+   WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
return -EINVAL;
 
@@ -337,6 +339,8 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
 {
int bit;
 
+   WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
return;
 
@@ -1482,6 +1486,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct 
device_node *node)
if (!pdev)
return -ENODEV;
 
+   mutex_init(&gmu->lock);
+
gmu->dev = &pdev->dev;
 
of_dma_configure(gmu->dev, node, true);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index 3c74f64e3126..84bd516f01e8 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -44,6 +44,9 @@ struct a6xx_gmu_bo {
 struct a6xx_gmu {
struct device *dev;
 
+   /* For serializing communication with the GMU: */
+   struct mutex lock;
+
struct msm_gem_address_space *aspace;
 
void * __iomem mmio;
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index f6a4dbef796b..bd7bdeff5d6f 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -881,7 +881,7 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
  A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
  A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR)
 
-static int a6xx_hw_init(struct msm_gpu *gpu)
+static int hw_init(struct msm_gpu *gpu)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
@@ -1135,6 +1135,19 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
return ret;
 }
 
+static int a6xx_hw_init(struct msm_gpu *gpu)
+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+   int ret;
+
+   mutex_lock(&a6xx_gpu->gmu.lock);
+   ret = hw_init(gpu);
+   mutex_unlock(&a6xx_gpu->gmu.lock);
+
+   return ret;
+}
+
 static void a6xx_dump(struct msm_gpu *gpu)
 {
DRM_DEV_INFO(&gpu->pdev->dev, "status:   %08x\n",
@@ -1509,7 +1522,9 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)
 
trace_msm_gpu_resume(0);
 
+   mutex_lock(&a6xx_gpu->gmu.lock);
ret = a6xx_gmu_resume(a6xx_gpu);
+   mutex_unlock(&a6xx_gpu->gmu.lock);
if (ret)
return ret;
 
@@ -1532,7 +1547,9 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
 
msm_devfreq_suspend(gpu);
 
+   mutex_lock(&a6xx_gpu->gmu.lock);
ret = a6xx_gmu_stop(a6xx_gpu);
+   mutex_unlock(&a6xx_gpu->gmu.lock);
if (ret)
return ret;
 
@@ -1547,18 +1564,19 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, 
uint64_t *value)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
-   static DEFINE_MUTEX(perfcounter_oob);
 
-   mutex_lock(&perfcounter_oob);
+   mutex_lock(&a6xx_gpu->gmu.lock);
 
/* Force the GPU power on so we can read this register */
a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
 
*value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
-   REG_A6XX_CP_ALWAYS_ON_COUNTER_HI);
+   REG_A6XX_CP_ALWAYS_ON_COUNTER_HI);
 
a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
-   mutex_unlock(&perfcounter_oob);
+
+   mutex_unlock(&a6xx_gpu->gmu.lock);
+
return 0;
 }
 
@@ -1622,6 +1640,16 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
return (unsigned long)busy_time;
 }
 
+void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+   mutex_lock(&a6xx_gpu->gmu.lock);
+   a6xx_gmu_set_freq(gpu, opp);
+   mutex_unlock(&a6xx_gpu->gmu.lock);
+}
+
 static struct msm_gem_address_space *
 a6xx_create_address_space(struct msm_gpu *gpu, struct platfo

Re: [PATCH v13 02/35] soc/tegra: Add devm_tegra_core_dev_init_opp_table_common()

2021-10-01 Thread Dmitry Osipenko
01.10.2021 15:50, Ulf Hansson пишет:
> On Mon, 27 Sept 2021 at 00:42, Dmitry Osipenko  wrote:
>>
>> Only couple drivers need to get the -ENODEV error code and majority of
>> drivers need to explicitly initialize the performance state. Add new
>> common helper which sets up OPP table for these drivers.
>>
>> Signed-off-by: Dmitry Osipenko 
>> ---
>>  include/soc/tegra/common.h | 24 
>>  1 file changed, 24 insertions(+)
>>
>> diff --git a/include/soc/tegra/common.h b/include/soc/tegra/common.h
>> index af41ad80ec21..5b4a042f60fb 100644
>> --- a/include/soc/tegra/common.h
>> +++ b/include/soc/tegra/common.h
>> @@ -39,4 +39,28 @@ devm_tegra_core_dev_init_opp_table(struct device *dev,
>>  }
>>  #endif
>>
>> +/*
>> + * This function should be invoked with the enabled runtime PM of the device
>> + * in order to initialize performance state properly. Most of Tegra devices
>> + * are assumed to be suspended at a probe time and GENPD require RPM to be
>> + * enabled to set up the rpm-resume state, otherwise device is active and
>> + * performance state is applied immediately. Note that it will initialize
>> + * OPP bandwidth if it's wired in a device-tree for this device, which is
>> + * undesirable for a suspended device.
>> + */
>> +static inline int
>> +devm_tegra_core_dev_init_opp_table_common(struct device *dev)
>> +{
>> +   struct tegra_core_opp_params opp_params = {};
>> +   int err;
>> +
>> +   opp_params.init_state = true;
>> +
>> +   err = devm_tegra_core_dev_init_opp_table(dev, &opp_params);
>> +   if (err != -ENODEV)
>> +   return err;
>> +
>> +   return 0;
>> +}
> 
> Just want to share a few thoughts around these functions.
> 
> So, I assume it's fine to call
> devm_tegra_core_dev_init_opp_table_common() or
> devm_tegra_core_dev_init_opp_table() from consumer drivers during
> ->probe(), as long as those drivers are tegra specific, which I assume
> all are in the series!?

That is correct, all drivers are tegra-specific in this series. External
devices are attached to the internal SoC devices and this series is
about the SoC power management.

> My point is, a cross SoC consumer driver that needs to initiate OPP
> tables can get rather messy, if it would need to make one specific
> function call per SoC.
> 
> That said, I hope we can tackle this as a separate/future problem, so
> the series can get merged as is.

Yes, as we already have seen, it's not an easy problem to make PD core
to handle it in a generic way. If there will be a similar demand from
other SoCs, then we may try to solve that problem again.


Re: [bug report] drm/msm: Add SDM845 DPU support

2021-10-01 Thread jesszhan

Hey Dan,

Thanks for the heads up, will take care of it.

On 2021-10-01 05:28, Dan Carpenter wrote:

Hello Jeykumar Sankaran,

The patch 25fdd5933e4c: "drm/msm: Add SDM845 DPU support" from Jun
27, 2018, leads to the following
Smatch static checker warning:

drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c:1679 dpu_plane_init()
warn: '&pdpu->mplane_list' not removed from list

drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
1567 struct drm_plane *dpu_plane_init(struct drm_device *dev,
1568 uint32_t pipe, enum drm_plane_type type,
1569 unsigned long possible_crtcs, u32 
master_plane_id)

1570 {
1571 struct drm_plane *plane = NULL, *master_plane = NULL;
1572 const uint32_t *format_list;
1573 struct dpu_plane *pdpu;
1574 struct msm_drm_private *priv = dev->dev_private;
1575 struct dpu_kms *kms = to_dpu_kms(priv->kms);
1576 int zpos_max = DPU_ZPOS_MAX;
1577 uint32_t num_formats;
1578 int ret = -EINVAL;
1579
1580 /* create and zero local structure */
1581 pdpu = kzalloc(sizeof(*pdpu), GFP_KERNEL);
1582 if (!pdpu) {
1583 DPU_ERROR("[%u]failed to allocate local plane
struct\n", pipe);
1584 ret = -ENOMEM;
1585 return ERR_PTR(ret);
1586 }
1587
1588 /* cache local stuff for later */
1589 plane = &pdpu->base;
1590 pdpu->pipe = pipe;
1591 pdpu->is_virtual = (master_plane_id != 0);
1592 INIT_LIST_HEAD(&pdpu->mplane_list);
1593 master_plane = drm_plane_find(dev, NULL, 
master_plane_id);

1594 if (master_plane) {
1595 struct dpu_plane *mpdpu = 
to_dpu_plane(master_plane);

1596
1597 list_add_tail(&pdpu->mplane_list, 
&mpdpu->mplane_list);

^
This is not removed from the list in the error handling code so it will
lead to a Use After Free.

1598 }
1599
1600 /* initialize underlying h/w driver */
1601 pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, 
kms->catalog,

1602
master_plane_id != 0);
1603 if (IS_ERR(pdpu->pipe_hw)) {
1604 DPU_ERROR("[%u]SSPP init failed\n", pipe);
1605 ret = PTR_ERR(pdpu->pipe_hw);
1606 goto clean_plane;
1607 } else if (!pdpu->pipe_hw->cap || 
!pdpu->pipe_hw->cap->sblk) {

1608 DPU_ERROR("[%u]SSPP init returned invalid
cfg\n", pipe);
1609 goto clean_sspp;
1610 }
1611
1612 /* cache features mask for later */
1613 pdpu->features = pdpu->pipe_hw->cap->features;
1614 pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
1615 if (!pdpu->pipe_sblk) {
1616 DPU_ERROR("[%u]invalid sblk\n", pipe);
1617 goto clean_sspp;
1618 }
1619
1620 if (pdpu->is_virtual) {
1621 format_list = 
pdpu->pipe_sblk->virt_format_list;
1622 num_formats = 
pdpu->pipe_sblk->virt_num_formats;

1623 }
1624 else {
1625 format_list = pdpu->pipe_sblk->format_list;
1626 num_formats = pdpu->pipe_sblk->num_formats;
1627 }
1628
1629 ret = drm_universal_plane_init(dev, plane, 0xff,
&dpu_plane_funcs,
1630 format_list, num_formats,
1631 supported_format_modifiers,
type, NULL);
1632 if (ret)
1633 goto clean_sspp;
1634
1635 pdpu->catalog = kms->catalog;
1636
1637 if (kms->catalog->mixer_count &&
1638 kms->catalog->mixer[0].sblk->maxblendstages) {
1639 zpos_max =
kms->catalog->mixer[0].sblk->maxblendstages - 1;
1640 if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 
1)
1641 zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 
- 1;

1642 }
1643
1644 ret = drm_plane_create_zpos_property(plane, 0, 0, 
zpos_max);

1645 if (ret)
1646 DPU_ERROR("failed to install zpos property,
rc = %d\n", ret);
1647
1648 drm_plane_create_alpha_property(plane);
1649 drm_plane_create_blend_mode_property(plane,
1650 BIT(DRM_MODE_BLEND_PIXEL_NONE) |
1651 BIT(DRM_MODE_BLEND_PREMULTI) |
1652 BIT(DRM_MODE_BLEND_COVERAGE));
1653
1654 drm_plane_create_rotation_property(plane,
1655 DRM_MODE_ROTATE_0,
1656 DRM_MODE_ROTATE_0 |
1657 DRM_MODE_ROTATE_180 |

Re: [bug report] drm/msm: Add SDM845 DPU support

2021-10-01 Thread jesszhan

Hey Dan,

Thanks for the report, will take care of it.

On 2021-10-01 06:50, Dan Carpenter wrote:

On Fri, Oct 01, 2021 at 04:49:12PM +0300, Dan Carpenter wrote:

Hello Jeykumar Sankaran,

This is a semi-automatic email about new static checker warnings.

The patch 25fdd5933e4c: "drm/msm: Add SDM845 DPU support" from Jun
27, 2018, leads to the following Smatch complaint:

drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c:422 
_dpu_hw_sspp_setup_scaler3()
warn: variable dereferenced before check 'ctx->cap->sblk' (see 
line 421)


drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
   420  (void)pe;
^
You should file a bug report with your compiler devs instead of adding
these sorts of statements to your code.  This function is used as a
function pointer so unused parameters are normal.

   421		if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || 
!sspp


The _sspp_subblk_offset() dereferenced "ctx" before it is checked and
then it also derefereces "ctx->cap->sblk" without checking.

   422  || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk)
   


So these will have already crashed before we reach this point.



Same thing later as well.

drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c:591 
dpu_hw_sspp_setup_creq_lut()

warn: variable dereferenced before check 'ctx->cap' (see line 588)

regards,
dan carpenter


Best,
Jessica Zhang


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

2021-10-01 Thread Rob Herring
On Fri, 01 Oct 2021 11:11:41 -0400, 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.
> 
> 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(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/msm/dp-controller.example.dt.yaml:
 example-0: displayport-controller@ae9:reg:0: [0, 183042048, 0, 5120] is 
too long
From schema: 
/usr/local/lib/python3.8/dist-packages/dtschema/schemas/reg.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/msm/dp-controller.example.dt.yaml:
 example-0: displayport-controller@ae9:reg:1: [0, 183308288, 0, 372] is too 
long
From schema: 
/usr/local/lib/python3.8/dist-packages/dtschema/schemas/reg.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/msm/dp-controller.example.dt.yaml:
 example-0: displayport-controller@ae9:reg:2: [0, 183373824, 0, 44] is too 
long
From schema: 
/usr/local/lib/python3.8/dist-packages/dtschema/schemas/reg.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1535361

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



Re: [PATCH v2 00/17] drm: cleanup: Use DRM_MODESET_LOCK_ALL_* helpers where possible

2021-10-01 Thread Ville Syrjälä
On Fri, Oct 01, 2021 at 02:36:55PM -0400, Sean Paul wrote:
> On Fri, Sep 24, 2021 at 08:43:07AM +0200, Fernando Ramos wrote:
> > Hi all,
> > 
> > One of the things in the DRM TODO list ("Documentation/gpu/todo.rst") was to
> > "use DRM_MODESET_LOCAL_ALL_* helpers instead of boilerplate". That's what 
> > this
> > patch series is about.
> > 
> > You will find two types of changes here:
> > 
> >   - Replacing "drm_modeset_lock_all_ctx()" (and surrounding boilerplate) 
> > with
> > "DRM_MODESET_LOCK_ALL_BEGIN()/END()" in the remaining places (as it has
> > already been done in previous commits such as b7ea04d2)
> > 
> >   - Replacing "drm_modeset_lock_all()" with 
> > "DRM_MODESET_LOCK_ALL_BEGIN()/END()"
> > in the remaining places (as it has already been done in previous commits
> > such as 57037094)
> > 
> > Most of the changes are straight forward, except for a few cases in the 
> > "amd"
> > and "i915" drivers where some extra dancing was needed to overcome the
> > limitation that the DRM_MODESET_LOCK_ALL_BEGIN()/END() macros can only be 
> > used
> > once inside the same function (the reason being that the macro expansion
> > includes *labels*, and you can not have two labels named the same inside one
> > function)
> > 
> > Notice that, even after this patch series, some places remain where
> > "drm_modeset_lock_all()" and "drm_modeset_lock_all_ctx()" are still present,
> > all inside drm core (which makes sense), except for two (in "amd" and 
> > "i915")
> > which cannot be replaced due to the way they are being used.
> > 
> > Changes in v2:
> > 
> >   - Fix commit message typo
> >   - Use the value returned by DRM_MODESET_LOCK_ALL_END when possible
> >   - Split drm/i915 patch into two simpler ones
> >   - Remove drm_modeset_(un)lock_all()
> >   - Fix build problems in non-x86 platforms
> > 
> > Fernando Ramos (17):
> >   drm: cleanup: drm_modeset_lock_all_ctx() --> DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/i915: cleanup: drm_modeset_lock_all_ctx() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/msm: cleanup: drm_modeset_lock_all_ctx() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN() 
> > drm/vmwgfx: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/tegra: cleanup: drm_modeset_lock_all() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/shmobile: cleanup: drm_modeset_lock_all() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/radeon: cleanup: drm_modeset_lock_all() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/omapdrm: cleanup: drm_modeset_lock_all() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/nouveau: cleanup: drm_modeset_lock_all() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/msm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/i915: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/i915: cleanup: drm_modeset_lock_all() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN() part 2
> >   drm/gma500: cleanup: drm_modeset_lock_all() --> 
> > DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm/amd: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
> >   drm: cleanup: remove drm_modeset_(un)lock_all()
> >   doc: drm: remove TODO entry regarding DRM_MODSET_LOCK_ALL cleanup
> > 
> 
> Thank you for revising, Fernando! I've pushed the set to drm-misc-next (along
> with the necessary drm-tip conflict resolutions).

Ugh. Did anyone actually review the locking changes this does?
I shot the previous i915 stuff down because the commit messages
did not address any of it.

-- 
Ville Syrjälä
Intel


Re: [bug report] drm/msm/dp: add debugfs support to DP driver

2021-10-01 Thread jesszhan

Hey Dan,

Thanks for the heads up, will take care of it.

On 2021-10-01 06:59, Dan Carpenter wrote:

Hello Abhinav Kumar,

The patch d11a93690df7: "drm/msm/dp: add debugfs support to DP
driver" from Sep 12, 2020, leads to the following
Smatch static checker warning:

drivers/gpu/drm/msm/dp/dp_debug.c:194 dp_debug_read_info()
warn: userbuf overflow? is 'len' <= 'count'

drivers/gpu/drm/msm/dp/dp_debug.c
46 static ssize_t dp_debug_read_info(struct file *file, char
__user *user_buff,
47 size_t count, loff_t *ppos)
48 {
49 struct dp_debug_private *debug = file->private_data;
50 char *buf;
51 u32 len = 0, rc = 0;
52 u64 lclk = 0;
53 u32 max_size = SZ_4K;
54 u32 link_params_rate;
55 struct drm_display_mode *drm_mode;
56
57 if (!debug)
58 return -ENODEV;
59
60 if (*ppos)
61 return 0;
62
63 buf = kzalloc(SZ_4K, GFP_KERNEL);
64 if (!buf)
65 return -ENOMEM;
66
67 drm_mode = &debug->panel->dp_mode.drm_mode;
68
69 rc = snprintf(buf + len, max_size, "\tname = %s\n", 
DEBUG_NAME);

70 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
71 goto error;
72
73 rc = snprintf(buf + len, max_size,
74 "\tdp_panel\n\t\tmax_pclk_khz = %d\n",
75 debug->panel->max_pclk_khz);
76 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
77 goto error;
78
79 rc = snprintf(buf + len, max_size,
80 "\tdrm_dp_link\n\t\trate = %u\n",
81 debug->panel->link_info.rate);
82 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
83 goto error;
84
85 rc = snprintf(buf + len, max_size,
86  "\t\tnum_lanes = %u\n",
87 debug->panel->link_info.num_lanes);
88 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
89 goto error;
90
91 rc = snprintf(buf + len, max_size,
92 "\t\tcapabilities = %lu\n",
93 debug->panel->link_info.capabilities);
94 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
95 goto error;
96
97 rc = snprintf(buf + len, max_size,
98 "\tdp_panel_info:\n\t\tactive = 
%dx%d\n",

99 drm_mode->hdisplay,
100 drm_mode->vdisplay);
101 if (dp_debug_check_buffer_overflow(rc, &max_size, 
&len))

102 goto error;
103
104 rc = snprintf(buf + len, max_size,
105 "\t\tback_porch = %dx%d\n",
106 drm_mode->htotal - drm_mode->hsync_end,
107 drm_mode->vtotal - 
drm_mode->vsync_end);
108 if (dp_debug_check_buffer_overflow(rc, &max_size, 
&len))

109 goto error;
110
111 rc = snprintf(buf + len, max_size,
112 "\t\tfront_porch = %dx%d\n",
113 drm_mode->hsync_start - 
drm_mode->hdisplay,
114 drm_mode->vsync_start - 
drm_mode->vdisplay);
115 if (dp_debug_check_buffer_overflow(rc, &max_size, 
&len))

116 goto error;
117
118 rc = snprintf(buf + len, max_size,
119 "\t\tsync_width = %dx%d\n",
120 drm_mode->hsync_end - 
drm_mode->hsync_start,
121 drm_mode->vsync_end - 
drm_mode->vsync_start);
122 if (dp_debug_check_buffer_overflow(rc, &max_size, 
&len))

123 goto error;
124
125 rc = snprintf(buf + len, max_size,
126 "\t\tactive_low = %dx%d\n",
127 debug->panel->dp_mode.h_active_low,
128 debug->panel->dp_mode.v_active_low);
129 if (dp_debug_check_buffer_overflow(rc, &max_size, 
&len))

130 goto error;
131
132 rc = snprintf(buf + len, max_size,
133 "\t\th_skew = %d\n",
134 drm_mode->hskew);
135 if (dp_debug_check_buffer_overflow(rc, &max_size, 
&len))

136 goto error;
137
138 rc = snprintf(buf + len, max_size,
139 "\t\trefresh rate = %d\n",
140 drm_mode_vrefresh(drm_mode));
141 if (dp_debug_check_buffer_overflow(rc, &max_size, 
&len))

142 goto error;
143
144 rc = snprint

Re: [PATCH v13 13/35] drm/tegra: gr2d: Support generic power domain and runtime PM

2021-10-01 Thread Dmitry Osipenko
01.10.2021 17:55, Ulf Hansson пишет:
> On Fri, 1 Oct 2021 at 16:29, Dmitry Osipenko  wrote:
>>
>> 01.10.2021 16:39, Ulf Hansson пишет:
>>> On Mon, 27 Sept 2021 at 00:42, Dmitry Osipenko  wrote:

 Add runtime power management and support generic power domains.

 Tested-by: Peter Geis  # Ouya T30
 Tested-by: Paul Fertser  # PAZ00 T20
 Tested-by: Nicolas Chauvet  # PAZ00 T20 and TK1 T124
 Tested-by: Matt Merhar  # Ouya T30
 Signed-off-by: Dmitry Osipenko 
 ---
  drivers/gpu/drm/tegra/gr2d.c | 155 +--
>>>
>>> [...]
>>>
  static int gr2d_remove(struct platform_device *pdev)
 @@ -259,15 +312,101 @@ static int gr2d_remove(struct platform_device *pdev)
 return err;
 }

 +   pm_runtime_dont_use_autosuspend(&pdev->dev);
 +   pm_runtime_disable(&pdev->dev);
>>>
>>> There is no guarantee that the ->runtime_suspend() has been invoked
>>> here, which means that clock may be left prepared/enabled beyond this
>>> point.
>>>
>>> I suggest you call pm_runtime_force_suspend(), instead of
>>> pm_runtime_disable(), to make sure that gets done.
>>
>> The pm_runtime_disable() performs the final synchronization, please see [1].
>>
>> [1]
>> https://elixir.bootlin.com/linux/v5.15-rc3/source/drivers/base/power/runtime.c#L1412
> 
> pm_runtime_disable() end up calling _pm_runtime_barrier(), which calls
> cancel_work_sync() if dev->power.request_pending has been set.
> 
> If the work that was punted to the pm_wq in rpm_idle() has not been
> started yet, we end up just canceling it. In other words, there are no
> guarantees it runs to completion.

You're right. Although, in a case of this particular patch, the syncing
is actually implicitly done by pm_runtime_dont_use_autosuspend().

But for drivers which don't use auto-suspend, there is no sync. This
looks like a disaster, it's a very common pattern for drivers to
'put+disable'.

> Moreover, use space may have bumped the usage count via sysfs for the
> device (pm_runtime_forbid()) to keep the device runtime resumed.

Right, this is also a disaster in a case of driver removal.

>> Calling pm_runtime_force_suspend() isn't correct because each 'enable'
>> must have the corresponding 'disable'. Hence there is no problem here.
> 
> pm_runtime_force_suspend() calls pm_runtime_disable(), so I think that
> should be fine. No?

[adding Rafael]

Rafael, could you please explain how drivers are supposed to properly
suspend and disable RPM to cut off power and reset state that was
altered by the driver's resume callback? What we're missing? Is Ulf's
suggestion acceptable?

The RPM state of a device is getting reset on driver's removal, hence
all refcounts that were bumped by the rpm-resume callback of the device
driver will be screwed up if device is kept resumed after removal. I
just verified that it's true in practice.


Re: [bug report] drm/msm: dsi: Handle dual-channel for 6G as well

2021-10-01 Thread jesszhan

Hey Dan,

Thanks for the report, will take care of it.

On 2021-10-01 05:31, Dan Carpenter wrote:

Hello Sean Paul,

The patch a6bcddbc2ee1: "drm/msm: dsi: Handle dual-channel for 6G as
well" from Jul 25, 2018, leads to the following
Smatch static checker warning:

drivers/gpu/drm/msm/dsi/dsi_host.c:729 dsi_calc_clk_rate_6g()
warn: wrong type for 'msm_host->esc_clk_rate' (should be 'ulong')

drivers/gpu/drm/msm/dsi/dsi_host.c
721 int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool
is_bonded_dsi)
722 {
723 if (!msm_host->mode) {
724 pr_err("%s: mode not set\n", __func__);
725 return -EINVAL;
726 }
727
728 dsi_calc_pclk(msm_host, is_bonded_dsi);
--> 729 msm_host->esc_clk_rate = 
clk_get_rate(msm_host->esc_clk);

^^
I don't know why Smatch is suddenly warning about ancient msm code, but
clock rates should be unsigned long.  (I don't remember why).

730 return 0;
731 }

regards,
dan carpenter


Thanks,
Jessica Zhang


Re: linux-next: Tree for Oct 1 [drivers/gpu/drm/amd/amdgpu/amdgpu.ko]

2021-10-01 Thread Randy Dunlap

On 10/1/21 12:09 AM, Stephen Rothwell wrote:

Hi all,

News: there will be no linux-next release on Monday.

Changes since 20210930:



on i386:

ERROR: modpost: "dm_ip_block" [drivers/gpu/drm/amd/amdgpu/amdgpu.ko] undefined!

Full randconfig file is attached.

--
~Randy


config-r5146.gz
Description: application/gzip


Re: [PATCH v2 00/17] drm: cleanup: Use DRM_MODESET_LOCK_ALL_* helpers where possible

2021-10-01 Thread Sean Paul
On Fri, Sep 24, 2021 at 08:43:07AM +0200, Fernando Ramos wrote:
> Hi all,
> 
> One of the things in the DRM TODO list ("Documentation/gpu/todo.rst") was to
> "use DRM_MODESET_LOCAL_ALL_* helpers instead of boilerplate". That's what this
> patch series is about.
> 
> You will find two types of changes here:
> 
>   - Replacing "drm_modeset_lock_all_ctx()" (and surrounding boilerplate) with
> "DRM_MODESET_LOCK_ALL_BEGIN()/END()" in the remaining places (as it has
> already been done in previous commits such as b7ea04d2)
> 
>   - Replacing "drm_modeset_lock_all()" with 
> "DRM_MODESET_LOCK_ALL_BEGIN()/END()"
> in the remaining places (as it has already been done in previous commits
> such as 57037094)
> 
> Most of the changes are straight forward, except for a few cases in the "amd"
> and "i915" drivers where some extra dancing was needed to overcome the
> limitation that the DRM_MODESET_LOCK_ALL_BEGIN()/END() macros can only be used
> once inside the same function (the reason being that the macro expansion
> includes *labels*, and you can not have two labels named the same inside one
> function)
> 
> Notice that, even after this patch series, some places remain where
> "drm_modeset_lock_all()" and "drm_modeset_lock_all_ctx()" are still present,
> all inside drm core (which makes sense), except for two (in "amd" and "i915")
> which cannot be replaced due to the way they are being used.
> 
> Changes in v2:
> 
>   - Fix commit message typo
>   - Use the value returned by DRM_MODESET_LOCK_ALL_END when possible
>   - Split drm/i915 patch into two simpler ones
>   - Remove drm_modeset_(un)lock_all()
>   - Fix build problems in non-x86 platforms
> 
> Fernando Ramos (17):
>   drm: cleanup: drm_modeset_lock_all_ctx() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/i915: cleanup: drm_modeset_lock_all_ctx() --> 
> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/msm: cleanup: drm_modeset_lock_all_ctx() --> 
> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN() 
> drm/vmwgfx: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/tegra: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/shmobile: cleanup: drm_modeset_lock_all() --> 
> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/radeon: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/omapdrm: cleanup: drm_modeset_lock_all() --> 
> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/nouveau: cleanup: drm_modeset_lock_all() --> 
> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/msm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/i915: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/i915: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN() 
> part 2
>   drm/gma500: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm/amd: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()
>   drm: cleanup: remove drm_modeset_(un)lock_all()
>   doc: drm: remove TODO entry regarding DRM_MODSET_LOCK_ALL cleanup
> 

Thank you for revising, Fernando! I've pushed the set to drm-misc-next (along
with the necessary drm-tip conflict resolutions).

Sean

>  Documentation/gpu/todo.rst| 17 
>  Documentation/locking/ww-mutex-design.rst |  2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 21 +++--
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 50 +-
>  .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 25 ++---
>  drivers/gpu/drm/drm_client_modeset.c  | 14 ++-
>  drivers/gpu/drm/drm_crtc_helper.c | 18 ++--
>  drivers/gpu/drm/drm_fb_helper.c   | 10 +-
>  drivers/gpu/drm/drm_framebuffer.c |  6 +-
>  drivers/gpu/drm/drm_modeset_lock.c| 94 +--
>  drivers/gpu/drm/gma500/psb_device.c   | 18 ++--
>  drivers/gpu/drm/i915/display/intel_audio.c| 16 ++--
>  drivers/gpu/drm/i915/display/intel_display.c  | 23 ++---
>  .../drm/i915/display/intel_display_debugfs.c  | 46 +
>  drivers/gpu/drm/i915/display/intel_overlay.c  | 46 -
>  drivers/gpu/drm/i915/display/intel_pipe_crc.c |  7 +-
>  drivers/gpu/drm/i915/i915_drv.c   | 13 ++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 10 +-
>  .../gpu/drm/msm/disp/msm_disp_snapshot_util.c | 12 +--
>  drivers/gpu/drm/nouveau/dispnv50/disp.c   | 15 ++-
>  drivers/gpu/drm/omapdrm/omap_fb.c |  9 +-
>  drivers/gpu/drm/radeon/radeon_device.c| 21 +++--
>  drivers/gpu/drm/radeon/radeon_dp_mst.c| 10 +-
>  drivers/gpu/drm/shmobile/shmob_drm_drv.c  |  6 +-
>  drivers/gpu/drm/tegra/dsi.c   |  6 +-
>  drivers/gpu/drm/tegra/hdmi.c  |  6 +-
>  drivers/gpu/drm/tegra/sor.c   | 11 ++-
>  drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 11 ++-
>  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   | 12 ++-
>  include/drm/drm_modeset_lock.h|  2 -
>  30 files changed, 265 ins

Re: [PATCH] drm/msm: Fix null pointer dereference on pointer edp

2021-10-01 Thread Dmitry Baryshkov

On 29/09/2021 15:18, Colin King wrote:

From: Colin Ian King 

The initialization of pointer dev dereferences pointer edp before
edp is null checked, so there is a potential null pointer deference
issue. Fix this by only dereferencing edp after edp has been null
checked.

Addresses-Coverity: ("Dereference before null check")
Fixes: ab5b0107ccf3 ("drm/msm: Initial add eDP support in msm drm driver (v5)")
Signed-off-by: Colin Ian King 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/edp/edp_ctrl.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c 
b/drivers/gpu/drm/msm/edp/edp_ctrl.c
index 4fb397ee7c84..fe1366b4c49f 100644
--- a/drivers/gpu/drm/msm/edp/edp_ctrl.c
+++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c
@@ -1116,7 +1116,7 @@ void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on)
  int msm_edp_ctrl_init(struct msm_edp *edp)
  {
struct edp_ctrl *ctrl = NULL;
-   struct device *dev = &edp->pdev->dev;
+   struct device *dev;
int ret;
  
  	if (!edp) {

@@ -1124,6 +1124,7 @@ int msm_edp_ctrl_init(struct msm_edp *edp)
return -EINVAL;
}
  
+	dev = &edp->pdev->dev;

ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
return -ENOMEM;




--
With best wishes
Dmitry


Re: [PATCH] drm/i915: Use fixed offset for PTEs location

2021-10-01 Thread Matt Roper
On Thu, Sep 30, 2021 at 03:01:19PM -0700, Matt Roper wrote:
> On Sun, Sep 26, 2021 at 10:10:05PM +0200, Michal Wajdeczko wrote:
> > We assumed that for all modern GENs the PTEs and register space are
> > split in the GTTMMADR BAR, but while it is true, we should rather use
> > fixed offset as it is defined in the specification.
> > 
> > Bspec: 4409, 4457, 4604, 11181, 9027, 13246, 13321, 44980
> > 
> > Signed-off-by: Michal Wajdeczko 
> > Cc: CQ Tang 
> > Cc: Matt Roper 
> 
> Matches the descriptions on all the various bspec pages.
> 
> Reviewed-by: Matt Roper 

And applied to drm-intel-gt-next.  Thanks for the patch.


Matt

> 
> > ---
> >  drivers/gpu/drm/i915/gt/intel_ggtt.c | 19 +--
> >  1 file changed, 17 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
> > b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> > index ba7c7ed89fa8..f17383e76eb7 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> > @@ -813,6 +813,21 @@ static unsigned int chv_get_total_gtt_size(u16 
> > gmch_ctrl)
> > return 0;
> >  }
> >  
> > +static unsigned int gen6_gttmmadr_size(struct drm_i915_private *i915)
> > +{
> > +   /*
> > +* GEN6: GTTMMADR size is 4MB and GTTADR starts at 2MB offset
> > +* GEN8: GTTMMADR size is 16MB and GTTADR starts at 8MB offset
> > +*/
> > +   GEM_BUG_ON(GRAPHICS_VER(i915) < 6);
> > +   return (GRAPHICS_VER(i915) < 8) ? SZ_4M : SZ_16M;
> > +}
> > +
> > +static unsigned int gen6_gttadr_offset(struct drm_i915_private *i915)
> > +{
> > +   return gen6_gttmmadr_size(i915) / 2;
> > +}
> > +
> >  static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
> >  {
> > struct drm_i915_private *i915 = ggtt->vm.i915;
> > @@ -821,8 +836,8 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
> > u64 size)
> > u32 pte_flags;
> > int ret;
> >  
> > -   /* For Modern GENs the PTEs and register space are split in the BAR */
> > -   phys_addr = pci_resource_start(pdev, 0) + pci_resource_len(pdev, 0) / 2;
> > +   GEM_WARN_ON(pci_resource_len(pdev, 0) != gen6_gttmmadr_size(i915));
> > +   phys_addr = pci_resource_start(pdev, 0) + gen6_gttadr_offset(i915);
> >  
> > /*
> >  * On BXT+/ICL+ writes larger than 64 bit to the GTT pagetable range
> > -- 
> > 2.25.1
> > 
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> VTT-OSGC Platform Enablement
> Intel Corporation
> (916) 356-2795

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795


Re: [PATCH v2 3/3] drm/bridge: ti-sn65dsi86: Add NO_CONNECTOR support

2021-10-01 Thread Doug Anderson
Hi,

On Thu, Sep 23, 2021 at 7:26 PM Laurent Pinchart
 wrote:
>
> > > >  err_conn_init:
> > > >   drm_dp_aux_unregister(&pdata->aux);
> > > >   return ret;
> > > > @@ -792,9 +790,30 @@ static void ti_sn_bridge_set_dsi_rate(struct 
> > > > ti_sn65dsi86 *pdata)
> > > >   regmap_write(pdata->regmap, SN_DSIA_CLK_FREQ_REG, val);
> > > >  }
> > > >
> > > > +/*
> > > > + * Find the connector and fish out the bpc from display_info.  It would
> > > > + * be nice if we could get this instead from drm_bridge_state, but that
> > > > + * doesn't yet appear to be the case.
> > >
> > > You already have a bus format in the bridge state, from which you can
> > > derive the bpp. Could you give it a try ?
> >
> > Possibly the bridge should be converted to ->atomic_enable(), etc..
> > I'll leave that for another time
>
> It should be fairly straightforward, and would avoid the hack below.

Given this point of controversy, my inclination is to wait and not
apply this patch now. I don't think there's anything urgent here,
right? Worst case eventually Laurent might pick it up in his patch
series? At least we know it will work with the MSM driver once patch
#1 lands. :-)


-Doug


Re: [RFC] drm/msm/a6xx: Serialize GMU communication

2021-10-01 Thread Dmitry Baryshkov

On 01/10/2021 21:05, Rob Clark wrote:

On Fri, Oct 1, 2021 at 10:39 AM Dmitry Baryshkov
 wrote:


On 27/09/2021 21:03, Rob Clark wrote:

From: Rob Clark 

I've seen some crashes in our crash reporting that *look* like multiple
threads stomping on each other while communicating with GMU.  So wrap
all those paths in a lock.

Signed-off-by: Rob Clark 
---
Are we allowed to use c99/gnu99 yet?

   drivers/gpu/drm/msm/Makefile  |  2 +-
   drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  6 
   drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  9 +
   drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 50 ---
   4 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 904535eda0c4..57283bbad3f0 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -1,5 +1,5 @@
   # SPDX-License-Identifier: GPL-2.0
-ccflags-y := -I $(srctree)/$(src)
+ccflags-y := -I $(srctree)/$(src) -std=gnu99
   ccflags-y += -I $(srctree)/$(src)/disp/dpu1
   ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi
   ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index a7c58018959f..8b73f70766a4 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -296,6 +296,8 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
   u32 val;
   int request, ack;

+ WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
   if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
   return -EINVAL;

@@ -337,6 +339,8 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
   {
   int bit;

+ WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
   if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
   return;

@@ -1482,6 +1486,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct 
device_node *node)
   if (!pdev)
   return -ENODEV;

+ mutex_init(&gmu->lock);
+
   gmu->dev = &pdev->dev;

   of_dma_configure(gmu->dev, node, true);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index 3c74f64e3126..f05a00c0afd0 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -44,6 +44,9 @@ struct a6xx_gmu_bo {
   struct a6xx_gmu {
   struct device *dev;

+ /* For serializing communication with the GMU: */
+ struct mutex lock;
+
   struct msm_gem_address_space *aspace;

   void * __iomem mmio;
@@ -88,6 +91,12 @@ struct a6xx_gmu {
   bool legacy; /* a618 or a630 */
   };

+/* Helper macro for serializing GMU access: */
+#define with_gmu_lock(gmu) \
+ for (bool done = ({ mutex_lock(&(gmu)->lock); false; }); \
+ !done; \
+ done = ({ mutex_unlock(&(gmu)->lock); true; }))


The intent is good, but I'm not sure this kind of syntax sugar would be
a good approach. What about calling lock/unlock explicitly, like we
typically do? Then we won't have to use c99.


Yeah, I was planning to resend without the sugar.. but it was a good
excuse to bring up c99.  Ie. I want c99 regardless ;-)

(The sugar was useful initially before I'd sorted thru all the code
paths and settled on using a mutex vs spinlock)


We can always have GMU_LOCK/GMU_UNLOCK macros.



BR,
-R


+
   static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
   {
   return msm_readl(gmu->mmio + (offset << 2));
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index f6a4dbef796b..5e1ae3df42ba 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -881,7 +881,7 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
 A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
 A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR)

-static int a6xx_hw_init(struct msm_gpu *gpu)
+static int hw_init(struct msm_gpu *gpu)
   {
   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
@@ -1135,6 +1135,19 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
   return ret;
   }

+static int a6xx_hw_init(struct msm_gpu *gpu)
+{
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+ int ret;
+
+ with_gmu_lock(&a6xx_gpu->gmu) {
+ ret = hw_init(gpu);
+ }
+
+ return ret;
+}
+
   static void a6xx_dump(struct msm_gpu *gpu)
   {
   DRM_DEV_INFO(&gpu->pdev->dev, "status:   %08x\n",
@@ -1509,7 +1522,9 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)

   trace_msm_gpu_resume(0);

- ret = a6xx_gmu_resume(a6xx_gpu);
+ with_gmu_lock(&a6xx_gpu->gmu) {
+ ret = a6xx_gmu_resume(a6xx_gpu);
+ }
   if (ret)
   return ret;

@@ -1532,7 +1547,9 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)

   msm_devfr

Re: [PATCH v2 2/3] drm/bridge: ti-sn65dsi86: Implement bridge->mode_valid()

2021-10-01 Thread Doug Anderson
Hi,

On Wed, Sep 22, 2021 at 5:31 PM Laurent Pinchart
 wrote:
>
> Hi Rob,
>
> Thank you for the patch.
>
> On Mon, Sep 20, 2021 at 03:57:59PM -0700, Rob Clark wrote:
> > From: Rob Clark 
> >
> > For the brave new world of bridges not creating their own connectors, we
> > need to implement the max clock limitation via bridge->mode_valid()
> > instead of connector->mode_valid().
> >
> > v2: Drop unneeded connector->mode_valid()
> >
> > Signed-off-by: Rob Clark 
> > Reviewed-by: Douglas Anderson 
>
> Reviewed-by: Laurent Pinchart 
>
> > ---
> >  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 25 +
> >  1 file changed, 13 insertions(+), 12 deletions(-)

There's no reason to wait on this patch. Landed to drm-misc-next.

77d40e0176a5 drm/bridge: ti-sn65dsi86: Implement bridge->mode_valid()

-Doug


Re: [RFC] drm/msm/a6xx: Serialize GMU communication

2021-10-01 Thread Rob Clark
On Fri, Oct 1, 2021 at 10:39 AM Dmitry Baryshkov
 wrote:
>
> On 27/09/2021 21:03, Rob Clark wrote:
> > From: Rob Clark 
> >
> > I've seen some crashes in our crash reporting that *look* like multiple
> > threads stomping on each other while communicating with GMU.  So wrap
> > all those paths in a lock.
> >
> > Signed-off-by: Rob Clark 
> > ---
> > Are we allowed to use c99/gnu99 yet?
> >
> >   drivers/gpu/drm/msm/Makefile  |  2 +-
> >   drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  6 
> >   drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  9 +
> >   drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 50 ---
> >   4 files changed, 54 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> > index 904535eda0c4..57283bbad3f0 100644
> > --- a/drivers/gpu/drm/msm/Makefile
> > +++ b/drivers/gpu/drm/msm/Makefile
> > @@ -1,5 +1,5 @@
> >   # SPDX-License-Identifier: GPL-2.0
> > -ccflags-y := -I $(srctree)/$(src)
> > +ccflags-y := -I $(srctree)/$(src) -std=gnu99
> >   ccflags-y += -I $(srctree)/$(src)/disp/dpu1
> >   ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi
> >   ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > index a7c58018959f..8b73f70766a4 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > @@ -296,6 +296,8 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
> > a6xx_gmu_oob_state state)
> >   u32 val;
> >   int request, ack;
> >
> > + WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
> > +
> >   if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
> >   return -EINVAL;
> >
> > @@ -337,6 +339,8 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum 
> > a6xx_gmu_oob_state state)
> >   {
> >   int bit;
> >
> > + WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
> > +
> >   if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
> >   return;
> >
> > @@ -1482,6 +1486,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct 
> > device_node *node)
> >   if (!pdev)
> >   return -ENODEV;
> >
> > + mutex_init(&gmu->lock);
> > +
> >   gmu->dev = &pdev->dev;
> >
> >   of_dma_configure(gmu->dev, node, true);
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
> > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> > index 3c74f64e3126..f05a00c0afd0 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> > @@ -44,6 +44,9 @@ struct a6xx_gmu_bo {
> >   struct a6xx_gmu {
> >   struct device *dev;
> >
> > + /* For serializing communication with the GMU: */
> > + struct mutex lock;
> > +
> >   struct msm_gem_address_space *aspace;
> >
> >   void * __iomem mmio;
> > @@ -88,6 +91,12 @@ struct a6xx_gmu {
> >   bool legacy; /* a618 or a630 */
> >   };
> >
> > +/* Helper macro for serializing GMU access: */
> > +#define with_gmu_lock(gmu) \
> > + for (bool done = ({ mutex_lock(&(gmu)->lock); false; }); \
> > + !done; \
> > + done = ({ mutex_unlock(&(gmu)->lock); true; }))
>
> The intent is good, but I'm not sure this kind of syntax sugar would be
> a good approach. What about calling lock/unlock explicitly, like we
> typically do? Then we won't have to use c99.

Yeah, I was planning to resend without the sugar.. but it was a good
excuse to bring up c99.  Ie. I want c99 regardless ;-)

(The sugar was useful initially before I'd sorted thru all the code
paths and settled on using a mutex vs spinlock)

BR,
-R

> > +
> >   static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
> >   {
> >   return msm_readl(gmu->mmio + (offset << 2));
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > index f6a4dbef796b..5e1ae3df42ba 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > @@ -881,7 +881,7 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
> > A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR)
> >
> > -static int a6xx_hw_init(struct msm_gpu *gpu)
> > +static int hw_init(struct msm_gpu *gpu)
> >   {
> >   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> >   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
> > @@ -1135,6 +1135,19 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
> >   return ret;
> >   }
> >
> > +static int a6xx_hw_init(struct msm_gpu *gpu)
> > +{
> > + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> > + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
> > + int ret;
> > +
> > + with_gmu_lock(&a6xx_gpu->gmu) {
> > + ret = hw_init(gpu);
> > + }
> > +
> > + return ret;
> > +}
> > +
> >   static void a6xx_dump(struct msm_gpu *gpu)
> >   {
> >   DRM_DEV_INFO(&gpu->pdev->dev, "status:   %08x\n",
> > @@ -150

[PATCH v3 2/5] drm/msm/dp: Modify prototype of encoder based API

2021-10-01 Thread Bjorn Andersson
Functions in the DisplayPort code that relates to individual instances
(encoders) are passed both the struct msm_dp and the struct drm_encoder. But
in a situation where multiple DP instances would exist this means that
the caller need to resolve which struct msm_dp relates to the struct
drm_encoder at hand.

Store a reference to the struct msm_dp associated with each
dpu_encoder_virt to allow the particular instance to be associate with
the encoder in the following patch.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0e9d3fa1544b..b7f33da2799c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -168,6 +168,7 @@ enum dpu_enc_rc_states {
  * @vsync_event_work:  worker to handle vsync event for autorefresh
  * @topology:   topology of the display
  * @idle_timeout:  idle timeout duration in milliseconds
+ * @dp:msm_dp pointer, for DP encoders
  */
 struct dpu_encoder_virt {
struct drm_encoder base;
@@ -206,6 +207,8 @@ struct dpu_encoder_virt {
struct msm_display_topology topology;
 
u32 idle_timeout;
+
+   struct msm_dp *dp;
 };
 
 #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base)
@@ -1000,8 +1003,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder 
*drm_enc,
 
trace_dpu_enc_mode_set(DRMID(drm_enc));
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp)
-   msm_dp_display_mode_set(priv->dp, drm_enc, mode, adj_mode);
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS)
+   msm_dp_display_mode_set(dpu_enc->dp, drm_enc, mode, adj_mode);
 
list_for_each_entry(conn_iter, connector_list, head)
if (conn_iter->encoder == drm_enc)
@@ -1182,9 +1185,8 @@ static void dpu_encoder_virt_enable(struct drm_encoder 
*drm_enc)
 
_dpu_encoder_virt_enable_helper(drm_enc);
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
-   ret = msm_dp_display_enable(priv->dp,
-   drm_enc);
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
+   ret = msm_dp_display_enable(dpu_enc->dp, drm_enc);
if (ret) {
DPU_ERROR_ENC(dpu_enc, "dp display enable failed: %d\n",
ret);
@@ -1224,8 +1226,8 @@ static void dpu_encoder_virt_disable(struct drm_encoder 
*drm_enc)
/* wait for idle */
dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
-   if (msm_dp_display_pre_disable(priv->dp, drm_enc))
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
+   if (msm_dp_display_pre_disable(dpu_enc->dp, drm_enc))
DPU_ERROR_ENC(dpu_enc, "dp display push idle failed\n");
}
 
@@ -1253,8 +1255,8 @@ static void dpu_encoder_virt_disable(struct drm_encoder 
*drm_enc)
 
DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
-   if (msm_dp_display_disable(priv->dp, drm_enc))
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
+   if (msm_dp_display_disable(dpu_enc->dp, drm_enc))
DPU_ERROR_ENC(dpu_enc, "dp display disable failed\n");
}
 
@@ -2170,7 +2172,8 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
timer_setup(&dpu_enc->vsync_event_timer,
dpu_encoder_vsync_event_handler,
0);
-
+   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
+   dpu_enc->dp = priv->dp;
 
INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
dpu_encoder_off_work);
-- 
2.29.2



[PATCH v3 3/5] drm/msm/dp: Support up to 3 DP controllers

2021-10-01 Thread Bjorn Andersson
Based on the removal of the g_dp_display and the movement of the
priv->dp lookup into the DP code it's now possible to have multiple
DP instances.

In line with the other controllers in the MSM driver, introduce a
per-compatible list of base addresses which is used to resolve the
"instance id" for the given DP controller. This instance id is used as
index in the priv->dp[] array.

Then extend the initialization code to initialize struct drm_encoder for
each of the registered priv->dp[] and update the logic for associating
each struct msm_dp with the struct dpu_encoder_virt.

Lastly, bump the number of struct msm_dp instances carries by priv->dp
to 3, the currently known maximum number of controllers found in a
Qualcomm SoC.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Added MSM_DRM_DP_COUNT to link the two 3s
- Moved NULL check for msm_dp_debugfs_init() to the call site
- Made struct dp_display_private->id unsigned

I also implemented added connector_type to each of the DP instances and
propagated this to dp_drm_connector_init() but later dropped this again per
Doug's suggestion that we'll base this on the presence/absence of a associated
drm bridge or panel.

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 66 +++
 .../gpu/drm/msm/disp/msm_disp_snapshot_util.c |  8 ++-
 drivers/gpu/drm/msm/dp/dp_display.c   | 44 -
 drivers/gpu/drm/msm/msm_drv.h |  4 +-
 5 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index b7f33da2799c..9cd9539a1504 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2173,7 +2173,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
dpu_encoder_vsync_event_handler,
0);
else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
-   dpu_enc->dp = priv->dp;
+   dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]];
 
INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
dpu_encoder_off_work);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index f655adbc2421..875b07e7183d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -188,6 +188,7 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct 
drm_minor *minor)
struct dentry *entry;
struct drm_device *dev;
struct msm_drm_private *priv;
+   int i;
 
if (!p)
return -EINVAL;
@@ -203,8 +204,10 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, 
struct drm_minor *minor)
dpu_debugfs_vbif_init(dpu_kms, entry);
dpu_debugfs_core_irq_init(dpu_kms, entry);
 
-   if (priv->dp)
-   msm_dp_debugfs_init(priv->dp, minor);
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (priv->dp[i])
+   msm_dp_debugfs_init(priv->dp[i], minor);
+   }
 
return dpu_core_perf_debugfs_init(dpu_kms, entry);
 }
@@ -544,35 +547,42 @@ static int _dpu_kms_initialize_displayport(struct 
drm_device *dev,
 {
struct drm_encoder *encoder = NULL;
struct msm_display_info info;
-   int rc = 0;
+   int rc;
+   int i;
 
-   if (!priv->dp)
-   return rc;
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (!priv->dp[i])
+   continue;
 
-   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
-   if (IS_ERR(encoder)) {
-   DPU_ERROR("encoder init failed for dsi display\n");
-   return PTR_ERR(encoder);
-   }
+   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
+   if (IS_ERR(encoder)) {
+   DPU_ERROR("encoder init failed for dsi display\n");
+   return PTR_ERR(encoder);
+   }
 
-   memset(&info, 0, sizeof(info));
-   rc = msm_dp_modeset_init(priv->dp, dev, encoder);
-   if (rc) {
-   DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
-   drm_encoder_cleanup(encoder);
-   return rc;
-   }
+   memset(&info, 0, sizeof(info));
+   rc = msm_dp_modeset_init(priv->dp[i], dev, encoder);
+   if (rc) {
+   DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
+   drm_encoder_cleanup(encoder);
+   return rc;
+   }
 
-   priv->encoders[priv->num_encoders++] = encoder;
+   priv->encoders[priv->num_encoders++] = encoder;
 
-   info.num_of_h_tiles = 1;
-   info.capabilities = MSM_DISPLAY_CAP_VID_MODE;
-   info.intf_type = encoder->encoder_type;
-   r

[PATCH v3 5/5] drm/msm/dp: Add sc8180x DP controllers

2021-10-01 Thread Bjorn Andersson
The sc8180x has 2 DP and 1 eDP controllers, add support for these to the
DP driver.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None

 drivers/gpu/drm/msm/dp/dp_display.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index ff3477474c5d..56a79aeffed4 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -127,8 +127,15 @@ static const struct msm_dp_config sc7180_dp_cfg = {
.num_descs = 1,
 };
 
+static const struct msm_dp_config sc8180x_dp_cfg = {
+   .io_start = { 0xae9, 0xae98000, 0xae9a000 },
+   .num_descs = 3,
+};
+
 static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg },
+   { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_cfg },
+   { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_cfg },
{}
 };
 
-- 
2.29.2



[PATCH v3 4/5] dt-bindings: msm/dp: Add SC8180x compatibles

2021-10-01 Thread Bjorn Andersson
The Qualcomm SC8180x has 2 DP controllers and 1 eDP controller, add
compatibles for these to the msm/dp binding.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None

 .../devicetree/bindings/display/msm/dp-controller.yaml  | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 6bb424c21340..63e585f48789 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -17,6 +17,8 @@ properties:
   compatible:
 enum:
   - qcom,sc7180-dp
+  - qcom,sc8180x-dp
+  - qcom,sc8180x-edp
 
   reg:
 items:
-- 
2.29.2



[PATCH v3 1/5] drm/msm/dp: Remove global g_dp_display variable

2021-10-01 Thread Bjorn Andersson
As the Qualcomm DisplayPort driver only supports a single instance of
the driver the commonly used struct dp_display is kept in a global
variable. As we introduce additional instances this obviously doesn't
work.

Replace this with a combination of existing references to adjacent
objects and drvdata.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None

 drivers/gpu/drm/msm/dp/dp_display.c | 80 -
 1 file changed, 21 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index fbe4c2cd52a3..5d3ee5ef07c2 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -27,7 +27,6 @@
 #include "dp_audio.h"
 #include "dp_debug.h"
 
-static struct msm_dp *g_dp_display;
 #define HPD_STRING_SIZE 30
 
 enum {
@@ -121,6 +120,13 @@ static const struct of_device_id dp_dt_match[] = {
{}
 };
 
+static struct dp_display_private *dev_get_dp_display_private(struct device 
*dev)
+{
+   struct msm_dp *dp = dev_get_drvdata(dev);
+
+   return container_of(dp, struct dp_display_private, dp_display);
+}
+
 static int dp_add_event(struct dp_display_private *dp_priv, u32 event,
u32 data, u32 delay)
 {
@@ -197,15 +203,12 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
   void *data)
 {
int rc = 0;
-   struct dp_display_private *dp;
-   struct drm_device *drm;
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);
struct msm_drm_private *priv;
+   struct drm_device *drm;
 
drm = dev_get_drvdata(master);
 
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
-
dp->dp_display.drm_dev = drm;
priv = drm->dev_private;
priv->dp = &(dp->dp_display);
@@ -240,13 +243,10 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
 static void dp_display_unbind(struct device *dev, struct device *master,
  void *data)
 {
-   struct dp_display_private *dp;
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;
 
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
-
dp_power_client_deinit(dp->power);
dp_aux_unregister(dp->aux);
priv->dp = NULL;
@@ -379,38 +379,17 @@ static void dp_display_host_deinit(struct 
dp_display_private *dp)
 
 static int dp_display_usbpd_configure_cb(struct device *dev)
 {
-   int rc = 0;
-   struct dp_display_private *dp;
-
-   if (!dev) {
-   DRM_ERROR("invalid dev\n");
-   rc = -EINVAL;
-   goto end;
-   }
-
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);
 
dp_display_host_init(dp, false);
 
-   rc = dp_display_process_hpd_high(dp);
-end:
-   return rc;
+   return dp_display_process_hpd_high(dp);
 }
 
 static int dp_display_usbpd_disconnect_cb(struct device *dev)
 {
int rc = 0;
-   struct dp_display_private *dp;
-
-   if (!dev) {
-   DRM_ERROR("invalid dev\n");
-   rc = -EINVAL;
-   return rc;
-   }
-
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);
 
dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
 
@@ -472,15 +451,7 @@ static int dp_display_usbpd_attention_cb(struct device 
*dev)
 {
int rc = 0;
u32 sink_request;
-   struct dp_display_private *dp;
-
-   if (!dev) {
-   DRM_ERROR("invalid dev\n");
-   return -EINVAL;
-   }
-
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);
 
/* check for any test request issued by sink */
rc = dp_link_process_request(dp->link);
@@ -647,7 +618,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private 
*dp, u32 data)
 
DRM_DEBUG_DP("hpd_state=%d\n", state);
/* signal the disconnect event early to ensure proper teardown */
-   dp_display_handle_plugged_change(g_dp_display, false);
+   dp_display_handle_plugged_change(&dp->dp_display, false);
 
/* enable HDP plug interrupt to prepare for next plugin */
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true);
@@ -842,9 +813,7 @@ static int dp_display_prepare(struct msm_dp *dp)
 static int dp_display_enable(struct dp_display_private *dp, u32 data)
 {
   

[PATCH v3 0/5] drm/msm/dp: Support multiple DP instances and add sc8180x

2021-10-01 Thread Bjorn Andersson
The current implementation supports a single DP instance and the DPU code will
only match it against INTF_DP instance 0. These patches extends this to allow
multiple DP instances and support for matching against DP instances beyond 0.

With that in place add SC8180x DP and eDP controllers.

Bjorn Andersson (5):
  drm/msm/dp: Remove global g_dp_display variable
  drm/msm/dp: Modify prototype of encoder based API
  drm/msm/dp: Support up to 3 DP controllers
  dt-bindings: msm/dp: Add SC8180x compatibles
  drm/msm/dp: Add sc8180x DP controllers

 .../bindings/display/msm/dp-controller.yaml   |   2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  23 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  66 +
 .../gpu/drm/msm/disp/msm_disp_snapshot_util.c |   8 +-
 drivers/gpu/drm/msm/dp/dp_display.c   | 131 +-
 drivers/gpu/drm/msm/msm_drv.h |   4 +-
 6 files changed, 132 insertions(+), 102 deletions(-)

-- 
2.29.2



Re: [PATCH v2 1/3] drm/msm/dsi: Support NO_CONNECTOR bridges

2021-10-01 Thread Rob Clark
On Fri, Oct 1, 2021 at 10:28 AM Dmitry Baryshkov
 wrote:
>
> On 21/09/2021 01:57, Rob Clark wrote:
> > From: Rob Clark 
> >
> > For now, since we have a mix of bridges which support this flag, which
> > which do *not* support this flag, or work both ways, try it once with
> > NO_CONNECTOR and then fall back to the old way if that doesn't work.
> > Eventually we can drop the fallback path.
> >
> > v2: Add missing drm_connector_attach_encoder() so display actually comes
> >  up when the bridge properly handles the NO_CONNECTOR flag
> >
> > Signed-off-by: Rob Clark 
> > Reviewed-by: Laurent Pinchart 
>
> Reviewed-by: Dmitry Baryshkov 
>
> I think this patch can go through the drm/msm, while two other patches
> would need to through the drm-misc. Is it correct?

Correct, I made sure things worked in either order (ie. with msm patch
but without bridge patches, and visa versa), so they can land through
different trees

BR,
-R

>
> > ---
> >   drivers/gpu/drm/msm/Kconfig   |  2 ++
> >   drivers/gpu/drm/msm/dsi/dsi_manager.c | 50 ---
> >   2 files changed, 39 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
> > index e9c6af78b1d7..36e5ba3ccc28 100644
> > --- a/drivers/gpu/drm/msm/Kconfig
> > +++ b/drivers/gpu/drm/msm/Kconfig
> > @@ -14,6 +14,8 @@ config DRM_MSM
> >   select REGULATOR
> >   select DRM_KMS_HELPER
> >   select DRM_PANEL
> > + select DRM_BRIDGE
> > + select DRM_PANEL_BRIDGE
> >   select DRM_SCHED
> >   select SHMEM
> >   select TMPFS
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
> > b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> > index c41d39f5b7cf..e25877073d31 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> > @@ -3,6 +3,8 @@
> >* Copyright (c) 2015, The Linux Foundation. All rights reserved.
> >*/
> >
> > +#include "drm/drm_bridge_connector.h"
> > +
> >   #include "msm_kms.h"
> >   #include "dsi.h"
> >
> > @@ -688,10 +690,10 @@ struct drm_connector 
> > *msm_dsi_manager_ext_bridge_init(u8 id)
> >   {
> >   struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> >   struct drm_device *dev = msm_dsi->dev;
> > + struct drm_connector *connector;
> >   struct drm_encoder *encoder;
> >   struct drm_bridge *int_bridge, *ext_bridge;
> > - struct drm_connector *connector;
> > - struct list_head *connector_list;
> > + int ret;
> >
> >   int_bridge = msm_dsi->bridge;
> >   ext_bridge = msm_dsi->external_bridge =
> > @@ -699,22 +701,44 @@ struct drm_connector 
> > *msm_dsi_manager_ext_bridge_init(u8 id)
> >
> >   encoder = msm_dsi->encoder;
> >
> > - /* link the internal dsi bridge to the external bridge */
> > - drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
> > -
> >   /*
> > -  * we need the drm_connector created by the external bridge
> > -  * driver (or someone else) to feed it to our driver's
> > -  * priv->connector[] list, mainly for msm_fbdev_init()
> > +  * Try first to create the bridge without it creating its own
> > +  * connector.. currently some bridges support this, and others
> > +  * do not (and some support both modes)
> >*/
> > - connector_list = &dev->mode_config.connector_list;
> > + ret = drm_bridge_attach(encoder, ext_bridge, int_bridge,
> > + DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> > + if (ret == -EINVAL) {
> > + struct drm_connector *connector;
> > + struct list_head *connector_list;
> > +
> > + /* link the internal dsi bridge to the external bridge */
> > + drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
> > +
> > + /*
> > +  * we need the drm_connector created by the external bridge
> > +  * driver (or someone else) to feed it to our driver's
> > +  * priv->connector[] list, mainly for msm_fbdev_init()
> > +  */
> > + connector_list = &dev->mode_config.connector_list;
> >
> > - list_for_each_entry(connector, connector_list, head) {
> > - if (drm_connector_has_possible_encoder(connector, encoder))
> > - return connector;
> > + list_for_each_entry(connector, connector_list, head) {
> > + if (drm_connector_has_possible_encoder(connector, 
> > encoder))
> > + return connector;
> > + }
> > +
> > + return ERR_PTR(-ENODEV);
> > + }
> > +
> > + connector = drm_bridge_connector_init(dev, encoder);
> > + if (IS_ERR(connector)) {
> > + DRM_ERROR("Unable to create bridge connector\n");
> > + return ERR_CAST(connector);
> >   }
> >
> > - return ERR_PTR(-ENODEV);
> > + drm_connector_attach_encoder(connector, encoder);
> > +
> > + return connector;
> >   }
> >
> >   void msm_dsi_manager_bridge_d

[PATCH 2/2] drm/msm: One sched entity per process per priority

2021-10-01 Thread Rob Clark
From: Rob Clark 

Some userspace apps make assumptions that rendering against multiple
contexts within the same process (from the same thread, with appropriate
MakeCurrent() calls) provides sufficient synchronization without any
external synchronization (ie. glFenceSync()/glWaitSync()).  Since a
submitqueue maps to a gl/vk context, having multiple sched entities of
the same priority only works with implicit sync enabled.

To fix this, limit things to a single sched entity per priority level
per process.

An alternative would be sharing submitqueues between contexts in
userspace, but tracking of per-context faults (ie. GL_EXT_robustness)
is already done at the submitqueue level, so this is not an option.

Signed-off-by: Rob Clark 
---
Unfortunately, due to a finch experiment (a sort of A/B experiment)
all my testing of the drm/scheduler with chrome(ium) was using
SkiaRenderer which does not trigger this bug.  It wasn't until folks
started reporting misrendering on dev channel, and I tracked it down
to legacy GLRenderer vs SkiaRenderer, that I realized the problem :-(

 drivers/gpu/drm/msm/msm_gem_submit.c  |  2 +-
 drivers/gpu/drm/msm/msm_gpu.h | 24 ++
 drivers/gpu/drm/msm/msm_submitqueue.c | 68 +++
 3 files changed, 74 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
index 924b01b9c105..34ed56b24224 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -46,7 +46,7 @@ static struct msm_gem_submit *submit_create(struct drm_device 
*dev,
if (!submit)
return ERR_PTR(-ENOMEM);
 
-   ret = drm_sched_job_init(&submit->base, &queue->entity, queue);
+   ret = drm_sched_job_init(&submit->base, queue->entity, queue);
if (ret) {
kfree(submit);
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 592334cb9a0b..d72b1de3cb1f 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -290,6 +290,19 @@ struct msm_file_private {
struct msm_gem_address_space *aspace;
struct kref ref;
int seqno;
+
+   /**
+* entities:
+*
+* Table of per-priority-level sched entities used by submitqueues
+* associated with this &drm_file.  Because some userspace apps
+* make assumptions about rendering from multiple gl contexts
+* (of the same priority) within the process happening in FIFO
+* order without requiring any fencing beyond MakeCurrent(), we
+* create at most one &drm_sched_entity per-process per-priority-
+* level.
+*/
+   struct drm_sched_entity *entities[NR_SCHED_PRIORITIES * 
MSM_GPU_MAX_RINGS];
 };
 
 /**
@@ -370,7 +383,7 @@ struct msm_gpu_submitqueue {
struct idr fence_idr;
struct mutex lock;
struct kref ref;
-   struct drm_sched_entity entity;
+   struct drm_sched_entity *entity;
 };
 
 struct msm_gpu_state_bo {
@@ -471,14 +484,7 @@ void msm_submitqueue_close(struct msm_file_private *ctx);
 
 void msm_submitqueue_destroy(struct kref *kref);
 
-static inline void __msm_file_private_destroy(struct kref *kref)
-{
-   struct msm_file_private *ctx = container_of(kref,
-   struct msm_file_private, ref);
-
-   msm_gem_address_space_put(ctx->aspace);
-   kfree(ctx);
-}
+void __msm_file_private_destroy(struct kref *kref);
 
 static inline void msm_file_private_put(struct msm_file_private *ctx)
 {
diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c 
b/drivers/gpu/drm/msm/msm_submitqueue.c
index 7ce0771b5582..b8621c6e0554 100644
--- a/drivers/gpu/drm/msm/msm_submitqueue.c
+++ b/drivers/gpu/drm/msm/msm_submitqueue.c
@@ -7,6 +7,24 @@
 
 #include "msm_gpu.h"
 
+void __msm_file_private_destroy(struct kref *kref)
+{
+   struct msm_file_private *ctx = container_of(kref,
+   struct msm_file_private, ref);
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(ctx->entities); i++) {
+   if (!ctx->entities[i])
+   continue;
+
+   drm_sched_entity_destroy(ctx->entities[i]);
+   kfree(ctx->entities[i]);
+   }
+
+   msm_gem_address_space_put(ctx->aspace);
+   kfree(ctx);
+}
+
 void msm_submitqueue_destroy(struct kref *kref)
 {
struct msm_gpu_submitqueue *queue = container_of(kref,
@@ -14,8 +32,6 @@ void msm_submitqueue_destroy(struct kref *kref)
 
idr_destroy(&queue->fence_idr);
 
-   drm_sched_entity_destroy(&queue->entity);
-
msm_file_private_put(queue->ctx);
 
kfree(queue);
@@ -61,13 +77,47 @@ void msm_submitqueue_close(struct msm_file_private *ctx)
}
 }
 
+static struct drm_sched_entity *
+get_sched_entity(struct msm_file_private *ctx, struct msm_ringbuffer *ring,
+unsigned ring_nr, enum drm_sched_priority sched_prio)
+{
+   static DEFINE_MUTEX(

[PATCH 1/2] drm/msm: A bit more docs + cleanup

2021-10-01 Thread Rob Clark
From: Rob Clark 

msm_file_private is more gpu related, and in the next commit it will
need access to other GPU specific #defines.  While we're at it, add
some comments.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.h | 44 --
 drivers/gpu/drm/msm/msm_gpu.h | 58 ++-
 2 files changed, 57 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 8633d0059a3e..31b39c27156d 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -53,15 +53,6 @@ struct msm_disp_state;
 
 #define FRAC_16_16(mult, div)(((mult) << 16) / (div))
 
-struct msm_file_private {
-   rwlock_t queuelock;
-   struct list_head submitqueues;
-   int queueid;
-   struct msm_gem_address_space *aspace;
-   struct kref ref;
-   int seqno;
-};
-
 enum msm_mdp_plane_property {
PLANE_PROP_ZPOS,
PLANE_PROP_ALPHA,
@@ -511,41 +502,6 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
   clockid_t clock_id,
   enum hrtimer_mode mode);
 
-struct msm_gpu_submitqueue;
-int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
-struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
-   u32 id);
-int msm_submitqueue_create(struct drm_device *drm,
-   struct msm_file_private *ctx,
-   u32 prio, u32 flags, u32 *id);
-int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
-   struct drm_msm_submitqueue_query *args);
-int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
-void msm_submitqueue_close(struct msm_file_private *ctx);
-
-void msm_submitqueue_destroy(struct kref *kref);
-
-static inline void __msm_file_private_destroy(struct kref *kref)
-{
-   struct msm_file_private *ctx = container_of(kref,
-   struct msm_file_private, ref);
-
-   msm_gem_address_space_put(ctx->aspace);
-   kfree(ctx);
-}
-
-static inline void msm_file_private_put(struct msm_file_private *ctx)
-{
-   kref_put(&ctx->ref, __msm_file_private_destroy);
-}
-
-static inline struct msm_file_private *msm_file_private_get(
-   struct msm_file_private *ctx)
-{
-   kref_get(&ctx->ref);
-   return ctx;
-}
-
 #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
 #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 2fcb6c195865..592334cb9a0b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -272,6 +272,26 @@ struct msm_gpu_perfcntr {
  */
 #define NR_SCHED_PRIORITIES (1 + DRM_SCHED_PRIORITY_HIGH - 
DRM_SCHED_PRIORITY_MIN)
 
+/**
+ * struct msm_file_private - per-drm_file context
+ *
+ * @queuelock:synchronizes access to submitqueues list
+ * @submitqueues: list of &msm_gpu_submitqueue created by userspace
+ * @queueid:  counter incremented each time a submitqueue is created,
+ *used to assign &msm_gpu_submitqueue.id
+ * @aspace:   the per-process GPU address-space
+ * @ref:  reference count
+ * @seqno:unique per process seqno
+ */
+struct msm_file_private {
+   rwlock_t queuelock;
+   struct list_head submitqueues;
+   int queueid;
+   struct msm_gem_address_space *aspace;
+   struct kref ref;
+   int seqno;
+};
+
 /**
  * msm_gpu_convert_priority - Map userspace priority to ring # and sched 
priority
  *
@@ -319,6 +339,8 @@ static inline int msm_gpu_convert_priority(struct msm_gpu 
*gpu, int prio,
 }
 
 /**
+ * struct msm_gpu_submitqueues - Userspace created context.
+ *
  * A submitqueue is associated with a gl context or vk queue (or equiv)
  * in userspace.
  *
@@ -336,7 +358,7 @@ static inline int msm_gpu_convert_priority(struct msm_gpu 
*gpu, int prio,
  * seqno, protected by submitqueue lock
  * @lock:  submitqueue lock
  * @ref:   reference count
- * @entity: the submit job-queue
+ * @entity:the submit job-queue
  */
 struct msm_gpu_submitqueue {
int id;
@@ -436,6 +458,40 @@ static inline void gpu_write64(struct msm_gpu *gpu, u32 
lo, u32 hi, u64 val)
 int msm_gpu_pm_suspend(struct msm_gpu *gpu);
 int msm_gpu_pm_resume(struct msm_gpu *gpu);
 
+int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
+struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
+   u32 id);
+int msm_submitqueue_create(struct drm_device *drm,
+   struct msm_file_private *ctx,
+   u32 prio, u32 flags, u32 *id);
+int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
+   struct drm_msm_submitqueue_query *args);
+int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
+void msm_submitqueue_close(struct msm_file_private *ctx);
+
+void msm_s

[PATCH 0/2] drm/msm: Un-break multi-context gl

2021-10-01 Thread Rob Clark
From: Rob Clark 

Userspace is expecting that a single thread doing rendering against
multiple contexts does not need additional synchronization between those
contexts beyond ensuring work is flushed to the kernel in the correct
order.  But if we have a sched-entity per-context, and are not using
implicit sync, GPU jobs from different contexts can execute in a
different order than they were flushed to the kernel.

To solve that, share sched-entities for a given priority level between
submitqueues (which map to gl contexts).

Rob Clark (2):
  drm/msm: A bit more docs + cleanup
  drm/msm: One sched entity per process per priority

 drivers/gpu/drm/msm/msm_drv.h | 44 -
 drivers/gpu/drm/msm/msm_gem_submit.c  |  2 +-
 drivers/gpu/drm/msm/msm_gpu.h | 66 +-
 drivers/gpu/drm/msm/msm_submitqueue.c | 68 +++
 4 files changed, 123 insertions(+), 57 deletions(-)

-- 
2.31.1



[PATCH v3 09/10] vfio: Export vfio_device_try_get()

2021-10-01 Thread Jason Gunthorpe
vfio_ccw will need it.

Signed-off-by: Jason Gunthorpe 
---
 drivers/vfio/vfio.c  | 3 ++-
 include/linux/vfio.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 08b27b64f0f935..44adf112e3b5dd 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -554,10 +554,11 @@ void vfio_device_put(struct vfio_device *device)
 }
 EXPORT_SYMBOL_GPL(vfio_device_put);
 
-static bool vfio_device_try_get(struct vfio_device *device)
+bool vfio_device_try_get(struct vfio_device *device)
 {
return refcount_inc_not_zero(&device->refcount);
 }
+EXPORT_SYMBOL_GPL(vfio_device_try_get);
 
 static struct vfio_device *vfio_group_get_device(struct vfio_group *group,
 struct device *dev)
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 76191d7abed185..f99e4b2d9b45f0 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -78,6 +78,7 @@ int vfio_register_group_dev(struct vfio_device *device);
 int vfio_register_emulated_iommu_dev(struct vfio_device *device);
 void vfio_unregister_group_dev(struct vfio_device *device);
 extern struct vfio_device *vfio_device_get_from_dev(struct device *dev);
+bool vfio_device_try_get(struct vfio_device *device);
 extern void vfio_device_put(struct vfio_device *device);
 
 int vfio_assign_device_set(struct vfio_device *device, void *set_id);
-- 
2.33.0



[PATCH v3 10/10] vfio/ccw: Move the lifecycle of the struct vfio_ccw_private to the mdev

2021-10-01 Thread Jason Gunthorpe
The css_driver's main purpose is to create/destroy the mdev and relay the
shutdown, irq, sch_event, and chp_event css_driver ops to the single
created vfio_device, if it exists.

Reframe the boundary where the css_driver domain switches to the vfio
domain by using rcu to read and refcount the vfio_device out of the sch's
drvdata. The mdev probe/remove will manage the drvdata of the parent.

The vfio core code refcounting thus guarantees that when a css_driver
callback is running the vfio_device is registered, simplifying the
understanding of the whole lifecycle.

Finally the vfio_ccw_private is allocated/freed during probe/remove of the
mdev like any other vfio_device struct.

Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_drv.c | 67 ++---
 drivers/s390/cio/vfio_ccw_ops.c | 40 +++--
 drivers/s390/cio/vfio_ccw_private.h | 23 +-
 3 files changed, 69 insertions(+), 61 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 18ad047811d111..c5582fc9c46c9e 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -86,13 +86,19 @@ static void vfio_ccw_crw_todo(struct work_struct *work)
  */
 static void vfio_ccw_sch_irq(struct subchannel *sch)
 {
-   struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
+   struct vfio_ccw_private *private = vfio_ccw_get_priv(sch);
+
+   /* IRQ should not be delivered after the mdev is destroyed */
+   if (WARN_ON(!private))
+   return;
 
inc_irq_stat(IRQIO_CIO);
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
+   vfio_device_put(&private->vdev);
 }
 
-static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch)
+struct vfio_ccw_private *vfio_ccw_alloc_private(struct mdev_device *mdev,
+   struct subchannel *sch)
 {
struct vfio_ccw_private *private;
 
@@ -100,6 +106,8 @@ static struct vfio_ccw_private 
*vfio_ccw_alloc_private(struct subchannel *sch)
if (!private)
return ERR_PTR(-ENOMEM);
 
+   vfio_init_group_dev(&private->vdev, &mdev->dev,
+   &vfio_ccw_dev_ops);
private->sch = sch;
mutex_init(&private->io_mutex);
private->state = VFIO_CCW_STATE_CLOSED;
@@ -145,11 +153,12 @@ static struct vfio_ccw_private 
*vfio_ccw_alloc_private(struct subchannel *sch)
kfree(private->cp.guest_cp);
 out_free_private:
mutex_destroy(&private->io_mutex);
+   vfio_uninit_group_dev(&private->vdev);
kfree(private);
return ERR_PTR(-ENOMEM);
 }
 
-static void vfio_ccw_free_private(struct vfio_ccw_private *private)
+void vfio_ccw_free_private(struct vfio_ccw_private *private)
 {
struct vfio_ccw_crw *crw, *temp;
 
@@ -164,14 +173,14 @@ static void vfio_ccw_free_private(struct vfio_ccw_private 
*private)
kmem_cache_free(vfio_ccw_io_region, private->io_region);
kfree(private->cp.guest_cp);
mutex_destroy(&private->io_mutex);
-   kfree(private);
+   vfio_uninit_group_dev(&private->vdev);
+   kfree_rcu(private, rcu);
 }
 
 static int vfio_ccw_sch_probe(struct subchannel *sch)
 {
struct pmcw *pmcw = &sch->schib.pmcw;
-   struct vfio_ccw_private *private;
-   int ret = -ENOMEM;
+   int ret;
 
if (pmcw->qf) {
dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n",
@@ -179,15 +188,9 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
return -ENODEV;
}
 
-   private = vfio_ccw_alloc_private(sch);
-   if (IS_ERR(private))
-   return PTR_ERR(private);
-
-   dev_set_drvdata(&sch->dev, private);
-
-   ret = vfio_ccw_mdev_reg(sch);
+   ret = mdev_register_device(&sch->dev, &vfio_ccw_mdev_ops);
if (ret)
-   goto out_free;
+   return ret;
 
if (dev_get_uevent_suppress(&sch->dev)) {
dev_set_uevent_suppress(&sch->dev, 0);
@@ -198,22 +201,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
   sch->schid.cssid, sch->schid.ssid,
   sch->schid.sch_no);
return 0;
-
-out_free:
-   dev_set_drvdata(&sch->dev, NULL);
-   vfio_ccw_free_private(private);
-   return ret;
 }
 
 static void vfio_ccw_sch_remove(struct subchannel *sch)
 {
-   struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
-
-   vfio_ccw_mdev_unreg(sch);
-
-   dev_set_drvdata(&sch->dev, NULL);
-
-   vfio_ccw_free_private(private);
+   mdev_unregister_device(&sch->dev);
 
VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n",
   sch->schid.cssid, sch->schid.ssid,
@@ -222,10 +214,14 @@ static void vfio_ccw_sch_remove(struct subchannel *sch)
 
 static void vfio_ccw_sch_shutdown(struct subchannel *sch)
 {
-   struct vfio_ccw_private *private

[PATCH v3 06/10] vfio/mdev: Consolidate all the device_api sysfs into the core code

2021-10-01 Thread Jason Gunthorpe
Every driver just emits a static string, simply feed it through the ops
and provide a standard sysfs show function.

Signed-off-by: Jason Gunthorpe 
---
 .../driver-api/vfio-mediated-device.rst   |  4 ++-
 drivers/gpu/drm/i915/gvt/kvmgt.c  |  9 +--
 drivers/s390/cio/vfio_ccw_ops.c   |  9 +--
 drivers/s390/crypto/vfio_ap_ops.c |  9 +--
 drivers/vfio/mdev/mdev_core.c |  2 +-
 drivers/vfio/mdev/mdev_sysfs.c| 27 ---
 include/linux/mdev.h  |  7 ++---
 samples/vfio-mdev/mbochs.c|  9 +--
 samples/vfio-mdev/mdpy.c  |  9 +--
 samples/vfio-mdev/mtty.c  | 10 +--
 10 files changed, 36 insertions(+), 59 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst 
b/Documentation/driver-api/vfio-mediated-device.rst
index 9f26079cacae35..f410a1cd98bb06 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -137,6 +137,7 @@ The structures in the mdev_parent_ops structure are as 
follows:
 * mdev_attr_groups: attributes of the mediated device
 * supported_config: attributes to define supported configurations
 * device_driver: device driver to bind for mediated device instances
+* device_api: String to pass through the sysfs file below
 
 The mdev_parent_ops also still has various functions pointers.  Theses exist
 for historical reasons only and shall not be used for new drivers.
@@ -225,7 +226,8 @@ Directories and files under the sysfs for Each Physical 
Device
 * device_api
 
   This attribute should show which device API is being created, for example,
-  "vfio-pci" for a PCI device.
+  "vfio-pci" for a PCI device. The core code maintins this sysfs using the
+  device_api member of mdev_parent_ops.
 
 * available_instances
 
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 7efa386449d104..d198cc3d132277 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -161,12 +161,6 @@ static ssize_t available_instances_show(struct mdev_type 
*mtype,
return sprintf(buf, "%u\n", num);
 }
 
-static ssize_t device_api_show(struct mdev_type *mtype,
-  struct mdev_type_attribute *attr, char *buf)
-{
-   return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
-}
-
 static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
 {
@@ -187,12 +181,10 @@ static ssize_t description_show(struct mdev_type *mtype,
 }
 
 static MDEV_TYPE_ATTR_RO(available_instances);
-static MDEV_TYPE_ATTR_RO(device_api);
 static MDEV_TYPE_ATTR_RO(description);
 
 static struct attribute *gvt_type_attrs[] = {
&mdev_type_attr_available_instances.attr,
-   &mdev_type_attr_device_api.attr,
&mdev_type_attr_description.attr,
NULL,
 };
@@ -1750,6 +1742,7 @@ static const struct attribute_group *intel_vgpu_groups[] 
= {
 
 static struct mdev_parent_ops intel_vgpu_ops = {
.mdev_attr_groups   = intel_vgpu_groups,
+   .device_api = VFIO_DEVICE_API_PCI_STRING,
.create = intel_vgpu_create,
.remove = intel_vgpu_remove,
 
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index bd4d08afa3e4dc..a7f642be9c8898 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,13 +70,6 @@ static ssize_t name_show(struct mdev_type *mtype,
 }
 static MDEV_TYPE_ATTR_RO(name);
 
-static ssize_t device_api_show(struct mdev_type *mtype,
-  struct mdev_type_attribute *attr, char *buf)
-{
-   return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);
-}
-static MDEV_TYPE_ATTR_RO(device_api);
-
 static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
@@ -90,7 +83,6 @@ static MDEV_TYPE_ATTR_RO(available_instances);
 
 static struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_name.attr,
-   &mdev_type_attr_device_api.attr,
&mdev_type_attr_available_instances.attr,
NULL,
 };
@@ -640,6 +632,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
 static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
.owner  = THIS_MODULE,
.device_driver  = &vfio_ccw_mdev_driver,
+   .device_api = VFIO_DEVICE_API_CCW_STRING,
.supported_type_groups  = mdev_type_groups,
 };
 
diff --git a/drivers/s390/crypto/vfio_ap_ops.c 
b/drivers/s390/crypto/vfio_ap_ops.c
index 2341425f69675a..f80246b30aff30 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -401,17 +401,9 @@ static ssize_t available_instances_show(struct mdev_

[PATCH v3 07/10] vfio/mdev: Add mdev available instance checking to the core

2021-10-01 Thread Jason Gunthorpe
Many of the mdev drivers use a simple counter for keeping track of the
available instances. Move this code to the core code and store the counter
in the mdev_type. Implement it using correct locking, fixing mdpy.

Drivers provide a get_available() callback to set the number of available
instances for their mtypes which is fixed at registration time. The core
provides a standard sysfs attribute to return the available_instances.

Reviewed-by: Christoph Hellwig 
Signed-off-by: Jason Gunthorpe 
---
 .../driver-api/vfio-mediated-device.rst   |  4 +-
 drivers/s390/cio/vfio_ccw_drv.c   |  1 -
 drivers/s390/cio/vfio_ccw_ops.c   | 26 -
 drivers/s390/cio/vfio_ccw_private.h   |  2 -
 drivers/s390/crypto/vfio_ap_ops.c | 32 
 drivers/s390/crypto/vfio_ap_private.h |  2 -
 drivers/vfio/mdev/mdev_core.c | 11 +-
 drivers/vfio/mdev/mdev_private.h  |  2 +
 drivers/vfio/mdev/mdev_sysfs.c| 37 +++
 include/linux/mdev.h  |  2 +
 samples/vfio-mdev/mdpy.c  | 22 +++
 11 files changed, 76 insertions(+), 65 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst 
b/Documentation/driver-api/vfio-mediated-device.rst
index f410a1cd98bb06..a4f7f1362fa8a5 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -106,6 +106,7 @@ structure to represent a mediated device's driver::
 int  (*probe)  (struct mdev_device *dev);
 void (*remove) (struct mdev_device *dev);
 struct device_driverdriver;
+unsigned int (*get_available)(struct mdev_type *mtype);
  };
 
 A mediated bus driver for mdev should use this structure in the function calls
@@ -232,7 +233,8 @@ Directories and files under the sysfs for Each Physical 
Device
 * available_instances
 
   This attribute should show the number of devices of type  that can 
be
-  created.
+  created. Drivers can supply a get_available() function pointer to have the
+  core code create and maintain this sysfs automatically.
 
 * [device]
 
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 769edbbd164313..df9e1e265bca1a 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -106,7 +106,6 @@ static struct vfio_ccw_private 
*vfio_ccw_alloc_private(struct subchannel *sch)
INIT_LIST_HEAD(&private->crw);
INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
-   atomic_set(&private->avail, 1);
 
private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
   GFP_KERNEL);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index a7f642be9c8898..97df5c711736c4 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,20 +70,9 @@ static ssize_t name_show(struct mdev_type *mtype,
 }
 static MDEV_TYPE_ATTR_RO(name);
 
-static ssize_t available_instances_show(struct mdev_type *mtype,
-   struct mdev_type_attribute *attr,
-   char *buf)
-{
-   struct vfio_ccw_private *private =
-   dev_get_drvdata(mtype_get_parent_dev(mtype));
-
-   return sprintf(buf, "%d\n", atomic_read(&private->avail));
-}
-static MDEV_TYPE_ATTR_RO(available_instances);
 
 static struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_name.attr,
-   &mdev_type_attr_available_instances.attr,
NULL,
 };
 
@@ -102,9 +91,6 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
int ret;
 
-   if (atomic_dec_if_positive(&private->avail) < 0)
-   return -EPERM;
-
memset(&private->vdev, 0, sizeof(private->vdev));
vfio_init_group_dev(&private->vdev, &mdev->dev,
&vfio_ccw_dev_ops);
@@ -118,13 +104,12 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 
ret = vfio_register_emulated_iommu_dev(&private->vdev);
if (ret)
-   goto err_atomic;
+   goto err_init;
dev_set_drvdata(&mdev->dev, private);
return 0;
 
-err_atomic:
+err_init:
vfio_uninit_group_dev(&private->vdev);
-   atomic_inc(&private->avail);
private->mdev = NULL;
return ret;
 }
@@ -141,7 +126,6 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
vfio_unregister_group_dev(&private->vdev);
vfio_uninit_group_dev(&private->vdev);
private->mdev = NULL;
-   atomic_inc(&private->avail);
 }
 
 static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
@@ -610,6 +594,11 @@ static void vfio_ccw_mdev_request(struct vfio_device 
*vdev, 

[PATCH v3 03/10] vfio/ccw: Pass vfio_ccw_private not mdev_device to various functions

2021-10-01 Thread Jason Gunthorpe
mdev_device should only be used in functions assigned to ops callbacks,
interior functions should use the struct vfio_ccw_private instead of
repeatedly trying to get it from the mdev.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Cornelia Huck 
Reviewed-by: Eric Farman 
Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_ops.c | 37 +
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 7f540ad0b568bc..1edbea9de0ec42 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -17,13 +17,11 @@
 
 #include "vfio_ccw_private.h"
 
-static int vfio_ccw_mdev_reset(struct mdev_device *mdev)
+static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private)
 {
-   struct vfio_ccw_private *private;
struct subchannel *sch;
int ret;
 
-   private = dev_get_drvdata(mdev_parent_dev(mdev));
sch = private->sch;
/*
 * TODO:
@@ -61,7 +59,7 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
if (!cp_iova_pinned(&private->cp, unmap->iova))
return NOTIFY_OK;
 
-   if (vfio_ccw_mdev_reset(private->mdev))
+   if (vfio_ccw_mdev_reset(private))
return NOTIFY_BAD;
 
cp_free(&private->cp);
@@ -201,7 +199,7 @@ static void vfio_ccw_mdev_close_device(struct mdev_device 
*mdev)
 
if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
(private->state != VFIO_CCW_STATE_STANDBY)) {
-   if (!vfio_ccw_mdev_reset(mdev))
+   if (!vfio_ccw_mdev_reset(private))
private->state = VFIO_CCW_STATE_STANDBY;
/* The state will be NOT_OPER on error. */
}
@@ -311,12 +309,9 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device 
*mdev,
return -EINVAL;
 }
 
-static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info,
-struct mdev_device *mdev)
+static int vfio_ccw_mdev_get_device_info(struct vfio_ccw_private *private,
+struct vfio_device_info *info)
 {
-   struct vfio_ccw_private *private;
-
-   private = dev_get_drvdata(mdev_parent_dev(mdev));
info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
info->num_regions = VFIO_CCW_NUM_REGIONS + private->num_regions;
info->num_irqs = VFIO_CCW_NUM_IRQS;
@@ -324,14 +319,12 @@ static int vfio_ccw_mdev_get_device_info(struct 
vfio_device_info *info,
return 0;
 }
 
-static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,
-struct mdev_device *mdev,
+static int vfio_ccw_mdev_get_region_info(struct vfio_ccw_private *private,
+struct vfio_region_info *info,
 unsigned long arg)
 {
-   struct vfio_ccw_private *private;
int i;
 
-   private = dev_get_drvdata(mdev_parent_dev(mdev));
switch (info->index) {
case VFIO_CCW_CONFIG_REGION_INDEX:
info->offset = 0;
@@ -406,19 +399,16 @@ static int vfio_ccw_mdev_get_irq_info(struct 
vfio_irq_info *info)
return 0;
 }
 
-static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
+static int vfio_ccw_mdev_set_irqs(struct vfio_ccw_private *private,
  uint32_t flags,
  uint32_t index,
  void __user *data)
 {
-   struct vfio_ccw_private *private;
struct eventfd_ctx **ctx;
 
if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))
return -EINVAL;
 
-   private = dev_get_drvdata(mdev_parent_dev(mdev));
-
switch (index) {
case VFIO_CCW_IO_IRQ_INDEX:
ctx = &private->io_trigger;
@@ -524,6 +514,8 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
   unsigned int cmd,
   unsigned long arg)
 {
+   struct vfio_ccw_private *private =
+   dev_get_drvdata(mdev_parent_dev(mdev));
int ret = 0;
unsigned long minsz;
 
@@ -540,7 +532,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
if (info.argsz < minsz)
return -EINVAL;
 
-   ret = vfio_ccw_mdev_get_device_info(&info, mdev);
+   ret = vfio_ccw_mdev_get_device_info(private, &info);
if (ret)
return ret;
 
@@ -558,7 +550,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
if (info.argsz < minsz)
return -EINVAL;
 
-   ret = vfio_ccw_mdev_get_region_info(&info, mdev, arg);
+   ret = vfio_ccw_mdev_get_region_info(private, &info, arg);
if (ret)
   

[PATCH v3 05/10] vfio/ccw: Make the FSM complete and synchronize it to the mdev

2021-10-01 Thread Jason Gunthorpe
The subchannel should be left in a quiescent state unless the VFIO device
FD is opened. When the FD is opened bring the chanel to active and allow
the VFIO device to operate. When the device FD is closed then quiesce the
channel.

To make this work the FSM needs to handle the transitions to/from open and
closed so everything is sequenced. Rename state NOT_OPER to BROKEN and use
it wheneven the driver has malfunctioned. STANDBY becomes CLOSED. The
normal case FSM looks like:
CLOSED -> IDLE -> PROCESS/PENDING* -> IDLE -> CLOSED

With a possible branch off to BROKEN from any state. Once the device is in
BROKEN it cannot be recovered other than be reloading the driver.

Delete the triply redundant calls to
vfio_ccw_sch_quiesce(). vfio_ccw_mdev_close_device() always leaves the
subchannel quiescent. vfio_ccw_mdev_remove() cannot return until
vfio_ccw_mdev_close_device() completes and vfio_ccw_sch_remove() cannot
return until vfio_ccw_mdev_remove() completes. Have the FSM code take care
of calling cp_free() when appropriate.

Device reset becomes a CLOSE/OPEN sequence which now properly handles the
situation if the device becomes BROKEN.

Machine shutdown via vfio_ccw_sch_shutdown() now simply tries to close and
leaves the device BROKEN (though arguably the bus should take care to
quiet down the subchannel HW during shutdown, not the drivers)

Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_drv.c |  74 ++-
 drivers/s390/cio/vfio_ccw_fsm.c | 110 +---
 drivers/s390/cio/vfio_ccw_ops.c |  49 -
 drivers/s390/cio/vfio_ccw_private.h |  12 +--
 4 files changed, 125 insertions(+), 120 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 0407427770955d..769edbbd164313 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -36,51 +36,6 @@ debug_info_t *vfio_ccw_debug_trace_id;
 /*
  * Helpers
  */
-int vfio_ccw_sch_quiesce(struct subchannel *sch)
-{
-   struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
-   DECLARE_COMPLETION_ONSTACK(completion);
-   int iretry, ret = 0;
-
-   spin_lock_irq(sch->lock);
-   if (!sch->schib.pmcw.ena)
-   goto out_unlock;
-   ret = cio_disable_subchannel(sch);
-   if (ret != -EBUSY)
-   goto out_unlock;
-
-   iretry = 255;
-   do {
-
-   ret = cio_cancel_halt_clear(sch, &iretry);
-
-   if (ret == -EIO) {
-   pr_err("vfio_ccw: could not quiesce subchannel 
0.%x.%04x!\n",
-  sch->schid.ssid, sch->schid.sch_no);
-   break;
-   }
-
-   /*
-* Flush all I/O and wait for
-* cancel/halt/clear completion.
-*/
-   private->completion = &completion;
-   spin_unlock_irq(sch->lock);
-
-   if (ret == -EBUSY)
-   wait_for_completion_timeout(&completion, 3*HZ);
-
-   private->completion = NULL;
-   flush_workqueue(vfio_ccw_work_q);
-   spin_lock_irq(sch->lock);
-   ret = cio_disable_subchannel(sch);
-   } while (ret == -EBUSY);
-out_unlock:
-   private->state = VFIO_CCW_STATE_NOT_OPER;
-   spin_unlock_irq(sch->lock);
-   return ret;
-}
-
 static void vfio_ccw_sch_io_todo(struct work_struct *work)
 {
struct vfio_ccw_private *private;
@@ -147,7 +102,7 @@ static struct vfio_ccw_private 
*vfio_ccw_alloc_private(struct subchannel *sch)
 
private->sch = sch;
mutex_init(&private->io_mutex);
-   private->state = VFIO_CCW_STATE_NOT_OPER;
+   private->state = VFIO_CCW_STATE_CLOSED;
INIT_LIST_HEAD(&private->crw);
INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
@@ -231,18 +186,9 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
 
dev_set_drvdata(&sch->dev, private);
 
-   spin_lock_irq(sch->lock);
-   sch->isc = VFIO_CCW_ISC;
-   ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
-   spin_unlock_irq(sch->lock);
-   if (ret)
-   goto out_free;
-
-   private->state = VFIO_CCW_STATE_STANDBY;
-
ret = vfio_ccw_mdev_reg(sch);
if (ret)
-   goto out_disable;
+   goto out_free;
 
if (dev_get_uevent_suppress(&sch->dev)) {
dev_set_uevent_suppress(&sch->dev, 0);
@@ -254,8 +200,6 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
   sch->schid.sch_no);
return 0;
 
-out_disable:
-   cio_disable_subchannel(sch);
 out_free:
dev_set_drvdata(&sch->dev, NULL);
vfio_ccw_free_private(private);
@@ -266,7 +210,6 @@ static void vfio_ccw_sch_remove(struct subchannel *sch)
 {
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
 
-  

[PATCH v3 02/10] vfio/ccw: Use functions for alloc/free of the vfio_ccw_private

2021-10-01 Thread Jason Gunthorpe
Makes the code easier to understand what is memory lifecycle and what is
other stuff.

Reviewed-by: Eric Farman 
Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_drv.c | 137 ++--
 1 file changed, 78 insertions(+), 59 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 371558ec92045d..e32678a71644fb 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -137,16 +137,80 @@ static void vfio_ccw_sch_irq(struct subchannel *sch)
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
 }
 
-static void vfio_ccw_free_regions(struct vfio_ccw_private *private)
+static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch)
 {
-   if (private->crw_region)
-   kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
-   if (private->schib_region)
-   kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
-   if (private->cmd_region)
-   kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
-   if (private->io_region)
-   kmem_cache_free(vfio_ccw_io_region, private->io_region);
+   struct vfio_ccw_private *private;
+
+   private = kzalloc(sizeof(*private), GFP_KERNEL);
+   if (!private)
+   return ERR_PTR(-ENOMEM);
+
+   private->sch = sch;
+   mutex_init(&private->io_mutex);
+   private->state = VFIO_CCW_STATE_NOT_OPER;
+   INIT_LIST_HEAD(&private->crw);
+   INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
+   INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
+   atomic_set(&private->avail, 1);
+
+   private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
+  GFP_KERNEL);
+   if (!private->cp.guest_cp)
+   goto out_free_private;
+
+   private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
+  GFP_KERNEL | GFP_DMA);
+   if (!private->io_region)
+   goto out_free_cp;
+
+   private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region,
+   GFP_KERNEL | GFP_DMA);
+   if (!private->cmd_region)
+   goto out_free_io;
+
+   private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region,
+ GFP_KERNEL | GFP_DMA);
+
+   if (!private->schib_region)
+   goto out_free_cmd;
+
+   private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region,
+   GFP_KERNEL | GFP_DMA);
+
+   if (!private->crw_region)
+   goto out_free_schib;
+   return private;
+
+out_free_schib:
+   kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
+out_free_cmd:
+   kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
+out_free_io:
+   kmem_cache_free(vfio_ccw_io_region, private->io_region);
+out_free_cp:
+   kfree(private->cp.guest_cp);
+out_free_private:
+   mutex_destroy(&private->io_mutex);
+   kfree(private);
+   return ERR_PTR(-ENOMEM);
+}
+
+static void vfio_ccw_free_private(struct vfio_ccw_private *private)
+{
+   struct vfio_ccw_crw *crw, *temp;
+
+   list_for_each_entry_safe(crw, temp, &private->crw, next) {
+   list_del(&crw->next);
+   kfree(crw);
+   }
+
+   kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
+   kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
+   kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
+   kmem_cache_free(vfio_ccw_io_region, private->io_region);
+   kfree(private->cp.guest_cp);
+   mutex_destroy(&private->io_mutex);
+   kfree(private);
 }
 
 static int vfio_ccw_sch_probe(struct subchannel *sch)
@@ -161,53 +225,19 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
return -ENODEV;
}
 
-   private = kzalloc(sizeof(*private), GFP_KERNEL);
-   if (!private)
-   return -ENOMEM;
+   private = vfio_ccw_alloc_private(sch);
+   if (IS_ERR(private))
+   return PTR_ERR(private);
 
-   private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
-  GFP_KERNEL);
-   if (!private->cp.guest_cp)
-   goto out_free;
-
-   private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
-  GFP_KERNEL | GFP_DMA);
-   if (!private->io_region)
-   goto out_free;
-
-   private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region,
-   GFP_KERNEL | GFP_DMA);
-   if (!private->cmd_region)
-   goto out_free;
-
-   private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region,
- GFP_KERNEL | GFP_DMA);
-
-   

[PATCH v3 08/10] vfio/ccw: Remove private->mdev

2021-10-01 Thread Jason Gunthorpe
Having a mdev pointer floating about in addition to a struct vfio_device
is confusing. It is only used for three things:

- Getting the mdev 'struct device *' - this is the same as
 private->vdev.dev

- Printing the uuid of the mdev in logging. The uuid is also the dev_name
  of the mdev so this is the same string as
 dev_name(private->vdev.dev)

- A weird attempt to fence the vfio_ccw_sch_io_todo() work. This work is
  only queued during states IDLE/PROCESSING/PENDING and flushed when
  entering CLOSED. Thus the work already cannot run when the mdev is NULL.
  Remove it.

Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_drv.c |  6 ++--
 drivers/s390/cio/vfio_ccw_fsm.c | 48 +
 drivers/s390/cio/vfio_ccw_ops.c | 16 --
 drivers/s390/cio/vfio_ccw_private.h |  2 --
 include/linux/mdev.h|  4 ---
 5 files changed, 30 insertions(+), 46 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index df9e1e265bca1a..18ad047811d111 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -64,7 +64,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
 * has finished. Do not overwrite a possible processing
 * state if the final interrupt was for HSCH or CSCH.
 */
-   if (private->mdev && cp_is_finished)
+   if (cp_is_finished)
private->state = VFIO_CCW_STATE_IDLE;
 
if (private->io_trigger)
@@ -302,8 +302,8 @@ static int vfio_ccw_chp_event(struct subchannel *sch,
return 0;
 
trace_vfio_ccw_chp_event(private->sch->schid, mask, event);
-   VFIO_CCW_MSG_EVENT(2, "%pUl (%x.%x.%04x): mask=0x%x event=%d\n",
-  mdev_uuid(private->mdev), sch->schid.cssid,
+   VFIO_CCW_MSG_EVENT(2, "%s (%x.%x.%04x): mask=0x%x event=%d\n",
+  dev_name(private->vdev.dev), sch->schid.cssid,
   sch->schid.ssid, sch->schid.sch_no,
   mask, event);
 
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c
index 64ff1a5e3cb475..0d4d4f425befac 100644
--- a/drivers/s390/cio/vfio_ccw_fsm.c
+++ b/drivers/s390/cio/vfio_ccw_fsm.c
@@ -245,7 +245,6 @@ static void fsm_io_request(struct vfio_ccw_private *private,
union orb *orb;
union scsw *scsw = &private->scsw;
struct ccw_io_region *io_region = private->io_region;
-   struct mdev_device *mdev = private->mdev;
char *errstr = "request";
struct subchannel_id schid = get_schid(private);
 
@@ -258,32 +257,30 @@ static void fsm_io_request(struct vfio_ccw_private 
*private,
/* Don't try to build a cp if transport mode is specified. */
if (orb->tm.b) {
io_region->ret_code = -EOPNOTSUPP;
-   VFIO_CCW_MSG_EVENT(2,
-  "%pUl (%x.%x.%04x): transport 
mode\n",
-  mdev_uuid(mdev), schid.cssid,
-  schid.ssid, schid.sch_no);
+   VFIO_CCW_MSG_EVENT(
+   2, "%s (%x.%x.%04x): transport mode\n",
+   dev_name(private->vdev.dev), schid.cssid,
+   schid.ssid, schid.sch_no);
errstr = "transport mode";
goto err_out;
}
-   io_region->ret_code = cp_init(&private->cp, mdev_dev(mdev),
+   io_region->ret_code = cp_init(&private->cp, private->vdev.dev,
  orb);
if (io_region->ret_code) {
-   VFIO_CCW_MSG_EVENT(2,
-  "%pUl (%x.%x.%04x): cp_init=%d\n",
-  mdev_uuid(mdev), schid.cssid,
-  schid.ssid, schid.sch_no,
-  io_region->ret_code);
+   VFIO_CCW_MSG_EVENT(2, "%s (%x.%x.%04x): cp_init=%d\n",
+  dev_name(private->vdev.dev),
+  schid.cssid, schid.ssid,
+  schid.sch_no, io_region->ret_code);
errstr = "cp init";
goto err_out;
}
 
io_region->ret_code = cp_prefetch(&private->cp);
if (io_region->ret_code) {
-   VFIO_CCW_MSG_EVENT(2,
-  "%pUl (%x.%x.%04x): 
cp_prefetch=%d\n",
-  mdev_uuid(mdev), schid.cssid,
-  schid.ssid, schid.sch_no,
-  io_region->ret_code);
+   VFIO_CCW_MSG_EVENT(
+  

[PATCH v3 04/10] vfio/ccw: Convert to use vfio_register_emulated_iommu_dev()

2021-10-01 Thread Jason Gunthorpe
This is a more complicated conversion because vfio_ccw is sharing the
vfio_device between both the mdev_device, its vfio_device and the
css_driver.

The mdev is a singleton, and the reason for this sharing is so the extra
css_driver function callbacks to be delivered to the vfio_device
implementation.

This keeps things as they are, with the css_driver allocating the
singleton, not the mdev_driver. Following patches work to clean this
further.

Embed the vfio_device in the vfio_ccw_private and instantiate it as a
vfio_device when the mdev probes. The drvdata of both the css_device and
the mdev_device point at the private, and container_of is used to get it
back from the vfio_device.

Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_drv.c |  21 --
 drivers/s390/cio/vfio_ccw_ops.c | 107 +---
 drivers/s390/cio/vfio_ccw_private.h |   5 ++
 3 files changed, 85 insertions(+), 48 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index e32678a71644fb..0407427770955d 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -468,7 +468,7 @@ static int __init vfio_ccw_sch_init(void)
vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw");
if (!vfio_ccw_work_q) {
ret = -ENOMEM;
-   goto out_err;
+   goto out_regions;
}
 
vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region",
@@ -477,7 +477,7 @@ static int __init vfio_ccw_sch_init(void)
sizeof(struct ccw_io_region), NULL);
if (!vfio_ccw_io_region) {
ret = -ENOMEM;
-   goto out_err;
+   goto out_regions;
}
 
vfio_ccw_cmd_region = kmem_cache_create_usercopy("vfio_ccw_cmd_region",
@@ -486,7 +486,7 @@ static int __init vfio_ccw_sch_init(void)
sizeof(struct ccw_cmd_region), NULL);
if (!vfio_ccw_cmd_region) {
ret = -ENOMEM;
-   goto out_err;
+   goto out_regions;
}
 
vfio_ccw_schib_region = 
kmem_cache_create_usercopy("vfio_ccw_schib_region",
@@ -496,7 +496,7 @@ static int __init vfio_ccw_sch_init(void)
 
if (!vfio_ccw_schib_region) {
ret = -ENOMEM;
-   goto out_err;
+   goto out_regions;
}
 
vfio_ccw_crw_region = kmem_cache_create_usercopy("vfio_ccw_crw_region",
@@ -506,19 +506,25 @@ static int __init vfio_ccw_sch_init(void)
 
if (!vfio_ccw_crw_region) {
ret = -ENOMEM;
-   goto out_err;
+   goto out_regions;
}
 
+   ret = mdev_register_driver(&vfio_ccw_mdev_driver);
+   if (ret)
+   goto out_regions;
+
isc_register(VFIO_CCW_ISC);
ret = css_driver_register(&vfio_ccw_sch_driver);
if (ret) {
isc_unregister(VFIO_CCW_ISC);
-   goto out_err;
+   goto out_driver;
}
 
return ret;
 
-out_err:
+out_driver:
+   mdev_unregister_driver(&vfio_ccw_mdev_driver);
+out_regions:
vfio_ccw_destroy_regions();
destroy_workqueue(vfio_ccw_work_q);
vfio_ccw_debug_exit();
@@ -528,6 +534,7 @@ static int __init vfio_ccw_sch_init(void)
 static void __exit vfio_ccw_sch_exit(void)
 {
css_driver_unregister(&vfio_ccw_sch_driver);
+   mdev_unregister_driver(&vfio_ccw_mdev_driver);
isc_unregister(VFIO_CCW_ISC);
vfio_ccw_destroy_regions();
destroy_workqueue(vfio_ccw_work_q);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 1edbea9de0ec42..d8589afac272f1 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -17,6 +17,8 @@
 
 #include "vfio_ccw_private.h"
 
+static const struct vfio_device_ops vfio_ccw_dev_ops;
+
 static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private)
 {
struct subchannel *sch;
@@ -111,10 +113,10 @@ static struct attribute_group *mdev_type_groups[] = {
NULL,
 };
 
-static int vfio_ccw_mdev_create(struct mdev_device *mdev)
+static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 {
-   struct vfio_ccw_private *private =
-   dev_get_drvdata(mdev_parent_dev(mdev));
+   struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
+   int ret;
 
if (private->state == VFIO_CCW_STATE_NOT_OPER)
return -ENODEV;
@@ -122,6 +124,10 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev)
if (atomic_dec_if_positive(&private->avail) < 0)
return -EPERM;
 
+   memset(&private->vdev, 0, sizeof(private->vdev));
+   vfio_init_group_dev(&private->vdev, &mdev->dev,
+   &vfio_ccw_dev_ops);
+
private->mdev = mdev;
private->state = VFIO_CCW_STATE_IDLE;
 
@@ -130,19 +136,31 @@ static int vfio_ccw_mdev_cre

[PATCH v3 00/10] Move vfio_ccw to the new mdev API

2021-10-01 Thread Jason Gunthorpe
This addresses Cornelia's remark on the earlier patch that ccw has a
confusing lifecycle. While it doesn't seem like the original attempt was
functionally wrong, the result can be made better with a lot of further
work.

Reorganize the driver so that the mdev owns the private memory and
controls the lifecycle, not the css_driver. The memory associated with the
css_driver lifecycle is only the mdev_parent/mdev_type registration.

Along the way we change when the sch is quiescent or not to be linked to
the open/close_device lifetime of the vfio_device, which is sort of what
it was tring to do already, just not completely.

The troublesome racey lifecycle of the css_driver callbacks is made clear
with simple vfio_device refcounting so a callback is only delivered into a
registered vfio_device and has obvious correctness.

Move the only per-css_driver state, the "available instance" counter, into
the core code and share that logic with many of the other drivers. The
value is kept in the mdev_type memory.

This is on github: https://github.com/jgunthorpe/linux/commits/vfio_ccw

v3:
 - Rebase to Christoph's group work & rc3; use
   vfio_register_emulated_iommu_dev()
 - Remove GFP_DMA
 - Order mdev_unregister_driver() symmetrically with init
 - Rework what is considered a BROKEN event in fsm_close()
 - NOP both CCW_EVENT_OPEN/CLOSE
 - Documentation updates
 - Remane goto label to err_init vfio_ccw_mdev_probe()
 - Fix NULL pointer deref in mdev_device_create()
v2: https://lore.kernel.org/r/0-v2-7d3a384024cf+2060-ccw_mdev_...@nvidia.com
 - Clean up the lifecycle in ccw with 7 new patches
 - Rebase
v1: https://lore.kernel.org/all/7-v2-7667f42c9bad+935-vfio3_...@nvidia.com

Jason Gunthorpe (10):
  vfio/ccw: Remove unneeded GFP_DMA
  vfio/ccw: Use functions for alloc/free of the vfio_ccw_private
  vfio/ccw: Pass vfio_ccw_private not mdev_device to various functions
  vfio/ccw: Convert to use vfio_register_emulated_iommu_dev()
  vfio/ccw: Make the FSM complete and synchronize it to the mdev
  vfio/mdev: Consolidate all the device_api sysfs into the core code
  vfio/mdev: Add mdev available instance checking to the core
  vfio/ccw: Remove private->mdev
  vfio: Export vfio_device_try_get()
  vfio/ccw: Move the lifecycle of the struct vfio_ccw_private to the
mdev

 .../driver-api/vfio-mediated-device.rst   |   8 +-
 drivers/gpu/drm/i915/gvt/kvmgt.c  |   9 +-
 drivers/s390/cio/vfio_ccw_drv.c   | 282 --
 drivers/s390/cio/vfio_ccw_fsm.c   | 158 +++---
 drivers/s390/cio/vfio_ccw_ops.c   | 240 +++
 drivers/s390/cio/vfio_ccw_private.h   |  42 ++-
 drivers/s390/crypto/vfio_ap_ops.c |  41 +--
 drivers/s390/crypto/vfio_ap_private.h |   2 -
 drivers/vfio/mdev/mdev_core.c |  13 +-
 drivers/vfio/mdev/mdev_private.h  |   2 +
 drivers/vfio/mdev/mdev_sysfs.c|  64 +++-
 drivers/vfio/vfio.c   |   3 +-
 include/linux/mdev.h  |  13 +-
 include/linux/vfio.h  |   1 +
 samples/vfio-mdev/mbochs.c|   9 +-
 samples/vfio-mdev/mdpy.c  |  31 +-
 samples/vfio-mdev/mtty.c  |  10 +-
 17 files changed, 482 insertions(+), 446 deletions(-)


base-commit: d9a0cd510c3383b61db6f70a84e0c3487f836a63
-- 
2.33.0



[PATCH v3 01/10] vfio/ccw: Remove unneeded GFP_DMA

2021-10-01 Thread Jason Gunthorpe
Since the ccw_io_region was split out of the private the allocation no
longer needs the GFP_DMA. Remove it.

Reported-by: Christoph Hellwig 
Fixes: c98e16b2fa12 ("s390/cio: Convert ccw_io_region to pointer")
Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 76099bcb765b45..371558ec92045d 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -161,7 +161,7 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
return -ENODEV;
}
 
-   private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
+   private = kzalloc(sizeof(*private), GFP_KERNEL);
if (!private)
return -ENOMEM;
 
-- 
2.33.0



Re: [PULL] drm-fixes

2021-10-01 Thread pr-tracker-bot
The pull request you sent on Fri, 1 Oct 2021 18:57:06 +0200:

> git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2021-10-01

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/24f67d82c43c9c594821ee1bc4367a23d89d9f8b

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


Re: [PATCH] drm/msm/dp: Remove redundant initialization of variable bpp

2021-10-01 Thread Dmitry Baryshkov

On 29/09/2021 13:54, Colin King wrote:

From: Colin Ian King 

The variable bpp is being initialized with a value that is never
read, it is being updated later on in both paths of an if statement.
The assignment is redundant and can be removed.

Addresses-Coverity: ("Unused value")
Signed-off-by: Colin Ian King 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/dp/dp_panel.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c 
b/drivers/gpu/drm/msm/dp/dp_panel.c
index 2181b60e1d1d..71db10c0f262 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -234,7 +234,7 @@ u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel,
u32 mode_edid_bpp, u32 mode_pclk_khz)
  {
struct dp_panel_private *panel;
-   u32 bpp = mode_edid_bpp;
+   u32 bpp;
  
  	if (!dp_panel || !mode_edid_bpp || !mode_pclk_khz) {

DRM_ERROR("invalid input\n");




--
With best wishes
Dmitry


[PATCH v3 5/5] drm/msm/dp: Allow sub-regions to be specified in DT

2021-10-01 Thread Bjorn Andersson
Not all platforms has P0 at an offset of 0x1000 from the base address,
so add support for specifying each sub-region in DT. The code falls back
to the predefined offsets in the case that only a single reg is
specified, in order to support existing DT.

Reviewed-by: Stephen Boyd 
Reviewed-by: Abhinav Kumar 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None

 drivers/gpu/drm/msm/dp/dp_parser.c | 49 +++---
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 1f084b2b5bd3..4d6e047f803d 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -50,18 +50,45 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
if (IS_ERR(dss->ahb.base))
return PTR_ERR(dss->ahb.base);
 
-   if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
-   DRM_ERROR("legacy memory region not large enough\n");
-   return -EINVAL;
-   }
+   dss->aux.base = dp_ioremap(pdev, 1, &dss->aux.len);
+   if (IS_ERR(dss->aux.base)) {
+   /*
+* The initial binding had a single reg, but in order to
+* support variation in the sub-region sizes this was split.
+* dp_ioremap() will fail with -ENODEV here if only a single
+* reg is specified, so fill in the sub-region offsets and
+* lengths based on this single region.
+*/
+   if (PTR_ERR(dss->aux.base) == -ENODEV) {
+   if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + 
DP_DEFAULT_P0_SIZE) {
+   DRM_ERROR("legacy memory region not large 
enough\n");
+   return -EINVAL;
+   }
+
+   dss->ahb.len = DP_DEFAULT_AHB_SIZE;
+   dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
+   dss->aux.len = DP_DEFAULT_AUX_SIZE;
+   dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
+   dss->link.len = DP_DEFAULT_LINK_SIZE;
+   dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
+   dss->p0.len = DP_DEFAULT_P0_SIZE;
+   } else {
+   DRM_ERROR("unable to remap aux region: %pe\n", 
dss->aux.base);
+   return PTR_ERR(dss->aux.base);
+   }
+   } else {
+   dss->link.base = dp_ioremap(pdev, 2, &dss->link.len);
+   if (IS_ERR(dss->link.base)) {
+   DRM_ERROR("unable to remap link region: %pe\n", 
dss->link.base);
+   return PTR_ERR(dss->link.base);
+   }
 
-   dss->ahb.len = DP_DEFAULT_AHB_SIZE;
-   dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
-   dss->aux.len = DP_DEFAULT_AUX_SIZE;
-   dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
-   dss->link.len = DP_DEFAULT_LINK_SIZE;
-   dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
-   dss->p0.len = DP_DEFAULT_P0_SIZE;
+   dss->p0.base = dp_ioremap(pdev, 3, &dss->p0.len);
+   if (IS_ERR(dss->p0.base)) {
+   DRM_ERROR("unable to remap p0 region: %pe\n", 
dss->p0.base);
+   return PTR_ERR(dss->p0.base);
+   }
+   }
 
io->phy = devm_phy_get(&pdev->dev, "dp");
if (IS_ERR(io->phy))
-- 
2.29.2



[PATCH v3 3/5] drm/msm/dp: Refactor ioremap wrapper

2021-10-01 Thread Bjorn Andersson
In order to deal with multiple memory ranges in the following commit
change the ioremap wrapper to not poke directly into the dss_io_data
struct.

While at it, devm_ioremap_resource() already prints useful error
messages on failure, so omit the unnecessary prints from the caller.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Switched to devm_platform_get_and_ioremap_resource()

 drivers/gpu/drm/msm/dp/dp_parser.c | 35 ++
 drivers/gpu/drm/msm/dp/dp_parser.h |  2 +-
 2 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index c064ced78278..c05ba1990218 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -19,40 +19,27 @@ static const struct dp_regulator_cfg sdm845_dp_reg_cfg = {
},
 };
 
-static int msm_dss_ioremap(struct platform_device *pdev,
-   struct dss_io_data *io_data)
+static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t 
*len)
 {
-   struct resource *res = NULL;
+   struct resource *res;
+   void __iomem *base;
 
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   if (!res) {
-   DRM_ERROR("%pS->%s: msm_dss_get_res failed\n",
-   __builtin_return_address(0), __func__);
-   return -ENODEV;
-   }
-
-   io_data->len = (u32)resource_size(res);
-   io_data->base = devm_ioremap(&pdev->dev, res->start, io_data->len);
-   if (!io_data->base) {
-   DRM_ERROR("%pS->%s: ioremap failed\n",
-   __builtin_return_address(0), __func__);
-   return -EIO;
-   }
+   base = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
+   if (!IS_ERR(base))
+   *len = resource_size(res);
 
-   return 0;
+   return base;
 }
 
 static int dp_parser_ctrl_res(struct dp_parser *parser)
 {
-   int rc = 0;
struct platform_device *pdev = parser->pdev;
struct dp_io *io = &parser->io;
+   struct dss_io_data *dss = &io->dp_controller;
 
-   rc = msm_dss_ioremap(pdev, &io->dp_controller);
-   if (rc) {
-   DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc);
-   return rc;
-   }
+   dss->base = dp_ioremap(pdev, 0, &dss->len);
+   if (IS_ERR(dss->base))
+   return PTR_ERR(dss->base);
 
io->phy = devm_phy_get(&pdev->dev, "dp");
if (IS_ERR(io->phy))
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h 
b/drivers/gpu/drm/msm/dp/dp_parser.h
index 34b49628bbaf..dc62e70b1640 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -26,7 +26,7 @@ enum dp_pm_type {
 };
 
 struct dss_io_data {
-   u32 len;
+   size_t len;
void __iomem *base;
 };
 
-- 
2.29.2



[PATCH v3 4/5] drm/msm/dp: Store each subblock in the io region

2021-10-01 Thread Bjorn Andersson
Not all platforms has DP_P0 at offset 0x1000 from the beginning of the
DP block. So split the dss_io_data memory region into a set of
sub-regions, to make it possible in the next patch to specify each of
the sub-regions individually.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Skipped the unnecessary reorder in struct dss_io_region 

 drivers/gpu/drm/msm/dp/dp_catalog.c | 64 +
 drivers/gpu/drm/msm/dp/dp_parser.c  | 28 +++--
 drivers/gpu/drm/msm/dp/dp_parser.h  |  9 +++-
 3 files changed, 53 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index cc2bb8295329..6ae9b29044b6 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -24,15 +24,6 @@
 #define DP_INTERRUPT_STATUS_ACK_SHIFT  1
 #define DP_INTERRUPT_STATUS_MASK_SHIFT 2
 
-#define MSM_DP_CONTROLLER_AHB_OFFSET   0x
-#define MSM_DP_CONTROLLER_AHB_SIZE 0x0200
-#define MSM_DP_CONTROLLER_AUX_OFFSET   0x0200
-#define MSM_DP_CONTROLLER_AUX_SIZE 0x0200
-#define MSM_DP_CONTROLLER_LINK_OFFSET  0x0400
-#define MSM_DP_CONTROLLER_LINK_SIZE0x0C00
-#define MSM_DP_CONTROLLER_P0_OFFSET0x1000
-#define MSM_DP_CONTROLLER_P0_SIZE  0x0400
-
 #define DP_INTERRUPT_STATUS1 \
(DP_INTR_AUX_I2C_DONE| \
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
@@ -66,82 +57,77 @@ void dp_catalog_snapshot(struct dp_catalog *dp_catalog, 
struct msm_disp_state *d
 {
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);
+   struct dss_io_data *dss = &catalog->io->dp_controller;
 
-   msm_disp_snapshot_add_block(disp_state, catalog->io->dp_controller.len,
-   catalog->io->dp_controller.base, "dp_ctrl");
+   msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, 
"dp_ahb");
+   msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, 
"dp_aux");
+   msm_disp_snapshot_add_block(disp_state, dss->link.len, dss->link.base, 
"dp_link");
+   msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, 
"dp_p0");
 }
 
 static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_AUX_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.aux.base + offset);
 }
 
 static inline void dp_write_aux(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_AUX_OFFSET;
/*
 * To make sure aux reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.aux.base + offset);
 }
 
 static inline u32 dp_read_ahb(struct dp_catalog_private *catalog, u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_AHB_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.ahb.base + offset);
 }
 
 static inline void dp_write_ahb(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_AHB_OFFSET;
/*
 * To make sure phy reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.ahb.base + offset);
 }
 
 static inline void dp_write_p0(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_P0_OFFSET;
/*
 * To make sure interface reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.p0.base + offset);
 }
 
 static inline u32 dp_read_p0(struct dp_catalog_private *catalog,
   u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_P0_OFFSET;
/*
 * To make sure interface reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.p0.base + offset);
 }
 
 static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_LINK_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.link.base + offset);
 }
 
 stat

[PATCH v3 1/5] dt-bindings: msm/dp: Change reg definition

2021-10-01 Thread Bjorn Andersson
reg was defined as one region covering the entire DP block, but the
memory map is actually split in 4 regions and obviously the size of
these regions differs between platforms.

Switch the reg to require that all four regions are specified instead.
It is expected that the implementation will handle existing DTBs, even
though the schema defines the new layout.

Reviewed-by: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None

 .../bindings/display/msm/dp-controller.yaml | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index d89b3c510c27..6bb424c21340 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -19,7 +19,12 @@ properties:
   - qcom,sc7180-dp
 
   reg:
-maxItems: 1
+items:
+  - description: ahb register block
+  - description: aux register block
+  - description: link register block
+  - description: p0 register block
+  - description: p1 register block
 
   interrupts:
 maxItems: 1
@@ -99,7 +104,11 @@ examples:
 
 displayport-controller@ae9 {
 compatible = "qcom,sc7180-dp";
-reg = <0xae9 0x1400>;
+reg = <0xae9 0x200>,
+  <0xae90200 0x200>,
+  <0xae90400 0xc00>,
+  <0xae91000 0x400>,
+  <0xae91400 0x400>;
 interrupt-parent = <&mdss>;
 interrupts = <12>;
 clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
-- 
2.29.2



[PATCH v3 2/5] drm/msm/dp: Use devres for ioremap()

2021-10-01 Thread Bjorn Andersson
The non-devres version of ioremap is used, which requires manual
cleanup. But the code paths leading here is mixed with other devres
users, so rely on this for ioremap as well to simplify the code.

Reviewed-by: Abhinav Kumar 
Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None

 drivers/gpu/drm/msm/dp/dp_parser.c | 29 -
 1 file changed, 4 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 0519dd3ac3c3..c064ced78278 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -32,7 +32,7 @@ static int msm_dss_ioremap(struct platform_device *pdev,
}
 
io_data->len = (u32)resource_size(res);
-   io_data->base = ioremap(res->start, io_data->len);
+   io_data->base = devm_ioremap(&pdev->dev, res->start, io_data->len);
if (!io_data->base) {
DRM_ERROR("%pS->%s: ioremap failed\n",
__builtin_return_address(0), __func__);
@@ -42,22 +42,6 @@ static int msm_dss_ioremap(struct platform_device *pdev,
return 0;
 }
 
-static void msm_dss_iounmap(struct dss_io_data *io_data)
-{
-   if (io_data->base) {
-   iounmap(io_data->base);
-   io_data->base = NULL;
-   }
-   io_data->len = 0;
-}
-
-static void dp_parser_unmap_io_resources(struct dp_parser *parser)
-{
-   struct dp_io *io = &parser->io;
-
-   msm_dss_iounmap(&io->dp_controller);
-}
-
 static int dp_parser_ctrl_res(struct dp_parser *parser)
 {
int rc = 0;
@@ -67,19 +51,14 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
rc = msm_dss_ioremap(pdev, &io->dp_controller);
if (rc) {
DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc);
-   goto err;
+   return rc;
}
 
io->phy = devm_phy_get(&pdev->dev, "dp");
-   if (IS_ERR(io->phy)) {
-   rc = PTR_ERR(io->phy);
-   goto err;
-   }
+   if (IS_ERR(io->phy))
+   return PTR_ERR(io->phy);
 
return 0;
-err:
-   dp_parser_unmap_io_resources(parser);
-   return rc;
 }
 
 static int dp_parser_misc(struct dp_parser *parser)
-- 
2.29.2



[PATCH v3 0/5] drm/msm/dp: Allow variation in register regions

2021-10-01 Thread Bjorn Andersson
It turns out that sc8180x (among others) doesn't have the same internal
layout of the 4 subblocks. This series therefor modifies the binding to
require all four regions to be described individually and then extends
the driver to read these four regions. The driver will fall back to read
the old single-reg format and apply the original offsets and sizes.

Bjorn Andersson (5):
  dt-bindings: msm/dp: Change reg definition
  drm/msm/dp: Use devres for ioremap()
  drm/msm/dp: Refactor ioremap wrapper
  drm/msm/dp: Store each subblock in the io region
  drm/msm/dp: Allow sub-regions to be specified in DT

 .../bindings/display/msm/dp-controller.yaml   |  13 ++-
 drivers/gpu/drm/msm/dp/dp_catalog.c   |  64 ---
 drivers/gpu/drm/msm/dp/dp_parser.c| 102 ++
 drivers/gpu/drm/msm/dp/dp_parser.h|  11 +-
 4 files changed, 100 insertions(+), 90 deletions(-)

-- 
2.29.2



Re: [RFC] drm/msm/a6xx: Serialize GMU communication

2021-10-01 Thread Dmitry Baryshkov

On 27/09/2021 21:03, Rob Clark wrote:

From: Rob Clark 

I've seen some crashes in our crash reporting that *look* like multiple
threads stomping on each other while communicating with GMU.  So wrap
all those paths in a lock.

Signed-off-by: Rob Clark 
---
Are we allowed to use c99/gnu99 yet?

  drivers/gpu/drm/msm/Makefile  |  2 +-
  drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  6 
  drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  9 +
  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 50 ---
  4 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 904535eda0c4..57283bbad3f0 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -1,5 +1,5 @@
  # SPDX-License-Identifier: GPL-2.0
-ccflags-y := -I $(srctree)/$(src)
+ccflags-y := -I $(srctree)/$(src) -std=gnu99
  ccflags-y += -I $(srctree)/$(src)/disp/dpu1
  ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi
  ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index a7c58018959f..8b73f70766a4 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -296,6 +296,8 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
u32 val;
int request, ack;
  
+	WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));

+
if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
return -EINVAL;
  
@@ -337,6 +339,8 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)

  {
int bit;
  
+	WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));

+
if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
return;
  
@@ -1482,6 +1486,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)

if (!pdev)
return -ENODEV;
  
+	mutex_init(&gmu->lock);

+
gmu->dev = &pdev->dev;
  
  	of_dma_configure(gmu->dev, node, true);

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index 3c74f64e3126..f05a00c0afd0 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -44,6 +44,9 @@ struct a6xx_gmu_bo {
  struct a6xx_gmu {
struct device *dev;
  
+	/* For serializing communication with the GMU: */

+   struct mutex lock;
+
struct msm_gem_address_space *aspace;
  
  	void * __iomem mmio;

@@ -88,6 +91,12 @@ struct a6xx_gmu {
bool legacy; /* a618 or a630 */
  };
  
+/* Helper macro for serializing GMU access: */

+#define with_gmu_lock(gmu) \
+   for (bool done = ({ mutex_lock(&(gmu)->lock); false; }); \
+   !done; \
+   done = ({ mutex_unlock(&(gmu)->lock); true; }))


The intent is good, but I'm not sure this kind of syntax sugar would be 
a good approach. What about calling lock/unlock explicitly, like we 
typically do? Then we won't have to use c99.



+
  static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
  {
return msm_readl(gmu->mmio + (offset << 2));
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index f6a4dbef796b..5e1ae3df42ba 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -881,7 +881,7 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
  A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
  A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR)
  
-static int a6xx_hw_init(struct msm_gpu *gpu)

+static int hw_init(struct msm_gpu *gpu)
  {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
@@ -1135,6 +1135,19 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
return ret;
  }
  
+static int a6xx_hw_init(struct msm_gpu *gpu)

+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+   int ret;
+
+   with_gmu_lock(&a6xx_gpu->gmu) {
+   ret = hw_init(gpu);
+   }
+
+   return ret;
+}
+
  static void a6xx_dump(struct msm_gpu *gpu)
  {
DRM_DEV_INFO(&gpu->pdev->dev, "status:   %08x\n",
@@ -1509,7 +1522,9 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)
  
  	trace_msm_gpu_resume(0);
  
-	ret = a6xx_gmu_resume(a6xx_gpu);

+   with_gmu_lock(&a6xx_gpu->gmu) {
+   ret = a6xx_gmu_resume(a6xx_gpu);
+   }
if (ret)
return ret;
  
@@ -1532,7 +1547,9 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
  
  	msm_devfreq_suspend(gpu);
  
-	ret = a6xx_gmu_stop(a6xx_gpu);

+   with_gmu_lock(&a6xx_gpu->gmu) {
+   ret = a6xx_gmu_stop(a6xx_gpu);
+   }
if (ret)
return ret;
  
@@ -1547,18 +1564,17 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)

  {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 

Re: [PATCH v2 1/5] [RFC]iommu: Add a IOMMU_DEVONLY protection flag

2021-10-01 Thread Alyssa Rosenzweig
> The IOMMU_DEVONLY flag allows the caller to flag a mappings backed by
> device-private buffers. That means other devices or CPUs are not
> expected to access the physical memory region pointed by the mapping,
> and the MMU driver can safely restrict the shareability domain to the
> device itself.
> 
> Will be used by the ARM MMU driver to flag Mali mappings accessed only
> by the GPU as Inner-shareable.
> 
> Signed-off-by: Boris Brezillon 
> ---
>  include/linux/iommu.h | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index d2f3435e7d17..db14781b522f 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -31,6 +31,13 @@
>   * if the IOMMU page table format is equivalent.
>   */
>  #define IOMMU_PRIV   (1 << 5)
> +/*
> + * Mapping is only accessed by the device behind the iommu. That means other
> + * devices or CPUs are not expected to access this physical memory region,
> + * and the MMU driver can safely restrict the shareability domain to the
> + * device itself.
> + */
> +#define IOMMU_DEVONLY(1 << 6)
>  
>  struct iommu_ops;
>  struct iommu_group;

This seems totally reasonable to me, but it is well-known that I'm not
on good terms with the iommu subsystem. Let's wait for Robin to NAK :-P


Re: [PATCH v2 4/5] drm/panfrost: Add a PANFROST_BO_GPUONLY flag

2021-10-01 Thread Alyssa Rosenzweig
> > This seems reasonable to me - it matches the kbase
> > BASE_MEM_COHERENT_SYSTEM (only backwards obviously) and it worked
> > reasonably well for the blob.

Oh, is that what that was for? I remember seeing it set on Midgard for
varyings. Good to go full circle now.

> > But I'm wondering if we need to do anything special to deal with the
> > fact we will now have some non-coherent mappings on an otherwise
> > coherent device.
> > 
> > There are certainly some oddities around how these buffers will be
> > mapped into user space if requested, e.g. panfrost_gem_create_object()
> > sets 'map_wc' based on pfdev->coherent which is arguably wrong for
> > GPUONLY. So there are two things we could consider:
> > 
> > a) Actually prevent user space mapping GPUONLY flagged buffers. Which
> > matches the intention of the name.
> 
> I intended to do that, just forgot to add wrappers around
> drm_gem_shmem_{mmap,vmap}() to forbid CPU-mappings on gpuonly buffers.

This feels like the cleaner solution to me.

> > b) Attempt to provide user space with the tools to safely interact with
> > the buffers (this is the kbase approach). This does have the benefit of
> > allowing *mostly* GPU access. An example here is the tiler heap where
> > the CPU could zero out as necessary but mostly the GPU has ownership and
> > the CPU never reads the contents. GPUONLY/DEVONLY might not be the best
> > name in that case.
> 
> Uh, right, I forgot we had to zero the tiler heap on Midgard (most of
> the time done with a WRITE_VALUE job, but there's an exception on some
> old Midgard GPUs IIRC).

"Attempt" is the key word here :|

We indeed only touch the tiler heap from the CPU on v4, and life's too
short to care about new optimizations for v4. Unless the patch is
trivial, my vote is for a) preventing the mappings and only setting
GPUONLY on the tiler_heap starting with v5.


Re: [PATCH v2 1/3] drm/msm/dsi: Support NO_CONNECTOR bridges

2021-10-01 Thread Dmitry Baryshkov

On 21/09/2021 01:57, Rob Clark wrote:

From: Rob Clark 

For now, since we have a mix of bridges which support this flag, which
which do *not* support this flag, or work both ways, try it once with
NO_CONNECTOR and then fall back to the old way if that doesn't work.
Eventually we can drop the fallback path.

v2: Add missing drm_connector_attach_encoder() so display actually comes
 up when the bridge properly handles the NO_CONNECTOR flag

Signed-off-by: Rob Clark 
Reviewed-by: Laurent Pinchart 


Reviewed-by: Dmitry Baryshkov 

I think this patch can go through the drm/msm, while two other patches 
would need to through the drm-misc. Is it correct?



---
  drivers/gpu/drm/msm/Kconfig   |  2 ++
  drivers/gpu/drm/msm/dsi/dsi_manager.c | 50 ---
  2 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index e9c6af78b1d7..36e5ba3ccc28 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -14,6 +14,8 @@ config DRM_MSM
select REGULATOR
select DRM_KMS_HELPER
select DRM_PANEL
+   select DRM_BRIDGE
+   select DRM_PANEL_BRIDGE
select DRM_SCHED
select SHMEM
select TMPFS
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index c41d39f5b7cf..e25877073d31 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -3,6 +3,8 @@
   * Copyright (c) 2015, The Linux Foundation. All rights reserved.
   */
  
+#include "drm/drm_bridge_connector.h"

+
  #include "msm_kms.h"
  #include "dsi.h"
  
@@ -688,10 +690,10 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)

  {
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
struct drm_device *dev = msm_dsi->dev;
+   struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_bridge *int_bridge, *ext_bridge;
-   struct drm_connector *connector;
-   struct list_head *connector_list;
+   int ret;
  
  	int_bridge = msm_dsi->bridge;

ext_bridge = msm_dsi->external_bridge =
@@ -699,22 +701,44 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 
id)
  
  	encoder = msm_dsi->encoder;
  
-	/* link the internal dsi bridge to the external bridge */

-   drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
-
/*
-* we need the drm_connector created by the external bridge
-* driver (or someone else) to feed it to our driver's
-* priv->connector[] list, mainly for msm_fbdev_init()
+* Try first to create the bridge without it creating its own
+* connector.. currently some bridges support this, and others
+* do not (and some support both modes)
 */
-   connector_list = &dev->mode_config.connector_list;
+   ret = drm_bridge_attach(encoder, ext_bridge, int_bridge,
+   DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+   if (ret == -EINVAL) {
+   struct drm_connector *connector;
+   struct list_head *connector_list;
+
+   /* link the internal dsi bridge to the external bridge */
+   drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
+
+   /*
+* we need the drm_connector created by the external bridge
+* driver (or someone else) to feed it to our driver's
+* priv->connector[] list, mainly for msm_fbdev_init()
+*/
+   connector_list = &dev->mode_config.connector_list;
  
-	list_for_each_entry(connector, connector_list, head) {

-   if (drm_connector_has_possible_encoder(connector, encoder))
-   return connector;
+   list_for_each_entry(connector, connector_list, head) {
+   if (drm_connector_has_possible_encoder(connector, 
encoder))
+   return connector;
+   }
+
+   return ERR_PTR(-ENODEV);
+   }
+
+   connector = drm_bridge_connector_init(dev, encoder);
+   if (IS_ERR(connector)) {
+   DRM_ERROR("Unable to create bridge connector\n");
+   return ERR_CAST(connector);
}
  
-	return ERR_PTR(-ENODEV);

+   drm_connector_attach_encoder(connector, encoder);
+
+   return connector;
  }
  
  void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)





--
With best wishes
Dmitry


Re: [PATCH] drm: msm: hdmi: Constify static structs

2021-10-01 Thread Dmitry Baryshkov

On 21/09/2021 00:20, Rikard Falkeborn wrote:

The only usage of hdmi_8996_pll_ops is to assign its address to the ops
field in the clk_init_data struct, and the only usage of pll_init is to
assign its address to the init field in the clk_hw struct, both which
are pointers to const. Make them const to allow the compiler to put them
in read-only memory.

Signed-off-by: Rikard Falkeborn 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c
index a8f3b2cbfdc5..99c7853353fd 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c
@@ -682,7 +682,7 @@ static int hdmi_8996_pll_is_enabled(struct clk_hw *hw)
return pll_locked;
  }
  
-static struct clk_ops hdmi_8996_pll_ops = {

+static const struct clk_ops hdmi_8996_pll_ops = {
.set_rate = hdmi_8996_pll_set_clk_rate,
.round_rate = hdmi_8996_pll_round_rate,
.recalc_rate = hdmi_8996_pll_recalc_rate,
@@ -695,7 +695,7 @@ static const char * const hdmi_pll_parents[] = {
"xo",
  };
  
-static struct clk_init_data pll_init = {

+static const struct clk_init_data pll_init = {
.name = "hdmipll",
.ops = &hdmi_8996_pll_ops,
.parent_names = hdmi_pll_parents,




--
With best wishes
Dmitry


Re: [PATCH] drm/msm: Avoid potential overflow in timeout_to_jiffies()

2021-10-01 Thread Dmitry Baryshkov

On 17/09/2021 03:59, Marek Vasut wrote:

The return type of ktime_divns() is s64. The timeout_to_jiffies() currently
assigns the result of this ktime_divns() to unsigned long, which on 32 bit
systems may overflow. Furthermore, the result of this function is sometimes
also passed to functions which expect signed long, dma_fence_wait_timeout()
is one such example.

Fix this by adjusting the type of remaining_jiffies to s64, so we do not
suffer overflow there, and return a value limited to range of 0..INT_MAX,
which is safe for all usecases of this timeout.

The above overflow can be triggered if userspace passes in too large timeout
value, larger than INT_MAX / HZ seconds. The kernel detects it and complains
about "schedule_timeout: wrong timeout value %lx" and generates a warning
backtrace.

Note that this fixes commit 6cedb8b377bb ("drm/msm: avoid using 'timespec'"),
because the previously used timespec_to_jiffies() function returned unsigned
long instead of s64:
static inline unsigned long timespec_to_jiffies(const struct timespec *value)

Fixes: 6cedb8b377bb ("drm/msm: avoid using 'timespec'")
Signed-off-by: Marek Vasut 
Cc: Arnd Bergmann 
Cc: Jordan Crouse 
Cc: Rob Clark 
Cc: sta...@vger.kernel.org # 5.6+


Reviewed-by: Dmitry Baryshkov 


---
NOTE: This is related to Mesa MR
   https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12886
---
  drivers/gpu/drm/msm/msm_drv.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 0b2686b060c73..d96b254b8aa46 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -543,7 +543,7 @@ static inline int align_pitch(int width, int bpp)
  static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
  {
ktime_t now = ktime_get();
-   unsigned long remaining_jiffies;
+   s64 remaining_jiffies;
  
  	if (ktime_compare(*timeout, now) < 0) {

remaining_jiffies = 0;
@@ -552,7 +552,7 @@ static inline unsigned long timeout_to_jiffies(const 
ktime_t *timeout)
remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
}
  
-	return remaining_jiffies;

+   return clamp(remaining_jiffies, 0LL, (s64)INT_MAX);
  }
  
  #endif /* __MSM_DRV_H__ */





--
With best wishes
Dmitry


Re: [PATCH] drm/msm/dsi: dsi_phy_14nm: Take ready-bit into account in poll_for_ready

2021-10-01 Thread Dmitry Baryshkov

On 06/09/2021 23:25, Marijn Suijten wrote:

The downstream driver models this PLL lock check as an if-elseif-else.
The only way to reach the else case where pll_locked=true [1] is by
succeeding both readl_poll_timeout_atomic calls (which return zero on
success) in the if _and_ elseif condition.  Hence both the "lock" and
"ready" bit need to be tested in the SM_READY_STATUS register before
considering the PLL locked and ready to go.

Tested on the Sony Xperia XA2 Ultra (nile-discovery, sdm630).

[1]: 
https://source.codeaurora.org/quic/la/kernel/msm-4.19/tree/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm-util.c?h=LA.UM.9.2.1.r1-08000-sdm660.0#n302

Fixes: f079f6d999cb ("drm/msm/dsi: Add PHY/PLL for 8x96")
Signed-off-by: Marijn Suijten 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 30 +++---
  1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c 
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
index 8905f365c932..789b08c24d25 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
@@ -110,14 +110,13 @@ static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX];
  static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm,
u32 nb_tries, u32 timeout_us)
  {
-   bool pll_locked = false;
+   bool pll_locked = false, pll_ready = false;
void __iomem *base = pll_14nm->phy->pll_base;
u32 tries, val;
  
  	tries = nb_tries;

while (tries--) {
-   val = dsi_phy_read(base +
-  REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+   val = dsi_phy_read(base + 
REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
pll_locked = !!(val & BIT(5));
  
  		if (pll_locked)

@@ -126,23 +125,24 @@ static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm 
*pll_14nm,
udelay(timeout_us);
}
  
-	if (!pll_locked) {

-   tries = nb_tries;
-   while (tries--) {
-   val = dsi_phy_read(base +
-   REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
-   pll_locked = !!(val & BIT(0));
+   if (!pll_locked)
+   goto out;
  
-			if (pll_locked)

-   break;
+   tries = nb_tries;
+   while (tries--) {
+   val = dsi_phy_read(base + 
REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+   pll_ready = !!(val & BIT(0));
  
-			udelay(timeout_us);

-   }
+   if (pll_ready)
+   break;
+
+   udelay(timeout_us);
}
  
-	DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");

+out:
+   DBG("DSI PLL is %slocked, %sready", pll_locked ? "" : "*not* ", pll_ready ? "" : 
"*not* ");
  
-	return pll_locked;

+   return pll_locked && pll_ready;
  }
  
  static void dsi_pll_14nm_config_init(struct dsi_pll_config *pconf)





--
With best wishes
Dmitry


Re: [PATCH 0/3] drm/msm: drop old eDP support

2021-10-01 Thread Bjorn Andersson
On Fri 01 Oct 09:50 PDT 2021, Dmitry Baryshkov wrote:

> MSM DRM driver has support for eDP block present on MSM 8x74/8x84 SoC
> families. However since addition back in 2015 this driver received only
> generic fixes. No actual devices with these SoCs supported upstream (or
> by the community) seem to support eDP panels. Judging from downstream
> kernels the eDP was present only on MSM8974 LIQUID or on APQ8084 CDP.
> Remove this driver.
> 

Nice!

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> 
> Dmitry Baryshkov (3):
>   drm/msm/mdp5: drop eDP support
>   drm/msm/edp: drop old eDP support
>   dt-bindings: display/msm: remove edp.txt
> 
>  .../devicetree/bindings/display/msm/edp.txt|   56 -
>  drivers/gpu/drm/msm/Makefile   |6 -
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c   |   17 +-
>  drivers/gpu/drm/msm/edp/edp.c  |  198 ---
>  drivers/gpu/drm/msm/edp/edp.h  |   77 --
>  drivers/gpu/drm/msm/edp/edp.xml.h  |  388 --
>  drivers/gpu/drm/msm/edp/edp_aux.c  |  265 
>  drivers/gpu/drm/msm/edp/edp_bridge.c   |  111 --
>  drivers/gpu/drm/msm/edp/edp_connector.c|  132 --
>  drivers/gpu/drm/msm/edp/edp_ctrl.c | 1375 
> 
>  drivers/gpu/drm/msm/edp/edp_phy.c  |   98 --
>  drivers/gpu/drm/msm/msm_drv.c  |2 -
>  drivers/gpu/drm/msm/msm_drv.h  |   12 -
>  13 files changed, 1 insertion(+), 2736 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/display/msm/edp.txt
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp.c
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp.h
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp.xml.h
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp_aux.c
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp_bridge.c
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp_connector.c
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp_ctrl.c
>  delete mode 100644 drivers/gpu/drm/msm/edp/edp_phy.c
> 


[PULL] drm-fixes

2021-10-01 Thread Daniel Vetter
Hi Linus,

Dave is out on a long w/e, should be back next week. Nothing nefarious,
just a bunch of driver fixes.

Cheers, Daniel

drm-fixes-2021-10-01:
drm fixes for -rc4:

amdgpu, i915, tegra, and one exynos driver fix

Cheers, Daniel

The following changes since commit 5816b3e6577eaa676ceb00a848f0fd65fe2adc29:

  Linux 5.15-rc3 (2021-09-26 14:08:19 -0700)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2021-10-01

for you to fetch changes up to 78ea81417944fe03f48648eddeb8e8a8e513c4ad:

  Merge tag 'exynos-drm-fixes-for-v5.15-rc4' of 
git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes 
(2021-10-01 18:14:39 +0200)


drm fixes for -rc4:

amdgpu, i915, tegra, and one exynos driver fix


Akira Yokosawa (1):
  drm/i915/guc, docs: Fix pdfdocs build error by removing nested grid

Cai Huoqing (1):
  drm/exynos: Make use of the helper function 
devm_platform_ioremap_resource()

Charlene Liu (1):
  drm/amd/display: Pass PCI deviceid into DC

Daniel Vetter (3):
  Merge tag 'drm-intel-fixes-2021-09-30' of 
git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
  Merge tag 'amd-drm-fixes-5.15-2021-09-29' of 
https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
  Merge tag 'exynos-drm-fixes-for-v5.15-rc4' of 
git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes

Dave Airlie (1):
  Merge tag 'drm/tegra/for-5.15-rc3' of 
ssh://git.freedesktop.org/git/tegra/linux into drm-fixes

Dmitry Osipenko (3):
  drm/tegra: dc: Remove unused variables
  drm/tegra: uapi: Fix wrong mapping end address in case of disabled IOMMU
  gpu/host1x: fence: Make spinlock static

Hawking Zhang (1):
  drm/amdgpu: correct initial cp_hqd_quantum for gfx9

Jani Nikula (1):
  Merge tag 'gvt-fixes-2021-09-18' of https://github.com/intel/gvt-linux 
into drm-intel-fixes

Josip Pavic (1):
  drm/amd/display: initialize backlight_ramping_override to false

Leslie Shi (1):
  drm/amdgpu: fix gart.bo pin_count leak

Matthew Auld (1):
  drm/i915/request: fix early tracepoints

Praful Swarnakar (1):
  drm/amd/display: Fix Display Flicker on embedded panels

Prike Liang (1):
  drm/amdgpu: force exit gfxoff on sdma resume for rmb s0ix

Simon Ser (1):
  drm/amdgpu: check tiling flags when creating FB on GFX8-

Tejas Upadhyay (1):
  drm/i915: Remove warning from the rps worker

Thierry Reding (1):
  gpu: host1x: Plug potential memory leak

Zhi A Wang (1):
  drm/i915/gvt: fix the usage of ww lock in gvt scheduler.

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c| 31 ++
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |  3 ++-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  |  3 ++-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c |  8 ++
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  2 ++
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   | 15 +--
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c  |  4 +--
 drivers/gpu/drm/exynos/exynos_drm_dsi.c|  4 +--
 drivers/gpu/drm/exynos/exynos_drm_fimc.c   |  5 +---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   |  4 +--
 drivers/gpu/drm/exynos/exynos_drm_g2d.c|  5 +---
 drivers/gpu/drm/exynos/exynos_drm_gsc.c|  6 +
 drivers/gpu/drm/exynos/exynos_drm_rotator.c|  4 +--
 drivers/gpu/drm/exynos/exynos_drm_scaler.c |  4 +--
 drivers/gpu/drm/exynos/exynos_hdmi.c   |  4 +--
 drivers/gpu/drm/i915/gt/intel_rps.c|  2 --
 .../drm/i915/gt/uc/abi/guc_communication_ctb_abi.h | 10 +++
 .../i915/gt/uc/abi/guc_communication_mmio_abi.h| 10 +++
 drivers/gpu/drm/i915/gvt/scheduler.c   |  4 +--
 drivers/gpu/drm/i915/i915_request.c| 11 ++--
 drivers/gpu/drm/tegra/dc.c |  3 ---
 drivers/gpu/drm/tegra/dc.h |  6 -
 drivers/gpu/drm/tegra/uapi.c   |  2 +-
 drivers/gpu/host1x/fence.c |  6 +++--
 25 files changed, 81 insertions(+), 77 deletions(-)

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


Re: [GIT PULL] exynos-drm-fixes

2021-10-01 Thread Daniel Vetter
On Tue, Sep 28, 2021 at 04:41:58PM +0900, Inki Dae wrote:
> Hi Dave,
> 
>Just one clean up to use helper function.
> 
> Please kindly let me know if there is any problem.
> 
> Thanks,
> Inki Dae
> 
> The following changes since commit 6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f:
> 
>   Linux 5.15-rc1 (2021-09-12 16:28:37 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos 
> tags/exynos-drm-fixes-for-v5.15-rc4
> 
> for you to fetch changes up to 17ac76e050c51497e75871a43aa3328ba54cdafd:
> 
>   drm/exynos: Make use of the helper function 
> devm_platform_ioremap_resource() (2021-09-16 14:05:07 +0900)
> 
> 
> One cleanup
> - Use devm_platform_ioremap_resource() helper function instead of old
>   one.

Pulled into drm-fixes, thanks.
-Daniel

> 
> 
> Cai Huoqing (1):
>   drm/exynos: Make use of the helper function 
> devm_platform_ioremap_resource()
> 
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 4 +---
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c   | 4 +---
>  drivers/gpu/drm/exynos/exynos_drm_fimc.c  | 5 +
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c  | 4 +---
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c   | 5 +
>  drivers/gpu/drm/exynos/exynos_drm_gsc.c   | 6 +-
>  drivers/gpu/drm/exynos/exynos_drm_rotator.c   | 4 +---
>  drivers/gpu/drm/exynos/exynos_drm_scaler.c| 4 +---
>  drivers/gpu/drm/exynos/exynos_hdmi.c  | 4 +---
>  9 files changed, 9 insertions(+), 31 deletions(-)

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


[PATCH 2/3] drm/msm/edp: drop old eDP support

2021-10-01 Thread Dmitry Baryshkov
MSM DRM driver has support for eDP block present on MSM 8x74/8x84 SoC
families. However since addition back in 2015 this driver received only
generic fixes. No actual devices with these SoCs supported upstream (or
by the community) seem to support eDP panels. Judging from downstream
kernels the eDP was present only on MSM8974 LIQUID or on APQ8084 CDP.
Remove this driver.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/Makefile|6 -
 drivers/gpu/drm/msm/edp/edp.c   |  198 
 drivers/gpu/drm/msm/edp/edp.h   |   77 --
 drivers/gpu/drm/msm/edp/edp.xml.h   |  388 ---
 drivers/gpu/drm/msm/edp/edp_aux.c   |  265 -
 drivers/gpu/drm/msm/edp/edp_bridge.c|  111 --
 drivers/gpu/drm/msm/edp/edp_connector.c |  132 ---
 drivers/gpu/drm/msm/edp/edp_ctrl.c  | 1375 ---
 drivers/gpu/drm/msm/edp/edp_phy.c   |   98 --
 drivers/gpu/drm/msm/msm_drv.c   |2 -
 drivers/gpu/drm/msm/msm_drv.h   |   12 -
 11 files changed, 2664 deletions(-)
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.h
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.xml.h
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_aux.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_bridge.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_connector.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_ctrl.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_phy.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 904535eda0c4..a6f67c8a5105 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -25,12 +25,6 @@ msm-y := \
hdmi/hdmi_phy_8960.o \
hdmi/hdmi_phy_8x60.o \
hdmi/hdmi_phy_8x74.o \
-   edp/edp.o \
-   edp/edp_aux.o \
-   edp/edp_bridge.o \
-   edp/edp_connector.o \
-   edp/edp_ctrl.o \
-   edp/edp_phy.o \
disp/mdp_format.o \
disp/mdp_kms.o \
disp/mdp4/mdp4_crtc.o \
diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c
deleted file mode 100644
index 106a67473af5..
--- a/drivers/gpu/drm/msm/edp/edp.c
+++ /dev/null
@@ -1,198 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
- */
-
-#include 
-#include "edp.h"
-
-static irqreturn_t edp_irq(int irq, void *dev_id)
-{
-   struct msm_edp *edp = dev_id;
-
-   /* Process eDP irq */
-   return msm_edp_ctrl_irq(edp->ctrl);
-}
-
-static void edp_destroy(struct platform_device *pdev)
-{
-   struct msm_edp *edp = platform_get_drvdata(pdev);
-
-   if (!edp)
-   return;
-
-   if (edp->ctrl) {
-   msm_edp_ctrl_destroy(edp->ctrl);
-   edp->ctrl = NULL;
-   }
-
-   platform_set_drvdata(pdev, NULL);
-}
-
-/* construct eDP at bind/probe time, grab all the resources. */
-static struct msm_edp *edp_init(struct platform_device *pdev)
-{
-   struct msm_edp *edp = NULL;
-   int ret;
-
-   if (!pdev) {
-   pr_err("no eDP device\n");
-   ret = -ENXIO;
-   goto fail;
-   }
-
-   edp = devm_kzalloc(&pdev->dev, sizeof(*edp), GFP_KERNEL);
-   if (!edp) {
-   ret = -ENOMEM;
-   goto fail;
-   }
-   DBG("eDP probed=%p", edp);
-
-   edp->pdev = pdev;
-   platform_set_drvdata(pdev, edp);
-
-   ret = msm_edp_ctrl_init(edp);
-   if (ret)
-   goto fail;
-
-   return edp;
-
-fail:
-   if (edp)
-   edp_destroy(pdev);
-
-   return ERR_PTR(ret);
-}
-
-static int edp_bind(struct device *dev, struct device *master, void *data)
-{
-   struct drm_device *drm = dev_get_drvdata(master);
-   struct msm_drm_private *priv = drm->dev_private;
-   struct msm_edp *edp;
-
-   DBG("");
-   edp = edp_init(to_platform_device(dev));
-   if (IS_ERR(edp))
-   return PTR_ERR(edp);
-   priv->edp = edp;
-
-   return 0;
-}
-
-static void edp_unbind(struct device *dev, struct device *master, void *data)
-{
-   struct drm_device *drm = dev_get_drvdata(master);
-   struct msm_drm_private *priv = drm->dev_private;
-
-   DBG("");
-   if (priv->edp) {
-   edp_destroy(to_platform_device(dev));
-   priv->edp = NULL;
-   }
-}
-
-static const struct component_ops edp_ops = {
-   .bind   = edp_bind,
-   .unbind = edp_unbind,
-};
-
-static int edp_dev_probe(struct platform_device *pdev)
-{
-   DBG("");
-   return component_add(&pdev->dev, &edp_ops);
-}
-
-static int edp_dev_remove(struct platform_device *pdev)
-{
-   DBG("");
-   component_del(&pdev->dev, &edp_ops);
-   return 0;
-}
-
-static const struct of_device_id dt_match[] = {
-   { .compatible = "qcom,mdss-edp" },
-   {}
-};
-
-static struct platform_driver edp_driver = {
-   .probe = edp_dev_probe,
- 

[PATCH 3/3] dt-bindings: display/msm: remove edp.txt

2021-10-01 Thread Dmitry Baryshkov
eDP driver is being removed, so drop bindings description.

Signed-off-by: Dmitry Baryshkov 
---
 .../devicetree/bindings/display/msm/edp.txt   | 56 ---
 1 file changed, 56 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/msm/edp.txt

diff --git a/Documentation/devicetree/bindings/display/msm/edp.txt 
b/Documentation/devicetree/bindings/display/msm/edp.txt
deleted file mode 100644
index eff9daff418c..
--- a/Documentation/devicetree/bindings/display/msm/edp.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-Qualcomm Technologies Inc. adreno/snapdragon eDP output
-
-Required properties:
-- compatible:
-  * "qcom,mdss-edp"
-- reg: Physical base address and length of the registers of controller and PLL
-- reg-names: The names of register regions. The following regions are required:
-  * "edp"
-  * "pll_base"
-- interrupts: The interrupt signal from the eDP block.
-- power-domains: Should be <&mmcc MDSS_GDSC>.
-- clocks: device clocks
-  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-- clock-names: the following clocks are required:
-  * "core"
-  * "iface"
-  * "mdp_core"
-  * "pixel"
-  * "link"
-- #clock-cells: The value should be 1.
-- vdda-supply: phandle to vdda regulator device node
-- lvl-vdd-supply: phandle to regulator device node which is used to supply 
power
-  to HPD receiving chip
-- panel-en-gpios: GPIO pin to supply power to panel.
-- panel-hpd-gpios: GPIO pin used for eDP hpd.
-
-
-Example:
-   mdss_edp: qcom,mdss_edp@fd923400 {
-   compatible = "qcom,mdss-edp";
-   reg-names =
-   "edp",
-   "pll_base";
-   reg =   <0xfd923400 0x700>,
-   <0xfd923a00 0xd4>;
-   interrupt-parent = <&mdss_mdp>;
-   interrupts = <12 0>;
-   power-domains = <&mmcc MDSS_GDSC>;
-   clock-names =
-   "core",
-   "pixel",
-   "iface",
-   "link",
-   "mdp_core";
-   clocks =
-   <&mmcc MDSS_EDPAUX_CLK>,
-   <&mmcc MDSS_EDPPIXEL_CLK>,
-   <&mmcc MDSS_AHB_CLK>,
-   <&mmcc MDSS_EDPLINK_CLK>,
-   <&mmcc MDSS_MDP_CLK>;
-   #clock-cells = <1>;
-   vdda-supply = <&pma8084_l12>;
-   lvl-vdd-supply = <&lvl_vreg>;
-   panel-en-gpios = <&tlmm 137 0>;
-   panel-hpd-gpios = <&tlmm 103 0>;
-   };
-- 
2.33.0



[PATCH 1/3] drm/msm/mdp5: drop eDP support

2021-10-01 Thread Dmitry Baryshkov
Prepare for removing old eDP support present in 8x74/8x84 SoC families.
No devices present in mainline support eDP ports.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 17 +
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index b3b42672b2d4..21707fcd883d 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -376,22 +376,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms,
 
switch (intf->type) {
case INTF_eDP:
-   if (!priv->edp)
-   break;
-
-   ctl = mdp5_ctlm_request(ctlm, intf->num);
-   if (!ctl) {
-   ret = -EINVAL;
-   break;
-   }
-
-   encoder = construct_encoder(mdp5_kms, intf, ctl);
-   if (IS_ERR(encoder)) {
-   ret = PTR_ERR(encoder);
-   break;
-   }
-
-   ret = msm_edp_modeset_init(priv->edp, dev, encoder);
+   DRM_DEV_INFO(dev->dev, "Skipping eDP interface %d\n", 
intf->num);
break;
case INTF_HDMI:
if (!priv->hdmi)
-- 
2.33.0



[PATCH 0/3] drm/msm: drop old eDP support

2021-10-01 Thread Dmitry Baryshkov
MSM DRM driver has support for eDP block present on MSM 8x74/8x84 SoC
families. However since addition back in 2015 this driver received only
generic fixes. No actual devices with these SoCs supported upstream (or
by the community) seem to support eDP panels. Judging from downstream
kernels the eDP was present only on MSM8974 LIQUID or on APQ8084 CDP.
Remove this driver.


Dmitry Baryshkov (3):
  drm/msm/mdp5: drop eDP support
  drm/msm/edp: drop old eDP support
  dt-bindings: display/msm: remove edp.txt

 .../devicetree/bindings/display/msm/edp.txt|   56 -
 drivers/gpu/drm/msm/Makefile   |6 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c   |   17 +-
 drivers/gpu/drm/msm/edp/edp.c  |  198 ---
 drivers/gpu/drm/msm/edp/edp.h  |   77 --
 drivers/gpu/drm/msm/edp/edp.xml.h  |  388 --
 drivers/gpu/drm/msm/edp/edp_aux.c  |  265 
 drivers/gpu/drm/msm/edp/edp_bridge.c   |  111 --
 drivers/gpu/drm/msm/edp/edp_connector.c|  132 --
 drivers/gpu/drm/msm/edp/edp_ctrl.c | 1375 
 drivers/gpu/drm/msm/edp/edp_phy.c  |   98 --
 drivers/gpu/drm/msm/msm_drv.c  |2 -
 drivers/gpu/drm/msm/msm_drv.h  |   12 -
 13 files changed, 1 insertion(+), 2736 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/msm/edp.txt
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.h
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.xml.h
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_aux.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_bridge.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_connector.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_ctrl.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_phy.c



Re: Handling DRM master transitions cooperatively

2021-10-01 Thread Simon Ser
On Wednesday, September 22nd, 2021 at 11:21, Hans de Goede 
 wrote:

> I would be happy to work on the plymouth side of this, so that we
> have at least one consumer of such a flag lined up for merging.

Do you have plans to work on the kernel side part of this? If so, feel free to
CC me for a review. If not, let me know if you'd like to switch roles, I could
work on a patch.

Simon


Re: [Intel-gfx] [PATCH] drm/i915: remove IS_ACTIVE

2021-10-01 Thread Lucas De Marchi

On Fri, Oct 01, 2021 at 12:57:13PM +0300, Jani Nikula wrote:

On Fri, 01 Oct 2021, Chris Wilson  wrote:

Quoting Lucas De Marchi (2021-10-01 08:40:41)

When trying to bring IS_ACTIVE to linux/kconfig.h I thought it wouldn't
provide much value just encapsulating it in a boolean context. So I also
added the support for handling undefined macros as the IS_ENABLED()
counterpart. However the feedback received from Masahiro Yamada was that
it is too ugly, not providing much value. And just wrapping in a boolean
context is too dumb - we could simply open code it.

As detailed in commit babaab2f4738 ("drm/i915: Encapsulate kconfig
constant values inside boolean predicates"), the IS_ACTIVE macro was
added to workaround a compilation warning. However after checking again
our current uses of IS_ACTIVE it turned out there is only
1 case in which it would potentially trigger a warning. All the others
  can simply use the shorter version, without wrapping it in any macro.
And even that single one didn't trigger any warning in gcc 10.3.

So here I'm dialing all the way back to simply removing the macro. If it
triggers warnings in future we may change the few cases to check for > 0
or != 0. Another possibility would be to use the great "not not
operator" for all positive checks, which would allow us to maintain
consistency.  However let's try first the simplest form though, hopefully
we don't hit broken compilers spitting a warning:


You didn't prevent the compilation warning this re-introduces.

drivers/gpu/drm/i915/i915_config.c:11 i915_fence_context_timeout() warn: should 
this be a bitwise op?
drivers/gpu/drm/i915/i915_request.c:1679 i915_request_wait() warn: should this 
be a bitwise op?


Looks like that's a Smatch warning. The immediate fix would be to just
add the != 0 in the relevant places. But this is stuff that's just going
to get broken again unless we add Smatch to CI. Most people aren't
running it on a regular basis.


it looks like the warning is also triggered with clang an as per
0day test.  What if we change all the positive caes to use !!?  That
would make it  consistent and IMO not as ugly as the != 0.

what about this?

-8<
diff --git a/drivers/gpu/drm/i915/i915_config.c 
b/drivers/gpu/drm/i915/i915_config.c
index ad228dd96a0b..0df3efa2e72d 100644
--- a/drivers/gpu/drm/i915/i915_config.c
+++ b/drivers/gpu/drm/i915/i915_config.c
@@ -8,7 +8,7 @@
 unsigned long
 i915_fence_context_timeout(const struct drm_i915_private *i915, u64 context)
 {
-   if (context && CONFIG_DRM_I915_FENCE_TIMEOUT)
+   if (context && !!CONFIG_DRM_I915_FENCE_TIMEOUT)
return msecs_to_jiffies_timeout(CONFIG_DRM_I915_FENCE_TIMEOUT);
 
 	return 0;

-8<

Lucas De Marchi


Re: [PATCH v2 4/5] drm/panfrost: Add a PANFROST_BO_GPUONLY flag

2021-10-01 Thread Boris Brezillon
On Fri, 1 Oct 2021 16:13:42 +0100
Steven Price  wrote:

> On 01/10/2021 15:34, Boris Brezillon wrote:
> > This lets the driver reduce shareability domain of the MMU mapping,
> > which can in turn reduce access time and save power on cache-coherent
> > systems.
> > 
> > Signed-off-by: Boris Brezillon   
> 
> This seems reasonable to me - it matches the kbase
> BASE_MEM_COHERENT_SYSTEM (only backwards obviously) and it worked
> reasonably well for the blob.
> 
> But I'm wondering if we need to do anything special to deal with the
> fact we will now have some non-coherent mappings on an otherwise
> coherent device.
> 
> There are certainly some oddities around how these buffers will be
> mapped into user space if requested, e.g. panfrost_gem_create_object()
> sets 'map_wc' based on pfdev->coherent which is arguably wrong for
> GPUONLY. So there are two things we could consider:
> 
> a) Actually prevent user space mapping GPUONLY flagged buffers. Which
> matches the intention of the name.

I intended to do that, just forgot to add wrappers around
drm_gem_shmem_{mmap,vmap}() to forbid CPU-mappings on gpuonly buffers.

> 
> b) Attempt to provide user space with the tools to safely interact with
> the buffers (this is the kbase approach). This does have the benefit of
> allowing *mostly* GPU access. An example here is the tiler heap where
> the CPU could zero out as necessary but mostly the GPU has ownership and
> the CPU never reads the contents. GPUONLY/DEVONLY might not be the best
> name in that case.

Uh, right, I forgot we had to zero the tiler heap on Midgard (most of
the time done with a WRITE_VALUE job, but there's an exception on some
old Midgard GPUs IIRC).


Re: [PATCH v3 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-01 Thread Chun-Kuang Hu
Hi, Markus:

Markus Schneider-Pargmann  於 2021年10月1日 週五 下午5:44寫道:
>
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC and a
> according phy driver mediatek-dp-phy.
>
> It supports both functional units on the mt8195, the embedded
> DisplayPort as well as the external DisplayPort units. It offers
> hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> to 4 lanes.
>
> The driver creates a child device for the phy. The child device will
> never exist without the parent being active. As they are sharing a
> register range, the parent passes a regmap pointer to the child so that
> both can work with the same register range. The phy driver sets device
> data that is read by the parent to get the phy device that can be used
> to control the phy properties.
>
> This driver is based on an initial version by
> Jason-JH.Lin .
>
> Signed-off-by: Markus Schneider-Pargmann 
> ---
>
> Notes:
> Changes v2 -> v3:
> - Solve TODOs and add defines for undescribed registers
> - Remove TODOs that were irrelevant
>
> Changes v1 -> v2:
> - Fix checkpatch --strict suggestions
> - General cleanups of the code.
> - Remove all remaining non-atomic functions.
> - Remove unused includes and sort them.
> - Remove unused select GENERIC_PHY
> - Rename phy registers DP_PHY -> MTK_DP_PHY
> - Replace usage of delays with usleep_range.
> - Split the phy register accesses into a separate phy driver.
> - Use a lock to guard access to mtk_dp->edid as it can be 
> allocated/used/freed
>   in different threads
> - use struct dp_sdp for sdp packets.
>
> Changes RFC -> v1:
> - Removed unused register definitions.
> - Replaced workqueue with threaded irq.
> - Removed connector code.
> - Move to atomic_* drm functions.
> - General cleanups of the code.
> - Remove unused select GENERIC_PHY.
>
>  drivers/gpu/drm/mediatek/Kconfig   |7 +
>  drivers/gpu/drm/mediatek/Makefile  |2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c  | 2825 
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  535 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
>  drivers/phy/mediatek/Kconfig   |8 +
>  drivers/phy/mediatek/Makefile  |1 +
>  drivers/phy/mediatek/phy-mtk-dp.c  |  218 ++

Separate the phy driver to another patch because phy driver would go
into different maintainer's tree.

Regards,
Chun-Kuang.

>  include/linux/soc/mediatek/mtk-mmsys.h |2 +
>  10 files changed, 3600 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
>


[PATCH] drm/i915: Fix bug in user proto-context creation that leaked contexts

2021-10-01 Thread Matthew Brost
Set number of engines before attempting to create contexts so the
function free_engines can clean up properly. Also check return of
alloc_engines for NULL.

v2:
 (Tvrtko)
  - Send as stand alone patch
 (John Harrison)
  - Check for alloc_engines returning NULL
v3:
 (Checkpatch / Tvrtko)
  - Remove braces around single line if statement

Cc: Jason Ekstrand 
Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle create 
parameters (v5)")
Reviewed-by: Tvrtko Ursulin 
Signed-off-by: Matthew Brost 
Cc: 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 8208fd5b72c3..8c7ea6e56262 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -898,6 +898,10 @@ static struct i915_gem_engines *user_engines(struct 
i915_gem_context *ctx,
unsigned int n;
 
e = alloc_engines(num_engines);
+   if (!e)
+   return ERR_PTR(-ENOMEM);
+   e->num_engines = num_engines;
+
for (n = 0; n < num_engines; n++) {
struct intel_context *ce;
int ret;
@@ -931,7 +935,6 @@ static struct i915_gem_engines *user_engines(struct 
i915_gem_context *ctx,
goto free_engines;
}
}
-   e->num_engines = num_engines;
 
return e;
 
-- 
2.32.0



Re: [Intel-gfx] [PATCH] drm/i915: Fix bug in user proto-context creation that leaked contexts

2021-10-01 Thread Matthew Brost
On Fri, Oct 01, 2021 at 09:40:19AM +0100, Tvrtko Ursulin wrote:
> 
> + Daniel as reviewer and maybe merge, avoid falling through cracks at least.
> 

Ty, working on push rights myself.

> On 22/09/2021 20:43, Matthew Brost wrote:
> > Set number of engines before attempting to create contexts so the
> > function free_engines can clean up properly. Also check return of
> > alloc_engines for NULL.
> > 
> > v2:
> >   (Tvrtko)
> >- Send as stand alone patch
> >   (John Harrison)
> >- Check for alloc_engines returning NULL
> > 
> > Cc: Jason Ekstrand 
> > Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle create 
> > parameters (v5)")
> > Signed-off-by: Matthew Brost 
> > Cc: 
> > ---
> >   drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 +-
> >   1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> > b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > index c2ab0e22db0a..9627c7aac6a3 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > @@ -898,6 +898,11 @@ static struct i915_gem_engines *user_engines(struct 
> > i915_gem_context *ctx,
> > unsigned int n;
> > e = alloc_engines(num_engines);
> > +   if (!e) {
> > +   return ERR_PTR(-ENOMEM);
> > +   }
> 
> Ideally remove the braces and respin.
>

Yep, checkpatch didn't like this. Will respin.
 
> > +   e->num_engines = num_engines;
> 
> Theoretically you could have put it next to "e->engines[n] = ce" assignment
> so the pattern is the same as in default_engines(). Kind of makes more sense
> that the number is not set before anything is created, but as it doesn't
> really matter since free_engines handles sparse arrays so there is argument
> to have a simpler single assignment as well.
>

I like a single assignment, let's not overthink this.
 
> > +
> > for (n = 0; n < num_engines; n++) {
> > struct intel_context *ce;
> > int ret;
> > @@ -931,7 +936,6 @@ static struct i915_gem_engines *user_engines(struct 
> > i915_gem_context *ctx,
> > goto free_engines;
> > }
> > }
> > -   e->num_engines = num_engines;
> > return e;
> > 
> 
> Fix looks good to me. I did not want to butt in but since more than a week
> has passed without it getting noticed:
> 

Again, ty.

Matt

> Reviewed-by: Tvrtko Ursulin 
> 
> Regards,
> 
> Tvrtko


Re: [v2 PATCH 1/3] drm/mediatek: Fix crash at using pkt->cl->chan in cmdq_pkt_finalize

2021-10-01 Thread Chun-Kuang Hu
Hi, Enric:

Enric Balletbo Serra  於 2021年9月30日 週四 下午9:48寫道:
>
> Hi Chun-Kuang,
>
> Missatge de Chun-Kuang Hu  del dia dj., 30 de
> set. 2021 a les 15:11:
> >
> > Hi, Enric:
> >
> > Enric Balletbo Serra  於 2021年9月30日 週四 下午3:12寫道:
> > >
> > > Hi Jason,
> > >
> > >
> > > Missatge de jason-jh.lin  del dia dj., 30
> > > de set. 2021 a les 4:47:
> > > >
> > > > Because mtk_drm_crtc_create_pkt didn't assign pkt->cl, it will
> > > > crash at using pkt->cl->chan in cmdq_pkt_finalize.
> > > >
> > > > So add struct cmdq_client and let mtk_drm_crtc instance define
> > > > cmdq_client as:
> > > >
> > > > struct mtk_drm_crtc {
> > > > /* client instance data */
> > > > struct cmdq_client cmdq_client;
> > > > };
> > > >
> > > > and in rx_callback function can use pkt->cl to get
> > > > struct cmdq_client.
> > > >
> > > > Fixes: f4be17cd5b14 ("drm/mediatek: Remove struct cmdq_client")
> > >
> > > Looking at this patchset looks like you're fixing the above commit by
> > > reintroducing the 'struct cmdq_client' again, which makes the above
> > > commit as a non-sense commit. That's confusing and not clear. I'm
> > > wondering if it wouldn't be more clear if you can just revert that
> > > patch. Then if there are more changes that need to be done do it with
> > > a follow up patch and really explain why these changes are needed.
> >
> > The patch f4be17cd5b14 ("drm/mediatek: Remove struct cmdq_client")
> > does two things. One is to remove struct cmdq_client, another one is
> > to embed cmdq_cl
>
> Then it should have been two patches, one thing for patch really
> helps, specially when something breaks and you try to bisect it.
>
> > in mtk_drm_crtc (This means the pointer of cmdq_cl could be used to
> > find the pointer of mtk_drm_crtc). The correct way to fix that patch
> > is to remove the access to cmdq_client in cmdq_pkt_finalize(), but
> > that would be a long term process. The simple way is to revert that
> > patch, but the other patches depend on embedding cmdq_cl in
> > mtk_drm_crtc. So this patch just revert the removing of struct
> > cmdq_client but keep embedding cmdq_cl in mtk_drm_crtc.
> >
>
> Yes, I know and I suffered that when bisecting and I ended to revert
> the full series in my local tree,  although I figured out that the
> problem was this specific patch.
>
> The following series landed during -rc1 cycle and break the Acer Chromebook 
> R13
>
>  9efb16c2fdd6 ("drm/mediatek: Clear pending flag when cmdq packet is done")
>  bc9241be73d9 ("drm/mediatek: Add cmdq_handle in mtk_crtc")
>  8cdcb3653424 ("drm/mediatek: Detect CMDQ execution timeout")
>  f4be17cd5b14 ("drm/mediatek: Remove struct cmdq_client")
>  c1ec54b7b5af ("drm/mediatek: Use mailbox rx_callback instead of 
> cmdq_task_cb")
>
> Apart from that it was a pain bisecting and introduced different
> behaviours between patches, all the above commits have a follow-up
> patch (see [1] and [2]) as a fix for the landed series. That makes me
> think that were no stable enough. As we're in the rc, and as you said
> this is not the correct way to fix it, and the landed patches seems
> more a cleanup that really solving a real problem I'd consider to just
> revert the full series and resubmit again for next release with these
> fixes squashed. IMO that will also help to no miss anything when
> someone would backport all this to the stable versions and understand
> better the history.
>
> Just my 5 cents. In any case, I can confirm that applying the full
> series solves the current problems that I have with my Acer Chromebook
> R13.

OK, that series depend on an WARN_ON fixes in mailbox driver, and need
a better solution in cmdq helper, so let's revert that series first.
Would you like to send the revert patches? Or I send the revert
patches and let you test?

Regards,
Chun-Kuang.

>
> Thanks,
>   Enric
>
> [1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=555383
> [2] https://patchwork.kernel.org/project/linux-mediatek/list/?series=554767
>
>
>
> > Regards,
> > Chun-Kuang.
> >
> > >
> > > Thanks,
> > >   Enric
> > >
> > >
> > > > Signed-off-by: jason-jh.lin 
> > > > ---
> > > >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 73 +
> > > >  1 file changed, 38 insertions(+), 35 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > > > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > > index 5f81489fc60c..411d99fcbb8f 100644
> > > > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > > @@ -52,8 +52,7 @@ struct mtk_drm_crtc {
> > > > boolpending_async_planes;
> > > >
> > > >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > > > -   struct mbox_client  cmdq_cl;
> > > > -   struct mbox_chan*cmdq_chan;
> > > > +   struct cmdq_client  cmdq_client;
> > > > struct cmdq_pkt cmdq_handle;
> > > > u32   

  1   2   3   >