Re: [Freedreno] [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

-- 

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(>dev, "failed to get irq: %d\n", ret);
+   return ret;
+   }
+
+   /* do not autoenable, will be enabled later */
+   ret = devm_request_irq(>dev, msm_host->irq, dsi_host_irq,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+   "dsi_isr", msm_host);
+   if (ret < 0) {
+   dev_err(>dev, "failed to request IRQ%u: %d\n",
+   msm_host->irq, ret);
+   return ret;
+   }
+
init_completion(_host->dma_comp);
init_completion(_host->video_comp);
mutex_init(_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(>dev, msm_host->irq,
-   dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-   "dsi_isr", msm_host);
-   if (ret < 0) {
-   DRM_DEV_ERROR(>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 

[Freedreno] [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(>dev, msm_host->num_bus_clks, 
msm_host->bus_clks);
+   if (ret < 0) {
+   dev_err(>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(>dev, msm_host->irq,
 > - dsi_host_irq, IRQF_TRIGGER_HIGH | 
IRQF_ONESHOT,

 > - "dsi_isr", msm_host);
 > - if (ret < 0) {
 > - DRM_DEV_ERROR(>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(_host->pdev->dev, 
msm_host->irq,
 > + dsi_host_irq, IRQF_TRIGGER_HIGH | 
IRQF_ONESHOT,

 > + "dsi_isr", msm_host);
 > + if (ret < 0) {
 > + DRM_DEV_ERROR(_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, _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 _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. What about moving to 

Re: [Freedreno] [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


[Freedreno] [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, );
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, );
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, );
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(>dev, irq, data->irq_handler, 0, 
dev_name(>dev), chip);
+   if (rc)
+   return rc;
+
irq_set_irq_wake(irq, 1);
 
rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, >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(>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: [Freedreno] [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


Re: [Freedreno] [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: [Freedreno] [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: [Freedreno] [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-de...@lists.freedesktop.org
Cc: freedreno@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: [Freedreno] [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-de...@lists.freedesktop.org
Cc: freedreno@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: [Freedreno] [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: [Freedreno] [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: [Freedreno] [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


Re: [Freedreno] [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, _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
--- 

Re: [Freedreno] [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 = _config } },
{ .revision = 11, .config = { .hw = _config } },
{ .revision = 15, .config = { .hw = _config } },
+   { .revision = 16, .config = { .hw = _config } },
  };
  
  static const struct mdp5_cfg_handler cfg_handlers_v3[] = {





--
With best wishes
Dmitry


Re: [Freedreno] [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, >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: [Freedreno] [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


[Freedreno] [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(>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(>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(>lock);
+
gmu->dev = >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(_gpu->gmu.lock);
+   ret = hw_init(gpu);
+   mutex_unlock(_gpu->gmu.lock);
+
+   return ret;
+}
+
 static void a6xx_dump(struct msm_gpu *gpu)
 {
DRM_DEV_INFO(>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(_gpu->gmu.lock);
ret = a6xx_gmu_resume(a6xx_gpu);
+   mutex_unlock(_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(_gpu->gmu.lock);
ret = a6xx_gmu_stop(a6xx_gpu);
+   mutex_unlock(_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(_oob);
+   mutex_lock(_gpu->gmu.lock);
 
/* Force the GPU power on so we can read this register */
a6xx_gmu_set_oob(_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(_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
-   mutex_unlock(_oob);
+
+   mutex_unlock(_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(_gpu->gmu.lock);
+   a6xx_gmu_set_freq(gpu, opp);
+   mutex_unlock(_gpu->gmu.lock);
+}
+
 static struct msm_gem_address_space *
 a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
 {
@@ -1766,7 +1794,7 @@ static const struct adreno_gpu_funcs funcs = {
 #endif
 

Re: [Freedreno] [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: [Freedreno] [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: [Freedreno] [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 

Re: [Freedreno] [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 = >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 = >pdev->dev;

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




--
With best wishes
Dmitry


Re: [Freedreno] [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: [Freedreno] [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(>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: [Freedreno] [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(>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(>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(>lock);
+
   gmu->dev = >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(_gpu->gmu) {
+ ret = hw_init(gpu);
+ }
+
+ return ret;
+}
+
   static void a6xx_dump(struct msm_gpu *gpu)
   {
   DRM_DEV_INFO(>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(_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 = 

Re: [Freedreno] [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(>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(>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(>lock);
> > +
> >   gmu->dev = >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(_gpu->gmu) {
> > + ret = hw_init(gpu);
> > + }
> > +
> > + return ret;
> > +}
> > +
> >   static void a6xx_dump(struct msm_gpu *gpu)
> >   {
> >   DRM_DEV_INFO(>pdev->dev, "status:   %08x\n",
> > @@ -1509,7 +1522,9 @@ static int 

[Freedreno] [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(_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(_enc->delayed_off_work,
dpu_encoder_off_work);
-- 
2.29.2



[Freedreno] [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(_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(, 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(, 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;
-   rc = 

[Freedreno] [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 = _dp_cfg },
+   { .compatible = "qcom,sc8180x-dp", .data = _dp_cfg },
+   { .compatible = "qcom,sc8180x-edp", .data = _dp_cfg },
{}
 };
 
-- 
2.29.2



[Freedreno] [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



[Freedreno] [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



[Freedreno] [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_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)
 {

Re: [Freedreno] [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 = >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 = >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 

[Freedreno] [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(>base, >entity, queue);
+   ret = drm_sched_job_init(>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 _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 _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(>fence_idr);
 
-   drm_sched_entity_destroy(>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(entity_lock);
+   unsigned idx = 

[Freedreno] [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(>ref, __msm_file_private_destroy);
-}
-
-static inline struct msm_file_private *msm_file_private_get(
-   struct msm_file_private *ctx)
-{
-   kref_get(>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 _gpu_submitqueue created by userspace
+ * @queueid:  counter incremented each time a submitqueue is created,
+ *used to assign _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 

[Freedreno] [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



Re: [Freedreno] [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


[Freedreno] [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, >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, >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, >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(>dev, "dp");
if (IS_ERR(io->phy))
-- 
2.29.2



[Freedreno] [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 = >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);
 }
 
 static 

[Freedreno] [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(>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, );
+   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 = >io;
+   struct dss_io_data *dss = >dp_controller;
 
-   rc = msm_dss_ioremap(pdev, >dp_controller);
-   if (rc) {
-   DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc);
-   return rc;
-   }
+   dss->base = dp_ioremap(pdev, 0, >len);
+   if (IS_ERR(dss->base))
+   return PTR_ERR(dss->base);
 
io->phy = devm_phy_get(>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



[Freedreno] [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(>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 = >io;
-
-   msm_dss_iounmap(>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, >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(>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



[Freedreno] [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 = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
2.29.2



[Freedreno] [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: [Freedreno] [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(>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(>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(>lock);

+
gmu->dev = >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(_gpu->gmu) {
+   ret = hw_init(gpu);
+   }
+
+   return ret;
+}
+
  static void a6xx_dump(struct msm_gpu *gpu)
  {
DRM_DEV_INFO(>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(_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(_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);
struct a6xx_gpu *a6xx_gpu = 

Re: [Freedreno] [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 = >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 = >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: [Freedreno] [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 = _8996_pll_ops,
.parent_names = hdmi_pll_parents,




--
With best wishes
Dmitry


Re: [Freedreno] [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: [Freedreno] [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: [Freedreno] [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
> 


[Freedreno] [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(>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(>dev, _ops);
-}
-
-static int edp_dev_remove(struct platform_device *pdev)
-{
-   DBG("");
-   component_del(>dev, _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,
-   .remove = 

[Freedreno] [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 < 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 = <_mdp>;
-   interrupts = <12 0>;
-   power-domains = < MDSS_GDSC>;
-   clock-names =
-   "core",
-   "pixel",
-   "iface",
-   "link",
-   "mdp_core";
-   clocks =
-   < MDSS_EDPAUX_CLK>,
-   < MDSS_EDPPIXEL_CLK>,
-   < MDSS_AHB_CLK>,
-   < MDSS_EDPLINK_CLK>,
-   < MDSS_MDP_CLK>;
-   #clock-cells = <1>;
-   vdda-supply = <_l12>;
-   lvl-vdd-supply = <_vreg>;
-   panel-en-gpios = < 137 0>;
-   panel-hpd-gpios = < 103 0>;
-   };
-- 
2.33.0



[Freedreno] [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



[Freedreno] [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



Re: [Freedreno] [PATCH] drm/msm/dsi: Fix some reference counted resource leaks

2021-10-01 Thread Dmitry Baryshkov

On 06/08/2021 12:15, Christophe JAILLET wrote:

'of_find_device_by_node()' takes a reference that must be released when
not needed anymore.
This is expected to be done in 'dsi_destroy()'.

However, there are 2 issues in 'dsi_get_phy()'.

First, if 'of_find_device_by_node()' succeeds but 'platform_get_drvdata()'
returns NULL, 'msm_dsi->phy_dev' will still be NULL, and the reference
won't be released in 'dsi_destroy()'.

Secondly, as 'of_find_device_by_node()' already takes a reference, there is
no need for an additional 'get_device()'.

Move the assignment to 'msm_dsi->phy_dev' a few lines above and remove the
unneeded 'get_device()' to solve both issues.

Fixes: ec31abf6684e ("drm/msm/dsi: Separate PHY to another platform device")
Signed-off-by: Christophe JAILLET 


Reviewed-by: Dmitry Baryshkov 


---
Review carefully, management of reference counted resources is sometimes
tricky.
---
  drivers/gpu/drm/msm/dsi/dsi.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 75afc12a7b25..29d11f1cb79b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -26,8 +26,10 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi)
}
  
  	phy_pdev = of_find_device_by_node(phy_node);

-   if (phy_pdev)
+   if (phy_pdev) {
msm_dsi->phy = platform_get_drvdata(phy_pdev);
+   msm_dsi->phy_dev = _pdev->dev;
+   }
  
  	of_node_put(phy_node);
  
@@ -36,8 +38,6 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi)

return -EPROBE_DEFER;
}
  
-	msm_dsi->phy_dev = get_device(_pdev->dev);

-
return 0;
  }
  




--
With best wishes
Dmitry


[Freedreno] [PATCH v3 14/14] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2021-10-01 Thread Sean Paul
From: Sean Paul 

This patch adds HDCP 1.x support to msm DP connectors using the new HDCP
helpers.

Cc: Stephen Boyd 
Cc: Abhinav Kumar 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions

[1] 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run
---
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/dp/dp_debug.c   |  46 ++-
 drivers/gpu/drm/msm/dp/dp_debug.h   |   6 +-
 drivers/gpu/drm/msm/dp/dp_display.c |  47 ++-
 drivers/gpu/drm/msm/dp/dp_display.h |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c |  68 -
 drivers/gpu/drm/msm/dp/dp_drm.h |   5 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c| 445 
 drivers/gpu/drm/msm/dp/dp_hdcp.h|  27 ++
 drivers/gpu/drm/msm/dp/dp_parser.c  |  23 +-
 drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h |  44 ++-
 drivers/gpu/drm/msm/msm_atomic.c|  15 +
 13 files changed, 717 insertions(+), 19 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 904535eda0c4..98731fd262d6 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -109,6 +109,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c 
b/drivers/gpu/drm/msm/dp/dp_debug.c
index 2f6247e80e9d..25dc55b5f083 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dp_parser.h"
 #include "dp_catalog.h"
@@ -15,6 +16,7 @@
 #include "dp_ctrl.h"
 #include "dp_debug.h"
 #include "dp_display.h"
+#include "dp_hdcp.h"
 
 #define DEBUG_NAME "msm_dp"
 
@@ -24,6 +26,7 @@ struct dp_debug_private {
struct dp_usbpd *usbpd;
struct dp_link *link;
struct dp_panel *panel;
+   struct dp_hdcp *hdcp;
struct drm_connector **connector;
struct device *dev;
struct drm_device *drm_dev;
@@ -349,6 +352,35 @@ static int dp_test_active_open(struct inode *inode,
inode->i_private);
 }
 
+static ssize_t dp_hdcp_key_write(struct file *file, const char __user *ubuf,
+size_t len, loff_t *offp)
+{
+   char *input_buffer;
+   int ret;
+   struct dp_debug_private *debug = file->private_data;
+
+   if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
+   return -EINVAL;
+
+   if (!debug->hdcp)
+   return -ENOENT;
+
+   input_buffer = memdup_user_nul(ubuf, len);
+   if (IS_ERR(input_buffer))
+   return PTR_ERR(input_buffer);
+
+   ret = dp_hdcp_ingest_key(debug->hdcp, input_buffer, len);
+
+   kfree(input_buffer);
+   if (ret < 0) {
+   DRM_ERROR("Could not ingest HDCP key, ret=%d\n", ret);
+   return ret;
+   }
+
+   *offp += len;
+   return len;
+}
+
 static const struct file_operations dp_debug_fops = {
.open = simple_open,
.read = dp_debug_read_info,
@@ -363,6 +395,12 @@ static const struct file_operations test_active_fops = {
.write = dp_test_active_write
 };
 
+static const struct file_operations dp_hdcp_key_fops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .write = dp_hdcp_key_write,
+};
+
 static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor)
 {
int rc = 0;
@@ -384,6 +422,10 @@ static int dp_debug_init(struct dp_debug *dp_debug, struct 
drm_minor *minor)
minor->debugfs_root,
debug, _test_type_fops);
 
+   debugfs_create_file("msm_dp_hdcp_key", 0222,
+   minor->debugfs_root,
+   debug, _hdcp_key_fops);
+
debug->root = minor->debugfs_root;
 
return rc;
@@ 

[Freedreno] [PATCH v3 13/14] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2021-10-01 Thread Sean Paul
From: Sean Paul 

This patch adds the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller. Now that these are supported, change the
compatible string to "dp-hdcp".

Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2

Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
---
 arch/arm64/boot/dts/qcom/sc7180.dtsi | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index c8921e2d6480..f2d7f3c95c1f 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -3085,10 +3085,12 @@ dsi_phy: dsi-phy@ae94400 {
};
 
mdss_dp: displayport-controller@ae9 {
-   compatible = "qcom,sc7180-dp";
+   compatible = "qcom,sc7180-dp-hdcp";
status = "disabled";
 
-   reg = <0 0x0ae9 0 0x1400>;
+   reg = <0 0x0ae9 0 0x1400>,
+ <0 0x0aed1000 0 0x174>,
+ <0 0x0aee1000 0 0x2c>;
 
interrupt-parent = <>;
interrupts = <12>;
-- 
Sean Paul, Software Engineer, Google / Chromium OS



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

2021-10-01 Thread Sean Paul
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(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 64d8d9e5e47a..a176f97b2f4c 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -17,9 +17,10 @@ properties:
   compatible:
 enum:
   - qcom,sc7180-dp
+  - qcom,sc7180-dp-hdcp
 
-  reg:
-maxItems: 1
+  # See compatible-specific constraints below.
+  reg: true
 
   interrupts:
 maxItems: 1
@@ -89,6 +90,29 @@ required:
   - power-domains
   - ports
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: qcom,sc7180-dp-hdcp
+then:
+  properties:
+reg:
+  minItems: 3
+  maxItems: 3
+  items:
+- description: Registers for base DP functionality
+- description: (Optional) Registers for HDCP device key injection
+- description: (Optional) Registers for HDCP TrustZone interaction
+else:
+  properties:
+reg:
+  minItems: 1
+  maxItems: 1
+  items:
+- description: Registers for base DP functionality
+
 additionalProperties: false
 
 examples:
@@ -99,8 +123,10 @@ examples:
 #include 
 
 displayport-controller@ae9 {
-compatible = "qcom,sc7180-dp";
-reg = <0xae9 0x1400>;
+compatible = "qcom,sc7180-dp-hdcp";
+reg = <0 0x0ae9 0 0x1400>,
+  <0 0x0aed1000 0 0x174>,
+  <0 0x0aee1000 0 0x2c>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[Freedreno] [PATCH v3 11/14] drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules

2021-10-01 Thread Sean Paul
From: Sean Paul 

Audio is initialized last, it should be de-initialized first to match
the order in dp_init_sub_modules().

Reviewed-by: Abhinav Kumar 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-12-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-12-s...@poorly.run
 #v2

Changes in v2:
-None
---
 drivers/gpu/drm/msm/dp/dp_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index fbe4c2cd52a3..19946024e235 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -714,9 +714,9 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, 
u32 data)
 static void dp_display_deinit_sub_modules(struct dp_display_private *dp)
 {
dp_debug_put(dp->debug);
+   dp_audio_put(dp->audio);
dp_panel_put(dp->panel);
dp_aux_put(dp->aux);
-   dp_audio_put(dp->audio);
 }
 
 static int dp_init_sub_modules(struct dp_display_private *dp)
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[Freedreno] [PATCH v3 10/14] drm/msm/dpu: Remove encoder->enable() hack

2021-10-01 Thread Sean Paul
From: Sean Paul 

encoder->commit() was being misused because there were some global
resources which needed to be tweaked in encoder->enable() which were not
accessible in dpu_encoder.c. That is no longer true and the redirect
serves no purpose any longer. So remove the indirection.

Reviewed-by: Stephen Boyd 
Tested-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-11-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-11-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  5 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 22 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  2 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  4 
 4 files changed, 1 insertion(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 984f8a59cb73..ddc542a0d41f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2122,11 +2122,8 @@ static void dpu_encoder_frame_done_timeout(struct 
timer_list *t)
 static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {
.mode_set = dpu_encoder_virt_mode_set,
.disable = dpu_encoder_virt_disable,
-   .enable = dpu_kms_encoder_enable,
+   .enable = dpu_encoder_virt_enable,
.atomic_check = dpu_encoder_virt_atomic_check,
-
-   /* This is called by dpu_kms_encoder_enable */
-   .commit = dpu_encoder_virt_enable,
 };
 
 static const struct drm_encoder_funcs dpu_encoder_funcs = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index fb0d9f781c66..4a0b55d145ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -381,28 +381,6 @@ static void dpu_kms_flush_commit(struct msm_kms *kms, 
unsigned crtc_mask)
}
 }
 
-/*
- * Override the encoder enable since we need to setup the inline rotator and do
- * some crtc magic before enabling any bridge that might be present.
- */
-void dpu_kms_encoder_enable(struct drm_encoder *encoder)
-{
-   const struct drm_encoder_helper_funcs *funcs = encoder->helper_private;
-   struct drm_device *dev = encoder->dev;
-   struct drm_crtc *crtc;
-
-   /* Forward this enable call to the commit hook */
-   if (funcs && funcs->commit)
-   funcs->commit(encoder);
-
-   drm_for_each_crtc(crtc, dev) {
-   if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder)))
-   continue;
-
-   trace_dpu_kms_enc_enable(DRMID(crtc));
-   }
-}
-
 static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
 {
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 323a6bce9e64..f1ebb60dacab 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -248,8 +248,6 @@ void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms);
 int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
 void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
 
-void dpu_kms_encoder_enable(struct drm_encoder *encoder);
-
 /**
  * dpu_kms_get_clk_rate() - get the clock rate
  * @dpu_kms:  pointer to dpu_kms structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 37bba57675a8..54d74341e690 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -266,10 +266,6 @@ DEFINE_EVENT(dpu_drm_obj_template, 
dpu_crtc_complete_commit,
TP_PROTO(uint32_t drm_id),
TP_ARGS(drm_id)
 );
-DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_enc_enable,
-   TP_PROTO(uint32_t drm_id),
-   TP_ARGS(drm_id)
-);
 DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_commit,
TP_PROTO(uint32_t drm_id),
TP_ARGS(drm_id)
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[Freedreno] [PATCH v3 09/14] drm/msm/dpu: Remove useless checks in dpu_encoder

2021-10-01 Thread Sean Paul
From: Sean Paul 

A couple more useless checks to remove in dpu_encoder.

Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-10-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-10-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 
 1 file changed, 12 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..984f8a59cb73 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1153,10 +1153,6 @@ static void dpu_encoder_virt_enable(struct drm_encoder 
*drm_enc)
struct msm_drm_private *priv;
struct drm_display_mode *cur_mode = NULL;
 
-   if (!drm_enc) {
-   DPU_ERROR("invalid encoder\n");
-   return;
-   }
dpu_enc = to_dpu_encoder_virt(drm_enc);
 
mutex_lock(_enc->enc_lock);
@@ -1203,14 +1199,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder 
*drm_enc)
struct msm_drm_private *priv;
int i = 0;
 
-   if (!drm_enc) {
-   DPU_ERROR("invalid encoder\n");
-   return;
-   } else if (!drm_enc->dev) {
-   DPU_ERROR("invalid dev\n");
-   return;
-   }
-
dpu_enc = to_dpu_encoder_virt(drm_enc);
DPU_DEBUG_ENC(dpu_enc, "\n");
 
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[Freedreno] [PATCH v3 08/14] drm/msm/dpu_kms: Re-order dpu includes

2021-10-01 Thread Sean Paul
From: Sean Paul 

Make includes alphabetical in dpu_kms.c

Reviewed-by: Abhinav Kumar 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-9-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-9-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ae48f41821cf..fb0d9f781c66 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -21,14 +21,14 @@
 #include "msm_gem.h"
 #include "disp/msm_disp_snapshot.h"
 
-#include "dpu_kms.h"
 #include "dpu_core_irq.h"
+#include "dpu_crtc.h"
+#include "dpu_encoder.h"
 #include "dpu_formats.h"
 #include "dpu_hw_vbif.h"
-#include "dpu_vbif.h"
-#include "dpu_encoder.h"
+#include "dpu_kms.h"
 #include "dpu_plane.h"
-#include "dpu_crtc.h"
+#include "dpu_vbif.h"
 
 #define CREATE_TRACE_POINTS
 #include "dpu_trace.h"
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[Freedreno] [PATCH v3 07/14] drm/i915/hdcp: Use HDCP helpers for i915

2021-10-01 Thread Sean Paul
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-8-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-8-s...@poorly.run
 #v2

Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  29 +-
 .../drm/i915/display/intel_display_debugfs.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  58 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 345 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  17 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 935 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |  31 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++---
 8 files changed, 418 insertions(+), 1259 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 51cd0420e00e..446544c75aa8 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -26,6 +26,7 @@
  */
 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "intel_audio.h"
@@ -3143,6 +3144,9 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector = 
to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!crtc_state->bigjoiner_slave)
@@ -3159,12 +3163,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+   >base,
+   _port->hdcp_mutex);
 }
 
 static void intel_disable_ddi_dp(struct intel_atomic_state *state,
@@ -3224,7 +3226,13 @@ static void intel_disable_ddi(struct intel_atomic_state 
*state,
  const struct intel_crtc_state *old_crtc_state,
  const struct drm_connector_state *old_conn_state)
 {
-   intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
+   struct intel_connector *connector = 
to_intel_connector(old_conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+   >base,
+   _port->hdcp_mutex);
 
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
@@ -3254,13 +3262,18 @@ void intel_ddi_update_pipe(struct intel_atomic_state 
*state,
   const struct intel_crtc_state *crtc_state,
   const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector = 
to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
!intel_encoder_is_mst(encoder))
intel_ddi_update_pipe_dp(state, encoder, crtc_state,
 conn_state);
 
-   intel_hdcp_update_pipe(state, encoder, crtc_state, conn_state);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ 

[Freedreno] [PATCH v3 06/14] drm/i915/hdcp: Retain hdcp_capable return codes

2021-10-01 Thread Sean Paul
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-7-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-7-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-None
---
 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 309d74fd86ce..88e71aeb88a2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -644,6 +644,7 @@ static void intel_panel_info(struct seq_file *m, struct 
intel_panel *panel)
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -651,8 +652,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, _cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, _cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index af166baf8c71..59275919e7b9 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -153,50 +153,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, );
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = >hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(_priv->hdcp_comp_mutex);
if (!dev_priv->hdcp_comp_added ||  !dev_priv->hdcp_master) {
mutex_unlock(_priv->hdcp_comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(_priv->hdcp_comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, );
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2332,6 +2331,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = >hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
+   bool capable;
int ret = -EINVAL;
 
if (!hdcp->shim)
@@ -2350,21 +2350,27 @@ int intel_hdcp_enable(struct intel_connector *connector,
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
 */
-   if (intel_hdcp2_capable(connector)) {
+   ret = intel_hdcp2_capable(connector, );
+   if (capable) {
ret = _intel_hdcp2_enable(connector);
-  

[Freedreno] [PATCH v3 05/14] drm/i915/hdcp: Consolidate HDCP setup/state cache

2021-10-01 Thread Sean Paul
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-6-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-6-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index feebafead046..af166baf8c71 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2167,6 +2167,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = >hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2306,28 +2337,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(>mutex);
mutex_lock(_port->hdcp_mutex);
drm_WARN_ON(_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2355,6 +2372,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(_port->hdcp_mutex);
mutex_unlock(>mutex);
return ret;
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[Freedreno] [PATCH v3 04/14] drm/hdcp: Expand HDCP helper library for enable/disable/check

2021-10-01 Thread Sean Paul
From: Sean Paul 

This patch expands upon the HDCP helper library to manage HDCP
enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the "shim" vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Cc: Abhinav Kumar 
Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-5-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-5-s...@poorly.run
 #v2

Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
---
 drivers/gpu/drm/drm_hdcp.c | 1103 
 include/drm/drm_hdcp.h |  191 +++
 2 files changed, 1294 insertions(+)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 8c851d40cd45..2bfa07fc3fbc 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -6,15 +6,20 @@
  * Ramalingam C 
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -513,3 +518,1101 @@ bool drm_hdcp_atomic_check(struct drm_connector 
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
+
+struct drm_hdcp_helper_data {
+   struct mutex mutex;
+   struct mutex *driver_mutex;
+
+   struct drm_connector *connector;
+   const struct drm_hdcp_helper_funcs *funcs;
+
+   u64 value;
+   unsigned int enabled_type;
+
+   struct delayed_work check_work;
+   struct work_struct prop_work;
+
+   struct drm_dp_aux *aux;
+   const struct drm_hdcp_hdcp1_receiver_reg_lut *hdcp1_lut;
+};
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_ddc_lut = {
+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_dpcd_lut = {
+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+* definition by different names. In the HDMI spec, it's called BSTATUS,
+* but in DP it's called BINFO.
+*/
+   .bstatus = DP_AUX_HDCP_BINFO,
+};
+
+static int drm_hdcp_remote_ddc_read(struct i2c_adapter *i2c,
+   unsigned int offset, u8 *value, size_t len)
+{
+   int ret;
+   u8 start = offset & 0xff;
+   struct i2c_msg msgs[] = {
+   {
+   .addr = DRM_HDCP_DDC_ADDR,
+   .flags 

[Freedreno] [PATCH v3 03/14] drm/hdcp: Update property value on content type and user changes

2021-10-01 Thread Sean Paul
From: Sean Paul 

This patch updates the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-4-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-4-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
---
 drivers/gpu/drm/drm_hdcp.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index dd8fa91c51d6..8c851d40cd45 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -487,21 +487,29 @@ bool drm_hdcp_atomic_check(struct drm_connector 
*connector,
return true;
 
/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
+* Content type changes require an HDCP disable/enable cycle.
+*/
+   if (new_conn_state->hdcp_content_type != 
old_conn_state->hdcp_content_type) {
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
 *  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+*  - Attempting to set to desired while already enabled
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}
 
-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[Freedreno] [PATCH v3 02/14] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2021-10-01 Thread Sean Paul
From: Sean Paul 

Instead of forcing a modeset in the hdcp atomic check, simply return
true if the content protection value is changing and let the driver
decide whether a modeset is required or not.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-3-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-3-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/drm_hdcp.c  | 33 +++--
 drivers/gpu/drm/i915/display/intel_atomic.c |  5 ++--
 include/drm/drm_hdcp.h  |  2 +-
 3 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 522326b03e66..dd8fa91c51d6 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -430,11 +430,14 @@ EXPORT_SYMBOL(drm_hdcp_update_content_protection);
  * @connector: drm_connector on which content protection state needs an update
  *
  * This function can be used by display drivers to perform an atomic check on 
the
- * hdcp state elements. If hdcp state has changed, this function will set
- * mode_changed on the crtc driving the connector so it can update its hardware
- * to match the hdcp state.
+ * hdcp state elements. If hdcp state has changed in a manner which requires 
the
+ * driver to enable or disable content protection, this function will return
+ * true.
+ *
+ * Returns:
+ * true if the driver must enable/disable hdcp, false otherwise
  */
-void drm_hdcp_atomic_check(struct drm_connector *connector,
+bool drm_hdcp_atomic_check(struct drm_connector *connector,
   struct drm_atomic_state *state)
 {
struct drm_connector_state *new_conn_state, *old_conn_state;
@@ -452,10 +455,12 @@ void drm_hdcp_atomic_check(struct drm_connector 
*connector,
 * If the connector is being disabled with CP enabled, mark it
 * desired so it's re-enabled when the connector is brought back
 */
-   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   return;
+   return true;
+   }
+   return false;
}
 
new_crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -467,9 +472,19 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
*/
if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
-new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Coming back from disable or changing CRTC with DESIRED state requires
+* that the driver try CP enable.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -484,9 +499,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 1e306e8427ec..c7b5470c40aa 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -122,8 +122,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hdcp_atomic_check(conn, state);
-
if (!new_state->crtc)
return 0;
 
@@ -139,7 +137,8 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
new_conn_state->base.picture_aspect_ratio != 
old_conn_state->base.picture_aspect_ratio ||
new_conn_state->base.content_type != 
old_conn_state->base.content_type ||
new_conn_state->base.scaling_mode != 
old_conn_state->base.scaling_mode ||
-   !drm_connector_atomic_hdr_metadata_equal(old_state, new_state))
+   !drm_connector_atomic_hdr_metadata_equal(old_state, new_state) ||
+   drm_hdcp_atomic_check(conn, 

[Freedreno] [PATCH v3 01/14] drm/hdcp: Add drm_hdcp_atomic_check()

2021-10-01 Thread Sean Paul
From: Sean Paul 

This patch moves the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-2-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-2-s...@poorly.run
 #v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/drm_hdcp.c  | 71 -
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 --
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/drm_hdcp.h  |  3 +
 5 files changed, 75 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index ca9b8f697202..522326b03e66 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -13,13 +13,14 @@
 #include 
 #include 
 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 
 #include "drm_internal.h"
 
@@ -421,3 +422,71 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs an update
+ *
+ * This function can be used by display drivers to perform an atomic check on 
the
+ * hdcp state elements. If hdcp state has changed, this function will set
+ * mode_changed on the crtc driving the connector so it can update its hardware
+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+   old_hdcp = old_conn_state->content_protection;
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state = drm_atomic_get_new_crtc_state(state,
+  new_conn_state->crtc);
+   /*
+   * Fix the HDCP uapi content protection state in case of modeset.
+   * FIXME: As per HDCP content protection property uapi doc, an uevent()
+   * need to be sent if there is transition from ENABLED->DESIRED.
+   */
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index b4e7ac51aa31..1e306e8427ec 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -32,13 +32,13 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "intel_atomic.h"
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
 #include "intel_global_state.h"
-#include "intel_hdcp.h"
 #include "intel_psr.h"
 #include "skl_universal_plane.h"
 
@@ -122,7 +122,7 @@ int 

[Freedreno] [PATCH v3 00/14] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2021-10-01 Thread Sean Paul
From: Sean Paul 

Hello again,
Here is v3 of the patch series. Notable changes include incorporating
review feedback involving:
 - Changed dt-bindings to introduce new compatible string
 - Code changes in msm driver as suggested by Stephen & Abhinav
 - Fixed issues found by 0-day

Thank you to the reviewers for their feedback thus far!

Please take a look,

Sean

Link: https://patchwork.freedesktop.org/series/94623/ #v1
Link: https://patchwork.freedesktop.org/series/94713/ #v2

Sean Paul (14):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  drm/msm/dpu_kms: Re-order dpu includes
  drm/msm/dpu: Remove useless checks in dpu_encoder
  drm/msm/dpu: Remove encoder->enable() hack
  drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules
  dt-bindings: msm/dp: Add bindings for HDCP registers
  arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |   34 +-
 arch/arm64/boot/dts/qcom/sc7180.dtsi  |6 +-
 drivers/gpu/drm/drm_hdcp.c| 1197 -
 drivers/gpu/drm/i915/display/intel_atomic.c   |7 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   29 +-
 .../drm/i915/display/intel_display_debugfs.c  |   11 +-
 .../drm/i915/display/intel_display_types.h|   58 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  345 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   17 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |   36 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  256 ++--
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |   17 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   30 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |4 -
 drivers/gpu/drm/msm/dp/dp_debug.c |   46 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |6 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   49 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |   68 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |5 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  445 ++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   27 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   23 +-
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   44 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   15 +
 include/drm/drm_hdcp.h|  194 +++
 30 files changed, 2600 insertions(+), 1392 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

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



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

2021-10-01 Thread Bjorn Andersson
On Fri 01 Oct 06:58 PDT 2021, Doug Anderson wrote:

> Hi,
> 
> On Thu, Aug 26, 2021 at 10:20 PM Stephen Boyd  wrote:
> >
> > Quoting Bjorn Andersson (2021-08-25 16:42:31)
> > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > > b/drivers/gpu/drm/msm/dp/dp_display.c
> > > index 2c7de43f655a..4a6132c18e57 100644
> > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > @@ -78,6 +78,8 @@ struct dp_display_private {
> > > char *name;
> > > int irq;
> > >
> > > +   int id;
> > > +
> > > /* state variables */
> > > bool core_initialized;
> > > bool hpd_irq_on;
> > > @@ -115,8 +117,19 @@ struct dp_display_private {
> > > struct dp_audio *audio;
> > >  };
> > >
> > > +
> > > +struct msm_dp_config {
> > > +   phys_addr_t io_start[3];
> >
> > Can this be made into another struct, like msm_dp_desc, that also
> > indicates what type of DP connector it is, i.e. eDP vs DP? That would
> > help me understand in modetest and /sys/class/drm what sort of connector
> > is probing. dp_drm_connector_init() would need to pass the type of
> > connector appropriately. Right now, eDP connectors still show up as DP
> > instead of eDP in sysfs.
> 
> I'm not convinced that's the right way to do it. I think the right way
> forward here is to look at whether drm_of_find_panel_or_bridge() finds
> a panel. If it finds a panel then we're eDP. If it doesn't then we're
> DP. That matches roughly what Laurent was planning to do for
> ti-sn65dsi86:
> 
> https://lore.kernel.org/all/20210322030128.2283-11-laurent.pinchart+rene...@ideasonboard.com/
> 

When we spoke about this earlier I got the impression that there was
interest in representing the DP display as a panel at some point in the
future. Did I misunderstand you or would we simply update the scheme
when that day comes?


I updated the patch based on Stephen's input and it looks nice, but I
could certainly respin it again to simply rely on us having an explicit
panel or not.

> I know technically an eDP and DP controller can have different sets of
> features but I think what we really are trying to communicate to
> modetest is whether an internal panel or external display is
> connected, right?
> 

For me Stephen's suggestion resulted in the monitor names in Wayland
suddenly making more sense, i.e. it makes more sense to say that the lid
on my laptop should control eDP-1, rather than DP-3 on this machine...

Regards,
Bjorn


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

2021-10-01 Thread Doug Anderson
Hi,

On Thu, Aug 26, 2021 at 10:20 PM Stephen Boyd  wrote:
>
> Quoting Bjorn Andersson (2021-08-25 16:42:31)
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > b/drivers/gpu/drm/msm/dp/dp_display.c
> > index 2c7de43f655a..4a6132c18e57 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -78,6 +78,8 @@ struct dp_display_private {
> > char *name;
> > int irq;
> >
> > +   int id;
> > +
> > /* state variables */
> > bool core_initialized;
> > bool hpd_irq_on;
> > @@ -115,8 +117,19 @@ struct dp_display_private {
> > struct dp_audio *audio;
> >  };
> >
> > +
> > +struct msm_dp_config {
> > +   phys_addr_t io_start[3];
>
> Can this be made into another struct, like msm_dp_desc, that also
> indicates what type of DP connector it is, i.e. eDP vs DP? That would
> help me understand in modetest and /sys/class/drm what sort of connector
> is probing. dp_drm_connector_init() would need to pass the type of
> connector appropriately. Right now, eDP connectors still show up as DP
> instead of eDP in sysfs.

I'm not convinced that's the right way to do it. I think the right way
forward here is to look at whether drm_of_find_panel_or_bridge() finds
a panel. If it finds a panel then we're eDP. If it doesn't then we're
DP. That matches roughly what Laurent was planning to do for
ti-sn65dsi86:

https://lore.kernel.org/all/20210322030128.2283-11-laurent.pinchart+rene...@ideasonboard.com/

I know technically an eDP and DP controller can have different sets of
features but I think what we really are trying to communicate to
modetest is whether an internal panel or external display is
connected, right?


-Doug


[Freedreno] [PATCH] drm/msm/a3xx: fix error handling in a3xx_gpu_init()

2021-10-01 Thread Dan Carpenter
These error paths returned 1 on failure, instead of a negative error
code.  This would lead to an Oops in the caller.  A second problem is
that the check for "if (ret != -ENODATA)" did not work because "ret" was
set to 1.

Fixes: 5785dd7a8ef0 ("drm/msm: Fix duplicate gpu node in icc summary")
Signed-off-by: Dan Carpenter 
---
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 4534633fe7cd..8fb847c174ff 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -571,13 +571,14 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
}
 
icc_path = devm_of_icc_get(>dev, "gfx-mem");
-   ret = IS_ERR(icc_path);
-   if (ret)
+   if (IS_ERR(icc_path)) {
+   ret = PTR_ERR(icc_path);
goto fail;
+   }
 
ocmem_icc_path = devm_of_icc_get(>dev, "ocmem");
-   ret = IS_ERR(ocmem_icc_path);
-   if (ret) {
+   if (IS_ERR(ocmem_icc_path)) {
+   ret = PTR_ERR(ocmem_icc_path);
/* allow -ENODATA, ocmem icc is optional */
if (ret != -ENODATA)
goto fail;
-- 
2.20.1



[Freedreno] [PATCH] drm/msm/a4xx: fix error handling in a4xx_gpu_init()

2021-10-01 Thread Dan Carpenter
This code returns 1 on error instead of a negative error.  It leads to
an Oops in the caller.  A second problem is that the check for
"if (ret != -ENODATA)" cannot be true because "ret" is set to 1.

Fixes: 5785dd7a8ef0 ("drm/msm: Fix duplicate gpu node in icc summary")
Signed-off-by: Dan Carpenter 
---
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 82bebb40234d..a96ee79cc5e0 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -699,13 +699,14 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
}
 
icc_path = devm_of_icc_get(>dev, "gfx-mem");
-   ret = IS_ERR(icc_path);
-   if (ret)
+   if (IS_ERR(icc_path)) {
+   ret = PTR_ERR(icc_path);
goto fail;
+   }
 
ocmem_icc_path = devm_of_icc_get(>dev, "ocmem");
-   ret = IS_ERR(ocmem_icc_path);
-   if (ret) {
+   if (IS_ERR(ocmem_icc_path)) {
+   ret = PTR_ERR(ocmem_icc_path);
/* allow -ENODATA, ocmem icc is optional */
if (ret != -ENODATA)
goto fail;
-- 
2.20.1



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

2021-10-01 Thread Dan Carpenter
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.

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;
}
 
-- 
2.20.1



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

2021-10-01 Thread Dan Carpenter
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 
---
 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;
-- 
2.20.1



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

2021-10-01 Thread Dan Carpenter
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 
---
 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;
 
-- 
2.20.1



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

2021-10-01 Thread mkrishn

On 2021-09-30 23:28, Stephen Boyd wrote:

Quoting mkri...@codeaurora.org (2021-09-30 04:56:59)

On 2021-08-19 01:27, Stephen Boyd wrote:
> Quoting Krishna Manikandan (2021-08-18 03:27:02)
>> diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi
>> b/arch/arm64/boot/dts/qcom/sc7280.dtsi
>> index 53a21d0..fd7ff1c 100644
>> --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
>> +
>> +   status = "disabled";
>> +
>> +   mdp: mdp@ae01000 {
>
> display-controller@ae01000

Stephen,
In the current driver code, there is a substring comparison for 
"mdp"

in device node name as part of probe sequence. If "mdp" is not present
in the node name, it will
return an error resulting in probe failure. Can we continue using 
mdp

as nodename instead of display controller?



Can we fix the driver to not look for node names and look for 
compatible

strings instead? It took me a minute to find compare_name_mdp() in
drivers/gpu/drm/msm/msm_drv.c to understand what you're talking about.
Perhaps looking for qcom,mdp5 in there will be sufficient instead of
looking at the node name.


Sure Stephen. I will make the necessary changes in msm_drv.c to look for 
compatible string instead of node name.
Can I include these two changes (changing mdp--> display controller and 
msm_drv.c changes) in a separate series ?


Thanks,
Krishna