Re: [PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-02-13 Thread Tomasz Figa
Hi Vivek,

Thanks for the patch. Please see some comments inline.

On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
 wrote:
> From: Sricharan R 
>
> The smmu needs to be functional only when the respective
> master's using it are active. The device_link feature
> helps to track such functional dependencies, so that the
> iommu gets powered when the master device enables itself
> using pm_runtime. So by adapting the smmu driver for
> runtime pm, above said dependency can be addressed.
>
> This patch adds the pm runtime/sleep callbacks to the
> driver and also the functions to parse the smmu clocks
> from DT and enable them in resume/suspend.
>
> Signed-off-by: Sricharan R 
> Signed-off-by: Archit Taneja 
> [vivek: Clock rework to request bulk of clocks]
> Signed-off-by: Vivek Gautam 
> ---
>  drivers/iommu/arm-smmu.c | 56 
> ++--
>  1 file changed, 54 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 69e7c60792a8..9e2f917e16c2 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -48,6 +48,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>
> @@ -205,6 +206,8 @@ struct arm_smmu_device {
> u32 num_global_irqs;
> u32 num_context_irqs;
> unsigned int*irqs;
> +   struct clk_bulk_data*clocks;
> +   int num_clks;

nit: Perhaps "num_clocks" to be consistent with "clocks"?

>
> u32 cavium_id_base; /* Specific to Cavium 
> */
>
> @@ -1897,10 +1900,12 @@ static int arm_smmu_device_cfg_probe(struct 
> arm_smmu_device *smmu)
>  struct arm_smmu_match_data {
> enum arm_smmu_arch_version version;
> enum arm_smmu_implementation model;
> +   const char * const *clks;
> +   int num_clks;

nit: Perhaps s/clks/clocks/ here or s/clocks/clks/ in struct arm_smmu_device?

>  };
>
>  #define ARM_SMMU_MATCH_DATA(name, ver, imp)\
> -static struct arm_smmu_match_data name = { .version = ver, .model = imp }
> +static const struct arm_smmu_match_data name = { .version = ver, .model = 
> imp }
>
>  ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
>  ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
> @@ -2001,6 +2006,7 @@ static int arm_smmu_device_dt_probe(struct 
> platform_device *pdev,
> data = of_device_get_match_data(dev);
> smmu->version = data->version;
> smmu->model = data->model;
> +   smmu->num_clks = data->num_clks;
>
> parse_driver_options(smmu);
>
> @@ -2039,6 +2045,28 @@ static void arm_smmu_bus_init(void)
>  #endif
>  }
>
> +static int arm_smmu_init_clks(struct arm_smmu_device *smmu)
> +{
> +   int i;
> +   int num = smmu->num_clks;
> +   const struct arm_smmu_match_data *data;
> +
> +   if (num < 1)
> +   return 0;
> +
> +   smmu->clocks = devm_kcalloc(smmu->dev, num,
> +   sizeof(*smmu->clocks), GFP_KERNEL);
> +   if (!smmu->clocks)
> +   return -ENOMEM;
> +
> +   data = of_device_get_match_data(smmu->dev);
> +
> +   for (i = 0; i < num; i++)
> +   smmu->clocks[i].id = data->clks[i];

I'd argue that arm_smmu_device_dt_probe() is a better place for all
the code above, since this function is called regardless of whether
the device is probed from DT or not. Going further,
arm_smmu_device_acpi_probe() could fill smmu->num_clks and ->clocks
using ACPI-like way (as opposed to OF match data) if necessary.

Best regards,
Tomasz
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers

2018-02-13 Thread Lukas Wunner
On Mon, Feb 12, 2018 at 01:58:32PM -0500, Alex Deucher wrote:
> On Mon, Feb 12, 2018 at 4:45 AM, Lukas Wunner  wrote:
> > On Mon, Feb 12, 2018 at 09:03:26AM +, Mike Lothian wrote:
> >> On 12 February 2018 at 03:39, Lukas Wunner  wrote:
> >> > On Mon, Feb 12, 2018 at 12:35:51AM +, Mike Lothian wrote:
> >> > > I've not been able to reproduce the original problem you're trying to
> >> > > solve on amdgpu thats with or without your patch set and the above
> >> > > "trigger" too
> >
> > Okay the reason you're not seeing deadlocks is because the output poll
> > worker is not enabled.  And the output poll worker is not enabled
> > because your discrete GPU doesn't have any outputs:
> >
> > [0.265568] [drm:dc_create] *ERROR* DC: Number of connectors is zero!
> >
> > The outputs are only polled if there are connectors which have the
> > DRM_CONNECTOR_POLL_CONNECT or DRM_CONNECTOR_POLL_DISCONNECT flag set.
> > And that only ever seems to be the case for VGA and DVI.
> >
> > We know based on bugzilla reports that hybrid graphics laptops do exist
> > which poll outputs with radeon and nouveau.  If there are no laptops
> > supported by amdgpu whose discrete GPU has polled connectors, then
> > patch [5/5] would be unnecessary.  That is for Alex to decide.
> 
> Most hybrid laptops don't have display connectors on the dGPU and we
> only use polling on analog connectors, so you are not likely to run
> into this on recent laptops.  That said, I don't know if there is some
> OEM system out there with a VGA port on the dGPU in a hybrid laptop.
> I guess another option is to just disable polling on hybrid laptops.

If we don't know for sure, applying patch [5/5] would seem to be the
safest approach.  (Assuming it doesn't break anything else.)

Right now runtime PM is only used on hybrid graphics dGPUs by nouveau,
radeon and amdgpu.  Would it be conceivable that its use is expanded
beyond that in the future?  E.g. on a desktop machine, if DPMS is off
on all screens, why keep the GPU in D0?  If that is conceivable, chances
that analog connectors are present are higher, and then the patch would
be necessary again.  (Of course this would mean that analog screens
wouldn't light up automatically if they're attached while the GPU is
in D3hot, but the user may forbid runtime PM via sysfs if that is
unwanted.)

Thanks,

Lukas
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-13 Thread Tomasz Figa
Hi Vivek,

Thanks for the patch. Please see my comments inline.

On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
 wrote:
> From: Sricharan R 
>
> The smmu device probe/remove and add/remove master device callbacks
> gets called when the smmu is not linked to its master, that is without
> the context of the master device. So calling runtime apis in those places
> separately.
>
> Signed-off-by: Sricharan R 
> [vivek: Cleanup pm runtime calls]
> Signed-off-by: Vivek Gautam 
> ---
>  drivers/iommu/arm-smmu.c | 42 ++
>  1 file changed, 38 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 9e2f917e16c2..c024f69c1682 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct 
> iommu_domain *domain)
> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> struct arm_smmu_device *smmu = smmu_domain->smmu;
> struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> -   int irq;
> +   int ret, irq;
>
> if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
> return;
>
> +   ret = pm_runtime_get_sync(smmu->dev);
> +   if (ret)
> +   return;

pm_runtime_get_sync() will return 0 if the device was powered off, 1
if it was already/still powered on or runtime PM is not compiled in,
or a negative value on error, so shouldn't the test be (ret < 0)?

Moreover, I'm actually wondering if it makes any sense to power up the
hardware just to program it and power it down again. In a system where
the IOMMU is located within a power domain, it would cause the IOMMU
block to lose its state anyway.

Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add
pm_runtime/sleep ops", perhaps it would make more sense to just
control the clocks independently of runtime PM? Then, runtime PM could
be used for real power management, e.g. really powering the block up
and down, for further power saving.

+Generally similar comments for other places in this patch.

> +
> /*
>  * Disable the context bank and free the page tables before freeing
>  * it.
> @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct 
> iommu_domain *domain)
>
> free_io_pgtable_ops(smmu_domain->pgtbl_ops);
> __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
> +
> +   pm_runtime_put_sync(smmu->dev);

Is there any point in the put being sync here?

[snip]

> @@ -2131,6 +2152,14 @@ static int arm_smmu_device_probe(struct 
> platform_device *pdev)
> if (err)
> return err;
>
> +   platform_set_drvdata(pdev, smmu);
> +
> +   pm_runtime_enable(dev);

I suspect this may be a disaster for systems where IOMMUs are located
inside power domains, because the driver doesn't take care of the
IOMMU block losing its state on physical power down, as I mentioned in
my comments above.

Best regards,
Tomasz
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-02-13 Thread Tomasz Figa
Hi Vivek,

Thanks for the patch. Please see my comments inline.

On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
 wrote:
> From: Sricharan R 
>
> Finally add the device link between the master device and
> smmu, so that the smmu gets runtime enabled/disabled only when the
> master needs it. This is done from add_device callback which gets
> called once when the master is added to the smmu.
>
> Signed-off-by: Sricharan R 
> Signed-off-by: Vivek Gautam 
> ---
>  drivers/iommu/arm-smmu.c | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index c024f69c1682..c7e924d553bd 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -215,6 +215,9 @@ struct arm_smmu_device {
>
> /* IOMMU core code handle */
> struct iommu_device iommu;
> +
> +   /* runtime PM link to master */
> +   struct device_link *link;
>  };
>
>  enum arm_smmu_context_fmt {
> @@ -1425,6 +1428,17 @@ static int arm_smmu_add_device(struct device *dev)
>
> pm_runtime_put_sync(smmu->dev);
>
> +   /*
> +* Establish the link between smmu and master, so that the
> +* smmu gets runtime enabled/disabled as per the master's
> +* needs.
> +*/
> +   smmu->link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);
> +   if (!smmu->link)
> +   dev_warn(smmu->dev,
> +"Unable to create device link between %s and %s\n",
> +dev_name(smmu->dev), dev_name(dev));

How likely it is that the master can work normally even if the link
add fails? Perhaps we should just return an error here?

> +
> return 0;
>
>  out_rpm_put:
> @@ -1449,6 +1463,8 @@ static void arm_smmu_remove_device(struct device *dev)
> cfg  = fwspec->iommu_priv;
> smmu = cfg->smmu;
>
> +   device_link_del(smmu->link);

We allowed smmu->link in arm_smmu_add_device(), but here we don't
check it. Looking at the code, device_link_del() doesn't seem to check
either.

Note that this problem would go away if we fail add_device on
device_link_add() failure, as I suggested above, so no change would be
necessary.

Best regards,
Tomasz
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/simple_kms_helper: Fix NULL pointer dereference with no active CRTC

2018-02-13 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

It is possible that drm_simple_kms_plane_atomic_check called
with no CRTC set, e.g. when user-space application sets CRTC_ID/FB_ID
to 0 before doing any actual drawing. This leads to NULL pointer
dereference because in this case new CRTC state is NULL and must be
checked before accessing.

Signed-off-by: Oleksandr Andrushchenko 
---
 drivers/gpu/drm/drm_simple_kms_helper.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c 
b/drivers/gpu/drm/drm_simple_kms_helper.c
index 9ca8a4a59b74..a05eca9cec8b 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -121,8 +121,10 @@ static int drm_simple_kms_plane_atomic_check(struct 
drm_plane *plane,
pipe = container_of(plane, struct drm_simple_display_pipe, plane);
crtc_state = drm_atomic_get_new_crtc_state(plane_state->state,
   &pipe->crtc);
-   if (!crtc_state->enable)
-   return 0; /* nothing to check when disabling or disabled */
+
+   if (!crtc_state || !crtc_state->enable)
+   /* nothing to check when disabling or disabled or no CRTC set */
+   return 0;
 
if (crtc_state->enable)
drm_mode_get_hv_timing(&crtc_state->mode,
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Pali Rohár
On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote:
> Hi! I'm periodically getting following message in dmesg on Lenovo
> Thinkpad X1 Carbon 3rd generation:
> 
> [drm] Reducing the compressed framebuffer size. This may lead to less power 
> savings than a non-reduced-size. Try to increase stolen memory size if 
> available in BIOS.
> 
> In BIOS I already set GPU size to 512M, but this did not help. Also
> update to last BIOS version did not help.
> 
> So why this message is periodically print in dmesg? And what can I do
> with this problem?
> 
> And why cannot Linux kernel allocate itself more memory for GPU (if BIOS
> can/could do that)? Is not 512MB for GPU enough?

And here is output from lspci, which clearly says that 512MB is already
set for GPU:

$ lspci -v -s 00:02.0
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 (rev 09) 
(prog-if 00 [VGA controller])
Subsystem: Lenovo HD Graphics 5500
Flags: bus master, fast devsel, latency 0, IRQ 46
Memory at e000 (64-bit, non-prefetchable) [size=16M]
Memory at c000 (64-bit, prefetchable) [size=512M]
I/O ports at 3000 [size=64]
[virtual] Expansion ROM at 000c [disabled] [size=128K]
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Capabilities: [d0] Power Management version 2
Capabilities: [a4] PCI Advanced Features
Kernel driver in use: i915
Kernel modules: i915

-- 
Pali Rohár
pali.ro...@gmail.com
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v8 5/6] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-02-13 Thread Tomasz Figa
Hi Vivek,

Thanks for the patch. Please see my comments inline.

On Fri, Feb 9, 2018 at 7:57 PM, Vivek Gautam
 wrote:
> qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
> clock and power requirements. This smmu core is used with
> multiple masters on msm8996, viz. mdss, video, etc.
> Add bindings for the same.
>
> Signed-off-by: Vivek Gautam 
> Reviewed-by: Rob Herring 
> ---
>
> Changes in v8:
>  - Added the missing IOMMU_OF_DECLARE declaration for "qcom,smmu-v2"
>
>  .../devicetree/bindings/iommu/arm,smmu.txt | 43 
> ++
>  drivers/iommu/arm-smmu.c   | 14 +++
>  2 files changed, 57 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
> b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> index 8a6ffce12af5..169222ae2706 100644
> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> @@ -17,10 +17,19 @@ conditions.
>  "arm,mmu-401"
>  "arm,mmu-500"
>  "cavium,smmu-v2"
> +"qcom,-smmu-v2", "qcom,smmu-v2"
>
>depending on the particular implementation and/or the
>version of the architecture implemented.
>
> +  A number of Qcom SoCs use qcom,smmu-v2 version of the IP.
> +  "qcom,-smmu-v2" represents a soc specific compatible
> +  string that should be present along with the "qcom,smmu-v2"
> +  to facilitate SoC specific clocks/power connections and to
> +  address specific bug fixes.
> +  An example string would be -
> +  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".

Hmm, I remember that for  and similar wildcards we required
explicitly listing allowed values. Rob, has it changed since I
stumbled upon such thing last time (or I just got it wrong before)?

> +
>  - reg   : Base address and size of the SMMU.
>
>  - #global-interrupts : The number of global interrupts exposed by the
> @@ -71,6 +80,23 @@ conditions.
>or using stream matching with #iommu-cells = <2>, and
>may be ignored if present in such cases.
>
> +- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2"
> +  implementation.
> +
> +  "bus" clock for "qcom,smmu-v2" is required for downstream
> +  bus access and for the smmu ptw.
> +
> +  "iface" clock is required to access smmu's registers 
> through
> +  the TCU's programming interface.

nit: Could we have it in a bit more structured way? E.g.

- clock-names: List of names of clocks input to the device. The
required list depends on particular implementation and is as follows:
 - for "qcom,smmu-v2":
   - "bus": clock required for downstream bus access and for the smmu ptw,
   - "iface":  clock required to access smmu's registers through the
TCU's programming interface.
 - unspecified for other implementations.

(+/- wrapping)

> +
> +- clocks: Phandles for respective clocks described by clock-names.

Phandle is just a pointer to another node. Clocks are however
specified using a phandle and a number of arguments, depending on the
clock controller. I'd change it to:

- clocks: Specifiers for all clocks listed in the clock-names
property, as per generic clock bindings.

> +
> +- power-domains:  Phandles to SMMU's power domain specifier. This is
> +  required even if SMMU belongs to the master's power
> +  domain, as the SMMU will have to be enabled and
> +  accessed before master gets enabled and linked to its
> +  SMMU.

From DT point of view, the relationship of SMMU belonging to a master
device doesn't exist. The power-domains property needs to be properly
specified for all devices within power domains represented in DT, with
an exception of the case when the parent-child relationship is
explicitly stated in DT by child devices being represented by child
nodes of the parent device node.

- power-domains: Specifiers for power domains required to be powered
on for the SMMU to operate, as per generic power domain bindings.

Best regards,
Tomasz
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105021] suspend / rx550 / extremely slow after 2nd thaw

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105021

--- Comment #8 from Michel Dänzer  ---
(In reply to arne_woerner from comment #4)
> in the first few seconds yes, but then no...

So the slowness is probably due to the GPU's IRQ no longer working, the
question is why that happens...

Assuming you're running with DC enabled, does amdgpu.dc=0 make a difference?
(Or amdgpu.dc=1 otherwise)

If not, since this seems to be a regression, bisecting between 4.14 and 4.15
would probably be the best way forward.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-13 Thread Tomasz Figa
Hi Vivek,

Thanks for the patch. Please see my comments inline.

On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
 wrote:
> While handling the concerned iommu, there should not be a
> need to power control the drm devices from iommu interface.
> If these drm devices need to be powered around this time,
> the respective drivers should take care of this.
>
> Replace the pm_runtime_get/put_sync() with
> pm_runtime_get/put_suppliers() calls, to power-up
> the connected iommu through the device link interface.
> In case the device link is not setup these get/put_suppliers()
> calls will be a no-op, and the iommu driver should take care of
> powering on its devices accordingly.
>
> Signed-off-by: Vivek Gautam 
> ---
>  drivers/gpu/drm/msm/msm_iommu.c | 16 
>  1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
> index b23d33622f37..1ab629bbee69 100644
> --- a/drivers/gpu/drm/msm/msm_iommu.c
> +++ b/drivers/gpu/drm/msm/msm_iommu.c
> @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char 
> * const *names,
> struct msm_iommu *iommu = to_msm_iommu(mmu);
> int ret;
>
> -   pm_runtime_get_sync(mmu->dev);
> +   pm_runtime_get_suppliers(mmu->dev);
> ret = iommu_attach_device(iommu->domain, mmu->dev);
> -   pm_runtime_put_sync(mmu->dev);
> +   pm_runtime_put_suppliers(mmu->dev);

For me, it looks like a wrong place to handle runtime PM of IOMMU
here. iommu_attach_device() calls into IOMMU driver's attach_device()
callback and that's where necessary runtime PM gets should happen, if
any. In other words, driver A (MSM DRM driver) shouldn't be dealing
with power state of device controlled by driver B (ARM SMMU).

This is also important for the reasons I stated in my comments to
"[PATCH v7 1/6] base: power: runtime: Export
pm_runtime_get/put_suppliers". Quoting for everyone's convenience:

>> There are however cases in which the consumer wants to power-on
>> the supplier, but not itself.
>> E.g., A Graphics or multimedia driver wants to power-on the SMMU
>> to unmap a buffer and finish the TLB operations without powering
>> on itself.
>
>This sounds strange to me. If the SMMU is powered down, wouldn't the
>TLB lose its contents as well (and so no flushing needed)?
>
>Other than that, what kind of hardware operations would be needed
>besides just updating the page tables from the CPU?
>

In other words, the SMMU driver can deal with hardware state based on
return value of pm_runtime_get_sync() or pm_runtime_get_if_in_use()
and decide whether some operations are necessary or not, e.g.
- a state restore is necessary if the domain was powered off, but we
are bringing the master on,
- a flush may not be required when (un)mapping with the domain powered off,
- etc.

Best regards,
Tomasz
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too

2018-02-13 Thread Maarten Lankhorst
Programs like redshift set the legacy gamma for X.org every 5 seconds.
Because atomic commits wait for vblank completion, we get a frame drop
every 5 seconds because of the legacy gamma update.

Work around this by setting the legacy_cursor_update flag, to force
legacy gamma updates not to be synced against vblank.

Reported-by: Tholin #intel-gfx
Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/drm_atomic_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index ae3cbfe9e01c..f37ab26ef4d2 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3806,6 +3806,9 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc 
*crtc,
if (!state)
return -ENOMEM;
 
+   /* Don't wait for vblank after updating gamma. */
+   state->legacy_cursor_update = true;
+
blob = drm_property_create_blob(dev,
sizeof(struct drm_color_lut) * size,
NULL);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too

2018-02-13 Thread Chris Wilson
Quoting Maarten Lankhorst (2018-02-13 09:12:01)
> Programs like redshift set the legacy gamma for X.org every 5 seconds.
> Because atomic commits wait for vblank completion, we get a frame drop
> every 5 seconds because of the legacy gamma update.
> 
> Work around this by setting the legacy_cursor_update flag, to force
> legacy gamma updates not to be synced against vblank.
> 
> Reported-by: Tholin #intel-gfx
> Signed-off-by: Maarten Lankhorst 

Reminiscing: Remember the time we had all those vblank workers patches,
one of which was to do async gamma updates (apply the last one on the
vblank). Motivated by gnome-shell and the ilk doing a gamma animation
for fade-out on logout (which I guess they gave up on since it happened
to be so slow as to extend logout ;).
-Chris
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: WARNING in drm_modeset_lock_all

2018-02-13 Thread Dmitry Vyukov
On Tue, Oct 31, 2017 at 2:03 PM, Dmitry Vyukov  wrote:
> On Tue, Oct 31, 2017 at 3:45 PM, Chris Wilson  
> wrote:
>> Quoting syzbot (2017-10-27 09:09:50)
>>> This bug is generated by a dumb bot. It may contain errors.
>>> See https://goo.gl/tpsmEJ for details.
>>> Direct all questions to syzkal...@googlegroups.com.
>>>
>>> syzbot will keep track of this bug report.
>>> Once a fix for this bug is committed, please reply to this email with:
>>> #syz fix: exact-commit-title
>>> To mark this as a duplicate of another syzbot report, please reply with:
>>> #syz dup: exact-subject-of-another-report
>>> If it's a one-off invalid bug report, please reply with:
>>> #syz invalid
>>> Note: if the crash happens again, it will cause creation of a new bug
>>> report.
>>
>> Can we use
>>
>> Reported-by: syzbot 
>> 
>>
>> as a unique tag for tracking purposes?
>
>
> Hi,
>
> Seems to be a common question. I've added the following to bug template:
>
> Please credit me with: Reported-by: syzbot 
>
> will now be present on newly reported bugs:
>
> https://groups.google.com/forum/#!topic/syzkaller-bugs/XE8YSiSZDdA


This was fixed by:
#syz fix: drm: Require __GFP_NOFAIL for the legacy drm_modeset_lock_all


Now we indeed can use:
Reported-by: syzbot

which avoids the need to go back and manually attach fixing commit to
the report like this.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/4] drm/mxsfb: Do not use deprecated drm_driver.{enable|disable)_vblank

2018-02-13 Thread Marek Vasut
On 02/12/2018 09:52 AM, Oleksandr Andrushchenko wrote:
> From: Oleksandr Andrushchenko 
> 
> Do not use deprecated drm_driver.{enable|disable)_vblank callbacks,
> but use drm_simple_kms_helpe's pipe callbacks instead.
> 
> Signed-off-by: Oleksandr Andrushchenko 
> Cc: Marek Vasut 

Reviewed-by: Marek Vasut 

> ---
>  drivers/gpu/drm/mxsfb/mxsfb_drv.c | 54 
> ---
>  1 file changed, 28 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c 
> b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> index 1207ffe36250..5cae8db9dcd4 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> @@ -131,11 +131,37 @@ static int mxsfb_pipe_prepare_fb(struct 
> drm_simple_display_pipe *pipe,
>   return drm_gem_fb_prepare_fb(&pipe->plane, plane_state);
>  }
>  
> +static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe *pipe)
> +{
> + struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
> +
> + /* Clear and enable VBLANK IRQ */
> + mxsfb_enable_axi_clk(mxsfb);
> + writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
> + writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
> + mxsfb_disable_axi_clk(mxsfb);
> +
> + return 0;
> +}
> +
> +static void mxsfb_pipe_disable_vblank(struct drm_simple_display_pipe *pipe)
> +{
> + struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
> +
> + /* Disable and clear VBLANK IRQ */
> + mxsfb_enable_axi_clk(mxsfb);
> + writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
> + writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
> + mxsfb_disable_axi_clk(mxsfb);
> +}
> +
>  static struct drm_simple_display_pipe_funcs mxsfb_funcs = {
>   .enable = mxsfb_pipe_enable,
>   .disable= mxsfb_pipe_disable,
>   .update = mxsfb_pipe_update,
>   .prepare_fb = mxsfb_pipe_prepare_fb,
> + .enable_vblank  = mxsfb_pipe_enable_vblank,
> + .disable_vblank = mxsfb_pipe_disable_vblank,
>  };
>  
>  static int mxsfb_load(struct drm_device *drm, unsigned long flags)
> @@ -274,33 +300,11 @@ static void mxsfb_lastclose(struct drm_device *drm)
>   drm_fbdev_cma_restore_mode(mxsfb->fbdev);
>  }
>  
> -static int mxsfb_enable_vblank(struct drm_device *drm, unsigned int crtc)
> -{
> - struct mxsfb_drm_private *mxsfb = drm->dev_private;
> -
> - /* Clear and enable VBLANK IRQ */
> - mxsfb_enable_axi_clk(mxsfb);
> - writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
> - writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
> - mxsfb_disable_axi_clk(mxsfb);
> -
> - return 0;
> -}
> -
> -static void mxsfb_disable_vblank(struct drm_device *drm, unsigned int crtc)
> +static void mxsfb_irq_preinstall(struct drm_device *drm)
>  {
>   struct mxsfb_drm_private *mxsfb = drm->dev_private;
>  
> - /* Disable and clear VBLANK IRQ */
> - mxsfb_enable_axi_clk(mxsfb);
> - writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
> - writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
> - mxsfb_disable_axi_clk(mxsfb);
> -}
> -
> -static void mxsfb_irq_preinstall(struct drm_device *drm)
> -{
> - mxsfb_disable_vblank(drm, 0);
> + mxsfb_pipe_disable_vblank(&mxsfb->pipe);
>  }
>  
>  static irqreturn_t mxsfb_irq_handler(int irq, void *data)
> @@ -333,8 +337,6 @@ static struct drm_driver mxsfb_driver = {
>   .irq_handler= mxsfb_irq_handler,
>   .irq_preinstall = mxsfb_irq_preinstall,
>   .irq_uninstall  = mxsfb_irq_preinstall,
> - .enable_vblank  = mxsfb_enable_vblank,
> - .disable_vblank = mxsfb_disable_vblank,
>   .gem_free_object_unlocked = drm_gem_cma_free_object,
>   .gem_vm_ops = &drm_gem_cma_vm_ops,
>   .dumb_create= drm_gem_cma_dumb_create,
> 


-- 
Best regards,
Marek Vasut
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/rockchip: Don't use spin_lock_irqsave in interrupt context

2018-02-13 Thread Marc Zyngier
Hi Heiko,

On 10/02/18 16:23, Heiko Stuebner wrote:
> Hi Marc,
> 
> Am Samstag, 10. Februar 2018, 15:35:01 CET schrieb Marc Zyngier:
>> The rockchip DRM driver is quite careful to disable interrupts
>> when taking a lock that is also taken in interrupt context,
>> which is a good thing.
>>
>> What is a bit over the top is to use spin_lock_irqsave when
>> already in interrupt context, as you cannot take another
>> interrupt again, and disabling interrupt is just pure
>> overhead.
>>
>> Switching to the non _irqsave version in interrupt context is
>> more logical, and less heavy handed.
>>
>> Signed-off-by: Marc Zyngier 
> 
> please note, that we had a maintainer swap for the Rockchip drm-component,
> where Sandy replaced Mark [0] ... with me acting as sort-of (and not yet
> up to speed) backup.
> 
> So I guess Rockchip drm patches should also include
>   Sandy Huang 

I guess that update didn't make it into 4.15, which is why I didn't spot
it. I'll repost the patches shortly including Sandy on Cc.

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too

2018-02-13 Thread Maarten Lankhorst
Hey,

Op 13-02-18 om 10:16 schreef Chris Wilson:
> Quoting Maarten Lankhorst (2018-02-13 09:12:01)
>> Programs like redshift set the legacy gamma for X.org every 5 seconds.
>> Because atomic commits wait for vblank completion, we get a frame drop
>> every 5 seconds because of the legacy gamma update.
>>
>> Work around this by setting the legacy_cursor_update flag, to force
>> legacy gamma updates not to be synced against vblank.
>>
>> Reported-by: Tholin #intel-gfx
>> Signed-off-by: Maarten Lankhorst 
> Reminiscing: Remember the time we had all those vblank workers patches,
> one of which was to do async gamma updates (apply the last one on the
> vblank). Motivated by gnome-shell and the ilk doing a gamma animation
> for fade-out on logout (which I guess they gave up on since it happened
> to be so slow as to extend logout ;).

That special case could be handled by userspace with atomic commits, I don't
think it's worth optimizing it further..

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 4/4 v2] drm_hwcomposer: Try to fallback if GLCompisition fails

2018-02-13 Thread Alexandru-Cosmin Gheorghe
On Mon, Feb 12, 2018 at 08:43:10PM -0800, John Stultz wrote:
> On Wed, Jan 31, 2018 at 11:03 AM, John Stultz  wrote:
> > On Wed, Jan 31, 2018 at 10:51 AM, Alexandru-Cosmin Gheorghe
> >  wrote:
> >> It seems that we don't pass any explicit fences to the kernel for
> >> IN_FENCE_FD property. This particular line seems wrong.
> >>
> >> @@ -593,14 +594,17 @@ int
> >> DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
> >>else
> >>  rotation |= DRM_MODE_ROTATE_0;
> >>
> >> -  if (fence_fd < 0) {
> >> +  if (fence_fd >= 0) {
> >
> > I'll give that a whirl.
>
> So I did give that a whirl after you suggested it, but it ended up
> causing nothing to be displayed, and I unfortunately didn't have time
> right then to dig much further.
>
> Rob however re-found this issue today, and I've been digging a bit
> more. At least with the HiKey board, it seem the trouble is when the
> IN_FENCE_FD is added to the pset, the atomic commit calls start to
> fail. I dug in and it seems we're catching in the kernel on the  if
> (file->f_op != &sync_file_fops) check in sync_file_fdget().
>
> I'm now trying to trace back to where the in fence was provided from
> to see what might be going wrong there.
I would be surprised if this fence is not created by the GPU driver.
But, the whole Android stack is new to me, so I might be wrong.
>
> Curious if this is anything you ran across in your attempts?
Sorry, on Hikey960, I don't have this problem. Are you using the
same 4.9 kernel from your branch(hikey-hwcomposer-deps)?
>
> thanks
> -john

Regards,
Alex Gheorghe
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Mesa-dev] [PATCH 6/7] vulkan: Add new VK_MESA_query_timestamp extension

2018-02-13 Thread Lionel Landwerlin

On 13/02/18 00:20, Dylan Baker wrote:

Quoting Keith Packard (2018-02-09 20:45:15)

This extension adds a single function to query the current GPU
timestamp, just like glGetInteger64v(GL_TIMESTAMP, ×tamp). This
function is needed to complete the implementation of
GOOGLE_display_timing, which needs to be able to coorelate GPU and CPU
timestamps.


I'm assuming the correlation is done outside the vulkan driver? With a 
clock_gettime() maybe?


If that's the case, I'm afraid this will be highly inaccurate.
The kernel might execute other tasks when the ioctl() happens and that 
might introduce (in my experience) a few milliseconds of delay.


I think if you want to do something like that, this has to be 
implemented in the kernel, making sure you disable interruptions while 
doing the correlation.




Signed-off-by: Keith Packard 
---
  include/vulkan/vulkan.h |  6 ++
  src/Makefile.am |  1 +
  src/amd/vulkan/Makefile.am  |  3 +++
  src/amd/vulkan/meson.build  |  8 
  src/amd/vulkan/radv_device.c|  8 
  src/amd/vulkan/radv_extensions.py   |  1 +
  src/intel/Makefile.vulkan.am|  7 +++
  src/intel/vulkan/anv_extensions.py  |  1 +
  src/intel/vulkan/anv_gem.c  | 13 +
  src/intel/vulkan/anv_private.h  |  1 +
  src/intel/vulkan/genX_query.c   | 15 +++
  src/intel/vulkan/meson.build| 12 ++--
  src/vulkan/meson.build  |  1 +
  src/vulkan/registry/vk_mesa_query_timestamp.xml | 22 ++
  14 files changed, 89 insertions(+), 10 deletions(-)
  create mode 100644 src/vulkan/registry/vk_mesa_query_timestamp.xml

diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
index d3e2e246cf3..5523eb7586f 100644
--- a/include/vulkan/vulkan.h
+++ b/include/vulkan/vulkan.h
@@ -7025,6 +7025,12 @@ VKAPI_ATTR VkResult VKAPI_CALL 
vkGetMemoryHostPointerPropertiesEXT(
  VkMemoryHostPointerPropertiesEXT*   pMemoryHostPointerProperties);
  #endif
  
+typedef VkResult (VKAPI_PTR *PFN_vkQueryCurrentTimestampMESA)(VkDevice device, uint64_t *timestamp);

+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueryCurrentTimestampMESA(
+VkDevice_device,
+uint64_t*timestamp);
+
  #ifdef __cplusplus
  }
  #endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 014ffaf3e29..74ff305d7c6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -68,6 +68,7 @@ endif
  
  EXTRA_DIST += vulkan/registry/vk.xml

  EXTRA_DIST += vulkan/registry/vk_android_native_buffer.xml
+EXTRA_DIST += vulkan/registry/vk_mesa_query_timestamp.xml
  
  if HAVE_AMD_DRIVERS

  SUBDIRS += amd
diff --git a/src/amd/vulkan/Makefile.am b/src/amd/vulkan/Makefile.am
index 94ece06e99e..0626fa2b3b3 100644
--- a/src/amd/vulkan/Makefile.am
+++ b/src/amd/vulkan/Makefile.am
@@ -129,12 +129,14 @@ libvulkan_radeon_la_SOURCES = $(VULKAN_GEM_FILES)
  
  vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml

  vk_android_native_buffer_xml = 
$(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml
+vk_mesa_query_timestamp_xml = 
$(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml
  
  radv_entrypoints.c: radv_entrypoints_gen.py radv_extensions.py $(vulkan_api_xml)

 $(MKDIR_GEN)
 $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_entrypoints_gen.py \
 --xml $(vulkan_api_xml) \
 --xml $(vk_android_native_buffer_xml) \
+   --xml $(vk_mesa_query_timestamp_xml) \
 --outdir $(builddir)
  radv_entrypoints.h: radv_entrypoints.c
  
@@ -144,6 +146,7 @@ radv_extensions.c: radv_extensions.py \

 $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_extensions.py \
 --xml $(vulkan_api_xml) \
 --xml $(vk_android_native_buffer_xml) \
+   --xml $(vk_mesa_query_timestamp_xml) \
 --out $@
  
  vk_format_table.c: vk_format_table.py \

diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build
index 0b92a1763a1..34f578476c0 100644
--- a/src/amd/vulkan/meson.build
+++ b/src/amd/vulkan/meson.build
@@ -20,10 +20,10 @@
  
  radv_entrypoints = custom_target(

'radv_entrypoints.[ch]',
-  input : ['radv_entrypoints_gen.py', vk_api_xml],
+  input : ['radv_entrypoints_gen.py', vk_api_xml, 
vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml],

some of these lines look a little long,
input : [
 'radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml,
 vk_mesa_query_timestamp_xml,
],


output : ['radv_entrypoints.h', 'radv_entrypoints.c'],
command : [
-prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
+prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', 
'--xml', '@INPUT3@', '--outdir',
  meson.current_b

Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers

2018-02-13 Thread Liviu Dudau
Hi Lukas,

On Sun, Feb 11, 2018 at 10:38:28AM +0100, Lukas Wunner wrote:
> Fix a deadlock on hybrid graphics laptops that's been present since 2013:
> 
> DRM drivers poll connectors in 10 sec intervals.  The poll worker is
> stopped on ->runtime_suspend with cancel_delayed_work_sync().  However
> the poll worker invokes the DRM drivers' ->detect callbacks, which call
> pm_runtime_get_sync().  If the poll worker starts after runtime suspend
> has begun, pm_runtime_get_sync() will wait for runtime suspend to finish
> with the intention of runtime resuming the device afterwards.  The result
> is a circular wait between poll worker and autosuspend worker.
> 
> I'm seeing this deadlock so often it's not funny anymore. I've also found
> 3 nouveau bugzillas about it and 1 radeon bugzilla. (See patch [3/5] and
> [4/5].)
> 
> One theoretical solution would be to add a flag to the ->detect callback
> to tell it that it's running in the poll worker's context.  In that case
> it doesn't need to call pm_runtime_get_sync() because the poll worker is
> only enabled while runtime active and we know that ->runtime_suspend
> waits for it to finish.  But this approach would require touching every
> single DRM driver's ->detect hook.  Moreover the ->detect hook is called
> from numerous other places, both in the DRM library as well as in each
> driver, making it necessary to trace every possible call chain and check
> if it's coming from the poll worker or not.  I've tried to do that for
> nouveau (see the call sites listed in the commit message of patch [3/5])
> and concluded that this approach is a nightmare to implement.
> 
> Another reason for the infeasibility of this approach is that ->detect
> is called from within the DRM library without driver involvement, e.g.
> via DRM's sysfs interface.  In those cases, pm_runtime_get_sync() would
> have to be called by the DRM library, but the DRM library is supposed to
> stay generic, wheras runtime PM is driver-specific.
> 
> So instead, I've come up with this much simpler solution which gleans
> from the current task's flags if it's a workqueue worker, retrieves the
> work_struct and checks if it's the poll worker.  All that's needed is
> one small helper in the workqueue code and another small helper in the
> DRM library.  This solution lends itself nicely to stable-backporting.
> 
> The patches for radeon and amdgpu are compile-tested only, I only have a
> MacBook Pro with an Nvidia GK107 to test.  To test the patches, add an
> "msleep(12*1000);" at the top of the driver's ->runtime_suspend hook.
> This ensures that the poll worker runs after ->runtime_suspend has begun.
> Wait 12 sec after the GPU has begun runtime suspend, then check
> /sys/bus/pci/devices/:01:00.0/power/runtime_status.  Without this
> series, the status will be stuck at "suspending" and you'll get hung task
> errors in dmesg after a few minutes.
> 
> i915, malidp and msm "solved" this issue by not stopping the poll worker
> on runtime suspend.  But this results in the GPU bouncing back and forth
> between D0 and D3 continuously.  That's a total no-go for GPUs which
> runtime suspend to D3cold since every suspend/resume cycle costs a
> significant amount of time and energy.  (i915 and malidp do not seem
> to acquire a runtime PM ref in the ->detect callbacks, which seems
> questionable.  msm however does and would also deadlock if it disabled
> the poll worker on runtime suspend.  cc += Archit, Liviu, intel-gfx)

I think I understand the problem you are trying to solve, but I'm
struggling to understand where malidp makes any specific mistakes. First
of all, malidp is only a display engine, so there is no GPU attached to
it, but that is only a small clarification. Second, malidp doesn't use
directly any of the callbacks that you are referring to, it uses the
drm_cma_() API plus the generic drm_() call. So if there are any
issues there (as they might well be) I think they would apply to a lot
more drivers and the fix will involve more than just malidp, i915 and
msm.

Would love to get any clarifications on what I might have misunderstood.

Best regards,
Liviu


> 
> Please review.  Thanks,
> 
> Lukas
> 
> Lukas Wunner (5):
>   workqueue: Allow retrieval of current task's work struct
>   drm: Allow determining if current task is output poll worker
>   drm/nouveau: Fix deadlock on runtime suspend
>   drm/radeon: Fix deadlock on runtime suspend
>   drm/amdgpu: Fix deadlock on runtime suspend
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 58 +---
>  drivers/gpu/drm/drm_probe_helper.c | 14 +
>  drivers/gpu/drm/nouveau/nouveau_connector.c| 18 +--
>  drivers/gpu/drm/radeon/radeon_connectors.c | 74 
> +-
>  include/drm/drm_crtc_helper.h  |  1 +
>  include/linux/workqueue.h  |  1 +
>  kernel/workqueue.c | 16 ++
>  7 files changed, 132 insertions(+), 50 deletions(-

[Bug 105072] Texture corruption covering screen

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105072

Bug ID: 105072
   Summary: Texture corruption covering screen
   Product: Mesa
   Version: 17.3
  Hardware: x86-64 (AMD64)
OS: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/Gallium/radeonsi
  Assignee: dri-devel@lists.freedesktop.org
  Reporter: sup...@gmail.com
QA Contact: dri-devel@lists.freedesktop.org

I tried to play "We need to go deeper" and the menu runs fine, but in game
there looks to be some sort of post effect which uses a corrupt texture.

I also get a similar problem in silent hunter III, so it is possibly the same
bug as this:
https://bugs.freedesktop.org/show_bug.cgi?id=104549

I run both of these games through wine. I tried "We need to go deeper" on a
Intel iGPU and it ran fine.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers

2018-02-13 Thread Lukas Wunner
On Tue, Feb 13, 2018 at 10:55:06AM +, Liviu Dudau wrote:
> On Sun, Feb 11, 2018 at 10:38:28AM +0100, Lukas Wunner wrote:
> > DRM drivers poll connectors in 10 sec intervals.  The poll worker is
> > stopped on ->runtime_suspend with cancel_delayed_work_sync().  However
> > the poll worker invokes the DRM drivers' ->detect callbacks, which call
> > pm_runtime_get_sync().  If the poll worker starts after runtime suspend
> > has begun, pm_runtime_get_sync() will wait for runtime suspend to finish
> > with the intention of runtime resuming the device afterwards.  The result
> > is a circular wait between poll worker and autosuspend worker.
> 
> I think I understand the problem you are trying to solve, but I'm
> struggling to understand where malidp makes any specific mistakes. First
> of all, malidp is only a display engine, so there is no GPU attached to
> it, but that is only a small clarification. Second, malidp doesn't use
> directly any of the callbacks that you are referring to, it uses the
> drm_cma_() API plus the generic drm_() call. So if there are any
> issues there (as they might well be) I think they would apply to a lot
> more drivers and the fix will involve more than just malidp, i915 and
> msm.

I don't know if malidp makes any specific mistakes and didn't mean to
cast it in a negative light, sorry.

So a lot of DRM drivers acquire a runtime PM ref in the connector ->detect
hook because they can't probe connectors while runtime suspended.
E.g. for a PCI device, probing might require mmio access, which isn't
possible outside of power state D0.  There are no ->detect hooks declared
in drivers/gpu/drm/arm/, so it's unclear to me whether you're able to probe
during runtime suspend.

hdlcd_drv.c and malidp_drv.c both enable output polling.  Output polling
is only necessary if you don't get HPD interrupts.

You're not disabling polling upon runtime suspend.  Thus, if a runtime PM
ref is acquired during polling (such as in a ->detect hook), the GPU will
be runtime resumed every 10 secs.  You may want to verify that's not the
case.  If you decide that you do want to stop polling during runtime
suspend because it runtime resumes the GPU continuously, you'll need the
helper introduced in this series.  So by cc'ing you I just wanted to keep
you in the loop about an issue that may potentially affect your driver.

Let me know if there are any questions.

Thanks,

Lukas
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 04/30] drm: omapdrm: dss: Pass PLL pointer to dss_ctrl_pll_enable()

2018-02-13 Thread Laurent Pinchart
This will allow accessing the PLL data to get the DSS device pointer,
removing the need to access the global DSS private data.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dss.c   | 13 +++--
 drivers/gpu/drm/omapdrm/dss/dss.h   |  2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi_pll.c  |  4 ++--
 drivers/gpu/drm/omapdrm/dss/video-pll.c |  6 +++---
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 6c28e13d9ae0..29c3a0dba698 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -152,17 +152,17 @@ static void dss_restore_context(void)
 #undef SR
 #undef RR
 
-void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
+void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable)
 {
unsigned int shift;
unsigned int val;
 
-   if (!dss.syscon_pll_ctrl)
+   if (!pll->dss->syscon_pll_ctrl)
return;
 
val = !enable;
 
-   switch (pll_id) {
+   switch (pll->id) {
case DSS_PLL_VIDEO1:
shift = 0;
break;
@@ -173,12 +173,13 @@ void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool 
enable)
shift = 2;
break;
default:
-   DSSERR("illegal DSS PLL ID %d\n", pll_id);
+   DSSERR("illegal DSS PLL ID %d\n", pll->id);
return;
}
 
-   regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
-   1 << shift, val << shift);
+   regmap_update_bits(pll->dss->syscon_pll_ctrl,
+  pll->dss->syscon_pll_ctrl_offset,
+  1 << shift, val << shift);
 }
 
 static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h 
b/drivers/gpu/drm/omapdrm/dss/dss.h
index a7aeb0e7e1ae..ea3eb6b0e7f1 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -310,7 +310,7 @@ struct dss_pll *dss_video_pll_init(struct dss_device *dss,
   struct regulator *regulator);
 void dss_video_pll_uninit(struct dss_pll *pll);
 
-void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
+void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable);
 
 void dss_sdi_init(int datapairs);
 int dss_sdi_enable(void);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
index 8ee9743e6fcf..4fb97cd0cc8d 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
@@ -48,7 +48,7 @@ static int hdmi_pll_enable(struct dss_pll *dsspll)
r = pm_runtime_get_sync(&pll->pdev->dev);
WARN_ON(r < 0);
 
-   dss_ctrl_pll_enable(DSS_PLL_HDMI, true);
+   dss_ctrl_pll_enable(dsspll, true);
 
r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
if (r)
@@ -65,7 +65,7 @@ static void hdmi_pll_disable(struct dss_pll *dsspll)
 
hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
 
-   dss_ctrl_pll_enable(DSS_PLL_HDMI, false);
+   dss_ctrl_pll_enable(dsspll, false);
 
r = pm_runtime_put_sync(&pll->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c 
b/drivers/gpu/drm/omapdrm/dss/video-pll.c
index 12997668730c..344e7e0bbc4e 100644
--- a/drivers/gpu/drm/omapdrm/dss/video-pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c
@@ -68,7 +68,7 @@ static int dss_video_pll_enable(struct dss_pll *pll)
if (r)
return r;
 
-   dss_ctrl_pll_enable(pll->id, true);
+   dss_ctrl_pll_enable(pll, true);
 
dss_dpll_enable_scp_clk(vpll);
 
@@ -82,7 +82,7 @@ static int dss_video_pll_enable(struct dss_pll *pll)
 
 err_reset:
dss_dpll_disable_scp_clk(vpll);
-   dss_ctrl_pll_enable(pll->id, false);
+   dss_ctrl_pll_enable(pll, false);
dss_runtime_put(pll->dss);
 
return r;
@@ -96,7 +96,7 @@ static void dss_video_pll_disable(struct dss_pll *pll)
 
dss_dpll_disable_scp_clk(vpll);
 
-   dss_ctrl_pll_enable(pll->id, false);
+   dss_ctrl_pll_enable(pll, false);
 
dss_runtime_put(pll->dss);
 }
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 03/30] drm: omapdrm: dss: Pass DSS private structure to runtime PM functions

2018-02-13 Thread Laurent Pinchart
To prepare for the removal of the global variable storing DSS private
data, pass its pointer to the dss_runtime_{get,put}() functions.

As this requires getting hold of the dss_device structure in the
callers, we add a new dss_get_device() function to retrieve it. The
function currently returns a pointer to the global data structure, and
will later be updated to get the pointer from device driver data when
the DSS private structure will be allocated dynamically.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c   |  7 +++--
 drivers/gpu/drm/omapdrm/dss/dss.c   | 47 +++--
 drivers/gpu/drm/omapdrm/dss/dss.h   | 12 ++---
 drivers/gpu/drm/omapdrm/dss/hdmi.h  |  6 +++--
 drivers/gpu/drm/omapdrm/dss/hdmi4.c |  3 ++-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c |  3 ++-
 drivers/gpu/drm/omapdrm/dss/hdmi_pll.c  | 10 ---
 drivers/gpu/drm/omapdrm/dss/video-pll.c | 12 +
 8 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 41d500eea843..7ba33fc5d245 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5322,7 +5322,8 @@ static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
.has_refsel = true,
 };
 
-static int dsi_init_pll_data(struct platform_device *dsidev)
+static int dsi_init_pll_data(struct dss_device *dss,
+struct platform_device *dsidev)
 {
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct dss_pll *pll = &dsi->pll;
@@ -5341,6 +5342,7 @@ static int dsi_init_pll_data(struct platform_device 
*dsidev)
pll->base = dsi->pll_base;
pll->hw = dsi->data->pll_hw;
pll->ops = &dsi_pll_ops;
+   pll->dss = dss;
 
r = dss_pll_register(pll);
if (r)
@@ -5417,6 +5419,7 @@ static const struct soc_device_attribute 
dsi_soc_devices[] = {
 static int dsi_bind(struct device *dev, struct device *master, void *data)
 {
struct platform_device *dsidev = to_platform_device(dev);
+   struct dss_device *dss = dss_get_device(master);
const struct soc_device_attribute *soc;
const struct dsi_module_id_data *d;
u32 rev;
@@ -5525,7 +5528,7 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
if (r)
return r;
 
-   dsi_init_pll_data(dsidev);
+   dsi_init_pll_data(dss, dsidev);
 
pm_runtime_enable(&dsidev->dev);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 245d8c0ae461..6c28e13d9ae0 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -345,7 +345,7 @@ static void dss_dump_clocks(struct seq_file *s)
const char *fclk_name;
unsigned long fclk_rate;
 
-   if (dss_runtime_get())
+   if (dss_runtime_get(&dss))
return;
 
seq_printf(s, "- DSS -\n");
@@ -357,7 +357,7 @@ static void dss_dump_clocks(struct seq_file *s)
fclk_name,
fclk_rate);
 
-   dss_runtime_put();
+   dss_runtime_put(&dss);
 }
 #endif
 
@@ -365,7 +365,7 @@ static void dss_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
 
-   if (dss_runtime_get())
+   if (dss_runtime_get(&dss))
return;
 
DUMPREG(DSS_REVISION);
@@ -379,7 +379,7 @@ static void dss_dump_regs(struct seq_file *s)
DUMPREG(DSS_SDI_STATUS);
}
 
-   dss_runtime_put();
+   dss_runtime_put(&dss);
 #undef DUMPREG
 }
 
@@ -837,27 +837,32 @@ static void dss_put_clocks(void)
clk_put(dss.parent_clk);
 }
 
-int dss_runtime_get(void)
+int dss_runtime_get(struct dss_device *dss)
 {
int r;
 
DSSDBG("dss_runtime_get\n");
 
-   r = pm_runtime_get_sync(&dss.pdev->dev);
+   r = pm_runtime_get_sync(&dss->pdev->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
 }
 
-void dss_runtime_put(void)
+void dss_runtime_put(struct dss_device *dss)
 {
int r;
 
DSSDBG("dss_runtime_put\n");
 
-   r = pm_runtime_put_sync(&dss.pdev->dev);
+   r = pm_runtime_put_sync(&dss->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
 }
 
+struct dss_device *dss_get_device(struct device *dev)
+{
+   return &dss;
+}
+
 /* DEBUGFS */
 #if defined(CONFIG_OMAP2_DSS_DEBUGFS)
 static void dss_debug_dump_clocks(struct seq_file *s)
@@ -1223,13 +1228,15 @@ static int dss_video_pll_probe(struct platform_device 
*pdev)
}
 
if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
-   dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
+   dss.video1_pll = dss_video_pll_init(&dss, pdev, 0,
+   pll_regulator);
if (IS_ERR(dss.video1_pll))

[PATCH v2 01/30] drm: omapdrm: Split init and cleanup from probe and remove functions

2018-02-13 Thread Laurent Pinchart
When merging the omapdrm and omapdss drivers there will be not omapdrm
platform device anymore, and thus no associated probe and remove
functions. To prepare for that, split all the initialization code from
the probe function to make it usable without a platform device.
Similarly, split the cleanup code from the remove function.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 83 +++---
 drivers/gpu/drm/omapdrm/omap_drv.h |  2 +
 2 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index dd68b2556f5b..b571cc04e08d 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -510,24 +510,16 @@ static const struct soc_device_attribute 
omapdrm_soc_devices[] = {
{ /* sentinel */ }
 };
 
-static int pdev_probe(struct platform_device *pdev)
+static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
 {
const struct soc_device_attribute *soc;
-   struct omap_drm_private *priv;
struct drm_device *ddev;
unsigned int i;
int ret;
 
-   DBG("%s", pdev->name);
-
-   if (omapdss_is_initialized() == false)
-   return -EPROBE_DEFER;
+   DBG("%s", dev_name(dev));
 
-   ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-   if (ret) {
-   dev_err(&pdev->dev, "Failed to set the DMA mask\n");
-   return ret;
-   }
+   priv->dev = dev;
 
omap_crtc_pre_init();
 
@@ -535,13 +527,6 @@ static int pdev_probe(struct platform_device *pdev)
if (ret)
goto err_crtc_uninit;
 
-   /* Allocate and initialize the driver private structure. */
-   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-   if (!priv) {
-   ret = -ENOMEM;
-   goto err_disconnect_dssdevs;
-   }
-
priv->dispc_ops = dispc_get_ops();
 
soc = soc_device_match(omapdrm_soc_devices);
@@ -552,14 +537,14 @@ static int pdev_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&priv->obj_list);
 
/* Allocate and initialize the DRM device. */
-   ddev = drm_dev_alloc(&omap_drm_driver, &pdev->dev);
+   ddev = drm_dev_alloc(&omap_drm_driver, priv->dev);
if (IS_ERR(ddev)) {
ret = PTR_ERR(ddev);
-   goto err_free_priv;
+   goto err_destroy_wq;
}
 
+   priv->ddev = ddev;
ddev->dev_private = priv;
-   platform_set_drvdata(pdev, ddev);
 
/* Get memory bandwidth limits */
if (priv->dispc_ops->get_memory_bandwidth_limit)
@@ -570,14 +555,14 @@ static int pdev_probe(struct platform_device *pdev)
 
ret = omap_modeset_init(ddev);
if (ret) {
-   dev_err(&pdev->dev, "omap_modeset_init failed: ret=%d\n", ret);
+   dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret);
goto err_free_drm_dev;
}
 
/* Initialize vblank handling, start with all CRTCs disabled. */
ret = drm_vblank_init(ddev, priv->num_crtcs);
if (ret) {
-   dev_err(&pdev->dev, "could not init vblank\n");
+   dev_err(priv->dev, "could not init vblank\n");
goto err_cleanup_modeset;
}
 
@@ -610,20 +595,17 @@ static int pdev_probe(struct platform_device *pdev)
 err_free_drm_dev:
omap_gem_deinit(ddev);
drm_dev_unref(ddev);
-err_free_priv:
+err_destroy_wq:
destroy_workqueue(priv->wq);
-   kfree(priv);
-err_disconnect_dssdevs:
omap_disconnect_dssdevs();
 err_crtc_uninit:
omap_crtc_pre_uninit();
return ret;
 }
 
-static int pdev_remove(struct platform_device *pdev)
+static void omapdrm_cleanup(struct omap_drm_private *priv)
 {
-   struct drm_device *ddev = platform_get_drvdata(pdev);
-   struct omap_drm_private *priv = ddev->dev_private;
+   struct drm_device *ddev = priv->ddev;
 
DBG("");
 
@@ -645,10 +627,45 @@ static int pdev_remove(struct platform_device *pdev)
drm_dev_unref(ddev);
 
destroy_workqueue(priv->wq);
-   kfree(priv);
 
omap_disconnect_dssdevs();
omap_crtc_pre_uninit();
+}
+
+static int pdev_probe(struct platform_device *pdev)
+{
+   struct omap_drm_private *priv;
+   int ret;
+
+   if (omapdss_is_initialized() == false)
+   return -EPROBE_DEFER;
+
+   ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+   if (ret) {
+   dev_err(&pdev->dev, "Failed to set the DMA mask\n");
+   return ret;
+   }
+
+   /* Allocate and initialize the driver private structure. */
+   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, priv);
+
+   ret = omapdrm_init(priv, &pdev->dev);
+   if (ret < 0)
+   kf

[PATCH v2 00/30] omapdrm: Allocate objects dynamically

2018-02-13 Thread Laurent Pinchart
Hello,

Most of this series has previously been posted as part of "[PATCH 00/48]
omapdrm: Merge omapdrm and omapdss". With "[PATCH v2 00/15] omapdrm:
Miscellaneous fixes and cleanups" posted and merged a few days ago, it
completes the rework of the omapdrm and omapdss drivers to replace most
global variables with dynamically-allocated objects. The actual merge of
the omapdrm and omapdss drivers has been left out for now as it still
suffers from unresolved issues.

As with the previous series I have other pending patches based on top of this,
as passing driver objects around explicitly helps not relying on more global
variables that would hinder the effort to move to the DRM bridge and DRM panel
APIs.

Patches 02/30, 14/30, 22/30 and 23/30 are new. Patch 21/30 has seen
significant changes and I have thus dropped the Reviewed-by tag from
Sebastian. All other patches have been rebased and reordered, thus sometimes
modified to resolve conflicts, but have otherwise seen only minor changes.

The series is based on top of the omapdrm-next branch from
git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git.

Tomi, as the series has been stripped of its controversial patches, I think
it's now ready to be merged (pending review of the patches mentioned above of
course). I have tested it on both a Panda board and an AM57xx EVM without any
issues (and this time I made sure to try with the drivers compiled as
modules).

Laurent Pinchart (30):
  drm: omapdrm: Split init and cleanup from probe and remove functions
  drm: omapdrm: dss: Expose DSS data in a dss_device structure
  drm: omapdrm: dss: Pass DSS private structure to runtime PM functions
  drm: omapdrm: dss: Pass PLL pointer to dss_ctrl_pll_enable()
  drm: omapdrm: dss: Pass DSS pointer to dss_sdi_*() functions
  drm: omapdrm: dss: Pass DSS pointer to dss_ops operations
  drm: omapdrm: dss: Pass DSS pointer to dss_get_*_clk_source()
  drm: omapdrm: dss: Pass DSS pointer to dss clock functions
  drm: omapdrm: dss: Pass DSS pointer to remaining dss functions
  drm: omapdrm: dss: Allocate the DSS private data structure dynamically
  drm: omapdrm: dss: Support passing private data to debugfs show
handlers
  drm: omapdrm: dss: Store the registered plls array in struct
dss_device
  drm: omapdrm: dss: Store the debugfs root directory in struct
dss_device
  drm: omapdrm: dss: Don't unnecessarily cast to dev to pdev and back
  drm: omapdrm: dsi: Pass the dsi_data pointer to internal functions
  drm: omapdrm: dsi: Combine two commonly used inline functions
  drm: omapdrm: dsi: Use dev pointer directly in dsi_bind() function
  drm: omapdrm: dsi: Store the struct device pointer in struct dsi_data
  drm: omapdrm: dsi: Don't pass channel to dispc init/uninit functions
  drm: omapdrm: dss: Pass omap_dss_device pointer to dss_mgr_*()
functions
  drm: omapdrm: dss: Pass omap_drm_private pointer to dss_mgr_ops
  drm: omapdrm: dss: Store DSS device pointer in the omapdrm private
data
  drm: omapdrm: dss: Store dispc ops in dss_device structure
  drm: omapdrm: dispc: Pass DISPC pointer to dispc_ops operations
  drm: omapdrm: dispc: Pass DISPC pointer to remaining dispc API
functions
  drm: omapdrm: dispc: Allocate the dispc private data structure
dynamically
  drm: omapdrm: hdmi4: Allocate the omap_hdmi data structure dynamically
  drm: omapdrm: hdmi5: Allocate the omap_hdmi data structure dynamically
  drm: omapdrm: sdi: Allocate the sdi private data structure dynamically
  drm: omapdrm: venc: Allocate the venc private data structure
dynamically

 drivers/gpu/drm/omapdrm/dss/base.c   |   27 +-
 drivers/gpu/drm/omapdrm/dss/dispc.c  | 2183 --
 drivers/gpu/drm/omapdrm/dss/dpi.c|   89 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c| 1466 ++--
 drivers/gpu/drm/omapdrm/dss/dss.c|  668 -
 drivers/gpu/drm/omapdrm/dss/dss.h|  229 ++--
 drivers/gpu/drm/omapdrm/dss/hdmi.h   |   11 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  |  371 ++---
 drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c  |4 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4_core.h |4 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c  |  379 +++---
 drivers/gpu/drm/omapdrm/dss/hdmi_pll.c   |   15 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  171 ++-
 drivers/gpu/drm/omapdrm/dss/output.c |   52 +-
 drivers/gpu/drm/omapdrm/dss/pll.c|   40 +-
 drivers/gpu/drm/omapdrm/dss/sdi.c|  162 ++-
 drivers/gpu/drm/omapdrm/dss/venc.c   |  453 ---
 drivers/gpu/drm/omapdrm/dss/video-pll.c  |   19 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c  |   62 +-
 drivers/gpu/drm/omapdrm/omap_crtc.h  |2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c   |  102 +-
 drivers/gpu/drm/omapdrm/omap_drv.h   |4 +
 drivers/gpu/drm/omapdrm/omap_irq.c   |   32 +-
 drivers/gpu/drm/omapdrm/omap_plane.c |   12 +-
 24 files changed, 3484 insertions(+), 3073 deletions(-)

-- 
Regards,

Laurent Pinchart

__

[PATCH v2 05/30] drm: omapdrm: dss: Pass DSS pointer to dss_sdi_*() functions

2018-02-13 Thread Laurent Pinchart
This removes the need to access the global DSS private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DSS device dynamically).

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dss.c |  8 
 drivers/gpu/drm/omapdrm/dss/dss.h | 14 --
 drivers/gpu/drm/omapdrm/dss/sdi.c | 13 -
 3 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 29c3a0dba698..c6a0b004b545 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -248,7 +248,7 @@ static int dss_ctrl_pll_set_control_mux(enum dss_clk_source 
clk_src,
return 0;
 }
 
-void dss_sdi_init(int datapairs)
+void dss_sdi_init(struct dss_device *dss, int datapairs)
 {
u32 l;
 
@@ -267,7 +267,7 @@ void dss_sdi_init(int datapairs)
dss_write_reg(DSS_PLL_CONTROL, l);
 }
 
-int dss_sdi_enable(void)
+int dss_sdi_enable(struct dss_device *dss)
 {
unsigned long timeout;
 
@@ -325,7 +325,7 @@ int dss_sdi_enable(void)
return -ETIMEDOUT;
 }
 
-void dss_sdi_disable(void)
+void dss_sdi_disable(struct dss_device *dss)
 {
dispc_lcd_enable_signal(0);
 
@@ -1150,7 +1150,7 @@ static int dss_init_ports(struct platform_device *pdev)
dpi_init_port(pdev, port, dss.feat->model);
break;
case OMAP_DISPLAY_TYPE_SDI:
-   sdi_init_port(pdev, port);
+   sdi_init_port(&dss, pdev, port);
break;
default:
break;
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h 
b/drivers/gpu/drm/omapdrm/dss/dss.h
index ea3eb6b0e7f1..e560803b5127 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -312,9 +312,9 @@ void dss_video_pll_uninit(struct dss_pll *pll);
 
 void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable);
 
-void dss_sdi_init(int datapairs);
-int dss_sdi_enable(void);
-void dss_sdi_disable(void);
+void dss_sdi_init(struct dss_device *dss, int datapairs);
+int dss_sdi_enable(struct dss_device *dss);
+void dss_sdi_disable(struct dss_device *dss);
 
 void dss_select_dsi_clk_source(int dsi_module,
enum dss_clk_source clk_src);
@@ -335,11 +335,13 @@ bool dss_div_calc(unsigned long pck, unsigned long 
fck_min,
 
 /* SDI */
 #ifdef CONFIG_OMAP2_DSS_SDI
-int sdi_init_port(struct platform_device *pdev, struct device_node *port);
+int sdi_init_port(struct dss_device *dss, struct platform_device *pdev,
+ struct device_node *port);
 void sdi_uninit_port(struct device_node *port);
 #else
-static inline int sdi_init_port(struct platform_device *pdev,
-   struct device_node *port)
+static inline int sdi_init_port(struct dss_device *dss,
+   struct platform_device *pdev,
+   struct device_node *port)
 {
return 0;
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c 
b/drivers/gpu/drm/omapdrm/dss/sdi.c
index d8ab31f3a813..f0564daa3831 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -31,6 +31,7 @@
 
 static struct {
struct platform_device *pdev;
+   struct dss_device *dss;
 
bool update_enabled;
struct regulator *vdds_sdi_reg;
@@ -187,8 +188,8 @@ static int sdi_display_enable(struct omap_dss_device 
*dssdev)
 */
dispc_mgr_set_clock_div(channel, &sdi.mgr_config.clock_info);
 
-   dss_sdi_init(sdi.datapairs);
-   r = dss_sdi_enable();
+   dss_sdi_init(sdi.dss, sdi.datapairs);
+   r = dss_sdi_enable(sdi.dss);
if (r)
goto err_sdi_enable;
mdelay(2);
@@ -200,7 +201,7 @@ static int sdi_display_enable(struct omap_dss_device 
*dssdev)
return 0;
 
 err_mgr_enable:
-   dss_sdi_disable();
+   dss_sdi_disable(sdi.dss);
 err_sdi_enable:
 err_set_dss_clock_div:
 err_calc_clock_div:
@@ -217,7 +218,7 @@ static void sdi_display_disable(struct omap_dss_device 
*dssdev)
 
dss_mgr_disable(channel);
 
-   dss_sdi_disable();
+   dss_sdi_disable(sdi.dss);
 
dispc_runtime_put();
 
@@ -345,7 +346,8 @@ static void sdi_uninit_output(struct platform_device *pdev)
omapdss_unregister_output(out);
 }
 
-int sdi_init_port(struct platform_device *pdev, struct device_node *port)
+int sdi_init_port(struct dss_device *dss, struct platform_device *pdev,
+ struct device_node *port)
 {
struct device_node *ep;
u32 datapairs;
@@ -362,6 +364,7 @@ int sdi_init_port(struct platform_device *pdev, struct 
device_node *port)
}
 
sdi.datapairs = datapairs;
+   sdi.dss = dss;
 
of_node_put(ep);
 
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.f

[PATCH v2 02/30] drm: omapdrm: dss: Expose DSS data in a dss_device structure

2018-02-13 Thread Laurent Pinchart
The anoonymous dss structure in dss.c is the top-level component in the
omapdss driver. As such it should store all internal instance-specific
data that is currently stored in global variables. This however requires
both naming the structure to pass it around functions, and accessing it
from various locations in the omapdss driver. While we could implement
get and set functions for every field that needs to be accessed outside
of dss.c, that would introduce overhead and complexity that we could
avoid by exposing the structure to internal components of the omapdss
driver. Do so to prepare for removal of global variables.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dss.c | 29 +
 drivers/gpu/drm/omapdrm/dss/dss.h | 29 +
 2 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index d5490336e7c7..245d8c0ae461 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -48,8 +48,6 @@
 #include "omapdss.h"
 #include "dss.h"
 
-#define DSS_SZ_REGSSZ_512
-
 struct dss_reg {
u16 idx;
 };
@@ -90,32 +88,7 @@ struct dss_features {
bool has_lcd_clk_src;
 };
 
-static struct {
-   struct platform_device *pdev;
-   void __iomem*base;
-   struct regmap   *syscon_pll_ctrl;
-   u32 syscon_pll_ctrl_offset;
-
-   struct clk  *parent_clk;
-   struct clk  *dss_clk;
-   unsigned long   dss_clk_rate;
-
-   unsigned long   cache_req_pck;
-   unsigned long   cache_prate;
-   struct dispc_clock_info cache_dispc_cinfo;
-
-   enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
-   enum dss_clk_source dispc_clk_source;
-   enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
-
-   boolctx_valid;
-   u32 ctx[DSS_SZ_REGS / sizeof(u32)];
-
-   const struct dss_features *feat;
-
-   struct dss_pll  *video1_pll;
-   struct dss_pll  *video2_pll;
-} dss;
+static struct dss_device dss;
 
 static const char * const dss_generic_clk_source_names[] = {
[DSS_CLK_SRC_FCK]   = "FCK",
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h 
b/drivers/gpu/drm/omapdrm/dss/dss.h
index 7f3fa5330408..257ff7c62764 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -235,6 +235,35 @@ struct dss_lcd_mgr_config {
 struct seq_file;
 struct platform_device;
 
+#define DSS_SZ_REGSSZ_512
+
+struct dss_device {
+   struct platform_device *pdev;
+   void __iomem*base;
+   struct regmap   *syscon_pll_ctrl;
+   u32 syscon_pll_ctrl_offset;
+
+   struct clk  *parent_clk;
+   struct clk  *dss_clk;
+   unsigned long   dss_clk_rate;
+
+   unsigned long   cache_req_pck;
+   unsigned long   cache_prate;
+   struct dispc_clock_info cache_dispc_cinfo;
+
+   enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
+   enum dss_clk_source dispc_clk_source;
+   enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
+
+   boolctx_valid;
+   u32 ctx[DSS_SZ_REGS / sizeof(u32)];
+
+   const struct dss_features *feat;
+
+   struct dss_pll  *video1_pll;
+   struct dss_pll  *video2_pll;
+};
+
 /* core */
 static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
 {
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 09/30] drm: omapdrm: dss: Pass DSS pointer to remaining dss functions

2018-02-13 Thread Laurent Pinchart
This removes the need to access the global DSS private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DSS device dynamically).

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dispc.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/dss.c   |  9 +
 drivers/gpu/drm/omapdrm/dss/dss.h   |  7 ---
 drivers/gpu/drm/omapdrm/dss/venc.c  | 11 +++
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 8d0de1b790b7..867887151565 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -2733,7 +2733,7 @@ static int dispc_ovl_enable(enum omap_plane_id plane, 
bool enable)
 
 static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum 
omap_channel channel)
 {
-   return dss_get_supported_outputs(channel);
+   return dss_get_supported_outputs(dispc.dss, channel);
 }
 
 static void dispc_lcd_enable_signal_polarity(bool act_high)
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 0d292da6757d..7820b04c43e2 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -666,9 +666,10 @@ unsigned long dss_get_max_fck_rate(struct dss_device *dss)
return dss->feat->fck_freq_max;
 }
 
-enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel)
+enum omap_dss_output_id dss_get_supported_outputs(struct dss_device *dss,
+ enum omap_channel channel)
 {
-   return dss.feat->outputs[channel];
+   return dss->feat->outputs[channel];
 }
 
 static int dss_setup_default_clock(void)
@@ -697,7 +698,7 @@ static int dss_setup_default_clock(void)
return 0;
 }
 
-void dss_set_venc_output(enum omap_dss_venc_type type)
+void dss_set_venc_output(struct dss_device *dss, enum omap_dss_venc_type type)
 {
int l = 0;
 
@@ -712,7 +713,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type)
REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
 }
 
-void dss_set_dac_pwrdn_bgz(bool enable)
+void dss_set_dac_pwrdn_bgz(struct dss_device *dss, bool enable)
 {
REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h 
b/drivers/gpu/drm/omapdrm/dss/dss.h
index 1d0edf2d145e..89d708e8e970 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -299,7 +299,8 @@ void dss_runtime_put(struct dss_device *dss);
 
 unsigned long dss_get_dispc_clk_rate(struct dss_device *dss);
 unsigned long dss_get_max_fck_rate(struct dss_device *dss);
-enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel);
+enum omap_dss_output_id dss_get_supported_outputs(struct dss_device *dss,
+ enum omap_channel channel);
 int dss_dpi_select_source(struct dss_device *dss, int port,
  enum omap_channel channel);
 void dss_select_hdmi_venc_clk_source(struct dss_device *dss,
@@ -329,8 +330,8 @@ enum dss_clk_source dss_get_dsi_clk_source(struct 
dss_device *dss,
 enum dss_clk_source dss_get_lcd_clk_source(struct dss_device *dss,
   enum omap_channel channel);
 
-void dss_set_venc_output(enum omap_dss_venc_type type);
-void dss_set_dac_pwrdn_bgz(bool enable);
+void dss_set_venc_output(struct dss_device *dss, enum omap_dss_venc_type type);
+void dss_set_dac_pwrdn_bgz(struct dss_device *dss, bool enable);
 
 int dss_set_fck_rate(struct dss_device *dss, unsigned long rate);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 6de9d734ddb9..08bae18be188 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -325,6 +325,7 @@ static struct {
struct mutex venc_lock;
u32 wss_data;
struct regulator *vdda_dac_reg;
+   struct dss_device *dss;
 
struct clk  *tv_dac_clk;
 
@@ -468,8 +469,8 @@ static int venc_power_on(struct omap_dss_device *dssdev)
venc_reset();
venc_write_config(venc_timings_to_config(&venc.vm));
 
-   dss_set_venc_output(venc.type);
-   dss_set_dac_pwrdn_bgz(1);
+   dss_set_venc_output(venc.dss, venc.type);
+   dss_set_dac_pwrdn_bgz(venc.dss, 1);
 
l = 0;
 
@@ -499,7 +500,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
regulator_disable(venc.vdda_dac_reg);
 err1:
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
-   dss_set_dac_pwrdn_bgz(0);
+   dss_set_dac_pwrdn_bgz(venc.dss, 0);
 
venc_runtime_put();
 err0:
@@ -511,7 +512,7 @@ static void venc_power_off(struct omap_dss_device *dssdev)
enum omap_channel channel = dssdev->dispc_channel;
 
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
-   dss_set_dac_pwrdn_bgz(0);
+   dss_set_dac_

[PATCH v2 07/30] drm: omapdrm: dss: Pass DSS pointer to dss_get_*_clk_source()

2018-02-13 Thread Laurent Pinchart
This removes the need to access the global DSS private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DSS device dynamically).

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dispc.c | 11 +++
 drivers/gpu/drm/omapdrm/dss/dsi.c   |  8 +---
 drivers/gpu/drm/omapdrm/dss/dss.c   | 18 ++
 drivers/gpu/drm/omapdrm/dss/dss.h   |  8 +---
 4 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 86d18f2d48ba..048b2e4d1f40 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -165,6 +165,7 @@ struct dispc_features {
 static struct {
struct platform_device *pdev;
void __iomem*base;
+   struct dss_device *dss;
 
int irq;
irq_handler_t user_handler;
@@ -3112,7 +3113,7 @@ static unsigned long dispc_fclk_rate(void)
unsigned long r;
enum dss_clk_source src;
 
-   src = dss_get_dispc_clk_source();
+   src = dss_get_dispc_clk_source(dispc.dss);
 
if (src == DSS_CLK_SRC_FCK) {
r = dss_get_dispc_clk_rate();
@@ -3139,7 +3140,7 @@ static unsigned long dispc_mgr_lclk_rate(enum 
omap_channel channel)
if (!dss_mgr_is_lcd(channel))
return dispc_fclk_rate();
 
-   src = dss_get_lcd_clk_source(channel);
+   src = dss_get_lcd_clk_source(dispc.dss, channel);
 
if (src == DSS_CLK_SRC_FCK) {
r = dss_get_dispc_clk_rate();
@@ -3219,7 +3220,7 @@ static void dispc_dump_clocks_channel(struct seq_file *s, 
enum omap_channel chan
 
seq_printf(s, "- %s -\n", mgr_desc[channel].name);
 
-   lcd_clk_src = dss_get_lcd_clk_source(channel);
+   lcd_clk_src = dss_get_lcd_clk_source(dispc.dss, channel);
 
seq_printf(s, "%s clk source = %s\n", mgr_desc[channel].name,
dss_get_clk_source_name(lcd_clk_src));
@@ -3236,7 +3237,7 @@ void dispc_dump_clocks(struct seq_file *s)
 {
int lcd;
u32 l;
-   enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
+   enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(dispc.dss);
 
if (dispc_runtime_get())
return;
@@ -4549,12 +4550,14 @@ static int dispc_bind(struct device *dev, struct device 
*master, void *data)
 {
struct platform_device *pdev = to_platform_device(dev);
const struct soc_device_attribute *soc;
+   struct dss_device *dss = dss_get_device(master);
u32 rev;
int r = 0;
struct resource *dispc_mem;
struct device_node *np = pdev->dev.of_node;
 
dispc.pdev = pdev;
+   dispc.dss = dss;
 
spin_lock_init(&dispc.control_lock);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 71f86a5d4029..26f4122f6784 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -1286,8 +1286,10 @@ static unsigned long dsi_fclk_rate(struct 
platform_device *dsidev)
 {
unsigned long r;
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   enum dss_clk_source source;
 
-   if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) {
+   source = dss_get_dsi_clk_source(dsi->dss, dsi->module_id);
+   if (source == DSS_CLK_SRC_FCK) {
/* DSI FCLK source is DSS_CLK_FCK */
r = clk_get_rate(dsi->dss_clk);
} else {
@@ -1506,8 +1508,8 @@ static void dsi_dump_dsidev_clocks(struct platform_device 
*dsidev,
int dsi_module = dsi->module_id;
struct dss_pll *pll = &dsi->pll;
 
-   dispc_clk_src = dss_get_dispc_clk_source();
-   dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
+   dispc_clk_src = dss_get_dispc_clk_source(dsi->dss);
+   dsi_clk_src = dss_get_dsi_clk_source(dsi->dss, dsi_module);
 
if (dsi_runtime_get(dsidev))
return;
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 73698a497e4a..bdf8f66002b6 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -570,25 +570,27 @@ void dss_select_lcd_clk_source(struct dss_device *dss,
dss->lcd_clk_source[idx] = clk_src;
 }
 
-enum dss_clk_source dss_get_dispc_clk_source(void)
+enum dss_clk_source dss_get_dispc_clk_source(struct dss_device *dss)
 {
-   return dss.dispc_clk_source;
+   return dss->dispc_clk_source;
 }
 
-enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
+enum dss_clk_source dss_get_dsi_clk_source(struct dss_device *dss,
+  int dsi_module)
 {
-   return dss.dsi_clk_source[dsi_module];
+   return dss->dsi_clk_source[dsi_module];
 }
 
-enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
+enum dss_clk_source dss_get_lcd_clk_source(

[PATCH v2 11/30] drm: omapdrm: dss: Support passing private data to debugfs show handlers

2018-02-13 Thread Laurent Pinchart
To simplify implementation of debugfs seq_file show handlers, the driver
passes the pointer to the show function through the debugfs_create_file
data pointer. This prevents using the pointer to pass driver private
data to the show handler, and requires all handlers to use global
variables to access private data.

To prepare for the removal of global private data in the driver, rework
the debugfs infrastructure to allow passing a private data pointer to
show handlers.

The price to pay is explicit removal of debugfs files to free the
internally allocated memory. This is desirable anyway as debugfs entries
should be removed when a component driver is unbound, otherwise crashes
will occur due to access to freed memory when the components will be
dynamically allocated instead of stored in global variables.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
Changes since v1:

- Removed unneeded declaration of struct dentry in dss.h
- Removed DSS debugfs files in driver remove handler
---
 drivers/gpu/drm/omapdrm/dss/dispc.c | 13 --
 drivers/gpu/drm/omapdrm/dss/dsi.c   | 40 -
 drivers/gpu/drm/omapdrm/dss/dss.c   | 89 -
 drivers/gpu/drm/omapdrm/dss/dss.h   | 31 -
 drivers/gpu/drm/omapdrm/dss/hdmi.h  |  2 +
 drivers/gpu/drm/omapdrm/dss/hdmi4.c |  9 ++--
 drivers/gpu/drm/omapdrm/dss/hdmi5.c |  9 ++--
 drivers/gpu/drm/omapdrm/dss/venc.c  | 11 +++--
 8 files changed, 141 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 867887151565..3428ffea70ee 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -167,6 +167,8 @@ static struct {
void __iomem*base;
struct dss_device *dss;
 
+   struct dss_debugfs_entry *debugfs;
+
int irq;
irq_handler_t user_handler;
void *user_data;
@@ -3268,7 +3270,7 @@ void dispc_dump_clocks(struct seq_file *s)
dispc_runtime_put();
 }
 
-static void dispc_dump_regs(struct seq_file *s)
+static int dispc_dump_regs(struct seq_file *s, void *p)
 {
int i, j;
const char *mgr_names[] = {
@@ -3289,7 +3291,7 @@ static void dispc_dump_regs(struct seq_file *s)
 #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
 
if (dispc_runtime_get())
-   return;
+   return 0;
 
/* DISPC common registers */
DUMPREG(DISPC_REVISION);
@@ -3461,6 +3463,8 @@ static void dispc_dump_regs(struct seq_file *s)
 
 #undef DISPC_REG
 #undef DUMPREG
+
+   return 0;
 }
 
 /* calculate clock rates using dividers in cinfo */
@@ -4620,7 +4624,8 @@ static int dispc_bind(struct device *dev, struct device 
*master, void *data)
 
dispc_set_ops(&dispc_ops);
 
-   dss_debugfs_create_file("dispc", dispc_dump_regs);
+   dispc.debugfs = dss_debugfs_create_file("dispc", dispc_dump_regs,
+   &dispc);
 
return 0;
 
@@ -4632,6 +4637,8 @@ static int dispc_bind(struct device *dev, struct device 
*master, void *data)
 static void dispc_unbind(struct device *dev, struct device *master,
   void *data)
 {
+   dss_debugfs_remove_file(dispc.debugfs);
+
dispc_set_ops(NULL);
 
pm_runtime_disable(dev);
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 26f4122f6784..a676d27dd479 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -401,6 +401,10 @@ struct dsi_data {
 #endif
int debug_read;
int debug_write;
+   struct {
+   struct dss_debugfs_entry *irqs;
+   struct dss_debugfs_entry *regs;
+   } debugfs;
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
spinlock_t irq_stats_lock;
@@ -1660,18 +1664,20 @@ static void dsi_dump_dsidev_irqs(struct platform_device 
*dsidev,
 #undef PIS
 }
 
-static void dsi1_dump_irqs(struct seq_file *s)
+static int dsi1_dump_irqs(struct seq_file *s, void *p)
 {
struct platform_device *dsidev = dsi_get_dsidev_from_id(0);
 
dsi_dump_dsidev_irqs(dsidev, s);
+   return 0;
 }
 
-static void dsi2_dump_irqs(struct seq_file *s)
+static int dsi2_dump_irqs(struct seq_file *s, void *p)
 {
struct platform_device *dsidev = dsi_get_dsidev_from_id(1);
 
dsi_dump_dsidev_irqs(dsidev, s);
+   return 0;
 }
 #endif
 
@@ -1759,18 +1765,20 @@ static void dsi_dump_dsidev_regs(struct platform_device 
*dsidev,
 #undef DUMPREG
 }
 
-static void dsi1_dump_regs(struct seq_file *s)
+static int dsi1_dump_regs(struct seq_file *s, void *p)
 {
struct platform_device *dsidev = dsi_get_dsidev_from_id(0);
 
dsi_dump_dsidev_regs(dsidev, s);
+   return 0;
 }
 
-static void dsi2_dump_regs(struct seq_file *s)
+static int dsi2_dump_regs(struct seq_file *s, void *p)
 {
struct platform_device *dsidev = dsi_get_dsidev_from_id(1);

[PATCH v2 10/30] drm: omapdrm: dss: Allocate the DSS private data structure dynamically

2018-02-13 Thread Laurent Pinchart
The DSS private data structure is currently stored as a global variable.
While no platform with multiple DSS devices currently exists nor is
planned, this doesn't comply with the kernel device model and should
thus be fixed.

Allocate the DSS private data structure dynamically for each DSS
instance and remove the global variable. All code that need access to
the structure now retrieves it dynamically so we can remove the global
variable.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
Changes since v1:

- Wrap lines at 80 columns limit
---
 drivers/gpu/drm/omapdrm/dss/dss.c | 341 +-
 1 file changed, 186 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 7820b04c43e2..4b00faa1a8cc 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -62,11 +62,12 @@ struct dss_reg {
 #define DSS_PLL_CONTROLDSS_REG(0x0048)
 #define DSS_SDI_STATUS DSS_REG(0x005C)
 
-#define REG_GET(idx, start, end) \
-   FLD_GET(dss_read_reg(idx), start, end)
+#define REG_GET(dss, idx, start, end) \
+   FLD_GET(dss_read_reg(dss, idx), start, end)
 
-#define REG_FLD_MOD(idx, val, start, end) \
-   dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
+#define REG_FLD_MOD(dss, idx, val, start, end) \
+   dss_write_reg(dss, idx, \
+ FLD_MOD(dss_read_reg(dss, idx), val, start, end))
 
 struct dss_ops {
int (*dpi_select_source)(struct dss_device *dss, int port,
@@ -90,8 +91,6 @@ struct dss_features {
bool has_lcd_clk_src;
 };
 
-static struct dss_device dss;
-
 static const char * const dss_generic_clk_source_names[] = {
[DSS_CLK_SRC_FCK]   = "FCK",
[DSS_CLK_SRC_PLL1_1]= "PLL1:1",
@@ -103,49 +102,50 @@ static const char * const dss_generic_clk_source_names[] 
= {
[DSS_CLK_SRC_HDMI_PLL]  = "HDMI PLL",
 };
 
-static inline void dss_write_reg(const struct dss_reg idx, u32 val)
+static inline void dss_write_reg(struct dss_device *dss,
+const struct dss_reg idx, u32 val)
 {
-   __raw_writel(val, dss.base + idx.idx);
+   __raw_writel(val, dss->base + idx.idx);
 }
 
-static inline u32 dss_read_reg(const struct dss_reg idx)
+static inline u32 dss_read_reg(struct dss_device *dss, const struct dss_reg 
idx)
 {
-   return __raw_readl(dss.base + idx.idx);
+   return __raw_readl(dss->base + idx.idx);
 }
 
-#define SR(reg) \
-   dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
-#define RR(reg) \
-   dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
+#define SR(dss, reg) \
+   dss->ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(dss, DSS_##reg)
+#define RR(dss, reg) \
+   dss_write_reg(dss, DSS_##reg, dss->ctx[(DSS_##reg).idx / sizeof(u32)])
 
-static void dss_save_context(void)
+static void dss_save_context(struct dss_device *dss)
 {
DSSDBG("dss_save_context\n");
 
-   SR(CONTROL);
+   SR(dss, CONTROL);
 
-   if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
-   SR(SDI_CONTROL);
-   SR(PLL_CONTROL);
+   if (dss->feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
+   SR(dss, SDI_CONTROL);
+   SR(dss, PLL_CONTROL);
}
 
-   dss.ctx_valid = true;
+   dss->ctx_valid = true;
 
DSSDBG("context saved\n");
 }
 
-static void dss_restore_context(void)
+static void dss_restore_context(struct dss_device *dss)
 {
DSSDBG("dss_restore_context\n");
 
-   if (!dss.ctx_valid)
+   if (!dss->ctx_valid)
return;
 
-   RR(CONTROL);
+   RR(dss, CONTROL);
 
-   if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
-   RR(SDI_CONTROL);
-   RR(PLL_CONTROL);
+   if (dss->feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
+   RR(dss, SDI_CONTROL);
+   RR(dss, PLL_CONTROL);
}
 
DSSDBG("context restored\n");
@@ -184,12 +184,13 @@ void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable)
   1 << shift, val << shift);
 }
 
-static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
-   enum omap_channel channel)
+static int dss_ctrl_pll_set_control_mux(struct dss_device *dss,
+   enum dss_clk_source clk_src,
+   enum omap_channel channel)
 {
unsigned int shift, val;
 
-   if (!dss.syscon_pll_ctrl)
+   if (!dss->syscon_pll_ctrl)
return -EINVAL;
 
switch (channel) {
@@ -244,7 +245,7 @@ static int dss_ctrl_pll_set_control_mux(enum dss_clk_source 
clk_src,
return -EINVAL;
}
 
-   regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
+   regmap_update_bits(ds

[PATCH v2 17/30] drm: omapdrm: dsi: Use dev pointer directly in dsi_bind() function

2018-02-13 Thread Laurent Pinchart
The dsi_bind() function receives a pointer to a struct device that it
casts to a struct platform_device, only to use the platform device's dev
field through the code. Use the dev pointer directly.

While at it rename the struct platform_device pointer dsidev to pdev to
make it more explicit.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index cb250dbf0f9b..62131d7593a7 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5299,9 +5299,10 @@ static const struct soc_device_attribute 
dsi_soc_devices[] = {
{ .machine = "AM35*",   .data = &dsi_of_data_omap34xx },
{ /* sentinel */ }
 };
+
 static int dsi_bind(struct device *dev, struct device *master, void *data)
 {
-   struct platform_device *dsidev = to_platform_device(dev);
+   struct platform_device *pdev = to_platform_device(dev);
struct dss_device *dss = dss_get_device(master);
const struct soc_device_attribute *soc;
const struct dsi_module_id_data *d;
@@ -5311,13 +5312,13 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
struct resource *dsi_mem;
struct resource *res;
 
-   dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
+   dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
return -ENOMEM;
 
dsi->dss = dss;
-   dsi->pdev = dsidev;
-   dev_set_drvdata(&dsidev->dev, dsi);
+   dsi->pdev = pdev;
+   dev_set_drvdata(dev, dsi);
 
spin_lock_init(&dsi->irq_lock);
spin_lock_init(&dsi->errors_lock);
@@ -5338,29 +5339,29 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
timer_setup(&dsi->te_timer, dsi_te_timeout, 0);
 #endif
 
-   dsi_mem = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto");
-   dsi->proto_base = devm_ioremap_resource(&dsidev->dev, dsi_mem);
+   dsi_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "proto");
+   dsi->proto_base = devm_ioremap_resource(dev, dsi_mem);
if (IS_ERR(dsi->proto_base))
return PTR_ERR(dsi->proto_base);
 
-   res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "phy");
-   dsi->phy_base = devm_ioremap_resource(&dsidev->dev, res);
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
+   dsi->phy_base = devm_ioremap_resource(dev, res);
if (IS_ERR(dsi->phy_base))
return PTR_ERR(dsi->phy_base);
 
-   res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "pll");
-   dsi->pll_base = devm_ioremap_resource(&dsidev->dev, res);
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
+   dsi->pll_base = devm_ioremap_resource(dev, res);
if (IS_ERR(dsi->pll_base))
return PTR_ERR(dsi->pll_base);
 
-   dsi->irq = platform_get_irq(dsi->pdev, 0);
+   dsi->irq = platform_get_irq(pdev, 0);
if (dsi->irq < 0) {
DSSERR("platform_get_irq failed\n");
return -ENODEV;
}
 
-   r = devm_request_irq(&dsidev->dev, dsi->irq, omap_dsi_irq_handler,
-IRQF_SHARED, dev_name(&dsidev->dev), dsi);
+   r = devm_request_irq(dev, dsi->irq, omap_dsi_irq_handler,
+IRQF_SHARED, dev_name(dev), dsi);
if (r < 0) {
DSSERR("request_irq failed\n");
return r;
@@ -5414,14 +5415,14 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
 
dsi_init_pll_data(dss, dsi);
 
-   pm_runtime_enable(&dsidev->dev);
+   pm_runtime_enable(dev);
 
r = dsi_runtime_get(dsi);
if (r)
goto err_runtime_get;
 
rev = dsi_read_reg(dsi, DSI_REVISION);
-   dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
+   dev_dbg(dev, "OMAP DSI rev %d.%d\n",
   FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
 
/* DSI on OMAP3 doesn't have register DSI_GNQ, set number
@@ -5442,7 +5443,7 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
goto err_probe_of;
}
 
-   r = of_platform_populate(dsidev->dev.of_node, NULL, NULL, &dsidev->dev);
+   r = of_platform_populate(dev->of_node, NULL, NULL, dev);
if (r)
DSSERR("Failed to populate DSI child devices: %d\n", r);
 
@@ -5474,7 +5475,7 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
dsi_runtime_put(dsi);
 
 err_runtime_get:
-   pm_runtime_disable(&dsidev->dev);
+   pm_runtime_disable(dev);
return r;
 }
 
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel

[PATCH v2 06/30] drm: omapdrm: dss: Pass DSS pointer to dss_ops operations

2018-02-13 Thread Laurent Pinchart
This removes the need to access the global DSS private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DSS device dynamically).

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c   | 12 ---
 drivers/gpu/drm/omapdrm/dss/dsi.c   | 18 +-
 drivers/gpu/drm/omapdrm/dss/dss.c   | 68 ++---
 drivers/gpu/drm/omapdrm/dss/dss.h   | 25 --
 drivers/gpu/drm/omapdrm/dss/hdmi.h  |  1 +
 drivers/gpu/drm/omapdrm/dss/hdmi4.c |  3 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c |  3 +-
 7 files changed, 77 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 0a6eb39be444..e7f50fabca6f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -38,6 +38,7 @@
 struct dpi_data {
struct platform_device *pdev;
enum dss_model dss_model;
+   struct dss_device *dss;
 
struct regulator *vdds_dsi_reg;
enum dss_clk_source clk_src;
@@ -302,7 +303,7 @@ static int dpi_set_pll_clk(struct dpi_data *dpi, enum 
omap_channel channel,
if (r)
return r;
 
-   dss_select_lcd_clk_source(channel, dpi->clk_src);
+   dss_select_lcd_clk_source(dpi->dss, channel, dpi->clk_src);
 
dpi->mgr_config.clock_info = ctx.dispc_cinfo;
 
@@ -412,7 +413,7 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err_get_dispc;
 
-   r = dss_dpi_select_source(out->port_num, channel);
+   r = dss_dpi_select_source(dpi->dss, out->port_num, channel);
if (r)
goto err_src_sel;
 
@@ -464,7 +465,7 @@ static void dpi_display_disable(struct omap_dss_device 
*dssdev)
dss_mgr_disable(channel);
 
if (dpi->pll) {
-   dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
+   dss_select_lcd_clk_source(dpi->dss, channel, DSS_CLK_SRC_FCK);
dss_pll_disable(dpi->pll);
}
 
@@ -748,8 +749,8 @@ static void dpi_uninit_output_port(struct device_node *port)
omapdss_unregister_output(out);
 }
 
-int dpi_init_port(struct platform_device *pdev, struct device_node *port,
- enum dss_model dss_model)
+int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
+ struct device_node *port, enum dss_model dss_model)
 {
struct dpi_data *dpi;
struct device_node *ep;
@@ -776,6 +777,7 @@ int dpi_init_port(struct platform_device *pdev, struct 
device_node *port,
 
dpi->pdev = pdev;
dpi->dss_model = dss_model;
+   dpi->dss = dss;
port->data = dpi;
 
mutex_init(&dpi->lock);
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 7ba33fc5d245..71f86a5d4029 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -343,6 +343,7 @@ struct dsi_data {
 
struct clk *dss_clk;
struct regmap *syscon;
+   struct dss_device *dss;
 
struct dispc_clock_info user_dispc_cinfo;
struct dss_pll_clock_info user_dsi_cinfo;
@@ -4206,7 +4207,7 @@ static int dsi_display_init_dispc(struct platform_device 
*dsidev,
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
 
-   dss_select_lcd_clk_source(channel, dsi->module_id == 0 ?
+   dss_select_lcd_clk_source(dsi->dss, channel, dsi->module_id == 0 ?
DSS_CLK_SRC_PLL1_1 :
DSS_CLK_SRC_PLL2_1);
 
@@ -4260,7 +4261,7 @@ static int dsi_display_init_dispc(struct platform_device 
*dsidev,
dss_mgr_unregister_framedone_handler(channel,
dsi_framedone_irq_callback, dsidev);
 err:
-   dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
+   dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
return r;
 }
 
@@ -4273,7 +4274,7 @@ static void dsi_display_uninit_dispc(struct 
platform_device *dsidev,
dss_mgr_unregister_framedone_handler(channel,
dsi_framedone_irq_callback, dsidev);
 
-   dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
+   dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
 }
 
 static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
@@ -4306,9 +4307,9 @@ static int dsi_display_init_dsi(struct platform_device 
*dsidev)
if (r)
goto err1;
 
-   dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ?
-   DSS_CLK_SRC_PLL1_2 :
-   DSS_CLK_SRC_PLL2_2);
+   dss_select_dsi_clk_source(dsi->dss, dsi->module_id,
+ dsi->module_id == 0 ?
+ DSS_CLK_SRC_PLL1_2 : DSS_CLK_SRC_PLL2_2);
 
DSSDBG("PLL OK\n");
 
@@ -4340,7 +4341,7 @@ static in

[PATCH v2 12/30] drm: omapdrm: dss: Store the registered plls array in struct dss_device

2018-02-13 Thread Laurent Pinchart
As part of an effort to remove the usage of global variables in the
driver, store the registered plls array in the dss_device structure
instead of a global variable.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dispc.c |  4 ++--
 drivers/gpu/drm/omapdrm/dss/dpi.c   | 17 +++---
 drivers/gpu/drm/omapdrm/dss/dsi.c   |  3 +--
 drivers/gpu/drm/omapdrm/dss/dss.h   |  8 ---
 drivers/gpu/drm/omapdrm/dss/hdmi_pll.c  |  3 +--
 drivers/gpu/drm/omapdrm/dss/pll.c   | 40 +
 drivers/gpu/drm/omapdrm/dss/video-pll.c |  3 +--
 7 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 3428ffea70ee..285d297db229 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -3123,7 +3123,7 @@ static unsigned long dispc_fclk_rate(void)
struct dss_pll *pll;
unsigned int clkout_idx;
 
-   pll = dss_pll_find_by_src(src);
+   pll = dss_pll_find_by_src(dispc.dss, src);
clkout_idx = dss_pll_get_clkout_idx_for_src(src);
 
r = pll->cinfo.clkout[clkout_idx];
@@ -3150,7 +3150,7 @@ static unsigned long dispc_mgr_lclk_rate(enum 
omap_channel channel)
struct dss_pll *pll;
unsigned int clkout_idx;
 
-   pll = dss_pll_find_by_src(src);
+   pll = dss_pll_find_by_src(dispc.dss, src);
clkout_idx = dss_pll_get_clkout_idx_for_src(src);
 
r = pll->cinfo.clkout[clkout_idx];
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index ba5adfb7ee70..338ceb1ba61b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -58,7 +58,8 @@ static struct dpi_data *dpi_get_data_from_dssdev(struct 
omap_dss_device *dssdev)
return container_of(dssdev, struct dpi_data, output);
 }
 
-static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel)
+static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi,
+ enum omap_channel channel)
 {
/*
 * Possible clock sources:
@@ -70,23 +71,23 @@ static enum dss_clk_source dpi_get_clk_src_dra7xx(enum 
omap_channel channel)
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
{
-   if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_1))
+   if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_1))
return DSS_CLK_SRC_PLL1_1;
break;
}
case OMAP_DSS_CHANNEL_LCD2:
{
-   if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
+   if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
return DSS_CLK_SRC_PLL1_3;
-   if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_3))
+   if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_3))
return DSS_CLK_SRC_PLL2_3;
break;
}
case OMAP_DSS_CHANNEL_LCD3:
{
-   if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_1))
+   if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_1))
return DSS_CLK_SRC_PLL2_1;
-   if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
+   if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
return DSS_CLK_SRC_PLL1_3;
break;
}
@@ -133,7 +134,7 @@ static enum dss_clk_source dpi_get_clk_src(struct dpi_data 
*dpi)
}
 
case DSS_MODEL_DRA7:
-   return dpi_get_clk_src_dra7xx(channel);
+   return dpi_get_clk_src_dra7xx(dpi, channel);
 
default:
return DSS_CLK_SRC_FCK;
@@ -605,7 +606,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
 
dpi->clk_src = dpi_get_clk_src(dpi);
 
-   pll = dss_pll_find_by_src(dpi->clk_src);
+   pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src);
if (!pll)
return;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index a676d27dd479..448986031a6a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5353,9 +5353,8 @@ static int dsi_init_pll_data(struct dss_device *dss,
pll->base = dsi->pll_base;
pll->hw = dsi->data->pll_hw;
pll->ops = &dsi_pll_ops;
-   pll->dss = dss;
 
-   r = dss_pll_register(pll);
+   r = dss_pll_register(dss, pll);
if (r)
return r;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h 
b/drivers/gpu/drm/omapdrm/dss/dss.h
index ec8e40e09141..8cc4b6ca203e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -267,6 +267,7 @@ struct dss_device {
struct dss_debugfs_entry *dss;
} de

[PATCH v2 20/30] drm: omapdrm: dss: Pass omap_dss_device pointer to dss_mgr_*() functions

2018-02-13 Thread Laurent Pinchart
The dss_mgr_*() functions take a channel argument to identify the
channel they operate on. This prevents the functions from accessing
driver data structures without resorting to global variables. In an
effort to remove global variables, pass the omap_dss_device pointer
associated with the channel instead. This will be used to look up the
omap_drm_private data structure to pass to the dss_mgr_ops.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 32 ++
 drivers/gpu/drm/omapdrm/dss/dsi.c | 30 +++--
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   | 20 ++---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   | 20 ++---
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 22 +-
 drivers/gpu/drm/omapdrm/dss/output.c  | 42 ++-
 drivers/gpu/drm/omapdrm/dss/sdi.c | 28 +--
 drivers/gpu/drm/omapdrm/dss/venc.c| 18 +--
 8 files changed, 88 insertions(+), 124 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 338ceb1ba61b..e818e7836cbb 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -343,8 +343,6 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned 
long pck_req,
 
 static int dpi_set_mode(struct dpi_data *dpi)
 {
-   struct omap_dss_device *out = &dpi->output;
-   enum omap_channel channel = out->dispc_channel;
struct videomode *vm = &dpi->vm;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
@@ -352,8 +350,8 @@ static int dpi_set_mode(struct dpi_data *dpi)
int r = 0;
 
if (dpi->pll)
-   r = dpi_set_pll_clk(dpi, channel, vm->pixelclock, &fck,
-   &lck_div, &pck_div);
+   r = dpi_set_pll_clk(dpi, dpi->output.dispc_channel,
+   vm->pixelclock, &fck, &lck_div, &pck_div);
else
r = dpi_set_dispc_clk(dpi, vm->pixelclock, &fck,
&lck_div, &pck_div);
@@ -369,16 +367,13 @@ static int dpi_set_mode(struct dpi_data *dpi)
vm->pixelclock = pck;
}
 
-   dss_mgr_set_timings(channel, vm);
+   dss_mgr_set_timings(&dpi->output, vm);
 
return 0;
 }
 
 static void dpi_config_lcd_manager(struct dpi_data *dpi)
 {
-   struct omap_dss_device *out = &dpi->output;
-   enum omap_channel channel = out->dispc_channel;
-
dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
dpi->mgr_config.stallmode = false;
@@ -388,14 +383,13 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
 
dpi->mgr_config.lcden_sig_polarity = 0;
 
-   dss_mgr_set_lcd_config(channel, &dpi->mgr_config);
+   dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
 }
 
 static int dpi_display_enable(struct omap_dss_device *dssdev)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_dss_device *out = &dpi->output;
-   enum omap_channel channel = out->dispc_channel;
int r;
 
mutex_lock(&dpi->lock);
@@ -416,7 +410,7 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err_get_dispc;
 
-   r = dss_dpi_select_source(dpi->dss, out->port_num, channel);
+   r = dss_dpi_select_source(dpi->dss, out->port_num, out->dispc_channel);
if (r)
goto err_src_sel;
 
@@ -434,7 +428,7 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
 
mdelay(2);
 
-   r = dss_mgr_enable(channel);
+   r = dss_mgr_enable(&dpi->output);
if (r)
goto err_mgr_enable;
 
@@ -461,14 +455,14 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
 static void dpi_display_disable(struct omap_dss_device *dssdev)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
-   enum omap_channel channel = dpi->output.dispc_channel;
 
mutex_lock(&dpi->lock);
 
-   dss_mgr_disable(channel);
+   dss_mgr_disable(&dpi->output);
 
if (dpi->pll) {
-   dss_select_lcd_clk_source(dpi->dss, channel, DSS_CLK_SRC_FCK);
+   dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
+ DSS_CLK_SRC_FCK);
dss_pll_disable(dpi->pll);
}
 
@@ -658,7 +652,6 @@ static int dpi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
-   enum omap_channel channel = dpi->output.dispc_channel;
int r;
 
r = dpi_init_regulator(dpi);
@@ -667,7 +660,7 @@ static int dpi_connect(struct omap_dss_device *dssdev,
 
dpi_init_pll(dpi);
 
-   r = dss_mgr_connect(channel, dssdev);
+   r = dss_mgr_connect(&dpi->output, dssdev);
if (r)
  

[PATCH v2 13/30] drm: omapdrm: dss: Store the debugfs root directory in struct dss_device

2018-02-13 Thread Laurent Pinchart
As part of an effort to remove the usage of global variables in the
driver, store the debugfs root directory in the dss_device structure
instead of a global variable.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
Changes since v1:

- Remove static keyword from dss_initialize_debugfs() local variable
- Remove NULL check before debugfs_remove_recursive()
---
 drivers/gpu/drm/omapdrm/dss/dispc.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c   |  8 
 drivers/gpu/drm/omapdrm/dss/dss.c   | 38 ++---
 drivers/gpu/drm/omapdrm/dss/dss.h   |  9 ++---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c |  3 ++-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c |  3 ++-
 drivers/gpu/drm/omapdrm/dss/venc.c  |  3 ++-
 7 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 285d297db229..8019cc9f4f97 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -4624,7 +4624,7 @@ static int dispc_bind(struct device *dev, struct device 
*master, void *data)
 
dispc_set_ops(&dispc_ops);
 
-   dispc.debugfs = dss_debugfs_create_file("dispc", dispc_dump_regs,
+   dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs,
&dispc);
 
return 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 448986031a6a..05030dc25c72 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5576,20 +5576,20 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
dsi_runtime_put(dsidev);
 
if (dsi->module_id == 0)
-   dsi->debugfs.regs = dss_debugfs_create_file("dsi1_regs",
+   dsi->debugfs.regs = dss_debugfs_create_file(dss, "dsi1_regs",
dsi1_dump_regs,
&dsi);
else
-   dsi->debugfs.regs = dss_debugfs_create_file("dsi2_regs",
+   dsi->debugfs.regs = dss_debugfs_create_file(dss, "dsi2_regs",
dsi2_dump_regs,
&dsi);
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
if (dsi->module_id == 0)
-   dsi->debugfs.irqs = dss_debugfs_create_file("dsi1_irqs",
+   dsi->debugfs.irqs = dss_debugfs_create_file(dss, "dsi1_irqs",
dsi1_dump_irqs,
&dsi);
else
-   dsi->debugfs.irqs = dss_debugfs_create_file("dsi2_irqs",
+   dsi->debugfs.irqs = dss_debugfs_create_file(dss, "dsi2_irqs",
dsi2_dump_irqs,
&dsi);
 #endif
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 14a86e2c6d83..7a5f5f233ad0 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -901,25 +901,22 @@ static int dss_debug_dump_clocks(struct seq_file *s, void 
*p)
return 0;
 }
 
-static struct dentry *dss_debugfs_dir;
-
 static int dss_initialize_debugfs(struct dss_device *dss)
 {
-   dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
-   if (IS_ERR(dss_debugfs_dir)) {
-   int err = PTR_ERR(dss_debugfs_dir);
+   struct dentry *dir;
 
-   dss_debugfs_dir = NULL;
-   return err;
-   }
+   dir = debugfs_create_dir("omapdss", NULL);
+   if (IS_ERR(dir))
+   return PTR_ERR(dir);
+
+   dss->debugfs.root = dir;
 
return 0;
 }
 
-static void dss_uninitialize_debugfs(void)
+static void dss_uninitialize_debugfs(struct dss_device *dss)
 {
-   if (dss_debugfs_dir)
-   debugfs_remove_recursive(dss_debugfs_dir);
+   debugfs_remove_recursive(dss->debugfs.root);
 }
 
 struct dss_debugfs_entry {
@@ -942,8 +939,10 @@ static const struct file_operations dss_debug_fops = {
.release= single_release,
 };
 
-struct dss_debugfs_entry *dss_debugfs_create_file(const char *name,
-   int (*show_fn)(struct seq_file *s, void *data), void *data)
+struct dss_debugfs_entry *
+dss_debugfs_create_file(struct dss_device *dss, const char *name,
+   int (*show_fn)(struct seq_file *s, void *data),
+   void *data)
 {
struct dss_debugfs_entry *entry;
struct dentry *d;
@@ -955,7 +954,7 @@ struct dss_debugfs_entry *dss_debugfs_create_file(const 
char *name,
entry->show_fn = show_fn;
entry->data = data;
 
-   d = debugfs_create_file(name, 0444, dss_debugfs_dir, entry,
+   d = debugfs_create_file(name, 0444, dss->debugfs.root

[PATCH v2 19/30] drm: omapdrm: dsi: Don't pass channel to dispc init/uninit functions

2018-02-13 Thread Laurent Pinchart
The dsi_display_init_dispc() and dsi_display_uninit_dispc() functions
take a channel argument that is reduntant as it is always identical to
the dsi->output.dispc_channel. Remove the argument and use the field
directly in the functions to avoid misuse.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index ecfdc6ef2500..0c4668e722b9 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -215,10 +215,8 @@ struct dsi_reg { u16 module; u16 idx; };
 typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
 struct dsi_data;
 
-static int dsi_display_init_dispc(struct dsi_data *dsi,
-   enum omap_channel channel);
-static void dsi_display_uninit_dispc(struct dsi_data *dsi,
-   enum omap_channel channel);
+static int dsi_display_init_dispc(struct dsi_data *dsi);
+static void dsi_display_uninit_dispc(struct dsi_data *dsi);
 
 static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
 
@@ -3845,7 +3843,7 @@ static int dsi_enable_video_output(struct omap_dss_device 
*dssdev, int channel)
return -ENODEV;
}
 
-   r = dsi_display_init_dispc(dsi, dispc_channel);
+   r = dsi_display_init_dispc(dsi);
if (r)
goto err_init_dispc;
 
@@ -3895,7 +3893,7 @@ static int dsi_enable_video_output(struct omap_dss_device 
*dssdev, int channel)
dsi_vc_enable(dsi, channel, false);
}
 err_pix_fmt:
-   dsi_display_uninit_dispc(dsi, dispc_channel);
+   dsi_display_uninit_dispc(dsi);
 err_init_dispc:
return r;
 }
@@ -3918,7 +3916,7 @@ static void dsi_disable_video_output(struct 
omap_dss_device *dssdev, int channel
 
dss_mgr_disable(dispc_channel);
 
-   dsi_display_uninit_dispc(dsi, dispc_channel);
+   dsi_display_uninit_dispc(dsi);
 }
 
 static void dsi_update_screen_dispc(struct dsi_data *dsi)
@@ -4104,9 +4102,9 @@ static int dsi_configure_dispc_clocks(struct dsi_data 
*dsi)
return 0;
 }
 
-static int dsi_display_init_dispc(struct dsi_data *dsi,
- enum omap_channel channel)
+static int dsi_display_init_dispc(struct dsi_data *dsi)
 {
+   enum omap_channel channel = dsi->output.dispc_channel;
int r;
 
dss_select_lcd_clk_source(dsi->dss, channel, dsi->module_id == 0 ?
@@ -4167,9 +4165,10 @@ static int dsi_display_init_dispc(struct dsi_data *dsi,
return r;
 }
 
-static void dsi_display_uninit_dispc(struct dsi_data *dsi,
-enum omap_channel channel)
+static void dsi_display_uninit_dispc(struct dsi_data *dsi)
 {
+   enum omap_channel channel = dsi->output.dispc_channel;
+
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
dss_mgr_unregister_framedone_handler(channel,
dsi_framedone_irq_callback, dsi);
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 25/30] drm: omapdrm: dispc: Pass DISPC pointer to remaining dispc API functions

2018-02-13 Thread Laurent Pinchart
This removes the need to access the global DISPC private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DISPC private data dynamically).

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dispc.c | 102 
 drivers/gpu/drm/omapdrm/dss/dpi.c   |  12 +++--
 drivers/gpu/drm/omapdrm/dss/dsi.c   |  22 
 drivers/gpu/drm/omapdrm/dss/dss.c   |  14 ++---
 drivers/gpu/drm/omapdrm/dss/dss.h   |  74 ++
 drivers/gpu/drm/omapdrm/dss/hdmi4.c |   4 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c |   4 +-
 drivers/gpu/drm/omapdrm/dss/sdi.c   |   9 ++--
 drivers/gpu/drm/omapdrm/dss/venc.c  |   2 +-
 9 files changed, 133 insertions(+), 110 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 6d8228f976f9..bd014bfc1cb6 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -704,7 +704,7 @@ static u32 dispc_mgr_get_sync_lost_irq(struct dispc_device 
*dispc,
return mgr_desc[channel].sync_lost_irq;
 }
 
-u32 dispc_wb_get_framedone_irq(void)
+u32 dispc_wb_get_framedone_irq(struct dispc_device *dispc)
 {
return DISPC_IRQ_FRAMEDONEWB;
 }
@@ -739,12 +739,12 @@ static void dispc_mgr_go(struct dispc_device *dispc, enum 
omap_channel channel)
mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
 }
 
-bool dispc_wb_go_busy(void)
+bool dispc_wb_go_busy(struct dispc_device *dispc)
 {
return REG_GET(DISPC_CONTROL2, 6, 6) == 1;
 }
 
-void dispc_wb_go(void)
+void dispc_wb_go(struct dispc_device *dispc)
 {
enum omap_plane_id plane = OMAP_DSS_WB;
bool enable, go;
@@ -1196,7 +1196,8 @@ static enum omap_channel dispc_ovl_get_channel_out(enum 
omap_plane_id plane)
}
 }
 
-void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
+void dispc_wb_set_channel_in(struct dispc_device *dispc,
+enum dss_writeback_channel channel)
 {
enum omap_plane_id plane = OMAP_DSS_WB;
 
@@ -1371,10 +1372,10 @@ static void dispc_init_fifos(void)
const bool use_fifomerge = false;
const bool manual_update = false;
 
-   dispc_ovl_compute_fifo_thresholds(i, &low, &high,
+   dispc_ovl_compute_fifo_thresholds(&dispc, i, &low, &high,
use_fifomerge, manual_update);
 
-   dispc_ovl_set_fifo_threshold(i, low, high);
+   dispc_ovl_set_fifo_threshold(&dispc, i, low, high);
}
 
if (dispc.feat->has_writeback) {
@@ -1382,10 +1383,11 @@ static void dispc_init_fifos(void)
const bool use_fifomerge = false;
const bool manual_update = false;
 
-   dispc_ovl_compute_fifo_thresholds(OMAP_DSS_WB, &low, &high,
-   use_fifomerge, manual_update);
+   dispc_ovl_compute_fifo_thresholds(&dispc, OMAP_DSS_WB,
+ &low, &high,
+ use_fifomerge, manual_update);
 
-   dispc_ovl_set_fifo_threshold(OMAP_DSS_WB, low, high);
+   dispc_ovl_set_fifo_threshold(&dispc, OMAP_DSS_WB, low, high);
}
 }
 
@@ -1402,13 +1404,14 @@ static u32 dispc_ovl_get_fifo_size(enum omap_plane_id 
plane)
return size;
 }
 
-void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
- u32 high)
+void dispc_ovl_set_fifo_threshold(struct dispc_device *dispc,
+ enum omap_plane_id plane,
+ u32 low, u32 high)
 {
u8 hi_start, hi_end, lo_start, lo_end;
u32 unit;
 
-   unit = dispc.feat->buffer_size_unit;
+   unit = dispc->feat->buffer_size_unit;
 
WARN_ON(low % unit != 0);
WARN_ON(high % unit != 0);
@@ -1436,12 +1439,12 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id 
plane, u32 low,
 * large for the preload field, set the threshold to the maximum value
 * that can be held by the preload register
 */
-   if (dispc_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
+   if (dispc_has_feature(FEAT_PRELOAD) && dispc->feat->set_max_preload &&
plane != OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));
 }
 
-void dispc_enable_fifomerge(bool enable)
+void dispc_enable_fifomerge(struct dispc_device *dispc, bool enable)
 {
if (!dispc_has_feature(FEAT_FIFO_MERGE)) {
WARN_ON(enable);
@@ -1452,15 +1455,16 @@ void dispc_enable_fifomerge(bool enable)
REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
 }
 
-void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
-   u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
-   bool manual_update)
+void dispc_ovl_

[PATCH v2 28/30] drm: omapdrm: hdmi5: Allocate the omap_hdmi data structure dynamically

2018-02-13 Thread Laurent Pinchart
The omap_hdmi private data structure is currently stored as a global
variable. While no platform with multiple HDMI5 encoders currently
exists nor is planned, this doesn't comply with the kernel device model
and should thus be fixed.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
Changes since v1:

- Fixed device name string that had been incorrectly modified
---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c | 364 +++-
 1 file changed, 196 insertions(+), 168 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index a83d70144f85..4a0178ab8016 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -46,15 +46,13 @@
 #include "hdmi5_core.h"
 #include "dss.h"
 
-static struct omap_hdmi hdmi;
-
-static int hdmi_runtime_get(void)
+static int hdmi_runtime_get(struct omap_hdmi *hdmi)
 {
int r;
 
DSSDBG("hdmi_runtime_get\n");
 
-   r = pm_runtime_get_sync(&hdmi.pdev->dev);
+   r = pm_runtime_get_sync(&hdmi->pdev->dev);
WARN_ON(r < 0);
if (r < 0)
return r;
@@ -62,19 +60,20 @@ static int hdmi_runtime_get(void)
return 0;
 }
 
-static void hdmi_runtime_put(void)
+static void hdmi_runtime_put(struct omap_hdmi *hdmi)
 {
int r;
 
DSSDBG("hdmi_runtime_put\n");
 
-   r = pm_runtime_put_sync(&hdmi.pdev->dev);
+   r = pm_runtime_put_sync(&hdmi->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
 }
 
 static irqreturn_t hdmi_irq_handler(int irq, void *data)
 {
-   struct hdmi_wp_data *wp = data;
+   struct omap_hdmi *hdmi = data;
+   struct hdmi_wp_data *wp = &hdmi->wp;
u32 irqstatus;
 
irqstatus = hdmi_wp_get_irqstatus(wp);
@@ -97,17 +96,17 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
 * setting the PHY to LDOON. To ignore those, we force the RXDET
 * line to 0 until the PHY power state has been changed.
 */
-   v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
+   v = hdmi_read_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
-   hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
+   hdmi_write_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
 
hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
HDMI_IRQ_LINK_DISCONNECT);
 
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
 
-   REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
+   REG_FLD_MOD(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
 
} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
@@ -118,69 +117,69 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int hdmi_init_regulator(void)
+static int hdmi_init_regulator(struct omap_hdmi *hdmi)
 {
struct regulator *reg;
 
-   if (hdmi.vdda_reg != NULL)
+   if (hdmi->vdda_reg != NULL)
return 0;
 
-   reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
+   reg = devm_regulator_get(&hdmi->pdev->dev, "vdda");
if (IS_ERR(reg)) {
DSSERR("can't get VDDA regulator\n");
return PTR_ERR(reg);
}
 
-   hdmi.vdda_reg = reg;
+   hdmi->vdda_reg = reg;
 
return 0;
 }
 
-static int hdmi_power_on_core(struct omap_dss_device *dssdev)
+static int hdmi_power_on_core(struct omap_hdmi *hdmi)
 {
int r;
 
-   r = regulator_enable(hdmi.vdda_reg);
+   r = regulator_enable(hdmi->vdda_reg);
if (r)
return r;
 
-   r = hdmi_runtime_get();
+   r = hdmi_runtime_get(hdmi);
if (r)
goto err_runtime_get;
 
/* Make selection of HDMI in DSS */
-   dss_select_hdmi_venc_clk_source(hdmi.dss, DSS_HDMI_M_PCLK);
+   dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK);
 
-   hdmi.core_enabled = true;
+   hdmi->core_enabled = true;
 
return 0;
 
 err_runtime_get:
-   regulator_disable(hdmi.vdda_reg);
+   regulator_disable(hdmi->vdda_reg);
 
return r;
 }
 
-static void hdmi_power_off_core(struct omap_dss_device *dssdev)
+static void hdmi_power_off_core(struct omap_hdmi *hdmi)
 {
-   hdmi.core_enabled = false;
+   hdmi->core_enabled = false;
 
-   hdmi_runtime_put();
-   regulator_disable(hdmi.vdda_reg);
+   hdmi_runtime_put(hdmi);
+   regulator_disable(hdmi->vdda_reg);
 }
 
-static int hdmi_power_on_full(struct omap_dss_device *dssdev)
+static int hdmi_power_on_full(struct omap_hdmi *hdmi)
 {
int r;
struct videomode *vm;
struct dss_pll_clock_info hdmi_cinfo = { 0 };
unsigned int pc;
 

[PATCH v2 15/30] drm: omapdrm: dsi: Pass the dsi_data pointer to internal functions

2018-02-13 Thread Laurent Pinchart
Internal dsi functions take a pointer to the DSI platform_device and
then cast it to a dsi_data pointer. That's pointless as the caller
already has the dsi_data pointer. Pass it directly instead of the
platform_device pointer.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 1228 +
 1 file changed, 564 insertions(+), 664 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 05030dc25c72..7b5656e6abbb 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -119,11 +119,11 @@ struct dsi_reg { u16 module; u16 idx; };
 #define DSI_PLL_CONFIGURATION1 DSI_REG(DSI_PLL, 0x000C)
 #define DSI_PLL_CONFIGURATION2 DSI_REG(DSI_PLL, 0x0010)
 
-#define REG_GET(dsidev, idx, start, end) \
-   FLD_GET(dsi_read_reg(dsidev, idx), start, end)
+#define REG_GET(dsi, idx, start, end) \
+   FLD_GET(dsi_read_reg(dsi, idx), start, end)
 
-#define REG_FLD_MOD(dsidev, idx, val, start, end) \
-   dsi_write_reg(dsidev, idx, FLD_MOD(dsi_read_reg(dsidev, idx), val, 
start, end))
+#define REG_FLD_MOD(dsi, idx, val, start, end) \
+   dsi_write_reg(dsi, idx, FLD_MOD(dsi_read_reg(dsi, idx), val, start, 
end))
 
 /* Global interrupts */
 #define DSI_IRQ_VC0(1 << 0)
@@ -213,13 +213,14 @@ struct dsi_reg { u16 module; u16 idx; };
 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
 
 typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
+struct dsi_data;
 
-static int dsi_display_init_dispc(struct platform_device *dsidev,
+static int dsi_display_init_dispc(struct dsi_data *dsi,
enum omap_channel channel);
-static void dsi_display_uninit_dispc(struct platform_device *dsidev,
+static void dsi_display_uninit_dispc(struct dsi_data *dsi,
enum omap_channel channel);
 
-static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
+static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
 
 /* DSI PLL HSDIV indices */
 #define HSDIV_DISPC0
@@ -282,7 +283,7 @@ struct dsi_isr_tables {
 };
 
 struct dsi_clk_calc_ctx {
-   struct platform_device *dsidev;
+   struct dsi_data *dsi;
struct dss_pll *pll;
 
/* inputs */
@@ -429,7 +430,7 @@ struct dsi_data {
 };
 
 struct dsi_packet_sent_handler_data {
-   struct platform_device *dsidev;
+   struct dsi_data *dsi;
struct completion *completion;
 };
 
@@ -448,7 +449,7 @@ static inline struct platform_device 
*dsi_get_dsidev_from_dssdev(struct omap_dss
return to_platform_device(dssdev->dev);
 }
 
-static struct platform_device *dsi_get_dsidev_from_id(int module)
+static struct dsi_data *dsi_get_dsi_from_id(int module)
 {
struct omap_dss_device *out;
enum omap_dss_output_id id;
@@ -466,13 +467,12 @@ static struct platform_device *dsi_get_dsidev_from_id(int 
module)
 
out = omap_dss_get_output(id);
 
-   return out ? to_platform_device(out->dev) : NULL;
+   return out ? dsi_get_dsidrv_data(to_platform_device(out->dev)) : NULL;
 }
 
-static inline void dsi_write_reg(struct platform_device *dsidev,
-   const struct dsi_reg idx, u32 val)
+static inline void dsi_write_reg(struct dsi_data *dsi,
+const struct dsi_reg idx, u32 val)
 {
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
void __iomem *base;
 
switch(idx.module) {
@@ -485,10 +485,8 @@ static inline void dsi_write_reg(struct platform_device 
*dsidev,
__raw_writel(val, base + idx.idx);
 }
 
-static inline u32 dsi_read_reg(struct platform_device *dsidev,
-   const struct dsi_reg idx)
+static inline u32 dsi_read_reg(struct dsi_data *dsi, const struct dsi_reg idx)
 {
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
void __iomem *base;
 
switch(idx.module) {
@@ -517,10 +515,8 @@ static void dsi_bus_unlock(struct omap_dss_device *dssdev)
up(&dsi->bus_lock);
 }
 
-static bool dsi_bus_is_locked(struct platform_device *dsidev)
+static bool dsi_bus_is_locked(struct dsi_data *dsi)
 {
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-
return dsi->bus_lock.count == 0;
 }
 
@@ -529,8 +525,9 @@ static void dsi_completion_handler(void *data, u32 mask)
complete((struct completion *)data);
 }
 
-static inline bool wait_for_bit_change(struct platform_device *dsidev,
-   const struct dsi_reg idx, int bitnum, int value)
+static inline bool wait_for_bit_change(struct dsi_data *dsi,
+  const struct dsi_reg idx,
+  int bitnum, int value)
 {
unsigned long timeout;
ktime_t wait;
@@ -539,14 +536,14 @@ static inline bool wait_for_bit_change(struct 
platform_device *dsidev,
/* first busyloop to see if the bit changes right away */
t = 100;
while (t-- > 0) {
-

[PATCH v2 24/30] drm: omapdrm: dispc: Pass DISPC pointer to dispc_ops operations

2018-02-13 Thread Laurent Pinchart
This removes the need to access the global DISPC private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DISPC private data dynamically).

In order to allow the omapdrm side to call the dispc_ops with a DISPC
pointer, we also introduce a new function dss_get_dispc() to retrieve
the DISPC corresponding to the DSS.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/base.c|   6 +
 drivers/gpu/drm/omapdrm/dss/dispc.c   | 223 ++
 drivers/gpu/drm/omapdrm/dss/dpi.c |   6 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c |   4 +-
 drivers/gpu/drm/omapdrm/dss/dss.h |   6 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   |   7 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   |   7 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  95 +--
 drivers/gpu/drm/omapdrm/dss/sdi.c |   6 +-
 drivers/gpu/drm/omapdrm/dss/venc.c|   4 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c   |  31 +++--
 drivers/gpu/drm/omapdrm/omap_drv.c|  13 +-
 drivers/gpu/drm/omapdrm/omap_drv.h|   1 +
 drivers/gpu/drm/omapdrm/omap_irq.c|  32 ++---
 drivers/gpu/drm/omapdrm/omap_plane.c  |  12 +-
 15 files changed, 257 insertions(+), 196 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index c248c3c31904..99e8cb8dc65b 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -44,6 +44,12 @@ void omapdss_set_dss(struct dss_device *dss)
 }
 EXPORT_SYMBOL(omapdss_set_dss);
 
+struct dispc_device *dispc_get_dispc(struct dss_device *dss)
+{
+   return dss->dispc;
+}
+EXPORT_SYMBOL(dispc_get_dispc);
+
 const struct dispc_ops *dispc_get_ops(struct dss_device *dss)
 {
return dss->dispc_ops;
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index aae6037f499f..6d8228f976f9 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -162,7 +162,7 @@ struct dispc_features {
 #define DISPC_MAX_NR_FIFOS 5
 #define DISPC_MAX_CHANNEL_GAMMA 4
 
-static struct {
+struct dispc_device {
struct platform_device *pdev;
void __iomem*base;
struct dss_device *dss;
@@ -194,7 +194,9 @@ static struct {
 
/* DISPC_CONTROL & DISPC_CONFIG lock*/
spinlock_t control_lock;
-} dispc;
+};
+
+static struct dispc_device dispc;
 
 enum omap_color_component {
/* used for all color formats for OMAP3 and earlier
@@ -361,9 +363,7 @@ static unsigned long dispc_mgr_pclk_rate(enum omap_channel 
channel);
 static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane);
 static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane);
 
-static void dispc_clear_irqstatus(u32 mask);
-static bool dispc_mgr_is_enabled(enum omap_channel channel);
-static void dispc_clear_irqstatus(u32 mask);
+static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask);
 
 static inline void dispc_write_reg(const u16 idx, u32 val)
 {
@@ -396,14 +396,14 @@ static void mgr_fld_write(enum omap_channel channel,
spin_unlock_irqrestore(&dispc.control_lock, flags);
 }
 
-static int dispc_get_num_ovls(void)
+static int dispc_get_num_ovls(struct dispc_device *dispc)
 {
-   return dispc.feat->num_ovls;
+   return dispc->feat->num_ovls;
 }
 
-static int dispc_get_num_mgrs(void)
+static int dispc_get_num_mgrs(struct dispc_device *dispc)
 {
-   return dispc.feat->num_mgrs;
+   return dispc->feat->num_mgrs;
 }
 
 static void dispc_get_reg_field(enum dispc_feat_reg_field id,
@@ -455,7 +455,7 @@ static void dispc_save_context(void)
SR(CONFIG3);
}
 
-   for (i = 0; i < dispc_get_num_mgrs(); i++) {
+   for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) {
SR(DEFAULT_COLOR(i));
SR(TRANS_COLOR(i));
SR(SIZE_MGR(i));
@@ -477,7 +477,7 @@ static void dispc_save_context(void)
}
}
 
-   for (i = 0; i < dispc_get_num_ovls(); i++) {
+   for (i = 0; i < dispc_get_num_ovls(&dispc); i++) {
SR(OVL_BA0(i));
SR(OVL_BA1(i));
SR(OVL_POSITION(i));
@@ -561,7 +561,7 @@ static void dispc_restore_context(void)
if (dispc_has_feature(FEAT_MGR_LCD3))
RR(CONFIG3);
 
-   for (i = 0; i < dispc_get_num_mgrs(); i++) {
+   for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) {
RR(DEFAULT_COLOR(i));
RR(TRANS_COLOR(i));
RR(SIZE_MGR(i));
@@ -583,7 +583,7 @@ static void dispc_restore_context(void)
}
}
 
-   for (i = 0; i < dispc_get_num_ovls(); i++) {
+   for (i = 0; i < dispc_get_num_ovls(&dispc); i++) {
RR(OVL_BA0(i));
RR(OVL_BA1(i));
RR(OVL_POSITION(i));
@@ -648,7 +648,7 @@ static void dispc_restore_context(void)
if (dispc_has_fea

[PATCH v2 22/30] drm: omapdrm: dss: Store DSS device pointer in the omapdrm private data

2018-02-13 Thread Laurent Pinchart
The dss_device is the top-level component in the omapdss driver. Give
the omapdrm driver access to the dss_device pointer in order to obtain
pointers to all other components from it. This requires a new global
variable in the omapdss driver that will be removed when merging the
omapdrm and omapdss drivers, but will already allow removal of several
other global variables.

As this partly duplicates the omapdss_is_initialized() API, reimplement
it as an inline function wrapping omapdss_get_dss().

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/base.c| 14 +++---
 drivers/gpu/drm/omapdrm/dss/dss.c |  5 +++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 10 +++---
 drivers/gpu/drm/omapdrm/omap_drv.c|  1 +
 drivers/gpu/drm/omapdrm/omap_drv.h|  1 +
 5 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 67cc87a4f1f6..6346bc967a77 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -20,7 +20,7 @@
 #include 
 #include "omapdss.h"
 
-static bool dss_initialized;
+static struct dss_device *dss_device;
 static const struct dispc_ops *ops;
 
 static struct list_head omapdss_comp_list;
@@ -31,17 +31,17 @@ struct omapdss_comp_node {
bool dss_core_component;
 };
 
-void omapdss_set_is_initialized(bool set)
+struct dss_device *omapdss_get_dss(void)
 {
-   dss_initialized = set;
+   return dss_device;
 }
-EXPORT_SYMBOL(omapdss_set_is_initialized);
+EXPORT_SYMBOL(omapdss_get_dss);
 
-bool omapdss_is_initialized(void)
+void omapdss_set_dss(struct dss_device *dss)
 {
-   return dss_initialized;
+   dss_device = dss;
 }
-EXPORT_SYMBOL(omapdss_is_initialized);
+EXPORT_SYMBOL(omapdss_set_dss);
 
 void dispc_set_ops(const struct dispc_ops *o)
 {
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 14d2f024eb70..ca2efb937d42 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1316,6 +1316,7 @@ static const struct soc_device_attribute 
dss_soc_devices[] = {
 
 static int dss_bind(struct device *dev)
 {
+   struct dss_device *dss = dev_get_drvdata(dev);
int r;
 
r = component_bind_all(dev, NULL);
@@ -1325,14 +1326,14 @@ static int dss_bind(struct device *dev)
pm_set_vt_switch(0);
 
omapdss_gather_components(dev);
-   omapdss_set_is_initialized(true);
+   omapdss_set_dss(dss);
 
return 0;
 }
 
 static void dss_unbind(struct device *dev)
 {
-   omapdss_set_is_initialized(false);
+   omapdss_set_dss(NULL);
 
component_unbind_all(dev, NULL);
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 318641f5bc24..312485714703 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -59,6 +59,7 @@
 #define DISPC_IRQ_ACBIAS_COUNT_STAT3   (1 << 29)
 #define DISPC_IRQ_FRAMEDONE3   (1 << 30)
 
+struct dss_device;
 struct omap_drm_private;
 struct omap_dss_device;
 struct dss_lcd_mgr_config;
@@ -586,7 +587,12 @@ struct omap_dss_driver {
const struct hdmi_avi_infoframe *avi);
 };
 
-bool omapdss_is_initialized(void);
+struct dss_device *omapdss_get_dss(void);
+void omapdss_set_dss(struct dss_device *dss);
+static inline bool omapdss_is_initialized(void)
+{
+   return !!omapdss_get_dss();
+}
 
 int omapdss_register_display(struct omap_dss_device *dssdev);
 void omapdss_unregister_display(struct omap_dss_device *dssdev);
@@ -630,8 +636,6 @@ static inline bool omapdss_device_is_enabled(struct 
omap_dss_device *dssdev)
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node);
 
-void omapdss_set_is_initialized(bool set);
-
 struct device_node *dss_of_port_get_parent_device(struct device_node *port);
 u32 dss_of_port_get_port_number(struct device_node *port);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 39e78f765f7e..003445b70ee7 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -527,6 +527,7 @@ static int omapdrm_init(struct omap_drm_private *priv, 
struct device *dev)
if (ret)
goto err_crtc_uninit;
 
+   priv->dss = omapdss_get_dss();
priv->dispc_ops = dispc_get_ops();
 
soc = soc_device_match(omapdrm_soc_devices);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 49351bb3731e..a7962c14fc7c 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -50,6 +50,7 @@ struct omap_drm_private {
struct device *dev;
u32 omaprev;
 
+   struct dss_device *dss;
const struct dispc_ops *dispc_ops;
 
unsigned int num_crtcs;
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freede

[PATCH v2 14/30] drm: omapdrm: dss: Don't unnecessarily cast to dev to pdev and back

2018-02-13 Thread Laurent Pinchart
The dss_unbind() function casts the struct device pointer to a struct
platform_device, only to later use the struct device pointer from
platform_device. Don't cast at all.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dss.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 7a5f5f233ad0..14d2f024eb70 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1332,11 +1332,9 @@ static int dss_bind(struct device *dev)
 
 static void dss_unbind(struct device *dev)
 {
-   struct platform_device *pdev = to_platform_device(dev);
-
omapdss_set_is_initialized(false);
 
-   component_unbind_all(&pdev->dev, NULL);
+   component_unbind_all(dev, NULL);
 }
 
 static const struct component_master_ops dss_component_ops = {
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 23/30] drm: omapdrm: dss: Store dispc ops in dss_device structure

2018-02-13 Thread Laurent Pinchart
Remove the global dispc ops variable by storing it in the dss_device
structure.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/base.c| 13 -
 drivers/gpu/drm/omapdrm/dss/dispc.c   |  6 --
 drivers/gpu/drm/omapdrm/dss/dss.h |  2 ++
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  3 +--
 drivers/gpu/drm/omapdrm/omap_crtc.c   |  4 +---
 drivers/gpu/drm/omapdrm/omap_drv.c|  5 ++---
 6 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 6346bc967a77..c248c3c31904 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -18,10 +18,11 @@
 #include 
 #include 
 #include 
+
+#include "dss.h"
 #include "omapdss.h"
 
 static struct dss_device *dss_device;
-static const struct dispc_ops *ops;
 
 static struct list_head omapdss_comp_list;
 
@@ -43,15 +44,9 @@ void omapdss_set_dss(struct dss_device *dss)
 }
 EXPORT_SYMBOL(omapdss_set_dss);
 
-void dispc_set_ops(const struct dispc_ops *o)
-{
-   ops = o;
-}
-EXPORT_SYMBOL(dispc_set_ops);
-
-const struct dispc_ops *dispc_get_ops(void)
+const struct dispc_ops *dispc_get_ops(struct dss_device *dss)
 {
-   return ops;
+   return dss->dispc_ops;
 }
 EXPORT_SYMBOL(dispc_get_ops);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 8019cc9f4f97..aae6037f499f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -4622,7 +4622,7 @@ static int dispc_bind(struct device *dev, struct device 
*master, void *data)
 
dispc_runtime_put();
 
-   dispc_set_ops(&dispc_ops);
+   dss->dispc_ops = &dispc_ops;
 
dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs,
&dispc);
@@ -4637,9 +4637,11 @@ static int dispc_bind(struct device *dev, struct device 
*master, void *data)
 static void dispc_unbind(struct device *dev, struct device *master,
   void *data)
 {
+   struct dss_device *dss = dispc.dss;
+
dss_debugfs_remove_file(dispc.debugfs);
 
-   dispc_set_ops(NULL);
+   dss->dispc_ops = NULL;
 
pm_runtime_disable(dev);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h 
b/drivers/gpu/drm/omapdrm/dss/dss.h
index 764c52025a27..348378f1b5a5 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -271,6 +271,8 @@ struct dss_device {
struct dss_pll *plls[4];
struct dss_pll  *video1_pll;
struct dss_pll  *video2_pll;
+
+   const struct dispc_ops *dispc_ops;
 };
 
 /* core */
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 312485714703..4bf7843b4aec 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -733,8 +733,7 @@ struct dispc_ops {
const u32 *(*ovl_get_color_modes)(enum omap_plane_id plane);
 };
 
-void dispc_set_ops(const struct dispc_ops *o);
-const struct dispc_ops *dispc_get_ops(void);
+const struct dispc_ops *dispc_get_ops(struct dss_device *dss);
 
 bool omapdss_component_is_display(struct device_node *node);
 bool omapdss_component_is_output(struct device_node *node);
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 61d8d17a4243..ffe4f698d291 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -117,12 +117,10 @@ static int omap_crtc_dss_connect(struct omap_drm_private 
*priv,
enum omap_channel channel,
struct omap_dss_device *dst)
 {
-   const struct dispc_ops *dispc_ops = dispc_get_ops();
-
if (omap_crtc_output[channel])
return -EINVAL;
 
-   if ((dispc_ops->mgr_get_supported_outputs(channel) & dst->id) == 0)
+   if (!(priv->dispc_ops->mgr_get_supported_outputs(channel) & dst->id))
return -EINVAL;
 
omap_crtc_output[channel] = dst;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 003445b70ee7..a93916cd0258 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -520,6 +520,8 @@ static int omapdrm_init(struct omap_drm_private *priv, 
struct device *dev)
DBG("%s", dev_name(dev));
 
priv->dev = dev;
+   priv->dss = omapdss_get_dss();
+   priv->dispc_ops = dispc_get_ops(priv->dss);
 
omap_crtc_pre_init(priv);
 
@@ -527,9 +529,6 @@ static int omapdrm_init(struct omap_drm_private *priv, 
struct device *dev)
if (ret)
goto err_crtc_uninit;
 
-   priv->dss = omapdss_get_dss();
-   priv->dispc_ops = dispc_get_ops();
-
soc = soc_device_match(omapdrm_soc_devices);
priv->omaprev = soc ? (unsigned int)soc->data : 0;
priv->wq = alloc_ordered_workqueue("omapdrm", 0);
-- 
Regards,

Laurent Pinchart

__

Re: [PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers

2018-02-13 Thread Robin Murphy

On 13/02/18 07:44, Tomasz Figa wrote:

Hi Vivek,

On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
 wrote:

The device link allows the pm framework to tie the supplier and
consumer. So, whenever the consumer is powered-on the supplier
is powered-on first.

There are however cases in which the consumer wants to power-on
the supplier, but not itself.
E.g., A Graphics or multimedia driver wants to power-on the SMMU
to unmap a buffer and finish the TLB operations without powering
on itself.


This sounds strange to me. If the SMMU is powered down, wouldn't the
TLB lose its contents as well (and so no flushing needed)?


Depends on implementation details - if runtime PM is actually 
implemented via external clock gating (in the absence of fine-grained 
power domains), then "suspended" TLBs might both retain state and not 
receive invalidation requests, which is really the worst case.



Other than that, what kind of hardware operations would be needed
besides just updating the page tables from the CPU?


Domain attach/detach also require updating SMMU hardware state (and 
possibly TLB maintenance), but don't logically require the master device 
itself to be active at the time.


Robin.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 30/30] drm: omapdrm: venc: Allocate the venc private data structure dynamically

2018-02-13 Thread Laurent Pinchart
The venc private data structure is currently stored as a global
variable. While no platform with multiple VENC encoders currently exists
nor is planned, this doesn't comply with the kernel device model and
should thus be fixed.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/venc.c | 442 -
 1 file changed, 238 insertions(+), 204 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 12a0ac4e1eb1..24d1ced210bd 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -319,7 +319,7 @@ static enum venc_videomode venc_get_videomode(const struct 
videomode *vm)
return VENC_MODE_UNKNOWN;
 }
 
-static struct {
+struct venc_device {
struct platform_device *pdev;
void __iomem *base;
struct mutex venc_lock;
@@ -337,81 +337,87 @@ static struct {
bool requires_tv_dac_clk;
 
struct omap_dss_device output;
-} venc;
+};
+
+#define dssdev_to_venc(dssdev) container_of(dssdev, struct venc_device, output)
 
-static inline void venc_write_reg(int idx, u32 val)
+static inline void venc_write_reg(struct venc_device *venc, int idx, u32 val)
 {
-   __raw_writel(val, venc.base + idx);
+   __raw_writel(val, venc->base + idx);
 }
 
-static inline u32 venc_read_reg(int idx)
+static inline u32 venc_read_reg(struct venc_device *venc, int idx)
 {
-   u32 l = __raw_readl(venc.base + idx);
+   u32 l = __raw_readl(venc->base + idx);
return l;
 }
 
-static void venc_write_config(const struct venc_config *config)
+static void venc_write_config(struct venc_device *venc,
+ const struct venc_config *config)
 {
DSSDBG("write venc conf\n");
 
-   venc_write_reg(VENC_LLEN, config->llen);
-   venc_write_reg(VENC_FLENS, config->flens);
-   venc_write_reg(VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr);
-   venc_write_reg(VENC_C_PHASE, config->c_phase);
-   venc_write_reg(VENC_GAIN_U, config->gain_u);
-   venc_write_reg(VENC_GAIN_V, config->gain_v);
-   venc_write_reg(VENC_GAIN_Y, config->gain_y);
-   venc_write_reg(VENC_BLACK_LEVEL, config->black_level);
-   venc_write_reg(VENC_BLANK_LEVEL, config->blank_level);
-   venc_write_reg(VENC_M_CONTROL, config->m_control);
-   venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
-   venc.wss_data);
-   venc_write_reg(VENC_S_CARR, config->s_carr);
-   venc_write_reg(VENC_L21__WC_CTL, config->l21__wc_ctl);
-   venc_write_reg(VENC_SAVID__EAVID, config->savid__eavid);
-   venc_write_reg(VENC_FLEN__FAL, config->flen__fal);
-   venc_write_reg(VENC_LAL__PHASE_RESET, config->lal__phase_reset);
-   venc_write_reg(VENC_HS_INT_START_STOP_X, config->hs_int_start_stop_x);
-   venc_write_reg(VENC_HS_EXT_START_STOP_X, config->hs_ext_start_stop_x);
-   venc_write_reg(VENC_VS_INT_START_X, config->vs_int_start_x);
-   venc_write_reg(VENC_VS_INT_STOP_X__VS_INT_START_Y,
+   venc_write_reg(venc, VENC_LLEN, config->llen);
+   venc_write_reg(venc, VENC_FLENS, config->flens);
+   venc_write_reg(venc, VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr);
+   venc_write_reg(venc, VENC_C_PHASE, config->c_phase);
+   venc_write_reg(venc, VENC_GAIN_U, config->gain_u);
+   venc_write_reg(venc, VENC_GAIN_V, config->gain_v);
+   venc_write_reg(venc, VENC_GAIN_Y, config->gain_y);
+   venc_write_reg(venc, VENC_BLACK_LEVEL, config->black_level);
+   venc_write_reg(venc, VENC_BLANK_LEVEL, config->blank_level);
+   venc_write_reg(venc, VENC_M_CONTROL, config->m_control);
+   venc_write_reg(venc, VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
+  venc->wss_data);
+   venc_write_reg(venc, VENC_S_CARR, config->s_carr);
+   venc_write_reg(venc, VENC_L21__WC_CTL, config->l21__wc_ctl);
+   venc_write_reg(venc, VENC_SAVID__EAVID, config->savid__eavid);
+   venc_write_reg(venc, VENC_FLEN__FAL, config->flen__fal);
+   venc_write_reg(venc, VENC_LAL__PHASE_RESET, config->lal__phase_reset);
+   venc_write_reg(venc, VENC_HS_INT_START_STOP_X,
+  config->hs_int_start_stop_x);
+   venc_write_reg(venc, VENC_HS_EXT_START_STOP_X,
+  config->hs_ext_start_stop_x);
+   venc_write_reg(venc, VENC_VS_INT_START_X, config->vs_int_start_x);
+   venc_write_reg(venc, VENC_VS_INT_STOP_X__VS_INT_START_Y,
   config->vs_int_stop_x__vs_int_start_y);
-   venc_write_reg(VENC_VS_INT_STOP_Y__VS_EXT_START_X,
+   venc_write_reg(venc, VENC_VS_INT_STOP_Y__VS_EXT_START_X,
   config->vs_int_stop_y__vs_ext_start_x);
-   venc_write_reg(VENC_VS_EXT_STOP_X__VS_EXT_START_Y,
+   venc_write_reg(venc, VENC_VS_EXT_STOP_X__VS_EXT_START_Y,
   config->vs_ext_stop_x__vs_ext_start_y);
-   venc_write_reg(V

[PATCH v2 27/30] drm: omapdrm: hdmi4: Allocate the omap_hdmi data structure dynamically

2018-02-13 Thread Laurent Pinchart
The omap_hdmi private data structure is currently stored as a global
variable. While no platform with multiple HDMI4 encoders currently
exists nor is planned, this doesn't comply with the kernel device model
and should thus be fixed.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
Changes since v1:

- Fixed device name string that had been incorrectly modified
---
 drivers/gpu/drm/omapdrm/dss/hdmi.h   |   2 +
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  | 356 +--
 drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c  |   4 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4_core.h |   4 +-
 4 files changed, 200 insertions(+), 166 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h 
b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index fa2fbdaa427c..3aeb4cabd59f 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -389,4 +389,6 @@ struct omap_hdmi {
bool display_enabled;
 };
 
+#define dssdev_to_hdmi(dssdev) container_of(dssdev, struct omap_hdmi, output)
+
 #endif
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 815865c09ac1..1f7897c58f2f 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -45,15 +45,13 @@
 #include "dss.h"
 #include "hdmi.h"
 
-static struct omap_hdmi hdmi;
-
-static int hdmi_runtime_get(void)
+static int hdmi_runtime_get(struct omap_hdmi *hdmi)
 {
int r;
 
DSSDBG("hdmi_runtime_get\n");
 
-   r = pm_runtime_get_sync(&hdmi.pdev->dev);
+   r = pm_runtime_get_sync(&hdmi->pdev->dev);
WARN_ON(r < 0);
if (r < 0)
return r;
@@ -61,13 +59,13 @@ static int hdmi_runtime_get(void)
return 0;
 }
 
-static void hdmi_runtime_put(void)
+static void hdmi_runtime_put(struct omap_hdmi *hdmi)
 {
int r;
 
DSSDBG("hdmi_runtime_put\n");
 
-   r = pm_runtime_put_sync(&hdmi.pdev->dev);
+   r = pm_runtime_put_sync(&hdmi->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
 }
 
@@ -110,14 +108,14 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int hdmi_init_regulator(void)
+static int hdmi_init_regulator(struct omap_hdmi *hdmi)
 {
struct regulator *reg;
 
-   if (hdmi.vdda_reg != NULL)
+   if (hdmi->vdda_reg != NULL)
return 0;
 
-   reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
+   reg = devm_regulator_get(&hdmi->pdev->dev, "vdda");
 
if (IS_ERR(reg)) {
if (PTR_ERR(reg) != -EPROBE_DEFER)
@@ -125,63 +123,63 @@ static int hdmi_init_regulator(void)
return PTR_ERR(reg);
}
 
-   hdmi.vdda_reg = reg;
+   hdmi->vdda_reg = reg;
 
return 0;
 }
 
-static int hdmi_power_on_core(struct omap_dss_device *dssdev)
+static int hdmi_power_on_core(struct omap_hdmi *hdmi)
 {
int r;
 
-   if (hdmi.core.core_pwr_cnt++)
+   if (hdmi->core.core_pwr_cnt++)
return 0;
 
-   r = regulator_enable(hdmi.vdda_reg);
+   r = regulator_enable(hdmi->vdda_reg);
if (r)
goto err_reg_enable;
 
-   r = hdmi_runtime_get();
+   r = hdmi_runtime_get(hdmi);
if (r)
goto err_runtime_get;
 
-   hdmi4_core_powerdown_disable(&hdmi.core);
+   hdmi4_core_powerdown_disable(&hdmi->core);
 
/* Make selection of HDMI in DSS */
-   dss_select_hdmi_venc_clk_source(hdmi.dss, DSS_HDMI_M_PCLK);
+   dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK);
 
-   hdmi.core_enabled = true;
+   hdmi->core_enabled = true;
 
return 0;
 
 err_runtime_get:
-   regulator_disable(hdmi.vdda_reg);
+   regulator_disable(hdmi->vdda_reg);
 err_reg_enable:
-   hdmi.core.core_pwr_cnt--;
+   hdmi->core.core_pwr_cnt--;
 
return r;
 }
 
-static void hdmi_power_off_core(struct omap_dss_device *dssdev)
+static void hdmi_power_off_core(struct omap_hdmi *hdmi)
 {
-   if (--hdmi.core.core_pwr_cnt)
+   if (--hdmi->core.core_pwr_cnt)
return;
 
-   hdmi.core_enabled = false;
+   hdmi->core_enabled = false;
 
-   hdmi_runtime_put();
-   regulator_disable(hdmi.vdda_reg);
+   hdmi_runtime_put(hdmi);
+   regulator_disable(hdmi->vdda_reg);
 }
 
-static int hdmi_power_on_full(struct omap_dss_device *dssdev)
+static int hdmi_power_on_full(struct omap_hdmi *hdmi)
 {
int r;
struct videomode *vm;
-   struct hdmi_wp_data *wp = &hdmi.wp;
+   struct hdmi_wp_data *wp = &hdmi->wp;
struct dss_pll_clock_info hdmi_cinfo = { 0 };
unsigned int pc;
 
-   r = hdmi_power_on_core(dssdev);
+   r = hdmi_power_on_core(hdmi);
if (r)
return r;
 
@@ -189,7 +187,7 @@ static int hdmi_power_on_full(struct omap_dss_device 
*dssdev)
hdmi_wp_clear_irqenable(wp, ~HDMI_IRQ_CORE);
hdmi_wp_set_irqstatus(wp, ~HDMI_IRQ_CORE);
 
-   vm = &hdmi.cfg.vm

[PATCH v2 16/30] drm: omapdrm: dsi: Combine two commonly used inline functions

2018-02-13 Thread Laurent Pinchart
The dsi_get_dsidrv_data() and dsi_get_dsidev_from_dssdev() inline
functions convert a struct omap_dss_device pointer to the corresponding
struct platform_device, and a struct platform_device pointer to the
corresponding struct dsi_data. They are nearly always called together
without any use of the intermediate platform_device, so combine them
into a single function.

In the three locations where only dsi_get_dsidrv_data() is used, call
dev_get_drvdata() directly.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 90 +--
 1 file changed, 30 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 7b5656e6abbb..cb250dbf0f9b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -439,14 +439,9 @@ static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
 #endif
 
-static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device 
*dsidev)
+static inline struct dsi_data *to_dsi_data(struct omap_dss_device *dssdev)
 {
-   return dev_get_drvdata(&dsidev->dev);
-}
-
-static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct 
omap_dss_device *dssdev)
-{
-   return to_platform_device(dssdev->dev);
+   return dev_get_drvdata(dssdev->dev);
 }
 
 static struct dsi_data *dsi_get_dsi_from_id(int module)
@@ -467,7 +462,7 @@ static struct dsi_data *dsi_get_dsi_from_id(int module)
 
out = omap_dss_get_output(id);
 
-   return out ? dsi_get_dsidrv_data(to_platform_device(out->dev)) : NULL;
+   return out ? to_dsi_data(out) : NULL;
 }
 
 static inline void dsi_write_reg(struct dsi_data *dsi,
@@ -501,16 +496,14 @@ static inline u32 dsi_read_reg(struct dsi_data *dsi, 
const struct dsi_reg idx)
 
 static void dsi_bus_lock(struct omap_dss_device *dssdev)
 {
-   struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   struct dsi_data *dsi = to_dsi_data(dssdev);
 
down(&dsi->bus_lock);
 }
 
 static void dsi_bus_unlock(struct omap_dss_device *dssdev)
 {
-   struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   struct dsi_data *dsi = to_dsi_data(dssdev);
 
up(&dsi->bus_lock);
 }
@@ -2534,8 +2527,7 @@ static int dsi_vc_config_source(struct dsi_data *dsi, int 
channel,
 static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable)
 {
-   struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   struct dsi_data *dsi = to_dsi_data(dssdev);
 
DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
 
@@ -2658,8 +2650,7 @@ static int dsi_vc_send_bta(struct dsi_data *dsi, int 
channel)
 
 static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 {
-   struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   struct dsi_data *dsi = to_dsi_data(dssdev);
DECLARE_COMPLETION_ONSTACK(completion);
int r = 0;
u32 err;
@@ -2861,8 +2852,7 @@ static int dsi_vc_write_nosync_common(struct dsi_data 
*dsi, int channel,
 static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
u8 *data, int len)
 {
-   struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   struct dsi_data *dsi = to_dsi_data(dssdev);
 
return dsi_vc_write_nosync_common(dsi, channel, data, len,
DSS_DSI_CONTENT_DCS);
@@ -2871,8 +2861,7 @@ static int dsi_vc_dcs_write_nosync(struct omap_dss_device 
*dssdev, int channel,
 static int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int 
channel,
u8 *data, int len)
 {
-   struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   struct dsi_data *dsi = to_dsi_data(dssdev);
 
return dsi_vc_write_nosync_common(dsi, channel, data, len,
DSS_DSI_CONTENT_GENERIC);
@@ -2882,8 +2871,7 @@ static int dsi_vc_write_common(struct omap_dss_device 
*dssdev,
   int channel, u8 *data, int len,
   enum dss_dsi_content_type type)
 {
-   struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-   struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+   struct dsi_data *dsi = to_dsi_data(dssdev);
int r;
 
r = dsi_vc_write_nosync_common(dsi, channel, data, len, type);
@@ -3088,8 +3076,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int 
channel, u8 *buf,
 static int dsi_vc_dcs_read(struct omap_dss_

[PATCH v2 08/30] drm: omapdrm: dss: Pass DSS pointer to dss clock functions

2018-02-13 Thread Laurent Pinchart
This removes the need to access the global DSS private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DSS device dynamically).

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dispc.c |  8 
 drivers/gpu/drm/omapdrm/dss/dpi.c   | 14 --
 drivers/gpu/drm/omapdrm/dss/dss.c   | 37 ++---
 drivers/gpu/drm/omapdrm/dss/dss.h   | 10 +-
 drivers/gpu/drm/omapdrm/dss/sdi.c   |  5 +++--
 5 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 048b2e4d1f40..8d0de1b790b7 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -3116,7 +3116,7 @@ static unsigned long dispc_fclk_rate(void)
src = dss_get_dispc_clk_source(dispc.dss);
 
if (src == DSS_CLK_SRC_FCK) {
-   r = dss_get_dispc_clk_rate();
+   r = dss_get_dispc_clk_rate(dispc.dss);
} else {
struct dss_pll *pll;
unsigned int clkout_idx;
@@ -3143,7 +3143,7 @@ static unsigned long dispc_mgr_lclk_rate(enum 
omap_channel channel)
src = dss_get_lcd_clk_source(dispc.dss, channel);
 
if (src == DSS_CLK_SRC_FCK) {
-   r = dss_get_dispc_clk_rate();
+   r = dss_get_dispc_clk_rate(dispc.dss);
} else {
struct dss_pll *pll;
unsigned int clkout_idx;
@@ -3499,7 +3499,7 @@ bool dispc_div_calc(unsigned long dispc_freq,
pckd_hw_min = dispc.feat->min_pcd;
pckd_hw_max = 255;
 
-   lck_max = dss_get_max_fck_rate();
+   lck_max = dss_get_max_fck_rate(dispc.dss);
 
pck_min = pck_min ? pck_min : 1;
pck_max = pck_max ? pck_max : ULONG_MAX;
@@ -4460,7 +4460,7 @@ static void dispc_errata_i734_wa(void)
 
/* Set up and enable display manager for LCD1 */
dispc_mgr_setup(OMAP_DSS_CHANNEL_LCD, &i734.mgri);
-   dispc_calc_clock_rates(dss_get_dispc_clk_rate(),
+   dispc_calc_clock_rates(dss_get_dispc_clk_rate(dispc.dss),
   &lcd_conf.clock_info);
dispc_mgr_set_lcd_config(OMAP_DSS_CHANNEL_LCD, &lcd_conf);
dispc_mgr_set_timings(OMAP_DSS_CHANNEL_LCD, &i734.vm);
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index e7f50fabca6f..ba5adfb7ee70 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -207,7 +207,7 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long 
fint,
ctx->pll_cinfo.clkdco = clkdco;
 
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
-   ctx->pck_min, dss_get_max_fck_rate(),
+   ctx->pck_min, dss_get_max_fck_rate(ctx->pll->dss),
dpi_calc_hsdiv_cb, ctx);
 }
 
@@ -256,7 +256,8 @@ static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned 
long pck,
}
 }
 
-static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
+static bool dpi_dss_clk_calc(struct dpi_data *dpi, unsigned long pck,
+struct dpi_clk_calc_ctx *ctx)
 {
int i;
 
@@ -277,7 +278,8 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct 
dpi_clk_calc_ctx *ctx)
ctx->pck_min = 0;
ctx->pck_max = pck + 1000 * i * i * i;
 
-   ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx);
+   ok = dss_div_calc(dpi->dss, pck, ctx->pck_min,
+ dpi_calc_dss_cb, ctx);
if (ok)
return ok;
}
@@ -321,11 +323,11 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, 
unsigned long pck_req,
int r;
bool ok;
 
-   ok = dpi_dss_clk_calc(pck_req, &ctx);
+   ok = dpi_dss_clk_calc(dpi, pck_req, &ctx);
if (!ok)
return -EINVAL;
 
-   r = dss_set_fck_rate(ctx.fck);
+   r = dss_set_fck_rate(dpi->dss, ctx.fck);
if (r)
return r;
 
@@ -530,7 +532,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
 
fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
} else {
-   ok = dpi_dss_clk_calc(vm->pixelclock, &ctx);
+   ok = dpi_dss_clk_calc(dpi, vm->pixelclock, &ctx);
if (!ok)
return -EINVAL;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index bdf8f66002b6..0d292da6757d 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -594,8 +594,8 @@ enum dss_clk_source dss_get_lcd_clk_source(struct 
dss_device *dss,
}
 }
 
-bool dss_div_calc(unsigned long pck, unsigned long fck_min,
-   dss_div_calc_func func, void *data)
+bool dss_div_calc(struct dss_device *dss, unsigned long pck,
+ unsigned long fc

[PATCH v2 29/30] drm: omapdrm: sdi: Allocate the sdi private data structure dynamically

2018-02-13 Thread Laurent Pinchart
The sdi private data structure is currently stored as a global
variable. While no platform with multiple SDI encoders currently exists
nor is planned, this doesn't comply with the kernel device model and
should thus be fixed.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/sdi.c | 151 ++
 1 file changed, 86 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c 
b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 9c2ed56a70c1..68a40ae26f5b 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -29,7 +29,7 @@
 #include "omapdss.h"
 #include "dss.h"
 
-static struct {
+struct sdi_device {
struct platform_device *pdev;
struct dss_device *dss;
 
@@ -41,11 +41,12 @@ static struct {
int datapairs;
 
struct omap_dss_device output;
+};
 
-   bool port_initialized;
-} sdi;
+#define dssdev_to_sdi(dssdev) container_of(dssdev, struct sdi_device, output)
 
 struct sdi_clk_calc_ctx {
+   struct sdi_device *sdi;
unsigned long pck_min, pck_max;
 
unsigned long fck;
@@ -71,17 +72,17 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
 
ctx->fck = fck;
 
-   return dispc_div_calc(sdi.dss->dispc, fck,
+   return dispc_div_calc(ctx->sdi->dss->dispc, fck,
  ctx->pck_min, ctx->pck_max,
  dpi_calc_dispc_cb, ctx);
 }
 
-static int sdi_calc_clock_div(unsigned long pclk,
-   unsigned long *fck,
-   struct dispc_clock_info *dispc_cinfo)
+static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk,
+ unsigned long *fck,
+ struct dispc_clock_info *dispc_cinfo)
 {
int i;
-   struct sdi_clk_calc_ctx ctx;
+   struct sdi_clk_calc_ctx ctx = { .sdi = sdi };
 
/*
 * DSS fclk gives us very few possibilities, so finding a good pixel
@@ -100,7 +101,7 @@ static int sdi_calc_clock_div(unsigned long pclk,
ctx.pck_min = 0;
ctx.pck_max = pclk + 1000 * i * i * i;
 
-   ok = dss_div_calc(sdi.dss, pclk, ctx.pck_min,
+   ok = dss_div_calc(sdi->dss, pclk, ctx.pck_min,
  dpi_calc_dss_cb, &ctx);
if (ok) {
*fck = ctx.fck;
@@ -112,48 +113,49 @@ static int sdi_calc_clock_div(unsigned long pclk,
return -EINVAL;
 }
 
-static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void sdi_config_lcd_manager(struct sdi_device *sdi)
 {
-   sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
+   sdi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
-   sdi.mgr_config.stallmode = false;
-   sdi.mgr_config.fifohandcheck = false;
+   sdi->mgr_config.stallmode = false;
+   sdi->mgr_config.fifohandcheck = false;
 
-   sdi.mgr_config.video_port_width = 24;
-   sdi.mgr_config.lcden_sig_polarity = 1;
+   sdi->mgr_config.video_port_width = 24;
+   sdi->mgr_config.lcden_sig_polarity = 1;
 
-   dss_mgr_set_lcd_config(&sdi.output, &sdi.mgr_config);
+   dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config);
 }
 
 static int sdi_display_enable(struct omap_dss_device *dssdev)
 {
-   struct videomode *vm = &sdi.vm;
+   struct sdi_device *sdi = dssdev_to_sdi(dssdev);
+   struct videomode *vm = &sdi->vm;
unsigned long fck;
struct dispc_clock_info dispc_cinfo;
unsigned long pck;
int r;
 
-   if (!sdi.output.dispc_channel_connected) {
+   if (!sdi->output.dispc_channel_connected) {
DSSERR("failed to enable display: no output/manager\n");
return -ENODEV;
}
 
-   r = regulator_enable(sdi.vdds_sdi_reg);
+   r = regulator_enable(sdi->vdds_sdi_reg);
if (r)
goto err_reg_enable;
 
-   r = dispc_runtime_get(sdi.dss->dispc);
+   r = dispc_runtime_get(sdi->dss->dispc);
if (r)
goto err_get_dispc;
 
/* 15.5.9.1.2 */
vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_SYNC_POSEDGE;
 
-   r = sdi_calc_clock_div(vm->pixelclock, &fck, &dispc_cinfo);
+   r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo);
if (r)
goto err_calc_clock_div;
 
-   sdi.mgr_config.clock_info = dispc_cinfo;
+   sdi->mgr_config.clock_info = dispc_cinfo;
 
pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
 
@@ -165,13 +167,13 @@ static int sdi_display_enable(struct omap_dss_device 
*dssdev)
}
 
 
-   dss_mgr_set_timings(&sdi.output, vm);
+   dss_mgr_set_timings(&sdi->output, vm);
 
-   r = dss_set_fck_rate(sdi.dss, fck);
+   r = dss_set_fck_rate(sdi->dss, fck);
if (r)
goto err_set_dss_clock_div;
 
-   sdi_config_lcd_manager(dssdev);
+  

[PATCH v2 18/30] drm: omapdrm: dsi: Store the struct device pointer in struct dsi_data

2018-02-13 Thread Laurent Pinchart
The dsi_data structure stores a pointer to a struct platform_device. The
driver only uses the dev member of the platform device structure. Store
the struct device pointer instead and use it directly.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 62131d7593a7..ecfdc6ef2500 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -330,7 +330,7 @@ struct dsi_of_data {
 };
 
 struct dsi_data {
-   struct platform_device *pdev;
+   struct device *dev;
void __iomem *proto_base;
void __iomem *phy_base;
void __iomem *pll_base;
@@ -1144,7 +1144,7 @@ static int dsi_runtime_get(struct dsi_data *dsi)
 
DSSDBG("dsi_runtime_get\n");
 
-   r = pm_runtime_get_sync(&dsi->pdev->dev);
+   r = pm_runtime_get_sync(dsi->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
 }
@@ -1155,7 +1155,7 @@ static void dsi_runtime_put(struct dsi_data *dsi)
 
DSSDBG("dsi_runtime_put\n");
 
-   r = pm_runtime_put_sync(&dsi->pdev->dev);
+   r = pm_runtime_put_sync(dsi->dev);
WARN_ON(r < 0 && r != -ENOSYS);
 }
 
@@ -1166,7 +1166,7 @@ static int dsi_regulator_init(struct dsi_data *dsi)
if (dsi->vdds_dsi_reg != NULL)
return 0;
 
-   vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdd");
+   vdds_dsi = devm_regulator_get(dsi->dev, "vdd");
 
if (IS_ERR(vdds_dsi)) {
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
@@ -4951,7 +4951,7 @@ static int dsi_get_clocks(struct dsi_data *dsi)
 {
struct clk *clk;
 
-   clk = devm_clk_get(&dsi->pdev->dev, "fck");
+   clk = devm_clk_get(dsi->dev, "fck");
if (IS_ERR(clk)) {
DSSERR("can't get fck\n");
return PTR_ERR(clk);
@@ -5046,7 +5046,7 @@ static void dsi_init_output(struct dsi_data *dsi)
 {
struct omap_dss_device *out = &dsi->output;
 
-   out->dev = &dsi->pdev->dev;
+   out->dev = dsi->dev;
out->id = dsi->module_id == 0 ?
OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
 
@@ -5068,7 +5068,7 @@ static void dsi_uninit_output(struct dsi_data *dsi)
 
 static int dsi_probe_of(struct dsi_data *dsi)
 {
-   struct device_node *node = dsi->pdev->dev.of_node;
+   struct device_node *node = dsi->dev->of_node;
struct property *prop;
u32 lane_arr[10];
int len, num_pins;
@@ -5082,7 +5082,7 @@ static int dsi_probe_of(struct dsi_data *dsi)
 
prop = of_find_property(ep, "lanes", &len);
if (prop == NULL) {
-   dev_err(&dsi->pdev->dev, "failed to find lane data\n");
+   dev_err(dsi->dev, "failed to find lane data\n");
r = -EINVAL;
goto err;
}
@@ -5091,14 +5091,14 @@ static int dsi_probe_of(struct dsi_data *dsi)
 
if (num_pins < 4 || num_pins % 2 != 0 ||
num_pins > dsi->num_lanes_supported * 2) {
-   dev_err(&dsi->pdev->dev, "bad number of lanes\n");
+   dev_err(dsi->dev, "bad number of lanes\n");
r = -EINVAL;
goto err;
}
 
r = of_property_read_u32_array(ep, "lanes", lane_arr, num_pins);
if (r) {
-   dev_err(&dsi->pdev->dev, "failed to read lane data\n");
+   dev_err(dsi->dev, "failed to read lane data\n");
goto err;
}
 
@@ -5108,7 +5108,7 @@ static int dsi_probe_of(struct dsi_data *dsi)
 
r = dsi_configure_pins(&dsi->output, &pin_cfg);
if (r) {
-   dev_err(&dsi->pdev->dev, "failed to configure pins");
+   dev_err(dsi->dev, "failed to configure pins");
goto err;
}
 
@@ -5214,7 +5214,7 @@ static int dsi_init_pll_data(struct dss_device *dss, 
struct dsi_data *dsi)
struct clk *clk;
int r;
 
-   clk = devm_clk_get(&dsi->pdev->dev, "sys_clk");
+   clk = devm_clk_get(dsi->dev, "sys_clk");
if (IS_ERR(clk)) {
DSSERR("can't get sys_clk\n");
return PTR_ERR(clk);
@@ -5317,7 +5317,7 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
return -ENOMEM;
 
dsi->dss = dss;
-   dsi->pdev = pdev;
+   dsi->dev = dev;
dev_set_drvdata(dev, dsi);
 
spin_lock_init(&dsi->irq_lock);
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 21/30] drm: omapdrm: dss: Pass omap_drm_private pointer to dss_mgr_ops

2018-02-13 Thread Laurent Pinchart
The dss_mgr_ops operations implemented by the omapdrm side have to look
up the omap_crtc objects from global variables as they are only passed a
channel number. In order to remove global variables in the omapdrm
driver pass the omap_drm_private pointer to the dss_mgr_ops. This
requires storing a pointer to the omap_drm_private in a global variable
on the DSS side as a temporary measure until the omapdrm and omapdss
drivers get merged.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 41 ++-
 drivers/gpu/drm/omapdrm/dss/output.c  | 28 +++-
 drivers/gpu/drm/omapdrm/omap_crtc.c   | 31 +++---
 drivers/gpu/drm/omapdrm/omap_crtc.h   |  2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c|  2 +-
 5 files changed, 64 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index aeaa337b29c7..318641f5bc24 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -59,6 +59,7 @@
 #define DISPC_IRQ_ACBIAS_COUNT_STAT3   (1 << 29)
 #define DISPC_IRQ_FRAMEDONE3   (1 << 30)
 
+struct omap_drm_private;
 struct omap_dss_device;
 struct dss_lcd_mgr_config;
 struct snd_aes_iec958;
@@ -635,25 +636,35 @@ struct device_node *dss_of_port_get_parent_device(struct 
device_node *port);
 u32 dss_of_port_get_port_number(struct device_node *port);
 
 struct dss_mgr_ops {
-   int (*connect)(enum omap_channel channel,
-   struct omap_dss_device *dst);
-   void (*disconnect)(enum omap_channel channel,
-   struct omap_dss_device *dst);
-
-   void (*start_update)(enum omap_channel channel);
-   int (*enable)(enum omap_channel channel);
-   void (*disable)(enum omap_channel channel);
-   void (*set_timings)(enum omap_channel channel,
-   const struct videomode *vm);
-   void (*set_lcd_config)(enum omap_channel channel,
-   const struct dss_lcd_mgr_config *config);
-   int (*register_framedone_handler)(enum omap_channel channel,
+   int (*connect)(struct omap_drm_private *priv,
+  enum omap_channel channel,
+  struct omap_dss_device *dst);
+   void (*disconnect)(struct omap_drm_private *priv,
+  enum omap_channel channel,
+  struct omap_dss_device *dst);
+
+   void (*start_update)(struct omap_drm_private *priv,
+enum omap_channel channel);
+   int (*enable)(struct omap_drm_private *priv,
+ enum omap_channel channel);
+   void (*disable)(struct omap_drm_private *priv,
+   enum omap_channel channel);
+   void (*set_timings)(struct omap_drm_private *priv,
+   enum omap_channel channel,
+   const struct videomode *vm);
+   void (*set_lcd_config)(struct omap_drm_private *priv,
+  enum omap_channel channel,
+  const struct dss_lcd_mgr_config *config);
+   int (*register_framedone_handler)(struct omap_drm_private *priv,
+   enum omap_channel channel,
void (*handler)(void *), void *data);
-   void (*unregister_framedone_handler)(enum omap_channel channel,
+   void (*unregister_framedone_handler)(struct omap_drm_private *priv,
+   enum omap_channel channel,
void (*handler)(void *), void *data);
 };
 
-int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
+int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops,
+   struct omap_drm_private *priv);
 void dss_uninstall_mgr_ops(void);
 
 int dss_mgr_connect(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c 
b/drivers/gpu/drm/omapdrm/dss/output.c
index 9ff29dea28ce..96b9d4cd505f 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -170,13 +170,16 @@ struct omap_dss_device 
*omapdss_find_output_from_display(struct omap_dss_device
 EXPORT_SYMBOL(omapdss_find_output_from_display);
 
 static const struct dss_mgr_ops *dss_mgr_ops;
+static struct omap_drm_private *dss_mgr_ops_priv;
 
-int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
+int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops,
+   struct omap_drm_private *priv)
 {
if (dss_mgr_ops)
return -EBUSY;
 
dss_mgr_ops = mgr_ops;
+   dss_mgr_ops_priv = priv;
 
return 0;
 }
@@ -185,58 +188,62 @@ EXPORT_SYMBOL(dss_install_mgr_ops);
 void dss_uninstall_mgr_ops(void)
 {
dss_mgr_ops = NULL;
+   dss_mgr_ops_priv = NULL;
 }
 EXPORT_SYMBOL(dss_uninstall_mgr_ops);
 
 int dss_mgr_connect(struct omap_dss_device *dssdev, struct omap_dss_device 
*dst)
 {
-   return dss_mgr_ops->connect(dssdev->dispc_c

Re: [PATCH v3 1/5] dt-bindings: media: adv7604: Add support for i2c_new_secondary_device

2018-02-13 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Tuesday, 13 February 2018 00:07:49 EET Kieran Bingham wrote:
> From: Jean-Michel Hautbois 
> 
> The ADV7604 has thirteen 256-byte maps that can be accessed via the main
> I²C ports. Each map has it own I²C address and acts as a standard slave
> device on the I²C bus.
> 
> Extend the device tree node bindings to be able to override the default
> addresses so that address conflicts with other devices on the same bus
> may be resolved at the board description level.
> 
> Signed-off-by: Jean-Michel Hautbois 
> [Kieran: Re-adapted for mainline]
> Signed-off-by: Kieran Bingham 
> Reviewed-by: Rob Herring 

Nitpicking, I might not mention i2c_new_secondary_device in the subject, as 
this is a DT bindings change. I don't mind too much though, as long as the 
bindings themselves don't contain Linux-specific information, and they don't, 
so

Reviewed-by: Laurent Pinchart 

> ---
> Based upon the original posting :
>   https://lkml.org/lkml/2014/10/22/469
> 
> v2:
>  - DT Binding update separated from code change
>  - Minor reword to commit message to account for DT only change.
>  - Collected Rob's RB tag.
> 
> v3:
>  - Split map register addresses into individual declarations.
> 
>  .../devicetree/bindings/media/i2c/adv7604.txt  | 18
> -- 1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt
> b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index
> 9cbd92eb5d05..ebb5f070c05b 100644
> --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt
> +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt
> @@ -13,7 +13,11 @@ Required Properties:
>  - "adi,adv7611" for the ADV7611
>  - "adi,adv7612" for the ADV7612
> 
> -  - reg: I2C slave address
> +  - reg: I2C slave addresses
> +The ADV76xx has up to thirteen 256-byte maps that can be accessed via
> the +main I²C ports. Each map has it own I²C address and acts as a
> standard +slave device on the I²C bus. The main address is mandatory,
> others are +optional and revert to defaults if not specified.
> 
>- hpd-gpios: References to the GPIOs that control the HDMI hot-plug
>  detection pins, one per HDMI input. The active flag indicates the GPIO
> @@ -35,6 +39,11 @@ Optional Properties:
> 
>- reset-gpios: Reference to the GPIO connected to the device's reset pin.
> - default-input: Select which input is selected after reset.
> +  - reg-names : Names of maps with programmable addresses.
> + It can contain any map needing a non-default address.
> + Possible maps names are :
> +   "main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe",
> +   "rep", "edid", "hdmi", "test", "cp", "vdp"
> 
>  Optional Endpoint Properties:
> 
> @@ -52,7 +61,12 @@ Example:
> 
>   hdmi_receiver@4c {
>   compatible = "adi,adv7611";
> - reg = <0x4c>;
> + /*
> +  * The edid page will be accessible @ 0x66 on the i2c bus. All
> +  * other maps will retain their default addresses.
> +  */
> + reg = <0x4c>, <0x66>;
> + reg-names "main", "edid";
> 
>   reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
>   hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;


-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3] Fix loading of module radeonfb on PowerMac

2018-02-13 Thread Bartlomiej Zolnierkiewicz
On Saturday, February 10, 2018 01:48:55 PM Mathieu Malaterre wrote:
>  Hi,
> 
> On Thu, Feb 8, 2018 at 2:28 PM, Bartlomiej Zolnierkiewicz
>  wrote:
> > On Wednesday, January 31, 2018 08:51:23 PM Mathieu Malaterre wrote:
> >> Bartlomiej,
> >>
> >> On Wed, Jan 31, 2018 at 12:57 PM, Bartlomiej Zolnierkiewicz
> >>  wrote:
> >> > On Tuesday, January 30, 2018 02:14:10 PM Mathieu Malaterre wrote:
> >> >> Bartlomiej,
> >> >>
> >> >> On Wed, Jan 3, 2018 at 3:47 PM, Bartlomiej Zolnierkiewicz
> >> >>  wrote:
> >> >> >
> >> >> > On Thursday, December 21, 2017 11:07:56 PM Mathieu Malaterre wrote:
> >> >> >> When the linux kernel is build with (typical kernel ship with Debian
> >> >> >> installer):
> >> >> >>
> >> >> >> CONFIG_FB_OF=y
> >> >> >> CONFIG_VT_HW_CONSOLE_BINDING=y
> >> >> >> CONFIG_FB_RADEON=m
> >> >> >>
> >> >> >> The offb driver takes precedence over module radeonfb. It is then
> >> >> >> impossible to load the module, error reported is:
> >> >> >>
> >> >> >> [   96.551486] radeonfb :00:10.0: enabling device (0006 -> 0007)
> >> >> >> [   96.551526] radeonfb :00:10.0: BAR 0: can't reserve [mem 
> >> >> >> 0x9800-0x9fff pref]
> >> >> >> [   96.551531] radeonfb (:00:10.0): cannot request region 0.
> >> >> >> [   96.551545] radeonfb: probe of :00:10.0 failed with error -16
> >> >> >>
> >> >> >> This patch reproduce the behavior of the module radeon, so as to 
> >> >> >> make it
> >> >> >> possible to load radeonfb when offb is first loaded.
> >> >> >>
> >> >> >> It should be noticed that `offb_destroy` is never called which 
> >> >> >> explain the
> >> >> >> need to skip error detection on the radeon side.
> >> >> >
> >> >> > This still needs to be explained more, from my last mail:
> >> >> >
> >> >> > "The last put_fb_info() on fb_info should call ->fb_destroy
> >> >> > (offb_destroy in our case) and remove_conflicting_framebuffers()
> >> >> > is calling put_fb_info() so there is some extra reference on
> >> >> > fb_info somewhere preventing it from going away.
> >> >> >
> >> >> > Please look into fixing this."
> >> >>
> >> >> I am not familiar with the fb stuff internals but here is what I see:
> >> >>
> >> >> # modprobe radeonfb
> >> >>
> >> >> leads to:
> >> >>
> >> >> [   52.058546] bus: 'pci': add driver radeonfb
> >> >> [   52.058588] bus: 'pci': driver_probe_device: matched device
> >> >> :00:10.0 with driver radeonfb
> >> >> [   52.058595] bus: 'pci': really_probe: probing driver radeonfb with
> >> >> device :00:10.0
> >> >> [   52.058608] devices_kset: Moving :00:10.0 to end of list
> >> >> [   52.058613] radeonfb_pci_register BEGIN
> >> >> [   52.058634] radeonfb :00:10.0: enabling device (0006 -> 0007)
> >> >> 
> >> >> [   52.058666] checking generic (9c008000 96000) vs hw (9800 
> >> >> 800)
> >> >> [   52.058667] fb: switching to radeonfb from OFfb ATY,RockHo
> >> >> [   52.058844] Console: switching to colour dummy device 80x25
> >> >> [   52.058860] device: 'fb0': device_unregister
> >> >> [   52.058956] PM: Removing info for No Bus:fb0
> >> >> [   52.059014] device: 'fb0': device_create_release
> >> >> 
> >> >> 
> >> >> [   52.059048] device: 'vtcon1': device_unregister
> >> >> [   52.059076] PM: Removing info for No Bus:vtcon1
> >> >> [   52.059091] device: 'vtcon1': device_create_release
> >> >> [   52.059107] radeonfb :00:10.0: BAR 0: can't reserve [mem
> >> >> 0x9800-0x9fff pref]
> >> >> [   52.256151] aper_base: 9800 MC_FB_LOC to: 9bff9800, MC_AGP_LOC
> >> >> to: a000
> >> >> [   52.256157] radeonfb (:00:10.0): Found 32768k of DDR 64 bits
> >> >> wide videoram
> >> >>
> >> >> I can confirm that offb_destroy is never called (not sure exactly
> >> >> why), but in any case the call to radeon_kick_out_firmware_fb happen
> >> >> much earlier, at least before the put_fb_info.
> >> >
> >> > It is okay, put_fb_info() is called indirectly by 
> >> > radeon_kick_out_firmware_fb()
> >> >
> >> > radeon_kick_out_firmware_fb()
> >> > remove_conflicting_framebuffers()
> >> > do_remove_conflicting_framebuffers()
> >> > do_unregister_framebuffer()
> >> > put_fb_info()
> >> >
> >> > offb_destroy() is not called because there is an extra reference on old
> >> > fb_info (->count == 2):
> >> >
> >> > static void put_fb_info(struct fb_info *fb_info)
> >> > {
> >> > if (!atomic_dec_and_test(&fb_info->count))
> >> > return;
> >> > if (fb_info->fbops->fb_destroy)
> >> > fb_info->fbops->fb_destroy(fb_info);
> >> > }
> >> >
> >> > The question is why there is an extra reference, probably user-space
> >> > is still holding the fb_info reference obtained in fb_open() call and
> >> > fb_release() is never called. Besides not calling fbops->fb_destroy()
> >> > this also causes missing call of fbops->fb_release() (in fb_release())
> >> > which some fb drivers are implementing (but not offb.c).
> >> >
> >> >> Could you descr

Re: [PATCH v3 2/5] dt-bindings: adv7511: Add support for i2c_new_secondary_device

2018-02-13 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Tuesday, 13 February 2018 00:07:50 EET Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> The ADV7511 has four 256-byte maps that can be accessed via the main I²C
> ports. Each map has it own I²C address and acts as a standard slave
> device on the I²C bus.
> 
> Extend the device tree node bindings to be able to override the default
> addresses so that address conflicts with other devices on the same bus
> may be resolved at the board description level.
> 
> Signed-off-by: Kieran Bingham 
> Reviewed-by: Rob Herring 

Same comment as for 1/5 about the subject line.

> ---
> v2:
>  - Fixed up reg: property description to account for multiple optional
>addresses.
>  - Minor reword to commit message to account for DT only change
>  - Collected Robs RB tag
> 
> v3:
>  - Split map register addresses into individual declarations.
> 
>  .../devicetree/bindings/display/bridge/adi,adv7511.txt | 18 +--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
> b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt index
> 0047b1394c70..3f85c351dd39 100644
> --- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
> @@ -14,7 +14,13 @@ Required properties:
>   "adi,adv7513"
>   "adi,adv7533"
> 
> -- reg: I2C slave address
> +- reg: I2C slave addresses
> +  The ADV7511 internal registers are split into four pages exposed through
> +  different I2C addresses, creating four register maps. Each map has it own
> +  I2C address and acts as a standard slave device on the I²C bus. The main
> +  address is mandatory, others are optional and revert to defaults if not
> +  specified.

Nitpicking again, you're mixing I2C and I²C.

> +
> 
>  The ADV7511 supports a large number of input data formats that differ by
> their color depth, color format, clock mode, bit justification and random
> @@ -70,6 +76,9 @@ Optional properties:
>rather than generate its own timings for HDMI output.
>  - clocks: from common clock binding: reference to the CEC clock.
>  - clock-names: from common clock binding: must be "cec".
> +- reg-names : Names of maps with programmable addresses.
> + It can contain any map needing a non-default address.
> + Possible maps names are : "main", "edid", "cec", "packet"
> 
>  Required nodes:
> 
> @@ -88,7 +97,12 @@ Example
> 
>   adv7511w: hdmi@39 {
>   compatible = "adi,adv7511w";
> - reg = <39>;
> + /*
> +  * The EDID page will be accessible on address 0x66 on the i2c

And now you're using lowercase :-)

> +  * bus. All other maps continue to use their default addresses.
> +  */
> + reg = <0x39>, <0x66>;
> + reg-names = "main", "edid";
>   interrupt-parent = <&gpio3>;
>   interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
>   clocks = <&cec_clock>;

With these fixed (or not, up to you),

Reviewed-by: Laurent Pinchart 

-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 3/5] [RFT] ARM: dts: wheat: Fix ADV7513 address usage

2018-02-13 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Tuesday, 13 February 2018 00:07:51 EET Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> The r8a7792 Wheat board has two ADV7513 devices sharing a single i2c
> bus, however in low power mode the ADV7513 will reset it's slave maps to
> use the hardware defined default addresses.
> 
> The ADV7511 driver was adapted to allow the two devices to be registered
> correctly - but it did not take into account the fault whereby the
> devices reset the addresses.
> 
> This results in an address conflict between the device using the default
> addresses, and the other device if it is in low-power-mode.
> 
> Repair this issue by moving both devices away from the default address
> definitions.
> 
> Signed-off-by: Kieran Bingham 

Reviewed-by: Laurent Pinchart 

> ---
> v2:
>  - Addition to series
> 
> v3:
>  - Split map register addresses into individual declarations.
> 
>  arch/arm/boot/dts/r8a7792-wheat.dts | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/r8a7792-wheat.dts
> b/arch/arm/boot/dts/r8a7792-wheat.dts index b9471b67b728..42fff8837eab
> 100644
> --- a/arch/arm/boot/dts/r8a7792-wheat.dts
> +++ b/arch/arm/boot/dts/r8a7792-wheat.dts
> @@ -240,9 +240,16 @@
>   status = "okay";
>   clock-frequency = <40>;
> 
> + /*
> +  * The adv75xx resets its addresses to defaults during low power power
> +  * mode. Because we have two ADV7513 devices on the same bus, we must
> +  * change both of them away from the defaults so that they do not
> +  * conflict.
> +  */
>   hdmi@3d {
>   compatible = "adi,adv7513";
> - reg = <0x3d>;
> + reg = <0x3d>, <0x2d>, <0x4d>, <0x5d>;
> + reg-names = "main", "cec", "edid", "packet";
> 
>   adi,input-depth = <8>;
>   adi,input-colorspace = "rgb";
> @@ -272,7 +279,8 @@
> 
>   hdmi@39 {
>   compatible = "adi,adv7513";
> - reg = <0x39>;
> + reg = <0x39>, <0x29>, <0x49>, <0x59>;
> + reg-names = "main", "cec", "edid", "packet";
> 
>   adi,input-depth = <8>;
>   adi,input-colorspace = "rgb";

-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 4/5] media: adv7604: Add support for i2c_new_secondary_device

2018-02-13 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Tuesday, 13 February 2018 00:07:52 EET Kieran Bingham wrote:
> From: Jean-Michel Hautbois 
> 
> The ADV7604 has thirteen 256-byte maps that can be accessed via the main
> I²C ports. Each map has it own I²C address and acts as a standard slave
> device on the I²C bus.
> 
> Allow a device tree node to override the default addresses so that
> address conflicts with other devices on the same bus may be resolved at
> the board description level.
> 
> Signed-off-by: Jean-Michel Hautbois 
> [Kieran: Re-adapted for mainline]
> Signed-off-by: Kieran Bingham 
> 
> ---
> Based upon the original posting :
>   https://lkml.org/lkml/2014/10/22/469
> 
> v2:
>  - Split out DT bindings from driver updates
>  - Return -EINVAL on error paths from adv76xx_dummy_client()
> 
>  drivers/media/i2c/adv7604.c | 62 ++
>  1 file changed, 40 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
> index 1544920ec52d..872e124793f8 100644
> --- a/drivers/media/i2c/adv7604.c
> +++ b/drivers/media/i2c/adv7604.c
> @@ -2734,6 +2734,27 @@ static const struct v4l2_ctrl_config
> adv76xx_ctrl_free_run_color = {
> 
>  /* - */
> 
> +struct adv76xx_register {

adv76xx_register seems to imply that this describes a particular register, 
while the structure describes a registers map. How about adv76xx_register_map, 
adv76xx_register_bank or adv76xx_register_page ?

> + const char *name;
> + u8 default_addr;
> +};
> +
> +static const struct adv76xx_register adv76xx_secondary_names[] = {

The table doesn't contain secondary names only as there's an entry for the 
main map. How about calling it adv76xx_default_addresses or something along 
the same line ?

> + [ADV76XX_PAGE_IO] = { "main", 0x4c },
> + [ADV7604_PAGE_AVLINK] = { "avlink", 0x42 },
> + [ADV76XX_PAGE_CEC] = { "cec", 0x40 },
> + [ADV76XX_PAGE_INFOFRAME] = { "infoframe", 0x3e },
> + [ADV7604_PAGE_ESDP] = { "esdp", 0x38 },
> + [ADV7604_PAGE_DPP] = { "dpp", 0x3c },
> + [ADV76XX_PAGE_AFE] = { "afe", 0x26 },
> + [ADV76XX_PAGE_REP] = { "rep", 0x32 },
> + [ADV76XX_PAGE_EDID] = { "edid", 0x36 },
> + [ADV76XX_PAGE_HDMI] = { "hdmi", 0x34 },
> + [ADV76XX_PAGE_TEST] = { "test", 0x30 },
> + [ADV76XX_PAGE_CP] = { "cp", 0x22 },
> + [ADV7604_PAGE_VDP] = { "vdp", 0x24 },
> +};
> +
>  static int adv76xx_core_init(struct v4l2_subdev *sd)
>  {
>   struct adv76xx_state *state = to_state(sd);
> @@ -2834,13 +2855,26 @@ static void adv76xx_unregister_clients(struct
> adv76xx_state *state) }
> 
>  static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd,
> - u8 addr, u8 io_reg)
> +unsigned int i)

Maybe unsigned int page ?

With these fixed,

Reviewed-by: Laurent Pinchart 

>  {
>   struct i2c_client *client = v4l2_get_subdevdata(sd);
> + struct adv76xx_state *state = to_state(sd);
> + struct adv76xx_platform_data *pdata = &state->pdata;
> + unsigned int io_reg = 0xf2 + i;
> + struct i2c_client *new_client;
> +
> + if (pdata && pdata->i2c_addresses[i])
> + new_client = i2c_new_dummy(client->adapter,
> +pdata->i2c_addresses[i]);
> + else
> + new_client = i2c_new_secondary_device(client,
> + adv76xx_secondary_names[i].name,
> + adv76xx_secondary_names[i].default_addr);
> 
> - if (addr)
> - io_write(sd, io_reg, addr << 1);
> - return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1);
> + if (new_client)
> + io_write(sd, io_reg, new_client->addr << 1);
> +
> + return new_client;
>  }
> 
>  static const struct adv76xx_reg_seq adv7604_recommended_settings_afe[] = {
> @@ -3115,20 +3149,6 @@ static int adv76xx_parse_dt(struct adv76xx_state
> *state) /* Disable the interrupt for now as no DT-based board uses it. */
> state->pdata.int1_config = ADV76XX_INT1_CONFIG_DISABLED;
> 
> - /* Use the default I2C addresses. */
> - state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_CEC] = 0x40;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_INFOFRAME] = 0x3e;
> - state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38;
> - state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_AFE] = 0x26;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_REP] = 0x32;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_EDID] = 0x36;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_HDMI] = 0x34;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_TEST] = 0x30;
> - state->pdata.i2c_addresses[ADV76XX_PAGE_CP] = 0x22;
> - state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24;
> -
>   /* Har

[Bug 117591] amdgpu: Black screens on A10-8700P (Carrizo) + R7 M260/M265 (Topaz) Combo

2018-02-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=117591

Jani Väinölä (jani.vain...@gmail.com) changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |CODE_FIX

--- Comment #13 from Jani Väinölä (jani.vain...@gmail.com) ---
I installed Kernel 4.15 on this machine now and it worked flawlessly. So I
consider this bug resolved on 4.15.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 117591] amdgpu: Black screens on A10-8700P (Carrizo) + R7 M260/M265 (Topaz) Combo

2018-02-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=117591

Jani Väinölä (jani.vain...@gmail.com) changed:

   What|Removed |Added

 Resolution|CODE_FIX|UNREPRODUCIBLE

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 5/5] drm: adv7511: Add support for i2c_new_secondary_device

2018-02-13 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Tuesday, 13 February 2018 00:07:53 EET Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> The ADV7511 has four 256-byte maps that can be accessed via the main I²C
> ports. Each map has it own I²C address and acts as a standard slave
> device on the I²C bus.
> 
> Allow a device tree node to override the default addresses so that
> address conflicts with other devices on the same bus may be resolved at
> the board description level.
> 
> Signed-off-by: Kieran Bingham 
> ---
> v2:
>  - Update missing edid-i2c address setting
>  - Split out DT bindings
>  - Rename and move the I2C default addresses to their own section
> 
>  drivers/gpu/drm/bridge/adv7511/adv7511.h |  6 
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 
>  2 files changed, 33 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index d034b2cb5eee..04e6759ee45b
> 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> @@ -93,6 +93,11 @@
>  #define ADV7511_REG_CHIP_ID_HIGH 0xf5
>  #define ADV7511_REG_CHIP_ID_LOW  0xf6
> 
> +/* Hardware defined default addresses for i2c register maps */

s/i2c/I2C/ ? That's really because I had to find something :-)

Reviewed-by: Laurent Pinchart 

> +#define ADV7511_CEC_I2C_ADDR_DEFAULT 0x3c
> +#define ADV7511_EDID_I2C_ADDR_DEFAULT0x3f
> +#define ADV7511_PACKET_I2C_ADDR_DEFAULT  0x38
> +
>  #define ADV7511_CSC_ENABLE   BIT(7)
>  #define ADV7511_CSC_UPDATE_MODE  BIT(5)
> 
> @@ -322,6 +327,7 @@ struct adv7511 {
>   struct i2c_client *i2c_main;
>   struct i2c_client *i2c_edid;
>   struct i2c_client *i2c_cec;
> + struct i2c_client *i2c_packet;
> 
>   struct regmap *regmap;
>   struct regmap *regmap_cec;
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index
> efa29db5fc2b..5e61b928c9c0 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
>   /* Reading the EDID only works if the device is powered */
>   if (!adv7511->powered) {
>   unsigned int edid_i2c_addr =
> - (adv7511->i2c_main->addr << 1) + 4;
> + (adv7511->i2c_edid->addr << 1);
> 
>   __adv7511_power_on(adv7511);
> 
> @@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511
> *adv) {
>   int ret;
> 
> - adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,
> -  adv->i2c_main->addr - 1);
> + adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
> + ADV7511_CEC_I2C_ADDR_DEFAULT);
>   if (!adv->i2c_cec)
> - return -ENOMEM;
> + return -EINVAL;
>   i2c_set_clientdata(adv->i2c_cec, adv);
> 
>   adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
> @@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const
> struct i2c_device_id *id) struct adv7511_link_config link_config;
>   struct adv7511 *adv7511;
>   struct device *dev = &i2c->dev;
> - unsigned int main_i2c_addr = i2c->addr << 1;
> - unsigned int edid_i2c_addr = main_i2c_addr + 4;
>   unsigned int val;
>   int ret;
> 
> @@ -1153,24 +1151,35 @@ static int adv7511_probe(struct i2c_client *i2c,
> const struct i2c_device_id *id) if (ret)
>   goto uninit_regulators;
> 
> - regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);
> - regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
> -  main_i2c_addr - 0xa);
> - regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
> -  main_i2c_addr - 2);
> -
>   adv7511_packet_disable(adv7511, 0x);
> 
> - adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1);
> + adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
> + ADV7511_EDID_I2C_ADDR_DEFAULT);
>   if (!adv7511->i2c_edid) {
> - ret = -ENOMEM;
> + ret = -EINVAL;
>   goto uninit_regulators;
>   }
> 
> + regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
> +  adv7511->i2c_edid->addr << 1);
> +
>   ret = adv7511_init_cec_regmap(adv7511);
>   if (ret)
>   goto err_i2c_unregister_edid;
> 
> + regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
> +  adv7511->i2c_cec->addr << 1);
> +
> + adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
> + ADV7511_PACKET_I2C_ADDR_DEFAULT);
> + if (!adv7511->i2c_packet) {
> +   

Re: [PATCH 02/11] video: fbdev: kconfig: Remove blank help text

2018-02-13 Thread Bartlomiej Zolnierkiewicz
On Thursday, February 01, 2018 05:56:18 PM Ulf Magnusson wrote:
> On Thu, Feb 1, 2018 at 4:52 PM, Bartlomiej Zolnierkiewicz
>  wrote:
> >
> > Hi,
> >
> > On Wednesday, January 31, 2018 10:34:21 AM Ulf Magnusson wrote:
> >> Blank help texts are probably either a typo, a Kconfig misunderstanding,
> >> or some kind of half-committing to adding a help text (in which case a
> >> TODO comment would be clearer, if the help text really can't be added
> >> right away).
> >>
> >> Best to remove them, IMO.
> >
> > How about actually adding some meaningful help texts instead
> > (as a general rule each user visible option should have valid
> > help text)?
> >
> >> Signed-off-by: Ulf Magnusson 
> >> ---
> >>  drivers/video/fbdev/Kconfig | 1 -
> >>  1 file changed, 1 deletion(-)
> >>
> >> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
> >> index 6962b4583fd7..11e699f1062b 100644
> >> --- a/drivers/video/fbdev/Kconfig
> >> +++ b/drivers/video/fbdev/Kconfig
> >> @@ -1156,7 +1156,6 @@ config FB_I810_I2C
> >>   bool "Enable DDC Support"
> >>   depends on FB_I810 && FB_I810_GTF
> >>   select FB_DDC
> >> - help
> >
> > Please add a missing help text instead (take a look at FB_SAVAGE_I2C
> > config option to see how a valid help text entry should look like).
> 
> The FB_I810_I2C option was added in 74f6ae84b23 ("[PATCH] i810fb: Add
> i2c/DDC support"). What do you think about adding this bit from the
> commit message as the help text?
> 
>   Add DDC/I2C support for i810fb.  This will allow the driver to get display
>   information, especially for monitors with fickle timings.

Seems fine to me, please add:

If unsure, say Y.

and send it as a proper patch.

> I'm not familiar with this code, so I don't want to do too much
> guessing myself. :)

:)

> > In the longer term we should consider removing *_I2C config options
> > and just make the main config options always enable I2C subsystem
> > directly if needed/useful (some fbdev drivers are doing it this way
> > already).
> >
> >>  config FB_LE80578
> >>   tristate "Intel LE80578 (Vermilion) support"
> >
> > Best regards,
> > --
> > Bartlomiej Zolnierkiewicz
> > Samsung R&D Institute Poland
> > Samsung Electronics
> >
> 
> Cheers,
> Ulf

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 99353] Kaveri 7400K shows random colored noise instead of GUI in X or Wayland

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=99353

--- Comment #27 from Bong Cosca  ---
Created attachment 137313
  --> https://bugs.freedesktop.org/attachment.cgi?id=137313&action=edit
drm.debug=0x1e

Output generated by: dmesg | grep drm

Additional trace log to aid perhaps in finding the root cause. I would gladly
help out in tracking this bug; already tried looking at the sources but really
don't know what to look for. Perhaps a nudge from someone knowledgeable so we
can narrow it down.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers

2018-02-13 Thread Tomasz Figa
On Tue, Feb 13, 2018 at 9:00 PM, Robin Murphy  wrote:
> On 13/02/18 07:44, Tomasz Figa wrote:
>>
>> Hi Vivek,
>>
>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
>>  wrote:
>>>
>>> The device link allows the pm framework to tie the supplier and
>>> consumer. So, whenever the consumer is powered-on the supplier
>>> is powered-on first.
>>>
>>> There are however cases in which the consumer wants to power-on
>>> the supplier, but not itself.
>>> E.g., A Graphics or multimedia driver wants to power-on the SMMU
>>> to unmap a buffer and finish the TLB operations without powering
>>> on itself.
>>
>>
>> This sounds strange to me. If the SMMU is powered down, wouldn't the
>> TLB lose its contents as well (and so no flushing needed)?
>
>
> Depends on implementation details - if runtime PM is actually implemented
> via external clock gating (in the absence of fine-grained power domains),
> then "suspended" TLBs might both retain state and not receive invalidation
> requests, which is really the worst case.

Agreed. That's why in "[PATCH v7 3/6] iommu/arm-smmu: Invoke
pm_runtime during probe, add/remove device" I actually suggested
managing clocks separately from runtime PM. At least until runtime PM
framework arrives at a state, where multiple power states can be
managed, i.e. full power state, clock-gated state, domain-off state.
(I think I might have seen some ongoing work on this on LWN though...)

>
>> Other than that, what kind of hardware operations would be needed
>> besides just updating the page tables from the CPU?
>
>
> Domain attach/detach also require updating SMMU hardware state (and possibly
> TLB maintenance), but don't logically require the master device itself to be
> active at the time.

Wouldn't this hardware state need to be reinitialized anyway after
respective power domain power cycles? (In other words, hardware would
only need programming if it's powered on at the moment.)

Best regards,
Tomasz
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-13 Thread Robin Murphy

On 13/02/18 08:24, Tomasz Figa wrote:

Hi Vivek,

Thanks for the patch. Please see my comments inline.

On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
 wrote:

From: Sricharan R 

The smmu device probe/remove and add/remove master device callbacks
gets called when the smmu is not linked to its master, that is without
the context of the master device. So calling runtime apis in those places
separately.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
---
  drivers/iommu/arm-smmu.c | 42 ++
  1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 9e2f917e16c2..c024f69c1682 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 struct arm_smmu_device *smmu = smmu_domain->smmu;
 struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
-   int irq;
+   int ret, irq;

 if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
 return;

+   ret = pm_runtime_get_sync(smmu->dev);
+   if (ret)
+   return;


pm_runtime_get_sync() will return 0 if the device was powered off, 1
if it was already/still powered on or runtime PM is not compiled in,
or a negative value on error, so shouldn't the test be (ret < 0)?

Moreover, I'm actually wondering if it makes any sense to power up the
hardware just to program it and power it down again. In a system where
the IOMMU is located within a power domain, it would cause the IOMMU
block to lose its state anyway.


This is generally for the case where the SMMU internal state remains 
active, but the programming interface needs to be powered up in order to 
access it.



Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add
pm_runtime/sleep ops", perhaps it would make more sense to just
control the clocks independently of runtime PM? Then, runtime PM could
be used for real power management, e.g. really powering the block up
and down, for further power saving.


Unfortunately that ends up pretty much unmanageable, because there are 
numerous different SMMU microarchitectures with fundamentally different 
clock/power domain schemes (multiplied by individual SoC integration 
possibilities). Since this is fundamentally a generic architectural 
driver, adding explicit clock support would probably make the whole 
thing about 50% clock code, with complicated decision trees around every 
hardware access calculating which clocks are necessary for a given 
operation on a given system. That maintainability aspect is why we've 
already nacked such a fine-grained approach in the past.


Robin.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 5/5] drm: adv7511: Add support for i2c_new_secondary_device

2018-02-13 Thread Kieran Bingham
Hi Dan

Thank you for the review,

On 13/02/18 07:23, Dan Carpenter wrote:
> On Mon, Feb 12, 2018 at 06:11:57PM +, Kieran Bingham wrote:
>> +adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
>> +ADV7511_PACKET_I2C_ADDR_DEFAULT);
>> +if (!adv7511->i2c_packet) {
>> +ret = -EINVAL;
>> +goto err_unregister_cec;
>> +}
>> +
>> +regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
>> + adv7511->i2c_packet->addr << 1);
>> +
>>  INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
>>  
>>  if (i2c->irq) {
>> @@ -1181,7 +1190,7 @@ static int adv7511_probe(struct i2c_client *i2c, const 
>> struct i2c_device_id *id)
>>  IRQF_ONESHOT, dev_name(dev),
>>  adv7511);
>>  if (ret)
>> -goto err_unregister_cec;
>> +goto err_unregister_packet;
>>  }
>>  
>>  adv7511_power_off(adv7511);
> 
> There is another goto which needs to be updated if adv7511_cec_init()
> fails.

Aha - thanks - I'll look into this now.


> 
>> @@ -1203,6 +1212,8 @@ static int adv7511_probe(struct i2c_client *i2c, const 
>> struct i2c_device_id *id)
>>  adv7511_audio_init(dev, adv7511);
>>  return 0;
>>  
>> +err_unregister_packet:
>> +i2c_unregister_device(adv7511->i2c_packet);
>>  err_unregister_cec:
>>  i2c_unregister_device(adv7511->i2c_cec);
>>  if (adv7511->cec_clk)
> 
> 
> regards,
> dan carpenter
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 1/5] dt-bindings: media: adv7604: Add support for i2c_new_secondary_device

2018-02-13 Thread Kieran Bingham
Hi Laurent,

On 13/02/18 12:06, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.

Thank you for your review,

> On Tuesday, 13 February 2018 00:07:49 EET Kieran Bingham wrote:
>> From: Jean-Michel Hautbois 
>>
>> The ADV7604 has thirteen 256-byte maps that can be accessed via the main
>> I²C ports. Each map has it own I²C address and acts as a standard slave
>> device on the I²C bus.
>>
>> Extend the device tree node bindings to be able to override the default
>> addresses so that address conflicts with other devices on the same bus
>> may be resolved at the board description level.
>>
>> Signed-off-by: Jean-Michel Hautbois 
>> [Kieran: Re-adapted for mainline]
>> Signed-off-by: Kieran Bingham 
>> Reviewed-by: Rob Herring 
> 
> Nitpicking, I might not mention i2c_new_secondary_device in the subject, as 
> this is a DT bindings change. I don't mind too much though, as long as the 
> bindings themselves don't contain Linux-specific information, and they don't, 
> so
How about: ... adv7604: Extend bindings to allow specifying slave map addresses



> Reviewed-by: Laurent Pinchart 

Collected, thanks.

--
Kieran


> 
>> ---
>> Based upon the original posting :
>>   https://lkml.org/lkml/2014/10/22/469
>>
>> v2:
>>  - DT Binding update separated from code change
>>  - Minor reword to commit message to account for DT only change.
>>  - Collected Rob's RB tag.
>>
>> v3:
>>  - Split map register addresses into individual declarations.
>>
>>  .../devicetree/bindings/media/i2c/adv7604.txt  | 18
>> -- 1 file changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt
>> b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index
>> 9cbd92eb5d05..ebb5f070c05b 100644
>> --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt
>> +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt
>> @@ -13,7 +13,11 @@ Required Properties:
>>  - "adi,adv7611" for the ADV7611
>>  - "adi,adv7612" for the ADV7612
>>
>> -  - reg: I2C slave address
>> +  - reg: I2C slave addresses
>> +The ADV76xx has up to thirteen 256-byte maps that can be accessed via
>> the +main I²C ports. Each map has it own I²C address and acts as a
>> standard +slave device on the I²C bus. The main address is mandatory,
>> others are +optional and revert to defaults if not specified.
>>
>>- hpd-gpios: References to the GPIOs that control the HDMI hot-plug
>>  detection pins, one per HDMI input. The active flag indicates the GPIO
>> @@ -35,6 +39,11 @@ Optional Properties:
>>
>>- reset-gpios: Reference to the GPIO connected to the device's reset pin.
>> - default-input: Select which input is selected after reset.
>> +  - reg-names : Names of maps with programmable addresses.
>> +It can contain any map needing a non-default address.
>> +Possible maps names are :
>> +  "main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe",
>> +  "rep", "edid", "hdmi", "test", "cp", "vdp"
>>
>>  Optional Endpoint Properties:
>>
>> @@ -52,7 +61,12 @@ Example:
>>
>>  hdmi_receiver@4c {
>>  compatible = "adi,adv7611";
>> -reg = <0x4c>;
>> +/*
>> + * The edid page will be accessible @ 0x66 on the i2c bus. All
>> + * other maps will retain their default addresses.
>> + */
>> +reg = <0x4c>, <0x66>;
>> +reg-names "main", "edid";
>>
>>  reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
>>  hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;
> 
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 5/8] drm: Handle aspect ratio info in atomic and legacy modeset paths

2018-02-13 Thread Ville Syrjälä
On Tue, Feb 13, 2018 at 10:21:15AM +0530, Nautiyal, Ankit K wrote:
> Hi Ville,
> 
> As per our last discussion, following points were discussed:
> 
> 1. To suppress the aspect-ratio info from getblob ioctl to a user that 
> does not support it:
> 
>  i. A new flag must be added to drm_blob_property to mark if the 
> blob has mode data.
> 
>  ii. This flag must be set when the user tries do an atomic modeset.
> 
>  iii. In the getblob ioctl, based on the above flag, it can be 
> determined that if the blob
> 
>  has mode data, and the aspect ratio info can be suppressed in 
> getblob ioctl, if user does not support it.
> 
> 2. Instead of adding aspect ratio capabilities in drm_atomic_state, pass 
> on the file_priv which already has
> 
> the required information to the function drm_mode_convert_umode.
> 
> It will require addition of an new argument file_priv to several 
> functions, but that is right thing to do,
> 
> as file_priv is the correct structure for the capability information.
> 
> 3. Changing the usermode aspect ratio flag bits, without change in the
> picture_aspect_ratio would not matter, and does not need to be handled 
> in this patch.
> 
> 
> I just have one query here. We have agreed to modify 
> drm_mode_convert_umode, to filter out the aspect-ratio
> 
> info if user has not set aspect-ratio capability, but do we need a 
> similar change the drm_mode_convert_to_umode?

I think you maybe had those backwards.

drm_mode_convert_umode(), or more likely its relevant callers setcrtc
and setproperty, need to reject the mode if the client cap is not set.

drm_mode_convert_to_umode(), or rather its callers getblob and getcrtc,
need to filter out the flags.

> 
> If we do, I am not sure if it would be possible to have the file_priv to 
> /drm_atomic_set_mode_for_crtc/, which calls
> 
> drm_mode_convert_to_umode.  The function /drm_atomic_set_mode_for_crtc/ 
> is used to set mode, originating by kernel,
> 
> and make a blob from the kernel mode, which it saves in crtc_state.
> 
> This function /: drm_atomic_set_mode_for_crtc, /is called by several 
> helper functions and driver functions, and passing
> 
> file_priv from all these functions does not seem to be plausible.

I don't think we need to plumb it quite that deep. Doing the
check in drm_atomic_crtc_set_property() should be sufficient.

> 
> Any suggestions on how to handle this situation?
> 
> 
> Regards,
> 
> Ankit
> 
> 
> On 2/8/2018 9:59 AM, Nautiyal, Ankit K wrote:
> > Hi Ville,
> >
> > I still have some queries regarding the handling of aspect ratio flags 
> > in getblob ioctl.
> >
> > Please find below my responses inline.
> >
> >
> > On 2/1/2018 6:24 PM, Ville Syrjälä wrote:
> >> On Thu, Feb 01, 2018 at 04:35:22PM +0530, Nautiyal, Ankit K wrote:
> >>> Hi Ville,
> >>>
> >>> Appreciate your time and the suggestions.
> >>> Please find my response inline:
> >>>
> >>> On 1/31/2018 6:39 PM, Ville Syrjälä wrote:
>  On Wed, Jan 31, 2018 at 12:04:52PM +0530, Nautiyal, Ankit K wrote:
> > On 1/30/2018 12:23 AM, Ville Syrjälä wrote:
> >> On Fri, Jan 12, 2018 at 11:51:33AM +0530, Nautiyal, Ankit K wrote:
> >>> From: Ankit Nautiyal 
> >>>
> >>> If the user mode does not support aspect-ratio, and requests for
> >>> a modeset, then the flag bits representing aspect ratio in the
> >>> given user-mode must be rejected.
> >>> Similarly, while preparing a user-mode from kernel mode, the
> >>> aspect-ratio info must not be given, if aspect-ratio is not
> >>> supported by the user.
> >>>
> >>> This patch:
> >>> 1. adds a new bit field aspect_ratio_allowed in drm_atomic_state,
> >>> which is set only if the aspect-ratio is supported by the user.
> >>> 2. discards the aspect-ratio info from the user mode while
> >>> preparing kernel mode structure, during modeset, if the
> >>> user does not support aspect ratio.
> >>> 3. avoids setting the aspect-ratio info in user-mode, while
> >>> converting user-mode from the kernel-mode.
> >>>
> >>> Signed-off-by: Ankit Nautiyal 
> >>>
> >>> V3: Addressed review comments from Ville:
> >>> -Do not corrupt the current crtc state by updating aspect ratio
> >>> on the fly.
> >>> ---
> >>> drivers/gpu/drm/drm_atomic.c | 61 
> >>> +---
> >>> drivers/gpu/drm/drm_crtc.c   | 19 ++
> >>> include/drm/drm_atomic.h |  2 ++
> >>> 3 files changed, 79 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/drm_atomic.c 
> >>> b/drivers/gpu/drm/drm_atomic.c
> >>> index 69ff763..39313e2 100644
> >>> --- a/drivers/gpu/drm/drm_atomic.c
> >>> +++ b/drivers/gpu/drm/drm_atomic.c
> >>> @@ -316,6 +316,35 @@ static s32 __user 
> >>> *get_out_fence_for_crtc(struct drm_atomic_state *state,
> >>> return fence_ptr;
> >>> }
> >>> +/**
> >>> + * drm_atomic_allow_a

Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Ville Syrjälä
On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote:
> On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote:
> > Hi! I'm periodically getting following message in dmesg on Lenovo
> > Thinkpad X1 Carbon 3rd generation:
> > 
> > [drm] Reducing the compressed framebuffer size. This may lead to less power 
> > savings than a non-reduced-size. Try to increase stolen memory size if 
> > available in BIOS.
> > 
> > In BIOS I already set GPU size to 512M, but this did not help. Also
> > update to last BIOS version did not help.
> > 
> > So why this message is periodically print in dmesg? And what can I do
> > with this problem?
> > 
> > And why cannot Linux kernel allocate itself more memory for GPU (if BIOS
> > can/could do that)? Is not 512MB for GPU enough?
> 
> And here is output from lspci, which clearly says that 512MB is already
> set for GPU:

The PCI BAR size has nothing to do with the size of the stolen memory.
The BAR just provides a window into the global GTT address space of the
GPU. Stolen memory is a contiguous chunk of physical memory carved out
by the BIOS. The BIOS may or may not provide a knob to change the size
of the stolen memory.

> 
> $ lspci -v -s 00:02.0
> 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 (rev 
> 09) (prog-if 00 [VGA controller])
> Subsystem: Lenovo HD Graphics 5500
> Flags: bus master, fast devsel, latency 0, IRQ 46
> Memory at e000 (64-bit, non-prefetchable) [size=16M]
> Memory at c000 (64-bit, prefetchable) [size=512M]
> I/O ports at 3000 [size=64]
> [virtual] Expansion ROM at 000c [disabled] [size=128K]
> Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
> Capabilities: [d0] Power Management version 2
> Capabilities: [a4] PCI Advanced Features
> Kernel driver in use: i915
> Kernel modules: i915
> 
> -- 
> Pali Rohár
> pali.ro...@gmail.com
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too

2018-02-13 Thread Ville Syrjälä
On Tue, Feb 13, 2018 at 10:33:28AM +0100, Maarten Lankhorst wrote:
> Hey,
> 
> Op 13-02-18 om 10:16 schreef Chris Wilson:
> > Quoting Maarten Lankhorst (2018-02-13 09:12:01)
> >> Programs like redshift set the legacy gamma for X.org every 5 seconds.
> >> Because atomic commits wait for vblank completion, we get a frame drop
> >> every 5 seconds because of the legacy gamma update.
> >>
> >> Work around this by setting the legacy_cursor_update flag, to force
> >> legacy gamma updates not to be synced against vblank.
> >>
> >> Reported-by: Tholin #intel-gfx
> >> Signed-off-by: Maarten Lankhorst 
> > Reminiscing: Remember the time we had all those vblank workers patches,
> > one of which was to do async gamma updates (apply the last one on the
> > vblank). Motivated by gnome-shell and the ilk doing a gamma animation
> > for fade-out on logout (which I guess they gave up on since it happened
> > to be so slow as to extend logout ;).
> 
> That special case could be handled by userspace with atomic commits, I don't
> think it's worth optimizing it further..

We need to eventually move the gamma updates (and other single buffered
registers) to a vblank worker or something similar. Otherwise they will
tear.

-- 
Ville Syrjälä
Intel OTC
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 1/5] dt-bindings: media: adv7604: Add support for i2c_new_secondary_device

2018-02-13 Thread Laurent Pinchart
Hi Kieran,

On Tuesday, 13 February 2018 15:14:43 EET Kieran Bingham wrote:
> On 13/02/18 12:06, Laurent Pinchart wrote:
> > On Tuesday, 13 February 2018 00:07:49 EET Kieran Bingham wrote:
> >> From: Jean-Michel Hautbois 
> >> 
> >> The ADV7604 has thirteen 256-byte maps that can be accessed via the main
> >> I²C ports. Each map has it own I²C address and acts as a standard slave
> >> device on the I²C bus.
> >> 
> >> Extend the device tree node bindings to be able to override the default
> >> addresses so that address conflicts with other devices on the same bus
> >> may be resolved at the board description level.
> >> 
> >> Signed-off-by: Jean-Michel Hautbois 
> >> [Kieran: Re-adapted for mainline]
> >> Signed-off-by: Kieran Bingham 
> >> Reviewed-by: Rob Herring 
> > 
> > Nitpicking, I might not mention i2c_new_secondary_device in the subject,
> > as this is a DT bindings change. I don't mind too much though, as long as
> > the bindings themselves don't contain Linux-specific information, and they
> > don't, so
> 
> How about: ... adv7604: Extend bindings to allow specifying slave map
> addresses

Sounds good to me.

> > Reviewed-by: Laurent Pinchart 
> 
> Collected, thanks.
> 
> --
> Kieran
> 
> >> ---
> >> 
> >> Based upon the original posting :
> >>   https://lkml.org/lkml/2014/10/22/469
> >> 
> >> v2:
> >>  - DT Binding update separated from code change
> >>  - Minor reword to commit message to account for DT only change.
> >>  - Collected Rob's RB tag.
> >> 
> >> v3:
> >>  - Split map register addresses into individual declarations.
> >>  
> >>  .../devicetree/bindings/media/i2c/adv7604.txt  | 18
> >> 
> >> -- 1 file changed, 16 insertions(+), 2 deletions(-)
> >> 
> >> diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt
> >> b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index
> >> 9cbd92eb5d05..ebb5f070c05b 100644
> >> --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt
> >> +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt
> >> 
> >> @@ -13,7 +13,11 @@ Required Properties:
> >>  - "adi,adv7611" for the ADV7611
> >>  - "adi,adv7612" for the ADV7612
> >> 
> >> -  - reg: I2C slave address
> >> +  - reg: I2C slave addresses
> >> +The ADV76xx has up to thirteen 256-byte maps that can be accessed
> >> via
> >> the +main I²C ports. Each map has it own I²C address and acts as a
> >> standard +slave device on the I²C bus. The main address is mandatory,
> >> others are +optional and revert to defaults if not specified.
> >> 
> >>- hpd-gpios: References to the GPIOs that control the HDMI hot-plug
> >>
> >>  detection pins, one per HDMI input. The active flag indicates the
> >>  GPIO
> >> 
> >> @@ -35,6 +39,11 @@ Optional Properties:
> >>- reset-gpios: Reference to the GPIO connected to the device's reset
> >>pin.
> >> 
> >> - default-input: Select which input is selected after reset.
> >> +  - reg-names : Names of maps with programmable addresses.
> >> +  It can contain any map needing a non-default address.
> >> +  Possible maps names are :
> >> +"main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe",
> >> +"rep", "edid", "hdmi", "test", "cp", "vdp"
> >> 
> >>  Optional Endpoint Properties:
> >> @@ -52,7 +61,12 @@ Example:
> >>hdmi_receiver@4c {
> >>
> >>compatible = "adi,adv7611";
> >> 
> >> -  reg = <0x4c>;
> >> +  /*
> >> +   * The edid page will be accessible @ 0x66 on the i2c bus. All
> >> +   * other maps will retain their default addresses.
> >> +   */
> >> +  reg = <0x4c>, <0x66>;
> >> +  reg-names "main", "edid";
> >> 
> >>reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
> >>hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;

-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers

2018-02-13 Thread Robin Murphy

On 13/02/18 12:54, Tomasz Figa wrote:

On Tue, Feb 13, 2018 at 9:00 PM, Robin Murphy  wrote:

On 13/02/18 07:44, Tomasz Figa wrote:


Hi Vivek,

On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
 wrote:


The device link allows the pm framework to tie the supplier and
consumer. So, whenever the consumer is powered-on the supplier
is powered-on first.

There are however cases in which the consumer wants to power-on
the supplier, but not itself.
E.g., A Graphics or multimedia driver wants to power-on the SMMU
to unmap a buffer and finish the TLB operations without powering
on itself.



This sounds strange to me. If the SMMU is powered down, wouldn't the
TLB lose its contents as well (and so no flushing needed)?



Depends on implementation details - if runtime PM is actually implemented
via external clock gating (in the absence of fine-grained power domains),
then "suspended" TLBs might both retain state and not receive invalidation
requests, which is really the worst case.


Agreed. That's why in "[PATCH v7 3/6] iommu/arm-smmu: Invoke
pm_runtime during probe, add/remove device" I actually suggested
managing clocks separately from runtime PM. At least until runtime PM
framework arrives at a state, where multiple power states can be
managed, i.e. full power state, clock-gated state, domain-off state.
(I think I might have seen some ongoing work on this on LWN though...)




Other than that, what kind of hardware operations would be needed
besides just updating the page tables from the CPU?



Domain attach/detach also require updating SMMU hardware state (and possibly
TLB maintenance), but don't logically require the master device itself to be
active at the time.


Wouldn't this hardware state need to be reinitialized anyway after
respective power domain power cycles? (In other words, hardware would
only need programming if it's powered on at the moment.)


Yes, if the entire SMMU was fully powered down because all masters were 
inactive, then all that should need to be done is to update the software 
shadow state in the expectation that arm_smmu_reset() would re-sync it 
upon TCU powerup. If at least some part of the internal logic remains 
active, though, then you may or may not need to fiddle with zero or more 
clocks and/or power domains (depending on microarchitecture and 
integration) in order to be sure that everything from the programming 
slave interface through to wherever that state is kept works correctly 
so that it can be changed.


The main motivation here is that the Qualcomm SMMU microarchitecture 
apparently allows the programming interface to be shut down separately 
from the TCU core (context banks, page table walker, etc.), and they get 
an appreciable power saving from doing so. This is different from, say, 
the Arm Ltd. implementations, where the entire TCU is a single 
clock/power domain internally (although you could maybe still gate the 
external APB interface clock).


As the previous discussions have shown, this is really, really hard to 
do properly in a generic manner.


Robin.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Pali Rohár
On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote:
> On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote:
> > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote:
> > > Hi! I'm periodically getting following message in dmesg on Lenovo
> > > Thinkpad X1 Carbon 3rd generation:
> > > 
> > > [drm] Reducing the compressed framebuffer size. This may lead to less 
> > > power savings than a non-reduced-size. Try to increase stolen memory size 
> > > if available in BIOS.
> > > 
> > > In BIOS I already set GPU size to 512M, but this did not help. Also
> > > update to last BIOS version did not help.
> > > 
> > > So why this message is periodically print in dmesg? And what can I do
> > > with this problem?
> > > 
> > > And why cannot Linux kernel allocate itself more memory for GPU (if BIOS
> > > can/could do that)? Is not 512MB for GPU enough?
> > 
> > And here is output from lspci, which clearly says that 512MB is already
> > set for GPU:
> 
> The PCI BAR size has nothing to do with the size of the stolen memory.
> The BAR just provides a window into the global GTT address space of the
> GPU. Stolen memory is a contiguous chunk of physical memory carved out
> by the BIOS.

Ok, how could I detect how much memory was stolen?

In dmesg I see following lines:

[0.00] e820: BIOS-provided physical RAM map:
[0.00] BIOS-e820: [mem 0x-0x00057fff] usable
[0.00] BIOS-e820: [mem 0x00058000-0x00058fff] reserved
[0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] usable
[0.00] BIOS-e820: [mem 0x0008c000-0x0009] reserved
[0.00] BIOS-e820: [mem 0x000e-0x000f] reserved
[0.00] BIOS-e820: [mem 0x0010-0xab908fff] usable
[0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] type 20
[0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] reserved
[0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] ACPI NVS
[0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] ACPI data
[0.00] BIOS-e820: [mem 0xacdff000-0xacdf] usable
[0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] reserved
[0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved
[0.00] BIOS-e820: [mem 0x0001-0x00024dff] usable

[0.00] Reserving Intel graphics memory at 
0xae00-0xafff

[0.00] Memory: 7972840K/8282704K available (6196K kernel code, 1159K 
rwdata, 2848K rodata, 1408K init, 688K bss, 309864K reserved, 0K cma-reserved)

> The BIOS may or may not provide a knob to change the size
> of the stolen memory.

In BIOS Setup screen I have option to choose GPU memory and I set it to
max 512MB. So this is not the right option...

And why cannot kernel use some continuous check of RAM itself?

> > 
> > $ lspci -v -s 00:02.0
> > 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 (rev 
> > 09) (prog-if 00 [VGA controller])
> > Subsystem: Lenovo HD Graphics 5500
> > Flags: bus master, fast devsel, latency 0, IRQ 46
> > Memory at e000 (64-bit, non-prefetchable) [size=16M]
> > Memory at c000 (64-bit, prefetchable) [size=512M]
> > I/O ports at 3000 [size=64]
> > [virtual] Expansion ROM at 000c [disabled] [size=128K]
> > Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
> > Capabilities: [d0] Power Management version 2
> > Capabilities: [a4] PCI Advanced Features
> > Kernel driver in use: i915
> > Kernel modules: i915
> > 
> > -- 
> > Pali Rohár
> > pali.ro...@gmail.com
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 

-- 
Pali Rohár
pali.ro...@gmail.com
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm: Use idr_init_base(1) when using id==0 for invalid

2018-02-13 Thread Christian König

Am 12.02.2018 um 18:14 schrieb Ville Syrjälä:

On Mon, Feb 12, 2018 at 02:55:33PM +, Chris Wilson wrote:

Use the new idr_init_base() function to create an IDR that knows id==0
is never allocated as it maps to an invalid identifier. By knowing that
id==0 is invalid, the IDR can start from id=1 instead avoiding the issue
of having to start each lookup from the zeroth leaf as id==0 is always
unused (and thus the tree-of-bitmaps indicate that is the first
available).

References: 6ce711f27500 ("idr: Make 1-based IDRs more efficient")
Signed-off-by: Chris Wilson 
Cc: Daniel Vetter 
Cc: Christian Konig 
Cc: Dave Airlie 

Yep, looks like all of these pass start==1 to idr_alloc().
Reviewed-by: Ville Syrjälä 


Acked-by: Christian König  as well.

Probably going to do this for the command submission context handles in 
amdgpu as well.


Thanks,
Christian.



Looks like at least tile_idr and crtc_idr could use this as well,
although I suppose they're not hit nearly as hard as the gem stuff.
Also someone should really s/crtc_idr/obj_id_idr/ or something
along those lines.


---
Note this requires 4.16-rc1.
---
  drivers/gpu/drm/drm_gem.c | 4 ++--
  drivers/gpu/drm/drm_syncobj.c | 2 +-
  2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 01f8d9481211..4975ba9a7bc8 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -98,7 +98,7 @@ drm_gem_init(struct drm_device *dev)
struct drm_vma_offset_manager *vma_offset_manager;
  
  	mutex_init(&dev->object_name_lock);

-   idr_init(&dev->object_name_idr);
+   idr_init_base(&dev->object_name_idr, 1);
  
  	vma_offset_manager = kzalloc(sizeof(*vma_offset_manager), GFP_KERNEL);

if (!vma_offset_manager) {
@@ -776,7 +776,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
  void
  drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
  {
-   idr_init(&file_private->object_idr);
+   idr_init_base(&file_private->object_idr, 1);
spin_lock_init(&file_private->table_lock);
  }
  
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c

index 0b7b0d1ad2d5..d4f4ce484529 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -546,7 +546,7 @@ static int drm_syncobj_export_sync_file(struct drm_file 
*file_private,
  void
  drm_syncobj_open(struct drm_file *file_private)
  {
-   idr_init(&file_private->syncobj_idr);
+   idr_init_base(&file_private->syncobj_idr, 1);
spin_lock_init(&file_private->syncobj_table_lock);
  }
  
--

2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 3/4] drm/tve200: Do not use deprecated drm_driver.{enable|disable)_vblank

2018-02-13 Thread Linus Walleij
On Mon, Feb 12, 2018 at 9:52 AM, Oleksandr Andrushchenko
 wrote:

> From: Oleksandr Andrushchenko 
>
> Do not use deprecated drm_driver.{enable|disable)_vblank callbacks,
> but use drm_simple_kms_helpe's pipe callbacks instead.
>
> Signed-off-by: Oleksandr Andrushchenko 
> Cc: Linus Walleij 

The new way of doing these abstractions seem good, so if people
agree on the general subject (other patches in the series I guess)
Reviewed-by: Linus Walleij 

Yours,
Linus Walleij
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-13 Thread Tomasz Figa
On Tue, Feb 13, 2018 at 9:57 PM, Robin Murphy  wrote:
> On 13/02/18 08:24, Tomasz Figa wrote:
>>
>> Hi Vivek,
>>
>> Thanks for the patch. Please see my comments inline.
>>
>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
>>  wrote:
>>>
>>> From: Sricharan R 
>>>
>>> The smmu device probe/remove and add/remove master device callbacks
>>> gets called when the smmu is not linked to its master, that is without
>>> the context of the master device. So calling runtime apis in those places
>>> separately.
>>>
>>> Signed-off-by: Sricharan R 
>>> [vivek: Cleanup pm runtime calls]
>>> Signed-off-by: Vivek Gautam 
>>> ---
>>>   drivers/iommu/arm-smmu.c | 42
>>> ++
>>>   1 file changed, 38 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>>> index 9e2f917e16c2..c024f69c1682 100644
>>> --- a/drivers/iommu/arm-smmu.c
>>> +++ b/drivers/iommu/arm-smmu.c
>>> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct
>>> iommu_domain *domain)
>>>  struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>>  struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>  struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>> -   int irq;
>>> +   int ret, irq;
>>>
>>>  if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
>>>  return;
>>>
>>> +   ret = pm_runtime_get_sync(smmu->dev);
>>> +   if (ret)
>>> +   return;
>>
>>
>> pm_runtime_get_sync() will return 0 if the device was powered off, 1
>> if it was already/still powered on or runtime PM is not compiled in,
>> or a negative value on error, so shouldn't the test be (ret < 0)?
>>
>> Moreover, I'm actually wondering if it makes any sense to power up the
>> hardware just to program it and power it down again. In a system where
>> the IOMMU is located within a power domain, it would cause the IOMMU
>> block to lose its state anyway.
>
>
> This is generally for the case where the SMMU internal state remains active,
> but the programming interface needs to be powered up in order to access it.

That's true for Qualcomm SMMU, but I think that would be different for
existing users of the driver?

>
>> Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add
>> pm_runtime/sleep ops", perhaps it would make more sense to just
>> control the clocks independently of runtime PM? Then, runtime PM could
>> be used for real power management, e.g. really powering the block up
>> and down, for further power saving.
>
>
> Unfortunately that ends up pretty much unmanageable, because there are
> numerous different SMMU microarchitectures with fundamentally different
> clock/power domain schemes (multiplied by individual SoC integration
> possibilities). Since this is fundamentally a generic architectural driver,
> adding explicit clock support would probably make the whole thing about 50%
> clock code, with complicated decision trees around every hardware access
> calculating which clocks are necessary for a given operation on a given
> system. That maintainability aspect is why we've already nacked such a
> fine-grained approach in the past.

Hmm, I think we are talking about different things here. My suggestion
would not add much more code to the driver than this patch does, calls
to arm_smmu_enable_clocks() instead of pm_runtime_get_sync() and
arm_smmu_disable_clocks() instead of pm_runtime_put(). The
implementation of both functions would be a simple call to clk_bulk_
API (possibly even no need to put this into functions, just call
directly).

Best regards,
Tomasz
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105076] [CI] results file indicate incomplete run.log says pass

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105076

Marta Löfstedt  changed:

   What|Removed |Added

 Whiteboard||ReadyForDev
  Component|DRM/Intel   |IGT
   Assignee|intel-gfx-bugs@lists.freede |dri-devel@lists.freedesktop
   |sktop.org   |.org
 QA Contact|intel-gfx-bugs@lists.freede |
   |sktop.org   |

--- Comment #1 from Marta Löfstedt  ---
Theory is that the individual jason file for the subtest wasn't written due to
disc/mem malfunction. Piglit the reprots incomplete on the tests however
testing goes on reporting pass to Jenkins over network...

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 3/4] drm/tve200: Do not use deprecated drm_driver.{enable|disable)_vblank

2018-02-13 Thread Oleksandr Andrushchenko

On 02/13/2018 03:51 PM, Linus Walleij wrote:

On Mon, Feb 12, 2018 at 9:52 AM, Oleksandr Andrushchenko
 wrote:


From: Oleksandr Andrushchenko 

Do not use deprecated drm_driver.{enable|disable)_vblank callbacks,
but use drm_simple_kms_helpe's pipe callbacks instead.

Signed-off-by: Oleksandr Andrushchenko 
Cc: Linus Walleij 

The new way of doing these abstractions seem good, so if people
agree on the general subject (other patches in the series I guess)

fair enough, thank you

Reviewed-by: Linus Walleij 

Yours,
Linus Walleij


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105076] [CI] results file indicate incomplete run.log say pass

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105076

Marta Löfstedt  changed:

   What|Removed |Added

Summary|[CI] results file indicate  |[CI] results file indicate
   |incomplete run.log says |incomplete run.log say pass
   |pass|

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 5/5] drm: adv7511: Add support for i2c_new_secondary_device

2018-02-13 Thread Kieran Bingham
Hi Laurent,

Thanks for the review,

On 13/02/18 12:23, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Tuesday, 13 February 2018 00:07:53 EET Kieran Bingham wrote:
>> From: Kieran Bingham 
>>
>> The ADV7511 has four 256-byte maps that can be accessed via the main I²C
>> ports. Each map has it own I²C address and acts as a standard slave
>> device on the I²C bus.
>>
>> Allow a device tree node to override the default addresses so that
>> address conflicts with other devices on the same bus may be resolved at
>> the board description level.
>>
>> Signed-off-by: Kieran Bingham 
>> ---
>> v2:
>>  - Update missing edid-i2c address setting
>>  - Split out DT bindings
>>  - Rename and move the I2C default addresses to their own section
>>
>>  drivers/gpu/drm/bridge/adv7511/adv7511.h |  6 
>>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 
>>  2 files changed, 33 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index d034b2cb5eee..04e6759ee45b
>> 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> @@ -93,6 +93,11 @@
>>  #define ADV7511_REG_CHIP_ID_HIGH0xf5
>>  #define ADV7511_REG_CHIP_ID_LOW 0xf6
>>
>> +/* Hardware defined default addresses for i2c register maps */
> 
> s/i2c/I2C/ ? That's really because I had to find something :-)

The I²C comes from JMH's original patch, but is much harder to grep for, so
normalising to I2C throughout.


> 
> Reviewed-by: Laurent Pinchart  
>> +#define ADV7511_CEC_I2C_ADDR_DEFAULT0x3c
>> +#define ADV7511_EDID_I2C_ADDR_DEFAULT   0x3f
>> +#define ADV7511_PACKET_I2C_ADDR_DEFAULT 0x38
>> +
>>  #define ADV7511_CSC_ENABLE  BIT(7)
>>  #define ADV7511_CSC_UPDATE_MODE BIT(5)
>>
>> @@ -322,6 +327,7 @@ struct adv7511 {
>>  struct i2c_client *i2c_main;
>>  struct i2c_client *i2c_edid;
>>  struct i2c_client *i2c_cec;
>> +struct i2c_client *i2c_packet;
>>
>>  struct regmap *regmap;
>>  struct regmap *regmap_cec;
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index
>> efa29db5fc2b..5e61b928c9c0 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> @@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
>>  /* Reading the EDID only works if the device is powered */
>>  if (!adv7511->powered) {
>>  unsigned int edid_i2c_addr =
>> -(adv7511->i2c_main->addr << 1) + 4;
>> +(adv7511->i2c_edid->addr << 1);
>>
>>  __adv7511_power_on(adv7511);
>>
>> @@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511
>> *adv) {
>>  int ret;
>>
>> -adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,
>> - adv->i2c_main->addr - 1);
>> +adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
>> +ADV7511_CEC_I2C_ADDR_DEFAULT);
>>  if (!adv->i2c_cec)
>> -return -ENOMEM;
>> +return -EINVAL;
>>  i2c_set_clientdata(adv->i2c_cec, adv);
>>
>>  adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
>> @@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const
>> struct i2c_device_id *id) struct adv7511_link_config link_config;
>>  struct adv7511 *adv7511;
>>  struct device *dev = &i2c->dev;
>> -unsigned int main_i2c_addr = i2c->addr << 1;
>> -unsigned int edid_i2c_addr = main_i2c_addr + 4;
>>  unsigned int val;
>>  int ret;
>>
>> @@ -1153,24 +1151,35 @@ static int adv7511_probe(struct i2c_client *i2c,
>> const struct i2c_device_id *id) if (ret)
>>  goto uninit_regulators;
>>
>> -regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);
>> -regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
>> - main_i2c_addr - 0xa);
>> -regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
>> - main_i2c_addr - 2);
>> -
>>  adv7511_packet_disable(adv7511, 0x);
>>
>> -adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1);
>> +adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
>> +ADV7511_EDID_I2C_ADDR_DEFAULT);
>>  if (!adv7511->i2c_edid) {
>> -ret = -ENOMEM;
>> +ret = -EINVAL;
>>  goto uninit_regulators;
>>  }
>>
>> +regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
>> + adv7511->i2c_edid->addr << 1);
>> +
>>  ret = adv7511_init_cec_regmap(adv7511);
>>  if (ret)
>>  goto err_i2c_unregister_edid;
>>
>> +regmap_write(adv7511->regmap, ADV7511_REG_

Re: [PATCH v3 1/2] drm/virtio: Add window server support

2018-02-13 Thread Tomeu Vizoso

On 02/12/2018 12:45 PM, Gerd Hoffmann wrote:

   Hi,


(a) software rendering: client allocates shared memory buffer, renders
into it, then passes a file handle for that shmem block together
with some meta data (size, format, ...) to the wayland server.

(b) gpu rendering: client opens a render node, allocates a buffer,
asks the cpu to renders into it, exports the buffer as dma-buf
(DRM_IOCTL_PRIME_HANDLE_TO_FD), passes this to the wayland server
(again including meta data of course).

Is that correct?


Both are correct descriptions of typical behaviors. But it isn't spec'ed
anywhere who has to do the buffer allocation.


Well, according to Pekka's reply it is spec'ed that way, for the
existing buffer types.  So for server allocated buffers you need
(a) a wayland protocol extension and (b) support for the extension
in the clients.


That's to say that if we cannot come up with a zero-copy solution for
unmodified clients, we should at least support zero-copy for cooperative
clients.


"cooperative clients" == "client which has support for the wayland
protocol extension", correct?


Guess it could be that, but I was rather thinking of clients that would 
allocate the buffer for wl_shm_pool with DRM_VIRTGPU_RESOURCE_CREATE or 
equivalent. Then that buffer would be exported and the fd passed using 
the standard wl_shm protocol.



4. QEMU maps that buffer to the guest's address space
(KVM_SET_USER_MEMORY_REGION), passes the guest PFN to the virtio driver


That part is problematic.  The host can't simply allocate something in
the physical address space, because most physical address space
management is done by the guest.  All pci bars are mapped by the guest
firmware for example (or by the guest OS in case of hotplug).


How can KVM_SET_USER_MEMORY_REGION ever be safely used then? I would have
expected that callers of that ioctl have enough knowledge to be able to
choose a physical address that won't conflict with the guest's kernel.


Depends on the kind of region.  Guest RAM is allocated and mapped by
qemu, guest firmware can query qemu about RAM mappings using a special
interface, then create a e820 memory map for the guest os.  PCI device
bars are mapped according to the pci config space registers, which in
turn are initialized by the guest firmware, so it is basically in the
guests hand where they show up.


I see that the ivshmem device in QEMU registers the memory region in BAR 2
of a PCI device instead. Would that be better in your opinion?


Yes.


Would it make sense for virtio-gpu to map buffers to the guest via PCI 
BARs? So we can use a single drm driver for both 2d and 3d.



4. QEMU pops data+buffers from the virtqueue, looks up shmem FD for each
resource, sends data + FDs to the compositor with SCM_RIGHTS


BTW: Is there a 1:1 relationship between buffers and shmem blocks?  Or
does the wayland protocol allow for offsets in buffer meta data, so you
can place multiple buffers in a single shmem block?


The latter:
https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_shm_pool


Ah, good, that makes it alot easier.

So, yes, using ivshmem would be one option.  Tricky part here is the
buffer management though.  It's just a raw piece of memory.  The guest
proxy could mmap the pci bar and manage it.  But then it is again either
unmodified guest + copying the data, or modified client (which requests
buffers from guest proxy) for zero-copy.

Another idea would be extending stdvga.  Basically qemu would have to
use shmem as backing storage for vga memory instead of anonymous memory,
so it would be very  simliar to ivshmem on the host side.  But on the
guest side we have a drm driver for it (bochs-drm).  So clients can
allocate dumb drm buffers for software rendering, and the buffer would
already be backed by a host shmem segment.  Given that wayland already
supports drm buffers for 3d rendering that could work without extending
the wayland protocol.  The client proxy would have to translate the drm
buffer into an pci bar offset and pass it to the host side.  The host
proxy could register the pci bar as wl_shm_pool, then just pass through
the offset to reference the individual buffers.

Drawback of both approaches would be that software rendering and gpu
rendering would use quite different code paths.


Yeah, would be great if we could find a way to avoid that.


We also need a solution for the keymap shmem block.  I guess the keymap
doesn't change all that often, so maybe it is easiest to just copy it
over (host proxy -> guest proxy) instead of trying to map the host shmem
into the guest?


I think that should be fine for now. Something similar will have to 
happen for the clipboard, which currently uses pipes to exchange data.


Thanks,

Tomeu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 99353] Kaveri 7400K shows random colored noise instead of GUI in X or Wayland

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=99353

--- Comment #28 from Bong Cosca  ---
I find this message particularly interesting because it occurs several times in
the dmesg log:

[drm:radeon_crtc_handle_flip [radeon]] radeon_crtc->flip_status = 0 !=
RADEON_FLIP_SUBMITTED(2)

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers

2018-02-13 Thread Alex Deucher
On Tue, Feb 13, 2018 at 3:17 AM, Lukas Wunner  wrote:
> On Mon, Feb 12, 2018 at 01:58:32PM -0500, Alex Deucher wrote:
>> On Mon, Feb 12, 2018 at 4:45 AM, Lukas Wunner  wrote:
>> > On Mon, Feb 12, 2018 at 09:03:26AM +, Mike Lothian wrote:
>> >> On 12 February 2018 at 03:39, Lukas Wunner  wrote:
>> >> > On Mon, Feb 12, 2018 at 12:35:51AM +, Mike Lothian wrote:
>> >> > > I've not been able to reproduce the original problem you're trying to
>> >> > > solve on amdgpu thats with or without your patch set and the above
>> >> > > "trigger" too
>> >
>> > Okay the reason you're not seeing deadlocks is because the output poll
>> > worker is not enabled.  And the output poll worker is not enabled
>> > because your discrete GPU doesn't have any outputs:
>> >
>> > [0.265568] [drm:dc_create] *ERROR* DC: Number of connectors is zero!
>> >
>> > The outputs are only polled if there are connectors which have the
>> > DRM_CONNECTOR_POLL_CONNECT or DRM_CONNECTOR_POLL_DISCONNECT flag set.
>> > And that only ever seems to be the case for VGA and DVI.
>> >
>> > We know based on bugzilla reports that hybrid graphics laptops do exist
>> > which poll outputs with radeon and nouveau.  If there are no laptops
>> > supported by amdgpu whose discrete GPU has polled connectors, then
>> > patch [5/5] would be unnecessary.  That is for Alex to decide.
>>
>> Most hybrid laptops don't have display connectors on the dGPU and we
>> only use polling on analog connectors, so you are not likely to run
>> into this on recent laptops.  That said, I don't know if there is some
>> OEM system out there with a VGA port on the dGPU in a hybrid laptop.
>> I guess another option is to just disable polling on hybrid laptops.
>
> If we don't know for sure, applying patch [5/5] would seem to be the
> safest approach.  (Assuming it doesn't break anything else.)


I don't have any objections.  I see no reason to leave out the amdgpu changes.

Alex
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 99353] Kaveri 7400K shows random colored noise instead of GUI in X or Wayland

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=99353

--- Comment #29 from Michel Dänzer  ---
(In reply to Bong Cosca from comment #28)
> [drm:radeon_crtc_handle_flip [radeon]] radeon_crtc->flip_status = 0 !=
> RADEON_FLIP_SUBMITTED(2)

This is harmless and not related to the issue this report is about.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Ville Syrjälä
On Tue, Feb 13, 2018 at 02:38:42PM +0100, Pali Rohár wrote:
> On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote:
> > On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote:
> > > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote:
> > > > Hi! I'm periodically getting following message in dmesg on Lenovo
> > > > Thinkpad X1 Carbon 3rd generation:
> > > > 
> > > > [drm] Reducing the compressed framebuffer size. This may lead to less 
> > > > power savings than a non-reduced-size. Try to increase stolen memory 
> > > > size if available in BIOS.
> > > > 
> > > > In BIOS I already set GPU size to 512M, but this did not help. Also
> > > > update to last BIOS version did not help.
> > > > 
> > > > So why this message is periodically print in dmesg? And what can I do
> > > > with this problem?
> > > > 
> > > > And why cannot Linux kernel allocate itself more memory for GPU (if BIOS
> > > > can/could do that)? Is not 512MB for GPU enough?
> > > 
> > > And here is output from lspci, which clearly says that 512MB is already
> > > set for GPU:
> > 
> > The PCI BAR size has nothing to do with the size of the stolen memory.
> > The BAR just provides a window into the global GTT address space of the
> > GPU. Stolen memory is a contiguous chunk of physical memory carved out
> > by the BIOS.
> 
> Ok, how could I detect how much memory was stolen?
> 
> In dmesg I see following lines:
> 
> [0.00] e820: BIOS-provided physical RAM map:
> [0.00] BIOS-e820: [mem 0x-0x00057fff] usable
> [0.00] BIOS-e820: [mem 0x00058000-0x00058fff] reserved
> [0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] usable
> [0.00] BIOS-e820: [mem 0x0008c000-0x0009] reserved
> [0.00] BIOS-e820: [mem 0x000e-0x000f] reserved
> [0.00] BIOS-e820: [mem 0x0010-0xab908fff] usable
> [0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] type 20
> [0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] reserved
> [0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] ACPI NVS
> [0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] ACPI 
> data
> [0.00] BIOS-e820: [mem 0xacdff000-0xacdf] usable
> [0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] reserved
> [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved
> [0.00] BIOS-e820: [mem 0x0001-0x00024dff] usable
> 
> [0.00] Reserving Intel graphics memory at 
> 0xae00-0xafff

That's the one. Since you have a BDW the amount FBC can actually use
will be 8MiB less than what's reported here. So looks like you should
have 24MiB total, minus whatever else we end up allocating from stolen.

Check /sys/kernel/debug/dri/0/i915_gem_stolen to see what's there. Most
likely you'll have the fbdev framebuffer taking up a sizeable chunk.
You could get some back by reducing fbdev depth to 16bpp, or even 8bpp,
but I'm not convinced the fbdev gamma LUT stuff really works currently
so you might end up with bogus colors in your vts with that.

> 
> [0.00] Memory: 7972840K/8282704K available (6196K kernel code, 1159K 
> rwdata, 2848K rodata, 1408K init, 688K bss, 309864K reserved, 0K cma-reserved)
> 
> > The BIOS may or may not provide a knob to change the size
> > of the stolen memory.
> 
> In BIOS Setup screen I have option to choose GPU memory and I set it to
> max 512MB. So this is not the right option...
> 
> And why cannot kernel use some continuous check of RAM itself?

Because the hardware won't allow it.

> 
> > > 
> > > $ lspci -v -s 00:02.0
> > > 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 
> > > (rev 09) (prog-if 00 [VGA controller])
> > > Subsystem: Lenovo HD Graphics 5500
> > > Flags: bus master, fast devsel, latency 0, IRQ 46
> > > Memory at e000 (64-bit, non-prefetchable) [size=16M]
> > > Memory at c000 (64-bit, prefetchable) [size=512M]
> > > I/O ports at 3000 [size=64]
> > > [virtual] Expansion ROM at 000c [disabled] [size=128K]
> > > Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
> > > Capabilities: [d0] Power Management version 2
> > > Capabilities: [a4] PCI Advanced Features
> > > Kernel driver in use: i915
> > > Kernel modules: i915
> > > 
> > > -- 
> > > Pali Rohár
> > > pali.ro...@gmail.com
> > > ___
> > > dri-devel mailing list
> > > dri-devel@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
> 
> -- 
> Pali Rohár
> pali.ro...@gmail.com

-- 
Ville Syrjälä
Intel OTC
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri

Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers

2018-02-13 Thread Liviu Dudau
On Tue, Feb 13, 2018 at 12:52:06PM +0100, Lukas Wunner wrote:
> On Tue, Feb 13, 2018 at 10:55:06AM +, Liviu Dudau wrote:
> > On Sun, Feb 11, 2018 at 10:38:28AM +0100, Lukas Wunner wrote:
> > > DRM drivers poll connectors in 10 sec intervals.  The poll worker is
> > > stopped on ->runtime_suspend with cancel_delayed_work_sync().  However
> > > the poll worker invokes the DRM drivers' ->detect callbacks, which call
> > > pm_runtime_get_sync().  If the poll worker starts after runtime suspend
> > > has begun, pm_runtime_get_sync() will wait for runtime suspend to finish
> > > with the intention of runtime resuming the device afterwards.  The result
> > > is a circular wait between poll worker and autosuspend worker.
> > 
> > I think I understand the problem you are trying to solve, but I'm
> > struggling to understand where malidp makes any specific mistakes. First
> > of all, malidp is only a display engine, so there is no GPU attached to
> > it, but that is only a small clarification. Second, malidp doesn't use
> > directly any of the callbacks that you are referring to, it uses the
> > drm_cma_() API plus the generic drm_() call. So if there are any
> > issues there (as they might well be) I think they would apply to a lot
> > more drivers and the fix will involve more than just malidp, i915 and
> > msm.
> 
> I don't know if malidp makes any specific mistakes and didn't mean to
> cast it in a negative light, sorry.

I did not take what you've said as a negative thing, only wanted to
understand how you came to your conclusions.

> 
> So a lot of DRM drivers acquire a runtime PM ref in the connector ->detect
> hook because they can't probe connectors while runtime suspended.
> E.g. for a PCI device, probing might require mmio access, which isn't
> possible outside of power state D0.  There are no ->detect hooks declared
> in drivers/gpu/drm/arm/, so it's unclear to me whether you're able to probe
> during runtime suspend.

That's because the drivers in drivers/gpu/drm/arm do not have
connectors, they are only the CRTC part of the driver. Both hdlcd and
mali-dp use the component framework to locate an encoder in device tree
that will then provide the connectors.

> 
> hdlcd_drv.c and malidp_drv.c both enable output polling.  Output polling
> is only necessary if you don't get HPD interrupts.

That's right, hdlcd and mali-dp don't receive HPD interrupts because
they don't have any. And because we don't know ahead of time which
encoder/connector will be paired with the driver, we enable polling as a
safe fallback.

> 
> You're not disabling polling upon runtime suspend.  Thus, if a runtime PM
> ref is acquired during polling (such as in a ->detect hook), the GPU will
> be runtime resumed every 10 secs.  You may want to verify that's not the
> case.  If you decide that you do want to stop polling during runtime
> suspend because it runtime resumes the GPU continuously, you'll need the
> helper introduced in this series.  So by cc'ing you I just wanted to keep
> you in the loop about an issue that may potentially affect your driver.

Again, we have no GPU linked to us and the polling during runtime
suspend should be handled by the driver for the paired encoder, not by
us. I understand the potential issue but I'm struggling to understand if
it really applies to the drivers/gpu/drm/arm drivers other than in an
abstract way.

Best regards,
Liviu

> 
> Let me know if there are any questions.
> 
> Thanks,
> 
> Lukas

-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Pali Rohár
On Tuesday 13 February 2018 17:36:54 Ville Syrjälä wrote:
> On Tue, Feb 13, 2018 at 02:38:42PM +0100, Pali Rohár wrote:
> > On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote:
> > > On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote:
> > > > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote:
> > > > > Hi! I'm periodically getting following message in dmesg on Lenovo
> > > > > Thinkpad X1 Carbon 3rd generation:
> > > > > 
> > > > > [drm] Reducing the compressed framebuffer size. This may lead to less 
> > > > > power savings than a non-reduced-size. Try to increase stolen memory 
> > > > > size if available in BIOS.
> > > > > 
> > > > > In BIOS I already set GPU size to 512M, but this did not help. Also
> > > > > update to last BIOS version did not help.
> > > > > 
> > > > > So why this message is periodically print in dmesg? And what can I do
> > > > > with this problem?
> > > > > 
> > > > > And why cannot Linux kernel allocate itself more memory for GPU (if 
> > > > > BIOS
> > > > > can/could do that)? Is not 512MB for GPU enough?
> > > > 
> > > > And here is output from lspci, which clearly says that 512MB is already
> > > > set for GPU:
> > > 
> > > The PCI BAR size has nothing to do with the size of the stolen memory.
> > > The BAR just provides a window into the global GTT address space of the
> > > GPU. Stolen memory is a contiguous chunk of physical memory carved out
> > > by the BIOS.
> > 
> > Ok, how could I detect how much memory was stolen?
> > 
> > In dmesg I see following lines:
> > 
> > [0.00] e820: BIOS-provided physical RAM map:
> > [0.00] BIOS-e820: [mem 0x-0x00057fff] usable
> > [0.00] BIOS-e820: [mem 0x00058000-0x00058fff] 
> > reserved
> > [0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] usable
> > [0.00] BIOS-e820: [mem 0x0008c000-0x0009] 
> > reserved
> > [0.00] BIOS-e820: [mem 0x000e-0x000f] 
> > reserved
> > [0.00] BIOS-e820: [mem 0x0010-0xab908fff] usable
> > [0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] type 
> > 20
> > [0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] 
> > reserved
> > [0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] ACPI 
> > NVS
> > [0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] ACPI 
> > data
> > [0.00] BIOS-e820: [mem 0xacdff000-0xacdf] usable
> > [0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] 
> > reserved
> > [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] 
> > reserved
> > [0.00] BIOS-e820: [mem 0x0001-0x00024dff] usable
> > 
> > [0.00] Reserving Intel graphics memory at 
> > 0xae00-0xafff
> 
> That's the one. Since you have a BDW the amount FBC can actually use
> will be 8MiB less than what's reported here. So looks like you should
> have 24MiB total, minus whatever else we end up allocating from stolen.
> 
> Check /sys/kernel/debug/dri/0/i915_gem_stolen to see what's there. Most

$ cat /sys/kernel/debug/dri/0/i915_gem_stolen
Stolen:
   8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: 1000)
   8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: 5000)
   8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: 9000)
   8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: d000)
   8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: 00019000)
   8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0  LLC (pinned x 1) 
(ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000)
   8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: 0012d000)
   8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: 00131000)
   8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: 00135000)
   8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned x 
1) (ggtt offset: 00156000, size: 4000, type: 0) (stolen: 00139000)
   8b55bf02da40:  p g 14400KiB 77 00 [ 0 0 0 0 ] 0  uncached dirty 
(name: 1) (pinned x 1) (display) (ggtt offset: 0015a000, size: 00e1, type: 
0) (stolen: 0013d000) (p mappable)
   8b556dfba780:g16KiB 40 40 [

Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Ville Syrjälä
On Tue, Feb 13, 2018 at 05:04:37PM +0100, Pali Rohár wrote:
> On Tuesday 13 February 2018 17:36:54 Ville Syrjälä wrote:
> > On Tue, Feb 13, 2018 at 02:38:42PM +0100, Pali Rohár wrote:
> > > On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote:
> > > > On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote:
> > > > > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote:
> > > > > > Hi! I'm periodically getting following message in dmesg on Lenovo
> > > > > > Thinkpad X1 Carbon 3rd generation:
> > > > > > 
> > > > > > [drm] Reducing the compressed framebuffer size. This may lead to 
> > > > > > less power savings than a non-reduced-size. Try to increase stolen 
> > > > > > memory size if available in BIOS.
> > > > > > 
> > > > > > In BIOS I already set GPU size to 512M, but this did not help. Also
> > > > > > update to last BIOS version did not help.
> > > > > > 
> > > > > > So why this message is periodically print in dmesg? And what can I 
> > > > > > do
> > > > > > with this problem?
> > > > > > 
> > > > > > And why cannot Linux kernel allocate itself more memory for GPU (if 
> > > > > > BIOS
> > > > > > can/could do that)? Is not 512MB for GPU enough?
> > > > > 
> > > > > And here is output from lspci, which clearly says that 512MB is 
> > > > > already
> > > > > set for GPU:
> > > > 
> > > > The PCI BAR size has nothing to do with the size of the stolen memory.
> > > > The BAR just provides a window into the global GTT address space of the
> > > > GPU. Stolen memory is a contiguous chunk of physical memory carved out
> > > > by the BIOS.
> > > 
> > > Ok, how could I detect how much memory was stolen?
> > > 
> > > In dmesg I see following lines:
> > > 
> > > [0.00] e820: BIOS-provided physical RAM map:
> > > [0.00] BIOS-e820: [mem 0x-0x00057fff] 
> > > usable
> > > [0.00] BIOS-e820: [mem 0x00058000-0x00058fff] 
> > > reserved
> > > [0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] 
> > > usable
> > > [0.00] BIOS-e820: [mem 0x0008c000-0x0009] 
> > > reserved
> > > [0.00] BIOS-e820: [mem 0x000e-0x000f] 
> > > reserved
> > > [0.00] BIOS-e820: [mem 0x0010-0xab908fff] 
> > > usable
> > > [0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] 
> > > type 20
> > > [0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] 
> > > reserved
> > > [0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] 
> > > ACPI NVS
> > > [0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] 
> > > ACPI data
> > > [0.00] BIOS-e820: [mem 0xacdff000-0xacdf] 
> > > usable
> > > [0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] 
> > > reserved
> > > [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] 
> > > reserved
> > > [0.00] BIOS-e820: [mem 0x0001-0x00024dff] 
> > > usable
> > > 
> > > [0.00] Reserving Intel graphics memory at 
> > > 0xae00-0xafff
> > 
> > That's the one. Since you have a BDW the amount FBC can actually use
> > will be 8MiB less than what's reported here. So looks like you should
> > have 24MiB total, minus whatever else we end up allocating from stolen.
> > 
> > Check /sys/kernel/debug/dri/0/i915_gem_stolen to see what's there. Most
> 
> $ cat /sys/kernel/debug/dri/0/i915_gem_stolen
> Stolen:
>8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: 1000)
>8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: 5000)
>8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: 9000)
>8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: d000)
>8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: 00019000)
>8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0  LLC (pinned x 1) 
> (ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000)
>8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: 0012d000)
>8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: 00131000)
>8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: 00135000)
>8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty (pinned 
> x 1) (ggtt 

[Bug 105018] Kernel panic when waking up after screen goes blank.

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105018

--- Comment #8 from Harry Wentland  ---
Created attachment 137322
  --> https://bugs.freedesktop.org/attachment.cgi?id=137322&action=edit
Patch 1 Use crtc enable/disable_vblank hooks

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105018] Kernel panic when waking up after screen goes blank.

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105018

--- Comment #9 from Harry Wentland  ---
Created attachment 137323
  --> https://bugs.freedesktop.org/attachment.cgi?id=137323&action=edit
Patch 2 Return success when enabling interrupt

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105018] Kernel panic when waking up after screen goes blank.

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105018

--- Comment #10 from Harry Wentland  ---
Created attachment 137324
  --> https://bugs.freedesktop.org/attachment.cgi?id=137324&action=edit
Patch 3 Clean up formatting in irq_service_dce110.c

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105018] Kernel panic when waking up after screen goes blank.

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105018

--- Comment #11 from Harry Wentland  ---
Created attachment 137325
  --> https://bugs.freedesktop.org/attachment.cgi?id=137325&action=edit
Patch 4 Don't blow up if TG is NULL in dce110_vblank_set

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105018] Kernel panic when waking up after screen goes blank.

2018-02-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105018

--- Comment #12 from Harry Wentland  ---
Are you able to rebuild the kernel with the attached patches and see if that
fixes things?

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 5/8] drm: Handle aspect ratio info in atomic and legacy modeset paths

2018-02-13 Thread Nautiyal, Ankit K

Hi Ville,

Thanks yet again to look into this.

I am still skeptical about rejecting the mode, if aspect ratio cap is 
not set.

Perhaps I am not aware with the userspace expectations.

Please find my response inline:

On 2/13/2018 6:48 PM, Ville Syrjälä wrote:

On Tue, Feb 13, 2018 at 10:21:15AM +0530, Nautiyal, Ankit K wrote:

Hi Ville,

As per our last discussion, following points were discussed:

1. To suppress the aspect-ratio info from getblob ioctl to a user that
does not support it:

  i. A new flag must be added to drm_blob_property to mark if the
blob has mode data.

  ii. This flag must be set when the user tries do an atomic modeset.

  iii. In the getblob ioctl, based on the above flag, it can be
determined that if the blob

  has mode data, and the aspect ratio info can be suppressed in
getblob ioctl, if user does not support it.

2. Instead of adding aspect ratio capabilities in drm_atomic_state, pass
on the file_priv which already has

the required information to the function drm_mode_convert_umode.

It will require addition of an new argument file_priv to several
functions, but that is right thing to do,

as file_priv is the correct structure for the capability information.

3. Changing the usermode aspect ratio flag bits, without change in the
picture_aspect_ratio would not matter, and does not need to be handled
in this patch.


I just have one query here. We have agreed to modify
drm_mode_convert_umode, to filter out the aspect-ratio

info if user has not set aspect-ratio capability, but do we need a
similar change the drm_mode_convert_to_umode?

I think you maybe had those backwards.

drm_mode_convert_umode(), or more likely its relevant callers setcrtc
and setproperty, need to reject the mode if the client cap is not set.

I guess, rejecting the mode, altogether can break the existing user-spaces.
Current user-spaces, oblivious of the aspect-ratio capability in drm, 
will not set the aspect-ratio capability.
Some of them, might have some garbage value in the aspect ratio bits of 
the user mode. If we reject such

modes, the user-spaces that were earlier working will break.
(But if we are sure, that the aspect ratio flag bits will all be reset, 
then it makes sense to reject the mode.)


Instead of rejecting such modes, if we just only ignore the aspect ratio 
bits in such cases, and carry on with the
modeset for the given user mode, the behaviour would be intact, just as 
prior to the aspect ratio changes.



drm_mode_convert_to_umode(), or rather its callers getblob and getcrtc,
need to filter out the flags.


Yes right. I'll be filtering out the flags in the getblob and getcrtc 
functions.


Thanks & Regards,
Ankit

If we do, I am not sure if it would be possible to have the file_priv to
/drm_atomic_set_mode_for_crtc/, which calls

drm_mode_convert_to_umode.  The function /drm_atomic_set_mode_for_crtc/
is used to set mode, originating by kernel,

and make a blob from the kernel mode, which it saves in crtc_state.

This function /: drm_atomic_set_mode_for_crtc, /is called by several
helper functions and driver functions, and passing

file_priv from all these functions does not seem to be plausible.

I don't think we need to plumb it quite that deep. Doing the
check in drm_atomic_crtc_set_property() should be sufficient.


Any suggestions on how to handle this situation?


Regards,

Ankit


On 2/8/2018 9:59 AM, Nautiyal, Ankit K wrote:

Hi Ville,

I still have some queries regarding the handling of aspect ratio flags
in getblob ioctl.

Please find below my responses inline.


On 2/1/2018 6:24 PM, Ville Syrjälä wrote:

On Thu, Feb 01, 2018 at 04:35:22PM +0530, Nautiyal, Ankit K wrote:

Hi Ville,

Appreciate your time and the suggestions.
Please find my response inline:

On 1/31/2018 6:39 PM, Ville Syrjälä wrote:

On Wed, Jan 31, 2018 at 12:04:52PM +0530, Nautiyal, Ankit K wrote:

On 1/30/2018 12:23 AM, Ville Syrjälä wrote:

On Fri, Jan 12, 2018 at 11:51:33AM +0530, Nautiyal, Ankit K wrote:

From: Ankit Nautiyal 

If the user mode does not support aspect-ratio, and requests for
a modeset, then the flag bits representing aspect ratio in the
given user-mode must be rejected.
Similarly, while preparing a user-mode from kernel mode, the
aspect-ratio info must not be given, if aspect-ratio is not
supported by the user.

This patch:
1. adds a new bit field aspect_ratio_allowed in drm_atomic_state,
which is set only if the aspect-ratio is supported by the user.
2. discards the aspect-ratio info from the user mode while
preparing kernel mode structure, during modeset, if the
user does not support aspect ratio.
3. avoids setting the aspect-ratio info in user-mode, while
converting user-mode from the kernel-mode.

Signed-off-by: Ankit Nautiyal 

V3: Addressed review comments from Ville:
-Do not corrupt the current crtc state by updating aspect ratio
on the fly.
---
 drivers/gpu/drm/drm_atomic.c | 61
+---
 drivers/gpu/drm/drm_crtc.c 

Re: [RFC][PATCH v3] drm_hwcomposer: Add platformhisi buffer importer for hikey and hikey960

2018-02-13 Thread Alexandru-Cosmin Gheorghe
Hi John,

Some comments bellow,

On Thu, Feb 08, 2018 at 04:40:05PM -0800, John Stultz wrote:
> This allows for importing buffers allocated from the
> hikey and hikey960 gralloc implelementations.
> 
> Feedback or comments would be greatly appreciated!
> 
> Cc: Marissa Wall 
> Cc: Sean Paul 
> Cc: Dmitry Shmidt 
> Cc: Robert Foss 
> Cc: Matt Szczesiak 
> Cc: Liviu Dudau 
> Cc: David Hanna 
> Cc: Rob Herring 
> Change-Id: I81abdd4d1dc7d9f2ef31078c91679b532d3262fd
> Signed-off-by: John Stultz 
> ---
> The full patchset I'm testing with can be found here:
> https://github.com/johnstultz-work/drm_hwcomposer/commits/drm_hwc
> 
> v2:
> * Make platformhisi and the generic importer exclusive in the build
> * Fixup vendor check
> v3:
> * Unify format conversions
> * Subclass the platformdrmgeneric importer implementation to reduce
>   code duplication
> * Rework to avoid board specific logic (tweak gralloc to be consistent
>   between the two)
> ---
>  Android.mk   |  13 +
>  platformdrmgeneric.h |   2 +-
>  platformhisi.cpp | 132 
> +++
>  platformhisi.h   |  48 +++
>  4 files changed, 194 insertions(+), 1 deletion(-)
>  create mode 100644 platformhisi.cpp
>  create mode 100644 platformhisi.h
> 
> diff --git a/Android.mk b/Android.mk
> index ee5b8bf..f37e4c3 100644
> --- a/Android.mk
> +++ b/Android.mk
> @@ -74,7 +74,20 @@ LOCAL_CPPFLAGS += \
>   -DHWC2_USE_CPP11 \
>   -DHWC2_INCLUDE_STRINGIFICATION
>  
> +
> +ifeq ($(TARGET_PRODUCT),hikey960)
> +LOCAL_CPPFLAGS += -DUSE_HISI_IMPORTER
> +LOCAL_SRC_FILES += platformhisi.cpp
> +LOCAL_C_INCLUDES += device/linaro/hikey/gralloc960/
> +else
> +ifeq ($(TARGET_PRODUCT),hikey)
> +LOCAL_CPPFLAGS += -DUSE_HISI_IMPORTER
> +LOCAL_SRC_FILES += platformhisi.cpp
> +LOCAL_C_INCLUDES += device/linaro/hikey/gralloc/
> +else
>  LOCAL_CPPFLAGS += -DUSE_DRM_GENERIC_IMPORTER
> +endif
> +endif
>  
>  LOCAL_MODULE := hwcomposer.drm
>  LOCAL_MODULE_TAGS := optional
> diff --git a/platformdrmgeneric.h b/platformdrmgeneric.h
> index 8376580..fbe059b 100644
> --- a/platformdrmgeneric.h
> +++ b/platformdrmgeneric.h
> @@ -35,8 +35,8 @@ class DrmGenericImporter : public Importer {
>int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
>int ReleaseBuffer(hwc_drm_bo_t *bo) override;
>  
> - private:
>uint32_t ConvertHalFormatToDrm(uint32_t hal_format);
> + private:
>  
>DrmResources *drm_;
>  
> diff --git a/platformhisi.cpp b/platformhisi.cpp
> new file mode 100644
> index 000..5f17c20
> --- /dev/null
> +++ b/platformhisi.cpp
> @@ -0,0 +1,132 @@
> +/*
> + * Copyright (C) 2015 The Android Open Source Project
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#define LOG_TAG "hwc-platform-hisi"
> +
> +#include "drmresources.h"
> +#include "platform.h"
> +#include "platformhisi.h"
> +
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include "gralloc_priv.h"
> +
> +
> +namespace android {
> +
> +#ifdef USE_HISI_IMPORTER

Isn't this pointless this file seems to be added only of if
USE_HISI_IMPORTER.

> +// static
> +Importer *Importer::CreateInstance(DrmResources *drm) {
> +  HisiImporter *importer = new HisiImporter(drm);
> +  if (!importer)
> +return NULL;
> +
> +  int ret = importer->Init();
> +  if (ret) {
> +ALOGE("Failed to initialize the hisi importer %d", ret);
> +delete importer;
> +return NULL;
> +  }
> +  return importer;
> +}
> +#endif
> +
> +HisiImporter::HisiImporter(DrmResources *drm) : DrmGenericImporter(drm), 
> drm_(drm) {
> +}
> +
> +HisiImporter::~HisiImporter() {
> +}
> +
> +int HisiImporter::Init() {
> +  int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
> +  (const hw_module_t **)&gralloc_);
> +  if (ret) {
> +ALOGE("Failed to open gralloc module %d", ret);
> +return ret;
> +  }
> +
> +  if (strcasecmp(gralloc_->common.author, "ARM Ltd."))
> +ALOGW("Using non-ARM gralloc module: %s/%s\n", gralloc_->common.name,
> +  gralloc_->common.author);
> +
> +  return 0;
> +}
> +
> +EGLImageKHR HisiImporter::ImportImage(EGLDisplay egl_display, 
> buffer_handle_t handle) {
If the scope is reusing, I think you could go further and create an
overload/helper ImportImage(EGLDisplay, width, height, fd, bystride),
that's called for both HisiImport and DrmGenericImporter.
> +  private_handle_t const *hnd = reinte

Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-13 Thread Jordan Crouse
On Tue, Feb 13, 2018 at 06:10:38PM +0900, Tomasz Figa wrote:
> Hi Vivek,
> 
> Thanks for the patch. Please see my comments inline.
> 
> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
>  wrote:
> > While handling the concerned iommu, there should not be a
> > need to power control the drm devices from iommu interface.
> > If these drm devices need to be powered around this time,
> > the respective drivers should take care of this.
> >
> > Replace the pm_runtime_get/put_sync() with
> > pm_runtime_get/put_suppliers() calls, to power-up
> > the connected iommu through the device link interface.
> > In case the device link is not setup these get/put_suppliers()
> > calls will be a no-op, and the iommu driver should take care of
> > powering on its devices accordingly.
> >
> > Signed-off-by: Vivek Gautam 
> > ---
> >  drivers/gpu/drm/msm/msm_iommu.c | 16 
> >  1 file changed, 8 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/msm_iommu.c 
> > b/drivers/gpu/drm/msm/msm_iommu.c
> > index b23d33622f37..1ab629bbee69 100644
> > --- a/drivers/gpu/drm/msm/msm_iommu.c
> > +++ b/drivers/gpu/drm/msm/msm_iommu.c
> > @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const 
> > char * const *names,
> > struct msm_iommu *iommu = to_msm_iommu(mmu);
> > int ret;
> >
> > -   pm_runtime_get_sync(mmu->dev);
> > +   pm_runtime_get_suppliers(mmu->dev);
> > ret = iommu_attach_device(iommu->domain, mmu->dev);
> > -   pm_runtime_put_sync(mmu->dev);
> > +   pm_runtime_put_suppliers(mmu->dev);
> 
> For me, it looks like a wrong place to handle runtime PM of IOMMU
> here. iommu_attach_device() calls into IOMMU driver's attach_device()
> callback and that's where necessary runtime PM gets should happen, if
> any. In other words, driver A (MSM DRM driver) shouldn't be dealing
> with power state of device controlled by driver B (ARM SMMU).
 
This whole thing is confused by the fact that on MSM the GPU and the GPU IOMMU
share some of the same clocks and power rail so turning on the GPU also
turned on the IOMMU register banks by extension.

But if we put that aside the question is who should be responsible for
controlling the power in this relationship and there are several good reasons to
leave it up to the client device. The most important reason is when we move to
the per-instance model where the GPU self-programmings the SMMU registers. In
that case, the driver will need to make sure that the SMMU is powered up before
submitting the command and then removing the power vote when the commands
are done to save energy.

Additionally, there might be legitimate reasons in the driver to batch
operations - you may wish to attach the device and then map several global
buffers immediately - having driver side control prevents several unneeded power
transitions.

Perhaps the right answer is to do both - allow for the driver to enable the
supplier but also do the right power operations at the appropriately places in
the IOMMU driver.

> This is also important for the reasons I stated in my comments to
> "[PATCH v7 1/6] base: power: runtime: Export
> pm_runtime_get/put_suppliers". Quoting for everyone's convenience:
> 
> >> There are however cases in which the consumer wants to power-on
> >> the supplier, but not itself.
> >> E.g., A Graphics or multimedia driver wants to power-on the SMMU
> >> to unmap a buffer and finish the TLB operations without powering
> >> on itself.
> >
> >This sounds strange to me. If the SMMU is powered down, wouldn't the
> >TLB lose its contents as well (and so no flushing needed)?
> >

> >Other than that, what kind of hardware operations would be needed
> >besides just updating the page tables from the CPU?
> >

> In other words, the SMMU driver can deal with hardware state based on
> return value of pm_runtime_get_sync() or pm_runtime_get_if_in_use()
> and decide whether some operations are necessary or not, e.g.
> - a state restore is necessary if the domain was powered off, but we
> are bringing the master on,
> - a flush may not be required when (un)mapping with the domain powered off,
> - etc.

I agree that there is probably some advanced logic that we can do to
conclusively figure out the state of the hardware and improve the behavior.
I would love to see the SMMU driver get smarter but for the moment we can't
trust it and so we need to force the behavior from the GPU driver. The current
code works for a5x and earlier but on sdm845 we can (no longer) treat the GPU
and the SMMU as the same device for power purposes so we need this code. If at
some point in the future we can start to selectively remove the supplier calls
I wouldn't mind one bit.

Jordan

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 5/8] drm: Handle aspect ratio info in atomic and legacy modeset paths

2018-02-13 Thread Ville Syrjälä
On Tue, Feb 13, 2018 at 09:53:53PM +0530, Nautiyal, Ankit K wrote:
> Hi Ville,
> 
> Thanks yet again to look into this.
> 
> I am still skeptical about rejecting the mode, if aspect ratio cap is 
> not set.
> Perhaps I am not aware with the userspace expectations.
> 
> Please find my response inline:
> 
> On 2/13/2018 6:48 PM, Ville Syrjälä wrote:
> > On Tue, Feb 13, 2018 at 10:21:15AM +0530, Nautiyal, Ankit K wrote:
> >> Hi Ville,
> >>
> >> As per our last discussion, following points were discussed:
> >>
> >> 1. To suppress the aspect-ratio info from getblob ioctl to a user that
> >> does not support it:
> >>
> >>   i. A new flag must be added to drm_blob_property to mark if the
> >> blob has mode data.
> >>
> >>   ii. This flag must be set when the user tries do an atomic modeset.
> >>
> >>   iii. In the getblob ioctl, based on the above flag, it can be
> >> determined that if the blob
> >>
> >>   has mode data, and the aspect ratio info can be suppressed in
> >> getblob ioctl, if user does not support it.
> >>
> >> 2. Instead of adding aspect ratio capabilities in drm_atomic_state, pass
> >> on the file_priv which already has
> >>
> >> the required information to the function drm_mode_convert_umode.
> >>
> >> It will require addition of an new argument file_priv to several
> >> functions, but that is right thing to do,
> >>
> >> as file_priv is the correct structure for the capability information.
> >>
> >> 3. Changing the usermode aspect ratio flag bits, without change in the
> >> picture_aspect_ratio would not matter, and does not need to be handled
> >> in this patch.
> >>
> >>
> >> I just have one query here. We have agreed to modify
> >> drm_mode_convert_umode, to filter out the aspect-ratio
> >>
> >> info if user has not set aspect-ratio capability, but do we need a
> >> similar change the drm_mode_convert_to_umode?
> > I think you maybe had those backwards.
> >
> > drm_mode_convert_umode(), or more likely its relevant callers setcrtc
> > and setproperty, need to reject the mode if the client cap is not set.
> I guess, rejecting the mode, altogether can break the existing user-spaces.
> Current user-spaces, oblivious of the aspect-ratio capability in drm, 
> will not set the aspect-ratio capability.
> Some of them, might have some garbage value in the aspect ratio bits of 
> the user mode. If we reject such
> modes, the user-spaces that were earlier working will break.
> (But if we are sure, that the aspect ratio flag bits will all be reset, 
> then it makes sense to reject the mode.)

We already reject all unspecified flags.

> 
> Instead of rejecting such modes, if we just only ignore the aspect ratio 
> bits in such cases, and carry on with the
> modeset for the given user mode, the behaviour would be intact, just as 
> prior to the aspect ratio changes.
> 
> > drm_mode_convert_to_umode(), or rather its callers getblob and getcrtc,
> > need to filter out the flags.
> 
> Yes right. I'll be filtering out the flags in the getblob and getcrtc 
> functions.
> 
> Thanks & Regards,
> Ankit
> >> If we do, I am not sure if it would be possible to have the file_priv to
> >> /drm_atomic_set_mode_for_crtc/, which calls
> >>
> >> drm_mode_convert_to_umode.  The function /drm_atomic_set_mode_for_crtc/
> >> is used to set mode, originating by kernel,
> >>
> >> and make a blob from the kernel mode, which it saves in crtc_state.
> >>
> >> This function /: drm_atomic_set_mode_for_crtc, /is called by several
> >> helper functions and driver functions, and passing
> >>
> >> file_priv from all these functions does not seem to be plausible.
> > I don't think we need to plumb it quite that deep. Doing the
> > check in drm_atomic_crtc_set_property() should be sufficient.
> >
> >> Any suggestions on how to handle this situation?
> >>
> >>
> >> Regards,
> >>
> >> Ankit
> >>
> >>
> >> On 2/8/2018 9:59 AM, Nautiyal, Ankit K wrote:
> >>> Hi Ville,
> >>>
> >>> I still have some queries regarding the handling of aspect ratio flags
> >>> in getblob ioctl.
> >>>
> >>> Please find below my responses inline.
> >>>
> >>>
> >>> On 2/1/2018 6:24 PM, Ville Syrjälä wrote:
>  On Thu, Feb 01, 2018 at 04:35:22PM +0530, Nautiyal, Ankit K wrote:
> > Hi Ville,
> >
> > Appreciate your time and the suggestions.
> > Please find my response inline:
> >
> > On 1/31/2018 6:39 PM, Ville Syrjälä wrote:
> >> On Wed, Jan 31, 2018 at 12:04:52PM +0530, Nautiyal, Ankit K wrote:
> >>> On 1/30/2018 12:23 AM, Ville Syrjälä wrote:
>  On Fri, Jan 12, 2018 at 11:51:33AM +0530, Nautiyal, Ankit K wrote:
> > From: Ankit Nautiyal 
> >
> > If the user mode does not support aspect-ratio, and requests for
> > a modeset, then the flag bits representing aspect ratio in the
> > given user-mode must be rejected.
> > Similarly, while preparing a user-mode from kernel mode, the
> > aspect-ratio info must not be given, if aspect-ratio is not
> > sup

Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Pali Rohár
On Tuesday 13 February 2018 18:12:21 Ville Syrjälä wrote:
> On Tue, Feb 13, 2018 at 05:04:37PM +0100, Pali Rohár wrote:
> > $ cat /sys/kernel/debug/dri/0/i915_gem_stolen
> > Stolen:
> >8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: 
> > 1000)
> >8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: 
> > 5000)
> >8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: 
> > 9000)
> >8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: 
> > d000)
> >8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: 
> > 00019000)
> >8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0  LLC (pinned x 
> > 1) (ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000)
> >8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: 
> > 0012d000)
> >8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: 
> > 00131000)
> >8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: 
> > 00135000)
> >8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 1) (ggtt offset: 00156000, size: 4000, type: 0) (stolen: 
> > 00139000)
> >8b55bf02da40:  p g 14400KiB 77 00 [ 0 0 0 0 ] 0  uncached dirty 
> > (name: 1) (pinned x 1) (display) (ggtt offset: 0015a000, size: 00e1, 
> > type: 0) (stolen: 0013d000) (p mappable)
> >8b556dfba780:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > (pinned x 0) (ggtt offset: 0ad2a000, size: 4000, type: 0) (stolen: 
> > 01655000)
> > 
> > > likely you'll have the fbdev framebuffer taking up a sizeable chunk.
> > 
> > Seems 14MB.
> > 
> > > You could get some back by reducing fbdev depth to 16bpp, or even 8bpp,
> > > but I'm not convinced the fbdev gamma LUT stuff really works currently
> > > so you might end up with bogus colors in your vts with that.
> > 
> > Ok, I could try it. Via fbset tool?
> 
> Kernel command line. We don't allow resizing the fbdev fb once it's
> created.

Ok, will try.

> > 
> > > > 
> > > > [0.00] Memory: 7972840K/8282704K available (6196K kernel code, 
> > > > 1159K rwdata, 2848K rodata, 1408K init, 688K bss, 309864K reserved, 0K 
> > > > cma-reserved)
> > > > 
> > > > > The BIOS may or may not provide a knob to change the size
> > > > > of the stolen memory.
> > > > 
> > > > In BIOS Setup screen I have option to choose GPU memory and I set it to
> > > > max 512MB. So this is not the right option...
> > > > 
> > > > And why cannot kernel use some continuous check of RAM itself?
> > > 
> > > Because the hardware won't allow it.
> > 
> > So it can be done only once after reboot? Or only prior to booting kernel?
> 
> Never.

Never? Now I'm lost. Why then dmesg message instruct user to try set up
it in BIOS if you say it is never possible?

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size

2018-02-13 Thread Ville Syrjälä
On Tue, Feb 13, 2018 at 06:43:41PM +0100, Pali Rohár wrote:
> On Tuesday 13 February 2018 18:12:21 Ville Syrjälä wrote:
> > On Tue, Feb 13, 2018 at 05:04:37PM +0100, Pali Rohár wrote:
> > > $ cat /sys/kernel/debug/dri/0/i915_gem_stolen
> > > Stolen:
> > >8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: 
> > > 1000)
> > >8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: 
> > > 5000)
> > >8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: 
> > > 9000)
> > >8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: 
> > > d000)
> > >8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: 
> > > 00019000)
> > >8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0  LLC (pinned x 
> > > 1) (ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000)
> > >8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: 
> > > 0012d000)
> > >8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: 
> > > 00131000)
> > >8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: 
> > > 00135000)
> > >8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 1) (ggtt offset: 00156000, size: 4000, type: 0) (stolen: 
> > > 00139000)
> > >8b55bf02da40:  p g 14400KiB 77 00 [ 0 0 0 0 ] 0  uncached 
> > > dirty (name: 1) (pinned x 1) (display) (ggtt offset: 0015a000, size: 
> > > 00e1, type: 0) (stolen: 0013d000) (p mappable)
> > >8b556dfba780:g16KiB 40 40 [ 0 0 0 0 ] 0  LLC dirty 
> > > (pinned x 0) (ggtt offset: 0ad2a000, size: 4000, type: 0) (stolen: 
> > > 01655000)
> > > 
> > > > likely you'll have the fbdev framebuffer taking up a sizeable chunk.
> > > 
> > > Seems 14MB.
> > > 
> > > > You could get some back by reducing fbdev depth to 16bpp, or even 8bpp,
> > > > but I'm not convinced the fbdev gamma LUT stuff really works currently
> > > > so you might end up with bogus colors in your vts with that.
> > > 
> > > Ok, I could try it. Via fbset tool?
> > 
> > Kernel command line. We don't allow resizing the fbdev fb once it's
> > created.
> 
> Ok, will try.
> 
> > > 
> > > > > 
> > > > > [0.00] Memory: 7972840K/8282704K available (6196K kernel 
> > > > > code, 1159K rwdata, 2848K rodata, 1408K init, 688K bss, 309864K 
> > > > > reserved, 0K cma-reserved)
> > > > > 
> > > > > > The BIOS may or may not provide a knob to change the size
> > > > > > of the stolen memory.
> > > > > 
> > > > > In BIOS Setup screen I have option to choose GPU memory and I set it 
> > > > > to
> > > > > max 512MB. So this is not the right option...
> > > > > 
> > > > > And why cannot kernel use some continuous check of RAM itself?
> > > > 
> > > > Because the hardware won't allow it.
> > > 
> > > So it can be done only once after reboot? Or only prior to booting kernel?
> > 
> > Never.
> 
> Never? Now I'm lost. Why then dmesg message instruct user to try set up
> it in BIOS if you say it is never possible?

You can change it in the BIOS. No way to change it from the operating system.

-- 
Ville Syrjälä
Intel OTC
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 2/5] dt-bindings: adv7511: Extend bindings to allow specifying slave map addresses

2018-02-13 Thread Kieran Bingham
From: Kieran Bingham 

The ADV7511 has four 256-byte maps that can be accessed via the main I2C
ports. Each map has it own I2C address and acts as a standard slave
device on the I2C bus.

Extend the device tree node bindings to be able to override the default
addresses so that address conflicts with other devices on the same bus
may be resolved at the board description level.

Signed-off-by: Kieran Bingham 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
v2:
 - Fixed up reg: property description to account for multiple optional
   addresses.
 - Minor reword to commit message to account for DT only change
 - Collected Robs RB tag

v3:
 - Split map register addresses into individual declarations.

v4:
 - Update commit title
 - Collect Laurent's RB tag
 - Fix nitpickings
 - Normalise I2C usage (I²C is harder to grep for)

 .../devicetree/bindings/display/bridge/adi,adv7511.txt | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt 
b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index 0047b1394c70..2c887536258c 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -14,7 +14,13 @@ Required properties:
"adi,adv7513"
"adi,adv7533"
 
-- reg: I2C slave address
+- reg: I2C slave addresses
+  The ADV7511 internal registers are split into four pages exposed through
+  different I2C addresses, creating four register maps. Each map has it own
+  I2C address and acts as a standard slave device on the I2C bus. The main
+  address is mandatory, others are optional and revert to defaults if not
+  specified.
+
 
 The ADV7511 supports a large number of input data formats that differ by their
 color depth, color format, clock mode, bit justification and random
@@ -70,6 +76,9 @@ Optional properties:
   rather than generate its own timings for HDMI output.
 - clocks: from common clock binding: reference to the CEC clock.
 - clock-names: from common clock binding: must be "cec".
+- reg-names : Names of maps with programmable addresses.
+   It can contain any map needing a non-default address.
+   Possible maps names are : "main", "edid", "cec", "packet"
 
 Required nodes:
 
@@ -88,7 +97,12 @@ Example
 
adv7511w: hdmi@39 {
compatible = "adi,adv7511w";
-   reg = <39>;
+   /*
+* The EDID page will be accessible on address 0x66 on the I2C
+* bus. All other maps continue to use their default addresses.
+*/
+   reg = <0x39>, <0x66>;
+   reg-names = "main", "edid";
interrupt-parent = <&gpio3>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
clocks = <&cec_clock>;
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 3/5] [RFT] ARM: dts: wheat: Fix ADV7513 address usage

2018-02-13 Thread Kieran Bingham
From: Kieran Bingham 

The r8a7792 Wheat board has two ADV7513 devices sharing a single I2C
bus, however in low power mode the ADV7513 will reset it's slave maps to
use the hardware defined default addresses.

The ADV7511 driver was adapted to allow the two devices to be registered
correctly - but it did not take into account the fault whereby the
devices reset the addresses.

This results in an address conflict between the device using the default
addresses, and the other device if it is in low-power-mode.

Repair this issue by moving both devices away from the default address
definitions.

Signed-off-by: Kieran Bingham 
Reviewed-by: Laurent Pinchart 
---
v2:
 - Addition to series

v3:
 - Split map register addresses into individual declarations.

v4:
 - Normalise I2C usage

 arch/arm/boot/dts/r8a7792-wheat.dts | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7792-wheat.dts 
b/arch/arm/boot/dts/r8a7792-wheat.dts
index b9471b67b728..42fff8837eab 100644
--- a/arch/arm/boot/dts/r8a7792-wheat.dts
+++ b/arch/arm/boot/dts/r8a7792-wheat.dts
@@ -240,9 +240,16 @@
status = "okay";
clock-frequency = <40>;
 
+   /*
+* The adv75xx resets its addresses to defaults during low power power
+* mode. Because we have two ADV7513 devices on the same bus, we must
+* change both of them away from the defaults so that they do not
+* conflict.
+*/
hdmi@3d {
compatible = "adi,adv7513";
-   reg = <0x3d>;
+   reg = <0x3d>, <0x2d>, <0x4d>, <0x5d>;
+   reg-names = "main", "cec", "edid", "packet";
 
adi,input-depth = <8>;
adi,input-colorspace = "rgb";
@@ -272,7 +279,8 @@
 
hdmi@39 {
compatible = "adi,adv7513";
-   reg = <0x39>;
+   reg = <0x39>, <0x29>, <0x49>, <0x59>;
+   reg-names = "main", "cec", "edid", "packet";
 
adi,input-depth = <8>;
adi,input-colorspace = "rgb";
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 5/5] drm: adv7511: Add support for i2c_new_secondary_device

2018-02-13 Thread Kieran Bingham
From: Kieran Bingham 

The ADV7511 has four 256-byte maps that can be accessed via the main I2C
ports. Each map has it own I2C address and acts as a standard slave
device on the I2C bus.

Allow a device tree node to override the default addresses so that
address conflicts with other devices on the same bus may be resolved at
the board description level.

Signed-off-by: Kieran Bingham 
Reviewed-by: Laurent Pinchart 
---
v2:
 - Update missing edid-i2c address setting
 - Split out DT bindings
 - Rename and move the I2C default addresses to their own section

v3:
 - No change

v4:
 - Change registration order of packet/cec to fix error path and
   simplify code change.
 - Collect Laurent's RB tag

 drivers/gpu/drm/bridge/adv7511/adv7511.h |  6 
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 ++--
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index d034b2cb5eee..73d8ccb97742 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -93,6 +93,11 @@
 #define ADV7511_REG_CHIP_ID_HIGH   0xf5
 #define ADV7511_REG_CHIP_ID_LOW0xf6
 
+/* Hardware defined default addresses for I2C register maps */
+#define ADV7511_CEC_I2C_ADDR_DEFAULT   0x3c
+#define ADV7511_EDID_I2C_ADDR_DEFAULT  0x3f
+#define ADV7511_PACKET_I2C_ADDR_DEFAULT0x38
+
 #define ADV7511_CSC_ENABLE BIT(7)
 #define ADV7511_CSC_UPDATE_MODEBIT(5)
 
@@ -321,6 +326,7 @@ enum adv7511_type {
 struct adv7511 {
struct i2c_client *i2c_main;
struct i2c_client *i2c_edid;
+   struct i2c_client *i2c_packet;
struct i2c_client *i2c_cec;
 
struct regmap *regmap;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index efa29db5fc2b..802bc433f54a 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
/* Reading the EDID only works if the device is powered */
if (!adv7511->powered) {
unsigned int edid_i2c_addr =
-   (adv7511->i2c_main->addr << 1) + 4;
+   (adv7511->i2c_edid->addr << 1);
 
__adv7511_power_on(adv7511);
 
@@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
 {
int ret;
 
-   adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,
-adv->i2c_main->addr - 1);
+   adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
+   ADV7511_CEC_I2C_ADDR_DEFAULT);
if (!adv->i2c_cec)
-   return -ENOMEM;
+   return -EINVAL;
i2c_set_clientdata(adv->i2c_cec, adv);
 
adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
@@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
struct adv7511_link_config link_config;
struct adv7511 *adv7511;
struct device *dev = &i2c->dev;
-   unsigned int main_i2c_addr = i2c->addr << 1;
-   unsigned int edid_i2c_addr = main_i2c_addr + 4;
unsigned int val;
int ret;
 
@@ -1153,23 +1151,34 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
if (ret)
goto uninit_regulators;
 
-   regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);
-   regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
-main_i2c_addr - 0xa);
-   regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
-main_i2c_addr - 2);
-
adv7511_packet_disable(adv7511, 0x);
 
-   adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1);
+   adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
+   ADV7511_EDID_I2C_ADDR_DEFAULT);
if (!adv7511->i2c_edid) {
-   ret = -ENOMEM;
+   ret = -EINVAL;
goto uninit_regulators;
}
 
+   regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
+adv7511->i2c_edid->addr << 1);
+
+   adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
+   ADV7511_PACKET_I2C_ADDR_DEFAULT);
+   if (!adv7511->i2c_packet) {
+   ret = -EINVAL;
+   goto err_i2c_unregister_edid;
+   }
+
+   regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
+adv7511->i2c_packet->addr << 1);
+
ret = adv7511_init_cec_regmap(adv7511);
if (ret)
-   goto err_i2c_unregister_edid;
+   goto err_i2c_unregister

  1   2   >