4.9-rc7 nouveau fails on arm64 64k page kernel but works with 4k

2016-12-01 Thread Ilia Mirkin
That's right -- nouveau currently requires 4k page sizes to work. This is a
software limitation, not a hardware one though.

On Dec 1, 2016 5:13 PM, "Jeremy Linton"  wrote:

Hi,

I placed a 9600GT in a softiron 3k running fedora 25, and the nouveau
driver failed to claim the device with :

[drm] Initialized
nouveau :01:00.0: NVIDIA G94 (094100a1)
nouveau :01:00.0: bios: version 62.94.0d.00.04
nouveau: probe of :01:00.0 failed with error -22

Which with a little bit of debugging seems to be a failure in:

[77216.692605] [] ttm_bo_validate+0xb0/0x1e8 [ttm]
[77216.698697] [] ttm_bo_init+0x354/0x410 [ttm]
[77216.704706] [] nouveau_bo_new+0x1f4/0x314 [nouveau]
[77216.711308] [] nv50_display_create+0x10c/0xa1c
[nouveau]
[77216.718340] [] nouveau_display_create+0x50c/0x59c
[nouveau]
[77216.725632] [] nouveau_drm_load+0x22c/0x8c0 [nouveau]
[77216.732286] [] drm_dev_register+0xc0/0xf0 [drm]
[77216.738409] [] drm_get_pci_dev+0xbc/0x188 [drm]
[77216.744663] [] nouveau_drm_probe+0x180/0x208 [nouveau]
[77216.751354] [] local_pci_probe+0x50/0xb4
[77216.756827] [] pci_device_probe+0xf8/0x148
[77216.762474] [] driver_probe_device+0x284/0x420
[77216.768467] [] __driver_attach+0x120/0x124
[77216.774115] [] bus_for_each_dev+0x6c/0xac
[77216.779673] [] driver_attach+0x2c/0x34
[77216.784972] [] bus_add_driver+0x244/0x2b0
[77216.790531] [] driver_register+0x68/0xfc
[77216.796004] [] __pci_register_driver+0x60/0x6c
[77216.802047] [] drm_pci_init+0x108/0x138 [drm]
[77216.808146] [] nouveau_drm_init+0x158/0x1 [nouveau]
[77216.814922] [] do_one_initcall+0x44/0x128
[77216.820483] [] do_init_module+0x68/0x1e0
[77216.825957] [] load_module+0xfac/0x12bc
[77216.831343] [] SyS_finit_module+0xe4/0xf0
[77216.836902] [] el0_svc_naked+0x24/0x28

By default fedora is using a 64k page kernel, switching to a mainline
4.9-rc7 kernel using the same configuration the same problem exists (there
are a couple others, mentioned briefly in the defect). Changing the
mainline kernel from 64k to 4k pages corrects the problem and a terminal
display can be seen.

The fedora defect is:
https://bugzilla.redhat.com/show_bug.cgi?id=1400623


Thanks,
___
dri-devel mailing list
dri-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20161201/98c4d7c3/attachment.html>


drm/radeon spamming alloc_contig_range: [xxx, yyy) PFNs busy busy

2016-12-01 Thread Michal Nazarewicz
On Thu, Dec 01 2016, Michal Hocko wrote:
> I am not familiar with this code so I cannot really argue but a quick
> look at rmem_cma_setup doesn't suggest any speicific placing or
> anything...

early_cma parses ‘cma’ command line argument which can specify where
exactly the default CMA area is to be located.  Furthermore, CMA areas
can be assigned per-device (via the Device Tree IIRC).

-- 
Best regards
ミハウ “𝓶𝓲𝓷𝓪86” ナザレヴイツ
«If at first you don’t succeed, give up skydiving»


[PATCH 18/18] drm/i915/dsi: Skip delays for v3 VBTs in vid-mode

2016-12-01 Thread Hans de Goede
For v3 VBTs in vid-mode the delays are part of the VBT sequences, so
we should not also delay ourselves otherwise we get double delays.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index bf956a3..b60612a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -555,6 +555,17 @@ static void intel_dsi_prepare(struct intel_encoder 
*intel_encoder,
  struct intel_crtc_state *pipe_config);
 static void intel_dsi_unprepare(struct intel_encoder *encoder);

+static void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec)
+{
+   struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
+
+   /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */
+   if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3)
+   return;
+
+   msleep(msec);
+}
+
 /*
  * Panel enable/disable sequences from the spec:
  *
@@ -651,7 +662,7 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
if (intel_dsi->gpio_panel)
gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
-   msleep(intel_dsi->panel_on_delay);
+   intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay);

/* Deassert reset */
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
@@ -673,7 +684,7 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
msleep(20); /* XXX */
for_each_dsi_port(port, intel_dsi->ports)
dpi_send_cmd(intel_dsi, TURN_ON, false, port);
-   msleep(100);
+   intel_dsi_msleep(intel_dsi, 100);

intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);

@@ -769,7 +780,7 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);

/* Power off, try both CRC pmic gpio and VBT */
-   msleep(intel_dsi->panel_off_delay);
+   intel_dsi_msleep(intel_dsi, intel_dsi->panel_off_delay);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
if (intel_dsi->gpio_panel)
gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);
@@ -778,7 +789,7 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
 * FIXME As we do with eDP, just make a note of the time here
 * and perform the wait before the next panel power on.
 */
-   msleep(intel_dsi->panel_pwr_cycle_delay);
+   intel_dsi_msleep(intel_dsi, intel_dsi->panel_pwr_cycle_delay);
 }

 static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
-- 
2.9.3



[PATCH 17/18] drm/i915/dsi: Call MIPI_SEQ_TEAR_ON and DISPLAY_ON for cmd-mode (untested)

2016-12-01 Thread Hans de Goede
According to the spec we should call MIPI_SEQ_TEAR_ON and DISPLAY_ON
on enable for cmd-mode, just like we already call their counterparts
on disable. Note: untested, my panel is a vid-mode panel.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index e3ecb5a..bf956a3 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -667,6 +667,8 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
if (is_cmd_mode(intel_dsi)) {
for_each_dsi_port(port, intel_dsi->ports)
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(port), 8 * 4);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_TEAR_ON);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
} else {
msleep(20); /* XXX */
for_each_dsi_port(port, intel_dsi->ports)
-- 
2.9.3



[PATCH 16/18] drm/i915/dsi: Execute MIPI_SEQ_TEAR_OFF from intel_dsi_post_disable

2016-12-01 Thread Hans de Goede
For v3 VBTs we should call MIPI_SEQ_TEAR_OFF before
MIPI_SEQ_DISPLAY_OFF, for non v3 VBTs this is a nop.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 7761806..e3ecb5a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -747,6 +747,7 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
 * XXX spec specifies SHUTDOWN before MIPI_SEQ_DISPLAY_OFF for
 * v3 VBTs, but not for v2 VBTs?
 */
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_TEAR_OFF);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);

/* Transition to LP-00 */
-- 
2.9.3



[PATCH 15/18] drm/i915/dsi: Document always using v3 SHUTDOWN / MIPI_SEQ_DISPLAY_OFF order

2016-12-01 Thread Hans de Goede
According to the spec for v2 VBTs we should call MIPI_SEQ_DISPLAY_OFF
before sending SHUTDOWN, where as for v3 VBTs we should send SHUTDOWN
first.

Since the v2 order has known issues, we use the v3 order everywhere,
add a comment documenting this.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 9b0c9152..7761806 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -708,6 +708,11 @@ static void intel_dsi_pre_disable(struct intel_encoder 
*encoder,
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
intel_panel_disable_backlight(intel_dsi->attached_connector);

+   /*
+* XXX: According to the spec we should send SHUTDOWN before
+* MIPI_SEQ_DISPLAY_OFF only for v3+ VBTs, but testing in the field
+* has shown that we should do this for v2 VBTs too?
+*/
if (is_vid_mode(intel_dsi)) {
/* Send Shutdown command to the panel in LP mode */
for_each_dsi_port(port, intel_dsi->ports)
@@ -739,6 +744,8 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
/*
 * if disable packets are sent before sending shutdown packet then in
 * some next enable sequence send turn on packet error is observed
+* XXX spec specifies SHUTDOWN before MIPI_SEQ_DISPLAY_OFF for
+* v3 VBTs, but not for v2 VBTs?
 */
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);

-- 
2.9.3



[PATCH 14/18] drm/i915/dsi: Group MIPI_SEQ_BACKLIGHT_ON/OFF with panel_[en|dis]able_backlight

2016-12-01 Thread Hans de Goede
Execute the MIPI_SEQ_BACKLIGHT_ON/OFF VBT sequences at the same time as
we call intel_panel_enable_backlight() / intel_panel_disable_backlight().

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 03a7a7c..9b0c9152 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -674,12 +674,13 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
msleep(100);

intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
-   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);

intel_dsi_port_enable(encoder);
}

+   /* Enable backlight, both pwm and VBT */
intel_panel_enable_backlight(intel_dsi->attached_connector);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
 }

 static void intel_dsi_enable_nop(struct intel_encoder *encoder,
@@ -703,6 +704,8 @@ static void intel_dsi_pre_disable(struct intel_encoder 
*encoder,

DRM_DEBUG_KMS("\n");

+   /* Disable backlight, both VBT and pwm */
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
intel_panel_disable_backlight(intel_dsi->attached_connector);

if (is_vid_mode(intel_dsi)) {
@@ -737,7 +740,6 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
 * if disable packets are sent before sending shutdown packet then in
 * some next enable sequence send turn on packet error is observed
 */
-   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);

/* Transition to LP-00 */
-- 
2.9.3



[PATCH 13/18] drm/i915/dsi: Execute MIPI_SEQ_DEASSERT_RESET before calling device_ready()

2016-12-01 Thread Hans de Goede
Execute MIPI_SEQ_DEASSERT_RESET before putting the device in ready
state (LP-11), this is the sequence in which things should be done
according to the spec.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 9e3cf54..03a7a7c 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -653,10 +653,13 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
msleep(intel_dsi->panel_on_delay);

-   /* put device in ready state */
+   /* Deassert reset */
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
+
+   /* Put device in ready state (LP-11) */
intel_dsi_device_ready(encoder);

-   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
+   /* Send initialization commands in LP mode */
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);

/* Enable port in pre-enable phase itself because as per hw team
@@ -737,6 +740,7 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);

+   /* Transition to LP-00 */
intel_dsi_clear_device_ready(encoder);

intel_disable_dsi_pll(encoder);
@@ -749,6 +753,7 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
I915_WRITE(DSPCLK_GATE_D, val);
}

+   /* Assert reset */
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);

/* Power off, try both CRC pmic gpio and VBT */
-- 
2.9.3



[PATCH 12/18] drm/i915/dsi: Group DPOunit clock gate workaround with PLL enable

2016-12-01 Thread Hans de Goede
Move the DPOunit clock gate workaround to directly after the PLL enable.

The exact location of the workaround does not matter and there are 2
reasons to group it with the PLL enable:

1) This moves it out of the middle of the init sequence from the spec,
   making it easier to follow the init sequence / compare it to the spec

2) It is grouped with the pll disable call in intel_dsi_post_disable,
   so for consistency it should be grouped with the pll enable in
   intel_dsi_pre_enable

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 8927c7a..9e3cf54 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -636,14 +636,6 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
intel_disable_dsi_pll(encoder);
intel_enable_dsi_pll(encoder, pipe_config);

-   intel_dsi_prepare(encoder, pipe_config);
-
-   /* Power on, try both CRC pmic gpio and VBT */
-   if (intel_dsi->gpio_panel)
-   gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
-   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
-   msleep(intel_dsi->panel_on_delay);
-
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
u32 val;

@@ -653,6 +645,14 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
I915_WRITE(DSPCLK_GATE_D, val);
}

+   intel_dsi_prepare(encoder, pipe_config);
+
+   /* Power on, try both CRC pmic gpio and VBT */
+   if (intel_dsi->gpio_panel)
+   gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
+   msleep(intel_dsi->panel_on_delay);
+
/* put device in ready state */
intel_dsi_device_ready(encoder);

-- 
2.9.3



[PATCH 11/18] drm/i915/dsi: Move MIPI_SEQ_POWER_ON/OFF calls together with pmic gpio calls

2016-12-01 Thread Hans de Goede
Now that we are no longer bound to the drm_panel_ callbacks, call
MIPI_SEQ_POWER_ON/OFF at the proper place.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 1f16211..8927c7a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -638,10 +638,10 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,

intel_dsi_prepare(encoder, pipe_config);

-   /* Panel Enable over CRC PMIC */
+   /* Power on, try both CRC pmic gpio and VBT */
if (intel_dsi->gpio_panel)
gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
-
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
msleep(intel_dsi->panel_on_delay);

if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
@@ -656,7 +656,6 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
/* put device in ready state */
intel_dsi_device_ready(encoder);

-   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);

@@ -751,11 +750,10 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
}

intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
-   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);

+   /* Power off, try both CRC pmic gpio and VBT */
msleep(intel_dsi->panel_off_delay);
-
-   /* Panel Disable over CRC PMIC */
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
if (intel_dsi->gpio_panel)
gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);

-- 
2.9.3



[PATCH 10/18] drm/i915/dsi: Drop bogus MIPI_SEQ_ASSERT_RESET before POWER_ON

2016-12-01 Thread Hans de Goede
MIPI_SEQ_ASSERT_RESET before POWER_ON is not necessary for 2 reasons:
1) The reset should already be asserted before intel_dsi_pre_enable()
   gets called
2) Most (some?) VBTs will ensure reset was asserted in their
   MIPI_SEQ_DEASSERT_RESET themselves

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index cf761e8..1f16211 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -656,7 +656,6 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
/* put device in ready state */
intel_dsi_device_ready(encoder);

-   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);
-- 
2.9.3



[PATCH 09/18] drm/i915/dsi: Make intel_dsi_enable/disable directly exec VBT sequences

2016-12-01 Thread Hans de Goede
The drm_panel_enable/disable and drm_panel_prepare/unprepare calls are
not fine grained enough to abstract all the different steps we need to
take (and VBT sequences we need to exec) properly. So simply remove the
panel _enable/disable and prepare/unprepare callbacks and instead
export intel_dsi_exec_vbt_sequence() from intel_dsi_panel_vbt.c
and call that from intel_dsi_enable/disable().

No functional changes.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c   | 14 +++---
 drivers/gpu/drm/i915/intel_dsi.h   |  3 +++
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 43 ++
 3 files changed, 15 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 85b748d..cf761e8 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -656,7 +656,10 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
/* put device in ready state */
intel_dsi_device_ready(encoder);

-   drm_panel_prepare(intel_dsi->panel);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);

/* Enable port in pre-enable phase itself because as per hw team
 * recommendation, port should be enabled befor plane & pipe */
@@ -669,7 +672,8 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
dpi_send_cmd(intel_dsi, TURN_ON, false, port);
msleep(100);

-   drm_panel_enable(intel_dsi->panel);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);

intel_dsi_port_enable(encoder);
}
@@ -732,7 +736,8 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
 * if disable packets are sent before sending shutdown packet then in
 * some next enable sequence send turn on packet error is observed
 */
-   drm_panel_disable(intel_dsi->panel);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);

intel_dsi_clear_device_ready(encoder);

@@ -746,7 +751,8 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
I915_WRITE(DSPCLK_GATE_D, val);
}

-   drm_panel_unprepare(intel_dsi->panel);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
+   intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);

msleep(intel_dsi->panel_off_delay);

diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index d567823..5486491 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -132,6 +132,9 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct 
drm_encoder *encoder)

 void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port);

+void intel_dsi_exec_vbt_sequence(struct intel_dsi *intel_dsi,
+enum mipi_seq seq_id);
+
 bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv);
 int intel_compute_dsi_pll(struct intel_encoder *encoder,
  struct intel_crtc_state *config);
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c 
b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index b5a02c6..f71f913 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -400,10 +400,9 @@ static const char *sequence_name(enum mipi_seq seq_id)
return "(unknown)";
 }

-static void generic_exec_sequence(struct drm_panel *panel, enum mipi_seq 
seq_id)
+void intel_dsi_exec_vbt_sequence(struct intel_dsi *intel_dsi,
+enum mipi_seq seq_id)
 {
-   struct vbt_panel *vbt_panel = to_vbt_panel(panel);
-   struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
const u8 *data;
fn_mipi_elem_exec mipi_elem_exec;
@@ -467,40 +466,6 @@ static void generic_exec_sequence(struct drm_panel *panel, 
enum mipi_seq seq_id)
}
 }

-static int vbt_panel_prepare(struct drm_panel *panel)
-{
-   generic_exec_sequence(panel, MIPI_SEQ_ASSERT_RESET);
-   generic_exec_sequence(panel, MIPI_SEQ_POWER_ON);
-   generic_exec_sequence(panel, MIPI_SEQ_DEASSERT_RESET);
-   generic_exec_sequence(panel, MIPI_SEQ_INIT_OTP);
-
-   return 0;
-}
-
-static int vbt_panel_unprepare(struct drm_panel *panel)
-{
-   generic_exec_sequence(panel, MIPI_SEQ_ASSERT_RESET);
-   generic_exec_sequence(panel, MIPI_SEQ_POWER_OFF);
-
-   return 0;
-}
-
-static int 

[PATCH 08/18] drm/i915/dsi: Document the panel enable / disable sequences from the spec

2016-12-01 Thread Hans de Goede
Document the DSI panel enable / disable sequences from the spec,
for easy comparison between the code and the spec.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 64 
 1 file changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 229..85b748d 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -555,6 +555,70 @@ static void intel_dsi_prepare(struct intel_encoder 
*intel_encoder,
  struct intel_crtc_state *pipe_config);
 static void intel_dsi_unprepare(struct intel_encoder *encoder);

+/*
+ * Panel enable/disable sequences from the spec:
+ *
+ * v2 sequence for video mode:
+ * - power on
+ * - wait t1+t2
+ * - MIPIDeassertResetPin
+ * - clk/data lines to lp-11
+ * - MIPISendInitialDcsCmds
+ * - turn on DPI
+ * - MIPIDisplayOn
+ * - wait t5
+ * - backlight on
+ * ...
+ * - backlight off
+ * - wait t6
+ * - MIPIDisplayOff
+ * - turn off DPI
+ * - clk/data lines to lp-00
+ * - MIPIAssertResetPin
+ * - wait t3
+ * - power off
+ * - wait t4
+ *
+ * v3 sequence for video mode:
+ * - MIPIPanelPowerOn
+ * - MIPIDeassertResetPin
+ * - set clk/data lines to lp-11
+ * - MIPISendInitialDcsCmds (LP)
+ * - turn on DPI
+ * - MIPITearOn (command mode only) + MIPIDisplayOn (LP and HS)
+ * - MIPIBacklightOn
+ * ...
+ * - MIPIBacklightOff
+ * - turn off DPI
+ * - MIPITearOff + MIPIDisplayOff (LP)
+ * - clk/data lines to lp-00
+ * - MIPIAssertResetPin
+ * - MIPIPanelPowerOff
+ *
+ * sequence for command mode:
+ * - power on
+ * - wait t1+t2
+ * - MIPIDeassertResetPin
+ * - clk/data lines to lp-11
+ * - MIPISendInitialDcsCmds
+ * - MIPITearOn
+ * - MIPIDisplayOn
+ * - set pipe to dsr mode
+ * - wait t5
+ * - backlight on
+ * ... issue write_mem_start/write_mem_continue commands ...
+ * - backlight off
+ * - wait t6
+ * - disable pipe dsr mode
+ * - MIPITearOff
+ * - MIPIDisplayOff
+ * - clk/data lines to lp-00
+ * - MIPIAssertResetPin
+ * - wait t3
+ * - power off
+ * - wait t4
+ */
+
 static void intel_dsi_pre_enable(struct intel_encoder *encoder,
 struct intel_crtc_state *pipe_config,
 struct drm_connector_state *conn_state)
-- 
2.9.3



[PATCH 07/18] drm/i915/dsi: Move intel_dsi_clear_device_ready()

2016-12-01 Thread Hans de Goede
Move the intel_dsi_clear_device_ready() function to higher up in
intel_dsi.c this pairs it with intel_dsi_device_ready(); and pairs
intel_dsi_*enable* with intel_dsi_*disable without
intel_dsi_clear_device_ready() sitting in the middle of them.

This commit purely moves code around, it does not make any
changes what-so-ever.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 86 
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index cb15c0a..229 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -445,6 +445,49 @@ static void intel_dsi_device_ready(struct intel_encoder 
*encoder)
bxt_dsi_device_ready(encoder);
 }

+static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
+{
+   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
+   enum port port;
+
+   DRM_DEBUG_KMS("\n");
+   for_each_dsi_port(port, intel_dsi->ports) {
+   /* Common bit for both MIPI Port A & MIPI Port C on VLV/CHV */
+   i915_reg_t port_ctrl = IS_BROXTON(dev_priv) ?
+   BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(PORT_A);
+   u32 val;
+
+   I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+   ULPS_STATE_ENTER);
+   usleep_range(2000, 2500);
+
+   I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+   ULPS_STATE_EXIT);
+   usleep_range(2000, 2500);
+
+   I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+   ULPS_STATE_ENTER);
+   usleep_range(2000, 2500);
+
+   /* Wait till Clock lanes are in LP-00 state for MIPI Port A
+* only. MIPI Port C has no similar bit for checking
+*/
+   if (intel_wait_for_register(dev_priv,
+   port_ctrl, AFE_LATCHOUT, 0,
+   30))
+   DRM_ERROR("DSI LP not going Low\n");
+
+   /* Disable MIPI PHY transparent latch */
+   val = I915_READ(port_ctrl);
+   I915_WRITE(port_ctrl, val & ~LP_OUTPUT_HOLD);
+   usleep_range(1000, 1500);
+
+   I915_WRITE(MIPI_DEVICE_READY(port), 0x00);
+   usleep_range(2000, 2500);
+   }
+}
+
 static void intel_dsi_port_enable(struct intel_encoder *encoder)
 {
struct drm_device *dev = encoder->base.dev;
@@ -601,49 +644,6 @@ static void intel_dsi_pre_disable(struct intel_encoder 
*encoder,
}
 }

-static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
-{
-   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-   struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
-   enum port port;
-
-   DRM_DEBUG_KMS("\n");
-   for_each_dsi_port(port, intel_dsi->ports) {
-   /* Common bit for both MIPI Port A & MIPI Port C on VLV/CHV */
-   i915_reg_t port_ctrl = IS_BROXTON(dev_priv) ?
-   BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(PORT_A);
-   u32 val;
-
-   I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
-   ULPS_STATE_ENTER);
-   usleep_range(2000, 2500);
-
-   I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
-   ULPS_STATE_EXIT);
-   usleep_range(2000, 2500);
-
-   I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
-   ULPS_STATE_ENTER);
-   usleep_range(2000, 2500);
-
-   /* Wait till Clock lanes are in LP-00 state for MIPI Port A
-* only. MIPI Port C has no similar bit for checking
-*/
-   if (intel_wait_for_register(dev_priv,
-   port_ctrl, AFE_LATCHOUT, 0,
-   30))
-   DRM_ERROR("DSI LP not going Low\n");
-
-   /* Disable MIPI PHY transparent latch */
-   val = I915_READ(port_ctrl);
-   I915_WRITE(port_ctrl, val & ~LP_OUTPUT_HOLD);
-   usleep_range(1000, 1500);
-
-   I915_WRITE(MIPI_DEVICE_READY(port), 0x00);
-   usleep_range(2000, 2500);
-   }
-}
-
 static void intel_dsi_post_disable(struct intel_encoder *encoder,
   struct intel_crtc_state *pipe_config,
   struct drm_connector_state *conn_state)
-- 
2.9.3



[PATCH 06/18] drm/i915/dsi: Move disable pll call outside of clear_device_ready()

2016-12-01 Thread Hans de Goede
On enable intel_dsi_enable() directly calls intel_enable_dsi_pll(),
make intel_dsi_disable() also directly call intel_disable_dsi_pll(),
rather then hiding the call in intel_dsi_clear_device_ready(),
no functional changes.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 967bae9..cb15c0a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -642,8 +642,6 @@ static void intel_dsi_clear_device_ready(struct 
intel_encoder *encoder)
I915_WRITE(MIPI_DEVICE_READY(port), 0x00);
usleep_range(2000, 2500);
}
-
-   intel_disable_dsi_pll(encoder);
 }

 static void intel_dsi_post_disable(struct intel_encoder *encoder,
@@ -674,6 +672,8 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,

intel_dsi_clear_device_ready(encoder);

+   intel_disable_dsi_pll(encoder);
+
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
u32 val;

-- 
2.9.3



[PATCH 05/18] drm/i915/dsi: Add intel_dsi_unprepare() helper

2016-12-01 Thread Hans de Goede
The enable path has an intel_dsi_prepare() helper which prepares various
registers for the mode-set. Move the function undoing this to a new
intel_dsi_unprepare() helper for better symmetry between the enable and
disable paths. No functional changes.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 38 --
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index b33381a..967bae9 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -510,6 +510,7 @@ static void intel_dsi_port_disable(struct intel_encoder 
*encoder)

 static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
  struct intel_crtc_state *pipe_config);
+static void intel_dsi_unprepare(struct intel_encoder *encoder);

 static void intel_dsi_pre_enable(struct intel_encoder *encoder,
 struct intel_crtc_state *pipe_config,
@@ -652,7 +653,6 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
enum port port;
-   u32 temp;

DRM_DEBUG_KMS("\n");

@@ -664,19 +664,7 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
usleep_range(2000, 5000);
}

-   for_each_dsi_port(port, intel_dsi->ports) {
-   /* Panel commands can be sent when clock is in LP11 */
-   I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
-
-   intel_dsi_reset_clocks(encoder, port);
-   I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
-
-   temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
-   temp &= ~VID_MODE_FORMAT_MASK;
-   I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp);
-
-   I915_WRITE(MIPI_DEVICE_READY(port), 0x1);
-   }
+   intel_dsi_unprepare(encoder);

/*
 * if disable packets are sent before sending shutdown packet then in
@@ -1272,6 +1260,28 @@ static void intel_dsi_prepare(struct intel_encoder 
*intel_encoder,
}
 }

+static void intel_dsi_unprepare(struct intel_encoder *encoder)
+{
+   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
+   enum port port;
+   u32 temp;
+
+   for_each_dsi_port(port, intel_dsi->ports) {
+   /* Panel commands can be sent when clock is in LP11 */
+   I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
+
+   intel_dsi_reset_clocks(encoder, port);
+   I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
+
+   temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
+   temp &= ~VID_MODE_FORMAT_MASK;
+   I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp);
+
+   I915_WRITE(MIPI_DEVICE_READY(port), 0x1);
+   }
+}
+
 static enum drm_connector_status
 intel_dsi_detect(struct drm_connector *connector, bool force)
 {
-- 
2.9.3



[PATCH 04/18] drm/i915/dsi: Merge intel_dsi_disable/enable into their respective callers

2016-12-01 Thread Hans de Goede
intel_dsi_disable/enable only have one caller, merge them into their
respective callers.

Change msleep(2) into usleep_range(2000, 5000) to make checkpatch happy,
otherwise no funtional changes.

The main advantage of this change is that it makes it easier to
follow all the steps of the panel enable / disable sequence when
reading the code.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c | 109 ---
 1 file changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 587ba07..b33381a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -508,32 +508,6 @@ static void intel_dsi_port_disable(struct intel_encoder 
*encoder)
}
 }

-static void intel_dsi_enable(struct intel_encoder *encoder)
-{
-   struct drm_device *dev = encoder->base.dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
-   enum port port;
-
-   DRM_DEBUG_KMS("\n");
-
-   if (is_cmd_mode(intel_dsi)) {
-   for_each_dsi_port(port, intel_dsi->ports)
-   I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(port), 8 * 4);
-   } else {
-   msleep(20); /* XXX */
-   for_each_dsi_port(port, intel_dsi->ports)
-   dpi_send_cmd(intel_dsi, TURN_ON, false, port);
-   msleep(100);
-
-   drm_panel_enable(intel_dsi->panel);
-
-   intel_dsi_port_enable(encoder);
-   }
-
-   intel_panel_enable_backlight(intel_dsi->attached_connector);
-}
-
 static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
  struct intel_crtc_state *pipe_config);

@@ -543,6 +517,7 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
+   enum port port;

DRM_DEBUG_KMS("\n");

@@ -577,7 +552,21 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,

/* Enable port in pre-enable phase itself because as per hw team
 * recommendation, port should be enabled befor plane & pipe */
-   intel_dsi_enable(encoder);
+   if (is_cmd_mode(intel_dsi)) {
+   for_each_dsi_port(port, intel_dsi->ports)
+   I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(port), 8 * 4);
+   } else {
+   msleep(20); /* XXX */
+   for_each_dsi_port(port, intel_dsi->ports)
+   dpi_send_cmd(intel_dsi, TURN_ON, false, port);
+   msleep(100);
+
+   drm_panel_enable(intel_dsi->panel);
+
+   intel_dsi_port_enable(encoder);
+   }
+
+   intel_panel_enable_backlight(intel_dsi->attached_connector);
 }

 static void intel_dsi_enable_nop(struct intel_encoder *encoder,
@@ -611,42 +600,6 @@ static void intel_dsi_pre_disable(struct intel_encoder 
*encoder,
}
 }

-static void intel_dsi_disable(struct intel_encoder *encoder)
-{
-   struct drm_device *dev = encoder->base.dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
-   enum port port;
-   u32 temp;
-
-   DRM_DEBUG_KMS("\n");
-
-   if (is_vid_mode(intel_dsi)) {
-   for_each_dsi_port(port, intel_dsi->ports)
-   wait_for_dsi_fifo_empty(intel_dsi, port);
-
-   intel_dsi_port_disable(encoder);
-   msleep(2);
-   }
-
-   for_each_dsi_port(port, intel_dsi->ports) {
-   /* Panel commands can be sent when clock is in LP11 */
-   I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
-
-   intel_dsi_reset_clocks(encoder, port);
-   I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
-
-   temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
-   temp &= ~VID_MODE_FORMAT_MASK;
-   I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp);
-
-   I915_WRITE(MIPI_DEVICE_READY(port), 0x1);
-   }
-   /* if disable packets are sent before sending shutdown packet then in
-* some next enable sequence send turn on packet error is observed */
-   drm_panel_disable(intel_dsi->panel);
-}
-
 static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -698,10 +651,38 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder,
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
+   enum port port;
+   u32 temp;

DRM_DEBUG_KMS("\n");

-   intel_dsi_disable(encoder);
+   if (is_vid_mode(intel_dsi)) {
+   for_each_dsi_port(port, intel_dsi->ports)
+  

[PATCH 03/18] drm/i915/dsi: Move calling of wait_for_dsi_fifo_empty to mipi_exec_send_packet

2016-12-01 Thread Hans de Goede
Instead of calling wait_for_dsi_fifo_empty on all dsi ports after calling
a drm_panel_foo helper which calls VBT sequences, move it to the VBT
mipi_exec_send_packet helper, which is the one VBT instruction which
actually puts data in the fifo.

This results in a nice cleanup making it clearer what all the steps on
intel_dsi_enable / disable are and this also makes the VBT code properly
wait till a command has actually been send before executing the next
steps (typically a delay) in the VBT sequence.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_dsi.c   | 12 +---
 drivers/gpu/drm/i915/intel_dsi.h   |  2 ++
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |  2 ++
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 3bc6213..587ba07 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -80,7 +80,7 @@ enum mipi_dsi_pixel_format 
pixel_format_from_register_bits(u32 fmt)
}
 }

-static void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port 
port)
+void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
 {
struct drm_encoder *encoder = _dsi->base.base;
struct drm_device *dev = encoder->dev;
@@ -528,9 +528,6 @@ static void intel_dsi_enable(struct intel_encoder *encoder)

drm_panel_enable(intel_dsi->panel);

-   for_each_dsi_port(port, intel_dsi->ports)
-   wait_for_dsi_fifo_empty(intel_dsi, port);
-
intel_dsi_port_enable(encoder);
}

@@ -546,7 +543,6 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base);
-   enum port port;

DRM_DEBUG_KMS("\n");

@@ -579,9 +575,6 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder,

drm_panel_prepare(intel_dsi->panel);

-   for_each_dsi_port(port, intel_dsi->ports)
-   wait_for_dsi_fifo_empty(intel_dsi, port);
-
/* Enable port in pre-enable phase itself because as per hw team
 * recommendation, port should be enabled befor plane & pipe */
intel_dsi_enable(encoder);
@@ -652,9 +645,6 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
/* if disable packets are sent before sending shutdown packet then in
 * some next enable sequence send turn on packet error is observed */
drm_panel_disable(intel_dsi->panel);
-
-   for_each_dsi_port(port, intel_dsi->ports)
-   wait_for_dsi_fifo_empty(intel_dsi, port);
 }

 static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 5967ea6..d567823 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -130,6 +130,8 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct 
drm_encoder *encoder)
return container_of(encoder, struct intel_dsi, base.base);
 }

+void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port);
+
 bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv);
 int intel_compute_dsi_pll(struct intel_encoder *encoder,
  struct intel_crtc_state *config);
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c 
b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 47cd1b2..b5a02c6 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -191,6 +191,8 @@ static const u8 *mipi_exec_send_packet(struct intel_dsi 
*intel_dsi,
break;
}

+   wait_for_dsi_fifo_empty(intel_dsi, port);
+
 out:
data += len;

-- 
2.9.3



[PATCH 02/18] drm/i915/dsi: Fix chv_exec_gpio disabling the GPIOs it is setting

2016-12-01 Thread Hans de Goede
Set the CHV_GPIO_GPIOEN bit when updating GPIOs from chv_exec_gpio.

Fixes: a0a6d4ffd2ad ("drm/i915/dsi: add support for gpio elements on CHV")
Cc: stable at vger.kernel.org
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Signed-off-by: Hans de Goede 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c 
b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 579d2f5..47cd1b2 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -300,7 +300,8 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
mutex_lock(_priv->sb_lock);
vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
vlv_iosf_sb_write(dev_priv, port, cfg0,
- CHV_GPIO_GPIOCFG_GPO | CHV_GPIO_GPIOTXSTATE(value));
+ CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
+ CHV_GPIO_GPIOTXSTATE(value));
mutex_unlock(_priv->sb_lock);
 }

-- 
2.9.3



[PATCH 01/18] drm/i915/dsi: Fix swapping of MIPI_SEQ_DEASSERT_RESET / MIPI_SEQ_ASSERT_RESET

2016-12-01 Thread Hans de Goede
Looking at the ADF code from the Android kernel sources for a
cherrytrail tablet I noticed that it is calling the
MIPI_SEQ_ASSERT_RESET sequence from the panel prepare hook.

Until commit b1cb1bd29189 ("drm/i915/dsi: update reset and power sequences
in panel prepare/unprepare hooks") the mainline i915 code was doing the
same. That commits effectively swaps the calling of MIPI_SEQ_ASSERT_RESET /
MIPI_SEQ_DEASSERT_RESET.

Looking at the naming of the sequences that is the right thing to do,
but the problem is, that the old mainline code and the ADF code was
actually calling the right sequence (tested on a cube iwork8 air tablet),
and the swapping of the calling breaks things.

This breakage was likely not noticed in testing because on cherrytrail,
currently chv_exec_gpio ends up disabling the gpio pins rather then
setting them (this is fixed in the next patch in this patch-set).

This commit fixes the swapping by fixing MIPI_SEQ_ASSERT/DEASSERT_RESET's
places in the enum defining them, so that their (new) names match their
actual use.

Fixes: b1cb1bd29189 ("drm/i915/dsi: update reset and power sequences...")
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_bios.h  | 4 ++--
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 8405b5a..642a5eb 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -49,11 +49,11 @@ struct edp_power_seq {
 /* MIPI Sequence Block definitions */
 enum mipi_seq {
MIPI_SEQ_END = 0,
-   MIPI_SEQ_ASSERT_RESET,
+   MIPI_SEQ_DEASSERT_RESET,
MIPI_SEQ_INIT_OTP,
MIPI_SEQ_DISPLAY_ON,
MIPI_SEQ_DISPLAY_OFF,
-   MIPI_SEQ_DEASSERT_RESET,
+   MIPI_SEQ_ASSERT_RESET,
MIPI_SEQ_BACKLIGHT_ON,  /* sequence block v2+ */
MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */
MIPI_SEQ_TEAR_ON,   /* sequence block v2+ */
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c 
b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 0d8ff00..579d2f5 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -376,11 +376,11 @@ static const fn_mipi_elem_exec exec_elem[] = {
  */

 static const char * const seq_name[] = {
-   [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
+   [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
[MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
[MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
[MIPI_SEQ_DISPLAY_OFF]  = "MIPI_SEQ_DISPLAY_OFF",
-   [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
+   [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
[MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
[MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
[MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",
-- 
2.9.3



[PATCH 00/18] drm/i915/dsi: Fix / cleanup dsi enable / disable sequences

2016-12-01 Thread Hans de Goede
Hi All,

So while trying to fix my cherrytrail tablet's screen sometimes not
initializing properly (*) I started working on this series to cleanup /
(minor) refactor the dsi enable / disable code, with as goal to then
change it to match the enable / disable sequences which Ville Syrjälä
recently dug up from within the spec.

The first 2 patches I've send before, but I'm resending them since
the other patches in this series depend on them.

The 3th patch is a (small) functional change, which makes the
patches following it move less code around.

Patches 4 - 9 move some stuff around with as goal to have
intel_dsi_pre_enable() and intel_dsi_pre_disable() +
intel_dsi_post_disable() have the entire (de)init sequence in a
clearly readable one function call per step (more or less)
style, so that the ordering is obvious and we can easily match
the code to the spec

Patches 10 - 18 actually modify the code to match the spec, there are
9 patches here as I've chosen to do one tiny change per patch so that
regressions can be bisected to a commit more specific then a
"change the world" commit.

After this patch-set the dsi enable / disable code is much easier to
read (IMHO), almost fully matches the spec (with the single exception
documented) and still works (for me).

There are still some possible improvements to consider:

1) intel_dsi_pre_enable starts with enabling the pll, but
   intel_dsi_post_disable disables it half-way through the
   sequence, since then it is no longer necessary. From a
   power-management pov this is good, but it is assymetrical

2) intel_dsi_pre_enable calls intel_dsi_prepare before calling
   intel_dsi_device_ready, so intel_dsi_post_disable should
   call intel_dsi_unprepare *after* intel_dsi_clear_device_ready,
   but it calls it *before*. Because of this intel_dsi_unprepare
   itself temporarily clears device-ready and resets it in the end.
   It would be good to move intel_dsi_unprepare to *after*
   intel_dsi_clear_device_ready and drop its toggling of the
   device-ready bit, but I'm not sure if that is safe. Perhaps
   there is a specific reason why this is done this way?

3) While working on this I found the following patch which maybe
   should be merged to the mainline i915 code ?  :
   
https://github.com/01org/ProductionKernelQuilts/blob/master/uefi/cht-m1stable/patches/0002-FOR_UPSTREAM-VPG-drm-i915-Move-port-enable-to-after-.patch

   The date on this patch is from long after the decision to
   move the intel_dsi_enable_port call to intel_dsi_pre_enable,
   so it seems to superseed that decision. Maybe we should move the
   intel_dsi_port_enable call from intel_dsi_pre_enable back
   to intel_dsi_enable[_nop] ?

Regards,

Hans


*) The root cause of which turns out to be something different, but since
I had done most of this work when I found that out, I decided to not throw
away my work and instead finish this series and post it upstream


[PATCH v2 7/7] ARM: bcm/dt: Enable the VEC IP on all RaspeberryPi boards

2016-12-01 Thread Boris Brezillon
Enable the VEC IP on all RaspeberryPi boards.

Signed-off-by: Boris Brezillon 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index e9b47b2bbc33..8893240da5f6 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -84,3 +84,8 @@
power-domains = < RPI_POWER_DOMAIN_HDMI>;
status = "okay";
 };
+
+ {
+   power-domains = < RPI_POWER_DOMAIN_VEC>;
+   status = "okay";
+};
-- 
2.7.4



[PATCH v2 6/7] ARM: bcm/dt: Add VEC node in bcm283x.dtsi

2016-12-01 Thread Boris Brezillon
Add the VEC (Video EnCoder) node definition in bcm283x.dtsi.

Signed-off-by: Boris Brezillon 
---
 arch/arm/boot/dts/bcm283x.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 46d46d894a44..44a9c0539437 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -266,6 +266,14 @@
status = "disabled";
};

+   vec: vec at 7e806000 {
+   compatible = "brcm,bcm2835-vec";
+   reg = <0x7e806000 0x1000>;
+   clocks = < BCM2835_CLOCK_VEC>;
+   interrupts = <2 27>;
+   status = "disabled";
+   };
+
pixelvalve at 7e807000 {
compatible = "brcm,bcm2835-pixelvalve2";
reg = <0x7e807000 0x100>;
-- 
2.7.4



[PATCH v2 5/7] drm/vc4: Document VEC DT binding

2016-12-01 Thread Boris Brezillon
Document the DT binding for the VEC (Video EnCoder) IP.

Signed-off-by: Boris Brezillon 
---
 Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt 
b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
index a5ea451e67fc..e2768703ac2b 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
+++ b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
@@ -43,6 +43,13 @@ Required properties for DPI:
 - port:Port node with a single endpoint connecting to the panel
  device, as defined in [1]

+Required properties for VEC:
+- compatible:  Should be "brcm,bcm2835-vec"
+- reg: Physical base address and length of the registers
+- clocks:  The core clock the unit runs on
+- interrupts:  The interrupt number
+ See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+
 Required properties for V3D:
 - compatible:  Should be "brcm,bcm2835-v3d"
 - reg: Physical base address and length of the V3D's registers
@@ -92,6 +99,13 @@ dpi: dpi at 7e208000 {
};
 };

+vec: vec at 7e806000 {
+   compatible = "brcm,bcm2835-vec";
+   reg = <0x7e806000 0x1000>;
+   clocks = < BCM2835_CLOCK_VEC>;
+   interrupts = <2 27>;
+};
+
 v3d: v3d at 7ec0 {
compatible = "brcm,bcm2835-v3d";
reg = <0x7ec0 0x1000>;
-- 
2.7.4



[PATCH v2 4/7] drm/vc4: Add support for the VEC (Video Encoder) IP

2016-12-01 Thread Boris Brezillon
The VEC IP is a TV DAC, providing support for PAL and NTSC standards.

Signed-off-by: Boris Brezillon 
---
 drivers/gpu/drm/vc4/Makefile  |   1 +
 drivers/gpu/drm/vc4/vc4_debugfs.c |   1 +
 drivers/gpu/drm/vc4/vc4_drv.c |   1 +
 drivers/gpu/drm/vc4/vc4_drv.h |   5 +
 drivers/gpu/drm/vc4/vc4_vec.c | 657 ++
 5 files changed, 665 insertions(+)
 create mode 100644 drivers/gpu/drm/vc4/vc4_vec.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index fb77db755e0a..7757f69a8a77 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -11,6 +11,7 @@ vc4-y := \
vc4_kms.o \
vc4_gem.o \
vc4_hdmi.o \
+   vc4_vec.o \
vc4_hvs.o \
vc4_irq.o \
vc4_plane.o \
diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c 
b/drivers/gpu/drm/vc4/vc4_debugfs.c
index 245115d49c46..caf817bac885 100644
--- a/drivers/gpu/drm/vc4/vc4_debugfs.c
+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
@@ -19,6 +19,7 @@ static const struct drm_info_list vc4_debugfs_list[] = {
{"bo_stats", vc4_bo_stats_debugfs, 0},
{"dpi_regs", vc4_dpi_debugfs_regs, 0},
{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
+   {"vec_regs", vc4_vec_debugfs_regs, 0},
{"hvs_regs", vc4_hvs_debugfs_regs, 0},
{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
{"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 8703f56b7947..3e6cb78f7381 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -289,6 +289,7 @@ static const struct component_master_ops vc4_drm_ops = {

 static struct platform_driver *const component_drivers[] = {
_hdmi_driver,
+   _vec_driver,
_dpi_driver,
_hvs_driver,
_crtc_driver,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 946d48c33668..b3a46a51f9d0 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -17,6 +17,7 @@ struct vc4_dev {
struct vc4_crtc *crtc[3];
struct vc4_v3d *v3d;
struct vc4_dpi *dpi;
+   struct vc4_vec *vec;

struct drm_fbdev_cma *fbdev;

@@ -484,6 +485,10 @@ int vc4_queue_seqno_cb(struct drm_device *dev,
 extern struct platform_driver vc4_hdmi_driver;
 int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);

+/* vc4_hdmi.c */
+extern struct platform_driver vc4_vec_driver;
+int vc4_vec_debugfs_regs(struct seq_file *m, void *unused);
+
 /* vc4_irq.c */
 irqreturn_t vc4_irq(int irq, void *arg);
 void vc4_irq_preinstall(struct drm_device *dev);
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
new file mode 100644
index ..2d4256fcc6f2
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2016 Broadcom Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+/**
+ * DOC: VC4 SDTV module
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+/* WSE Registers */
+#define VEC_WSE_RESET  0xc0
+
+#define VEC_WSE_CONTROL0xc4
+#define VEC_WSE_WSS_ENABLE BIT(7)
+
+#define VEC_WSE_WSS_DATA   0xc8
+#define VEC_WSE_VPS_DATA1  0xcc
+#define VEC_WSE_VPS_CONTROL0xd0
+
+/* VEC Registers */
+#define VEC_REVID  0x100
+
+#define VEC_CONFIG00x104
+#define VEC_CONFIG0_YDEL_MASK  GENMASK(28, 26)
+#define VEC_CONFIG0_YDEL(x)((x) << 26)
+#define VEC_CONFIG0_CDEL_MASK  GENMASK(25, 24)
+#define VEC_CONFIG0_CDEL(x)((x) << 24)
+#define VEC_CONFIG0_PBPR_FIL   BIT(18)
+#define VEC_CONFIG0_CHROMA_GAIN_MASK   GENMASK(17, 16)
+#define VEC_CONFIG0_CHROMA_GAIN_UNITY  (0 << 16)
+#define VEC_CONFIG0_CHROMA_GAIN_1_32   (1 << 16)
+#define VEC_CONFIG0_CHROMA_GAIN_1_16   (2 << 16)
+#define VEC_CONFIG0_CHROMA_GAIN_1_8(3 << 16)
+#define VEC_CONFIG0_CBURST_GAIN_MASK   GENMASK(14, 13)
+#define VEC_CONFIG0_CBURST_GAIN_UNITY  (0 << 13)
+#define VEC_CONFIG0_CBURST_GAIN_1_128  (1 << 13)
+#define VEC_CONFIG0_CBURST_GAIN_1_64   (2 << 13)
+#define VEC_CONFIG0_CBURST_GAIN_1_32   (3 << 13)
+#define VEC_CONFIG0_CHRBW1 BIT(11)
+#define VEC_CONFIG0_CHRBW0

[PATCH v2 3/7] drm: Add TV connector states to drm_connector_state

2016-12-01 Thread Boris Brezillon
Some generic TV connector properties are exposed in drm_mode_config, but
they are currently handled independently in each DRM encoder driver.

Extend the drm_connector_state to store TV related states, and modify the
drm_atomic_connector_{set,get}_property() helpers to fill the connector
state accordingly.

Each driver is then responsible for checking and applying the new config
in its ->atomic_mode_{check,set}() operations.

Signed-off-by: Boris Brezillon 
Reviewed-by: Daniel Vetter 
---
Changes in v2
- fix copy/paste errors
- use an enum for the subconnector field
- switch all fields to unsigned int
---
 drivers/gpu/drm/drm_atomic.c | 50 
 include/drm/drm_connector.h  | 32 
 2 files changed, 82 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index e6862a744210..f93395c3c181 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -989,12 +989,38 @@ int drm_atomic_connector_set_property(struct 
drm_connector *connector,
 * now?) atomic writes to DPMS property:
 */
return -EINVAL;
+   } else if (property == config->tv_select_subconnector_property) {
+   state->tv.subconnector = val;
+   } else if (property == config->tv_left_margin_property) {
+   state->tv.margins.left = val;
+   } else if (property == config->tv_right_margin_property) {
+   state->tv.margins.right = val;
+   } else if (property == config->tv_top_margin_property) {
+   state->tv.margins.top = val;
+   } else if (property == config->tv_bottom_margin_property) {
+   state->tv.margins.bottom = val;
+   } else if (property == config->tv_mode_property) {
+   state->tv.mode = val;
+   } else if (property == config->tv_brightness_property) {
+   state->tv.brightness = val;
+   } else if (property == config->tv_contrast_property) {
+   state->tv.contrast = val;
+   } else if (property == config->tv_flicker_reduction_property) {
+   state->tv.flicker_reduction = val;
+   } else if (property == config->tv_overscan_property) {
+   state->tv.overscan = val;
+   } else if (property == config->tv_saturation_property) {
+   state->tv.saturation = val;
+   } else if (property == config->tv_hue_property) {
+   state->tv.hue = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
} else {
return -EINVAL;
}
+
+   return 0;
 }
 EXPORT_SYMBOL(drm_atomic_connector_set_property);

@@ -1025,6 +1051,30 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = (state->crtc) ? state->crtc->base.id : 0;
} else if (property == config->dpms_property) {
*val = connector->dpms;
+   } else if (property == config->tv_select_subconnector_property) {
+   *val = state->tv.subconnector;
+   } else if (property == config->tv_left_margin_property) {
+   *val = state->tv.margins.left;
+   } else if (property == config->tv_right_margin_property) {
+   *val = state->tv.margins.right;
+   } else if (property == config->tv_top_margin_property) {
+   *val = state->tv.margins.top;
+   } else if (property == config->tv_bottom_margin_property) {
+   *val = state->tv.margins.bottom;
+   } else if (property == config->tv_mode_property) {
+   *val = state->tv.mode;
+   } else if (property == config->tv_brightness_property) {
+   *val = state->tv.brightness;
+   } else if (property == config->tv_contrast_property) {
+   *val = state->tv.contrast;
+   } else if (property == config->tv_flicker_reduction_property) {
+   *val = state->tv.flicker_reduction;
+   } else if (property == config->tv_overscan_property) {
+   *val = state->tv.overscan;
+   } else if (property == config->tv_saturation_property) {
+   *val = state->tv.saturation;
+   } else if (property == config->tv_hue_property) {
+   *val = state->tv.hue;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ac9d7d8e0e43..2645e8038572 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -194,10 +194,40 @@ int drm_display_info_set_bus_formats(struct 
drm_display_info *info,
 unsigned int num_formats);

 /**
+ * struct drm_tv_connector_state - TV connector related states
+ * 

[PATCH v2 2/7] drm: Turn DRM_MODE_SUBCONNECTOR_xx definitions into an enum

2016-12-01 Thread Boris Brezillon
List of values like the DRM_MODE_SUBCONNECTOR_xx ones are better
represented with enums.

Turn the DRM_MODE_SUBCONNECTOR_xx macros into an enum.

Signed-off-by: Boris Brezillon 
Suggested-by: Daniel Vetter 
---
 include/uapi/drm/drm_mode.h | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index df0e3504c349..970bfc0d7107 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -220,14 +220,16 @@ struct drm_mode_get_encoder {

 /* This is for connectors with multiple signal types. */
 /* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
-#define DRM_MODE_SUBCONNECTOR_Automatic0
-#define DRM_MODE_SUBCONNECTOR_Unknown  0
-#define DRM_MODE_SUBCONNECTOR_DVID 3
-#define DRM_MODE_SUBCONNECTOR_DVIA 4
-#define DRM_MODE_SUBCONNECTOR_Composite5
-#define DRM_MODE_SUBCONNECTOR_SVIDEO   6
-#define DRM_MODE_SUBCONNECTOR_Component8
-#define DRM_MODE_SUBCONNECTOR_SCART9
+enum drm_mode_subconnector {
+   DRM_MODE_SUBCONNECTOR_Automatic = 0,
+   DRM_MODE_SUBCONNECTOR_Unknown = 0,
+   DRM_MODE_SUBCONNECTOR_DVID = 3,
+   DRM_MODE_SUBCONNECTOR_DVIA = 4,
+   DRM_MODE_SUBCONNECTOR_Composite = 5,
+   DRM_MODE_SUBCONNECTOR_SVIDEO = 6,
+   DRM_MODE_SUBCONNECTOR_Component = 8,
+   DRM_MODE_SUBCONNECTOR_SCART = 9,
+};

 #define DRM_MODE_CONNECTOR_Unknown 0
 #define DRM_MODE_CONNECTOR_VGA 1
-- 
2.7.4



[PATCH v2 1/7] drm/vc4: Fix ->clock_select setting for the VEC encoder

2016-12-01 Thread Boris Brezillon
PV_CONTROL_CLK_SELECT_VEC is actually 2 and not 0. Fix the definition and
rework the vc4_set_crtc_possible_masks() to cover the full range of the
PV_CONTROL_CLK_SELECT field.

Signed-off-by: Boris Brezillon 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 38 +++---
 drivers/gpu/drm/vc4/vc4_drv.h  |  1 +
 drivers/gpu/drm/vc4/vc4_regs.h |  3 ++-
 3 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 7f08d681a74b..c317e9103f9b 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -83,8 +83,7 @@ struct vc4_crtc_data {
/* Which channel of the HVS this pixelvalve sources from. */
int hvs_channel;

-   enum vc4_encoder_type encoder0_type;
-   enum vc4_encoder_type encoder1_type;
+   enum vc4_encoder_type encoder_types[4];
 };

 #define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
@@ -859,20 +858,26 @@ static const struct drm_crtc_helper_funcs 
vc4_crtc_helper_funcs = {

 static const struct vc4_crtc_data pv0_data = {
.hvs_channel = 0,
-   .encoder0_type = VC4_ENCODER_TYPE_DSI0,
-   .encoder1_type = VC4_ENCODER_TYPE_DPI,
+   .encoder_types = {
+   [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
+   [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
+   },
 };

 static const struct vc4_crtc_data pv1_data = {
.hvs_channel = 2,
-   .encoder0_type = VC4_ENCODER_TYPE_DSI1,
-   .encoder1_type = VC4_ENCODER_TYPE_SMI,
+   .encoder_types = {
+   [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
+   [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
+   },
 };

 static const struct vc4_crtc_data pv2_data = {
.hvs_channel = 1,
-   .encoder0_type = VC4_ENCODER_TYPE_VEC,
-   .encoder1_type = VC4_ENCODER_TYPE_HDMI,
+   .encoder_types = {
+   [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI,
+   [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
+   },
 };

 static const struct of_device_id vc4_crtc_dt_match[] = {
@@ -886,17 +891,20 @@ static void vc4_set_crtc_possible_masks(struct drm_device 
*drm,
struct drm_crtc *crtc)
 {
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+   const struct vc4_crtc_data *crtc_data = vc4_crtc->data;
+   const enum vc4_encoder_type *encoder_types = crtc_data->encoder_types;
struct drm_encoder *encoder;

drm_for_each_encoder(encoder, drm) {
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
-
-   if (vc4_encoder->type == vc4_crtc->data->encoder0_type) {
-   vc4_encoder->clock_select = 0;
-   encoder->possible_crtcs |= drm_crtc_mask(crtc);
-   } else if (vc4_encoder->type == vc4_crtc->data->encoder1_type) {
-   vc4_encoder->clock_select = 1;
-   encoder->possible_crtcs |= drm_crtc_mask(crtc);
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(crtc_data->encoder_types); i++) {
+   if (vc4_encoder->type == encoder_types[i]) {
+   vc4_encoder->clock_select = i;
+   encoder->possible_crtcs |= drm_crtc_mask(crtc);
+   break;
+   }
}
}
 }
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 7c1e4d97486f..946d48c33668 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -194,6 +194,7 @@ to_vc4_plane(struct drm_plane *plane)
 }

 enum vc4_encoder_type {
+   VC4_ENCODER_TYPE_NONE,
VC4_ENCODER_TYPE_HDMI,
VC4_ENCODER_TYPE_VEC,
VC4_ENCODER_TYPE_DSI0,
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 1aa44c2db556..39f6886b2410 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -177,8 +177,9 @@
 # define PV_CONTROL_WAIT_HSTARTBIT(12)
 # define PV_CONTROL_PIXEL_REP_MASK VC4_MASK(5, 4)
 # define PV_CONTROL_PIXEL_REP_SHIFT4
-# define PV_CONTROL_CLK_SELECT_DSI_VEC 0
+# define PV_CONTROL_CLK_SELECT_DSI 0
 # define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI1
+# define PV_CONTROL_CLK_SELECT_VEC 2
 # define PV_CONTROL_CLK_SELECT_MASKVC4_MASK(3, 2)
 # define PV_CONTROL_CLK_SELECT_SHIFT   2
 # define PV_CONTROL_FIFO_CLR   BIT(1)
-- 
2.7.4



[PATCH v2 0/7] drm/vc4: VEC (SDTV) output support

2016-12-01 Thread Boris Brezillon
Here is the 2nd version of the VC4/VEC series.

We still miss the two clock patches mentioned by Eric in the first
version to make the encoder work no matter the setting applied by the
bootloader.

Regards,

Boris

Boris Brezillon (7):
  drm/vc4: Fix ->clock_select setting for the VEC encoder
  drm: Turn DRM_MODE_SUBCONNECTOR_xx definitions into an enum
  drm: Add TV connector states to drm_connector_state
  drm/vc4: Add support for the VEC (Video Encoder) IP
  drm/vc4: Document VEC DT binding
  ARM: bcm/dt: Add VEC node in bcm283x.dtsi
  ARM: bcm/dt: Enable the VEC IP on all RaspeberryPi boards

 .../devicetree/bindings/display/brcm,bcm-vc4.txt   |  14 +
 arch/arm/boot/dts/bcm2835-rpi.dtsi |   5 +
 arch/arm/boot/dts/bcm283x.dtsi |   8 +
 drivers/gpu/drm/drm_atomic.c   |  50 ++
 drivers/gpu/drm/vc4/Makefile   |   1 +
 drivers/gpu/drm/vc4/vc4_crtc.c |  38 +-
 drivers/gpu/drm/vc4/vc4_debugfs.c  |   1 +
 drivers/gpu/drm/vc4/vc4_drv.c  |   1 +
 drivers/gpu/drm/vc4/vc4_drv.h  |   6 +
 drivers/gpu/drm/vc4/vc4_regs.h |   3 +-
 drivers/gpu/drm/vc4/vc4_vec.c  | 657 +
 include/drm/drm_connector.h|  32 +
 include/uapi/drm/drm_mode.h|  18 +-
 13 files changed, 810 insertions(+), 24 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_vec.c

-- 
2.7.4



[Bug 189451] New: UVD not responding with Mobility Radeon HD 5650

2016-12-01 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=189451

Bug ID: 189451
   Summary: UVD not responding with Mobility Radeon HD 5650
   Product: Drivers
   Version: 2.5
Kernel Version: 4.8.8
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-dri at kernel-bugs.osdl.org
  Reporter: raffamaiden at gmail.com
Regression: No

Created attachment 246561
  --> https://bugzilla.kernel.org/attachment.cgi?id=246561=edit
dmesg log

When I boot I get a series of "UVD not repsonding" errors until it gives up

[   30.060452] [drm:uvd_v1_0_start [radeon]] *ERROR* UVD not responding, giving
up!!!
[   30.060642] radeon :01:00.0: failed initializing UVD (-1).

I have Fedora 25, kernel version 4.8.8

lspci -k | grep VGA -A 4
01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI]
Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M]
Subsystem: Hewlett-Packard Company Mobility Radeon HD 5650
Kernel driver in use: radeon
Kernel modules: radeon

I am attaching the full dmesg log

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


linux-next: problems fetching the drm-intel, etc trees

2016-12-01 Thread Daniel Stone
Hi Stephen,

On 1 December 2016 at 20:45, Stephen Rothwell  wrote:
> On Thu, 01 Dec 2016 11:02:26 + Daniel Stone  
> wrote:
>> Sorry about this, it is quite bad. I think having mirrors for the key DRM
>> trees on GitHub is a good idea though, and I can get to setting that up.
>> Stephen, you need DRM (airlied), drm-misc, drm-panel, drm-intel, drm-tegra,
>> drm-exynos and drm-msm, right?
>
> Well, here are the trees I fetch from *.freedesktop.org:
>
> [...]
>
> I did not have any trouble with the people.fd.o ones.

That's actually interesting, given that they lie on the same host.
Perhaps it means that the locally-mounted ones were fine, and it was
the NFS (cough) mount between git/anongit which took a dive ... thanks
for the datapoint!

Cheers,
Daniel


[Bug 98874] Desktop suddenly freezes, login via ssh possible, no error messages, unable to power off

2016-12-01 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98874

--- Comment #8 from Matthias Nagel  ---
Created attachment 128305
  --> https://bugs.freedesktop.org/attachment.cgi?id=128305=edit
2nd dump

Here is a new dump from a another crash

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20161201/7d3077aa/attachment.html>


[PATCH V3 3/3] drm: Add new driver for MXSFB controller

2016-12-01 Thread Marek Vasut
On 11/29/2016 09:15 PM, Daniel Vetter wrote:
> On Tue, Nov 29, 2016 at 06:27:30PM +0100, Marek Vasut wrote:
>> On 11/14/2016 12:47 PM, Daniel Vetter wrote:
>>> On Mon, Nov 14, 2016 at 11:10:36AM +0100, Marek Vasut wrote:
 Add new driver for the MXSFB controller found in i.MX23/28/6SX .
 The MXSFB controller is a simple framebuffer controller with one
 parallel LCD output. Unlike the MXSFB fbdev driver that is used
 on these systems now, this driver uses the DRM/KMS framework.

 Signed-off-by: Marek Vasut 
 Cc: Lucas Stach 
 Cc: Fabio Estevam 
 Cc: Shawn Guo 
 Cc: Daniel Vetter 
 --
 V2: - Use drm_simple_kms_helper to reduce amount of common code
 - Add dedicated OF compatible for i.MX6SX
 V3: - Update to latest next/master
>>>
>>> Imo looks all pretty. Please wrap up in a pull request as soon as you have
>>> acks from dt and all that and then send a pull request to Dave.
>>
>> I finally got an ACK from Rob on 2/3 , which Dave do you mean, Airlie ?
> 
> Yup. We only have 1 drm maintainer ;-)

OK, PR is out.

-- 
Best regards,
Marek Vasut


[PULL] MXSFB driver

2016-12-01 Thread Marek Vasut
Hi,

as asked by Daniel, I collected the MXSFB DT Acks and the driver and
wrapped it into PR (below).

--

The following changes since commit 09bfc750ec237029d69ebb749602b6f1304d028a:

  Add linux-next specific files for 20161125 (2016-11-25 14:11:29 +1100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/marex/linux-2.6.git
next/mxsfb

for you to fetch changes up to 037c4f02b617383a8d6af6e8d89f4e142ad71470:

  drm: Add new driver for MXSFB controller (2016-12-01 18:55:17 +0100)


Marek Vasut (3):
  dt-bindings: mxsfb: Indentation cleanup
  dt-bindings: mxsfb: Add new bindings for the MXSFB driver
  drm: Add new driver for MXSFB controller

 Documentation/devicetree/bindings/display/mxsfb.txt |  53 +--
 MAINTAINERS |   6 ++
 drivers/gpu/drm/Kconfig |   2 +
 drivers/gpu/drm/Makefile|   1 +
 drivers/gpu/drm/mxsfb/Kconfig   |  18 
 drivers/gpu/drm/mxsfb/Makefile  |   2 +
 drivers/gpu/drm/mxsfb/mxsfb_crtc.c  | 241
++
 drivers/gpu/drm/mxsfb/mxsfb_drv.c   | 444
+
 drivers/gpu/drm/mxsfb/mxsfb_drv.h   |  54 +++
 drivers/gpu/drm/mxsfb/mxsfb_out.c   | 131
+
 drivers/gpu/drm/mxsfb/mxsfb_regs.h  | 114
++
 11 files changed, 1058 insertions(+), 8 deletions(-)
 create mode 100644 drivers/gpu/drm/mxsfb/Kconfig
 create mode 100644 drivers/gpu/drm/mxsfb/Makefile
 create mode 100644 drivers/gpu/drm/mxsfb/mxsfb_crtc.c
 create mode 100644 drivers/gpu/drm/mxsfb/mxsfb_drv.c
 create mode 100644 drivers/gpu/drm/mxsfb/mxsfb_drv.h
 create mode 100644 drivers/gpu/drm/mxsfb/mxsfb_out.c
 create mode 100644 drivers/gpu/drm/mxsfb/mxsfb_regs.h


[PATCH v2 0/7] Tests for sync infrastructure

2016-12-01 Thread Shuah Khan
On 10/19/2016 06:49 AM, Emilio López wrote:
> Hello everyone,
> 
> This is a series of tests to exercise the sync kernel infrastructure. It is
> meant to be a test suite for the work Gustavo has been doing to destage it.
> 
> These tests were originally part of a battery of tests shipping with
> Android's libsync that were rewritten to use the new userspace interfaces.
> 
> This is the second iteration of the test suite. Main changes over v1 are
> a reworked Makefile and small code style fixes.
> 
> If you are testing this on v4.9-rc1, do note that the last test will
> currently fail due to a regression[0].

Hi Emilio,

Thanks. I will apply these to linux-kselftest next for 4.10-rc1

-- Shuah
> 
> As usual, all comments are welcome.
> 
> Cheers!
> Emilio
> 
> [0] https://patchwork.kernel.org/patch/9343347/
> 
> Emilio López (7):
>   selftest: sync: basic tests for sw_sync framework
>   selftest: sync: fence tests for sw_sync framework
>   selftest: sync: merge tests for sw_sync framework
>   selftest: sync: wait tests for sw_sync framework
>   selftest: sync: stress test for parallelism
>   selftest: sync: stress consumer/producer test
>   selftest: sync: stress test for merges
> 
>  tools/testing/selftests/Makefile   |   1 +
>  tools/testing/selftests/sync/.gitignore|   1 +
>  tools/testing/selftests/sync/Makefile  |  24 +++
>  tools/testing/selftests/sync/sw_sync.h |  46 +
>  tools/testing/selftests/sync/sync.c| 221 
> +
>  tools/testing/selftests/sync/sync.h|  40 
>  tools/testing/selftests/sync/sync_alloc.c  |  74 +++
>  tools/testing/selftests/sync/sync_fence.c  | 132 
>  tools/testing/selftests/sync/sync_merge.c  |  60 ++
>  .../testing/selftests/sync/sync_stress_consumer.c  | 185 +
>  tools/testing/selftests/sync/sync_stress_merge.c   | 115 +++
>  .../selftests/sync/sync_stress_parallelism.c   | 111 +++
>  tools/testing/selftests/sync/sync_test.c   |  79 
>  tools/testing/selftests/sync/sync_wait.c   |  91 +
>  tools/testing/selftests/sync/synctest.h|  66 ++
>  15 files changed, 1246 insertions(+)
>  create mode 100644 tools/testing/selftests/sync/.gitignore
>  create mode 100644 tools/testing/selftests/sync/Makefile
>  create mode 100644 tools/testing/selftests/sync/sw_sync.h
>  create mode 100644 tools/testing/selftests/sync/sync.c
>  create mode 100644 tools/testing/selftests/sync/sync.h
>  create mode 100644 tools/testing/selftests/sync/sync_alloc.c
>  create mode 100644 tools/testing/selftests/sync/sync_fence.c
>  create mode 100644 tools/testing/selftests/sync/sync_merge.c
>  create mode 100644 tools/testing/selftests/sync/sync_stress_consumer.c
>  create mode 100644 tools/testing/selftests/sync/sync_stress_merge.c
>  create mode 100644 tools/testing/selftests/sync/sync_stress_parallelism.c
>  create mode 100644 tools/testing/selftests/sync/sync_test.c
>  create mode 100644 tools/testing/selftests/sync/sync_wait.c
>  create mode 100644 tools/testing/selftests/sync/synctest.h
> 



[PATCH RFC 3/3] drm/tilcdc: Adapt to bridge object refcounting

2016-12-01 Thread Jyri Sarha
Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_external.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c 
b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 80184f0..31c6092 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -154,8 +154,10 @@ void tilcdc_remove_external_device(struct drm_device *dev)
drm_connector_helper_add(priv->external_connector,
 priv->connector_funcs);

-   if (priv->external_encoder && priv->external_encoder->bridge)
+   if (priv->external_encoder && priv->external_encoder->bridge) {
drm_bridge_detach(priv->external_encoder->bridge);
+   drm_bridge_put(priv->external_encoder->bridge);
+   }
 }

 static const struct drm_encoder_funcs tilcdc_external_encoder_funcs = {
@@ -234,7 +236,7 @@ int tilcdc_attach_external_device(struct drm_device *ddev)
if (!remote_node)
return 0;

-   bridge = of_drm_find_bridge(remote_node);
+   bridge = of_drm_get_bridge(remote_node);
of_node_put(remote_node);
if (!bridge)
return -EPROBE_DEFER;
@@ -242,20 +244,25 @@ int tilcdc_attach_external_device(struct drm_device *ddev)
priv->external_encoder = devm_kzalloc(ddev->dev,
  sizeof(*priv->external_encoder),
  GFP_KERNEL);
-   if (!priv->external_encoder)
+   if (!priv->external_encoder) {
+   drm_bridge_put(bridge);
return -ENOMEM;
+   }

ret = drm_encoder_init(ddev, priv->external_encoder,
   _external_encoder_funcs,
   DRM_MODE_ENCODER_NONE, NULL);
if (ret) {
dev_err(ddev->dev, "drm_encoder_init() failed %d\n", ret);
+   drm_bridge_put(bridge);
return ret;
}

ret = tilcdc_attach_bridge(ddev, bridge);
-   if (ret)
+   if (ret) {
drm_encoder_cleanup(priv->external_encoder);
+   drm_bridge_put(bridge);
+   }

return ret;
 }
-- 
1.9.1



[PATCH RFC 2/3] drm/bridge: ti-tfp410: Adapt to bridge object and module refcounting

2016-12-01 Thread Jyri Sarha
Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index b054ea3..f0c81dd 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -19,7 +19,7 @@
 #include 

 struct tfp410 {
-   struct drm_bridge   bridge;
+   struct drm_bridge   *bridge;
struct drm_connectorconnector;

struct i2c_adapter  *ddc;
@@ -30,7 +30,7 @@ struct tfp410 {
 static inline struct tfp410 *
 drm_bridge_to_tfp410(struct drm_bridge *bridge)
 {
-   return container_of(bridge, struct tfp410, bridge);
+   return bridge->driver_private;
 }

 static inline struct tfp410 *
@@ -171,16 +171,18 @@ static int tfp410_init(struct device *dev)
if (!dvi)
return -ENOMEM;
dev_set_drvdata(dev, dvi);
+   dvi->bridge = drm_bridge_alloc(THIS_MODULE);
+   dvi->bridge->driver_private = dvi;

-   dvi->bridge.funcs = _bridge_funcs;
-   dvi->bridge.of_node = dev->of_node;
+   dvi->bridge->funcs = _bridge_funcs;
+   dvi->bridge->of_node = dev->of_node;
dvi->dev = dev;

ret = tfp410_get_connector_ddc(dvi);
if (ret)
goto fail;

-   ret = drm_bridge_add(>bridge);
+   ret = drm_bridge_add(dvi->bridge);
if (ret) {
dev_err(dev, "drm_bridge_add() failed: %d\n", ret);
goto fail;
@@ -196,11 +198,13 @@ static int tfp410_fini(struct device *dev)
 {
struct tfp410 *dvi = dev_get_drvdata(dev);

-   drm_bridge_remove(>bridge);
+   drm_bridge_remove(dvi->bridge);

if (dvi->ddc)
i2c_put_adapter(dvi->ddc);

+   drm_bridge_put(dvi->bridge);
+
return 0;
 }

-- 
1.9.1



[PATCH RFC 1/3] drm/drm_bridge: adjust bridge module's refcount

2016-12-01 Thread Jyri Sarha
Store the module that provides the bridge and adjust its reference
count accordingly. The bridge module unload should not be allowed
while the bridge is attached. To do this safely we need to add
reference counting to drm_bridge objects. This has impact to both
bridge drivers and the drivers using the bridges.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/drm_bridge.c | 78 +++-
 include/drm/drm_bridge.h | 10 +-
 2 files changed, 78 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 0ee052b..4b0ff45 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 

@@ -60,6 +61,39 @@
 static DEFINE_MUTEX(bridge_lock);
 static LIST_HEAD(bridge_list);

+static void drm_bridge_release(struct kref *ref)
+{
+   struct drm_bridge *bridge = container_of(ref, struct drm_bridge, kref);
+
+   kfree(bridge);
+}
+
+struct drm_bridge *drm_bridge_alloc(struct module *module)
+{
+   struct drm_bridge *bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
+
+   if (!bridge)
+   return NULL;
+
+   bridge->module = module;
+   kref_init(>kref);
+
+   return bridge;
+}
+EXPORT_SYMBOL(drm_bridge_alloc);
+
+void drm_bridge_get(struct drm_bridge *bridge)
+{
+   kref_get(>kref);
+}
+EXPORT_SYMBOL(drm_bridge_get);
+
+void drm_bridge_put(struct drm_bridge *bridge)
+{
+   kref_put(>kref, drm_bridge_release);
+}
+EXPORT_SYMBOL(drm_bridge_put);
+
 /**
  * drm_bridge_add - add the given bridge to the global bridge list
  *
@@ -70,6 +104,8 @@
  */
 int drm_bridge_add(struct drm_bridge *bridge)
 {
+   drm_bridge_get(bridge);
+
mutex_lock(_lock);
list_add_tail(>list, _list);
mutex_unlock(_lock);
@@ -88,6 +124,8 @@ void drm_bridge_remove(struct drm_bridge *bridge)
mutex_lock(_lock);
list_del_init(>list);
mutex_unlock(_lock);
+
+   drm_bridge_put(bridge);
 }
 EXPORT_SYMBOL(drm_bridge_remove);

@@ -108,18 +146,35 @@ void drm_bridge_remove(struct drm_bridge *bridge)
  */
 int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
 {
+   int ret = 0;
+
if (!dev || !bridge)
return -EINVAL;

+   mutex_lock(_lock);
+
if (bridge->dev)
-   return -EBUSY;
+   ret = -EBUSY;
+   /* Check that the bridge is still part of the list */
+   else if (list_empty(>list))
+   ret = -ENOENT;
+   else if (!try_module_get(bridge->module))
+   ret = -ENOENT;
+   else
+   bridge->dev = dev;

-   bridge->dev = dev;
+   mutex_unlock(_lock);

-   if (bridge->funcs->attach)
-   return bridge->funcs->attach(bridge);
+   if (ret)
+   return ret;

-   return 0;
+   if (bridge->funcs->attach) {
+   ret = bridge->funcs->attach(bridge);
+   if (ret)
+   module_put(bridge->module);
+   }
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_bridge_attach);

@@ -144,6 +199,8 @@ void drm_bridge_detach(struct drm_bridge *bridge)
if (bridge->funcs->detach)
bridge->funcs->detach(bridge);

+   module_put(bridge->module);
+
bridge->dev = NULL;
 }
 EXPORT_SYMBOL(drm_bridge_detach);
@@ -312,15 +369,17 @@ void drm_bridge_enable(struct drm_bridge *bridge)

 #ifdef CONFIG_OF
 /**
- * of_drm_find_bridge - find the bridge corresponding to the device node in
- * the global bridge list
+ * of_drm_get_bridge - find the bridge corresponding to the device node in
+ *the global bridge list and increase its refcount.
+ * It is caller responsibility to call drm_bridge_put()
+ * when it no longer needs the object.
  *
  * @np: device node
  *
  * RETURNS:
  * drm_bridge control struct on success, NULL on failure
  */
-struct drm_bridge *of_drm_find_bridge(struct device_node *np)
+struct drm_bridge *of_drm_get_bridge(struct device_node *np)
 {
struct drm_bridge *bridge;

@@ -328,6 +387,7 @@ struct drm_bridge *of_drm_find_bridge(struct device_node 
*np)

list_for_each_entry(bridge, _list, list) {
if (bridge->of_node == np) {
+   drm_bridge_get(bridge);
mutex_unlock(_lock);
return bridge;
}
@@ -336,7 +396,7 @@ struct drm_bridge *of_drm_find_bridge(struct device_node 
*np)
mutex_unlock(_lock);
return NULL;
 }
-EXPORT_SYMBOL(of_drm_find_bridge);
+EXPORT_SYMBOL(of_drm_get_bridge);
 #endif

 MODULE_AUTHOR("Ajay Kumar ");
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 530a1d6..cd39b7c 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -25,6 +25,7 @@

 #include 
 #include 
+#include 
 #include 
 #include 

@@ -192,15 

[PATCH RFC 0/3] drm/bridge: adjust bridge module's refcount and more

2016-12-01 Thread Jyri Sarha
Note! This series is not yet ready and should not be used as is, it is
just an RFC.

The function documentation is missing and so are the modifications to
all affected drivers. I have added the modification patches for tilcdc
and ti-tfp410 to serve as an example and I have put them into separate
patches for readability.

For the matter of adding devres version of of_drm_get_bridge() and
drm_bridge_alloc(), I think that is a good idea. With reference
counting, each user can hold on to their reference to the bridge
object as long as they need it. The bridge object exists as long as
any of the users still holds on to it.

Cheers,
Jyri

Jyri Sarha (3):
  drm/drm_bridge: adjust bridge module's refcount
  drm/bridge: ti-tfp410: Adapt to bridge object and module refcounting
  drm/tilcdc: Adapt to bridge object refcounting

 drivers/gpu/drm/bridge/ti-tfp410.c   | 16 ---
 drivers/gpu/drm/drm_bridge.c | 78 
 drivers/gpu/drm/tilcdc/tilcdc_external.c | 15 --
 include/drm/drm_bridge.h | 10 +++-
 4 files changed, 99 insertions(+), 20 deletions(-)

-- 
1.9.1



[PATCH] gpu: vmwgfx: Use dma_pool_zalloc

2016-12-01 Thread Sinclair Yeh
Applied.  Thanks.

Reviewed-by: Sinclair Yeh 

On Fri, Dec 02, 2016 at 01:25:45AM +0530, Souptick Joarder wrote:
> We should use dma_pool_zalloc instead of dma_pool_alloc/memset
> 
> Signed-off-by: Souptick joarder 
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
> index aa04fb0..fa097cc 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
> @@ -784,8 +784,8 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man 
> *man,
>   if (ret)
>   return ret;
> 
> - header->cb_header = dma_pool_alloc(man->headers, GFP_KERNEL,
> ->handle);
> + header->cb_header = dma_pool_zalloc(man->headers, GFP_KERNEL,
> + >handle);
>   if (!header->cb_header) {
>   ret = -ENOMEM;
>   goto out_no_cb_header;
> @@ -795,7 +795,6 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man 
> *man,
>   cb_hdr = header->cb_header;
>   offset = header->node.start << PAGE_SHIFT;
>   header->cmd = man->map + offset;
> - memset(cb_hdr, 0, sizeof(*cb_hdr));
>   if (man->using_mob) {
>   cb_hdr->flags = SVGA_CB_FLAG_MOB;
>   cb_hdr->ptr.mob.mobid = man->cmd_space->mem.start;
> @@ -832,8 +831,8 @@ static int vmw_cmdbuf_space_inline(struct vmw_cmdbuf_man 
> *man,
>   if (WARN_ON_ONCE(size > VMW_CMDBUF_INLINE_SIZE))
>   return -ENOMEM;
> 
> - dheader = dma_pool_alloc(man->dheaders, GFP_KERNEL,
> -  >handle);
> + dheader = dma_pool_zalloc(man->dheaders, GFP_KERNEL,
> +   >handle);
>   if (!dheader)
>   return -ENOMEM;
> 
> @@ -842,7 +841,6 @@ static int vmw_cmdbuf_space_inline(struct vmw_cmdbuf_man 
> *man,
>   cb_hdr = >cb_header;
>   header->cb_header = cb_hdr;
>   header->cmd = dheader->cmd;
> - memset(dheader, 0, sizeof(*dheader));
>   cb_hdr->status = SVGA_CB_STATUS_NONE;
>   cb_hdr->flags = SVGA_CB_FLAG_NONE;
>   cb_hdr->ptr.pa = (u64)header->handle +
> --
> 1.9.1
> 


[PATCH v2 01/11] drm/vgem: Use ww_mutex_(un)lock even with a NULL context

2016-12-01 Thread Peter Zijlstra

Just to let you know, I've not been ignoring all the ww_mutex stuff,
I've been ill this week. I'm slowly returning to feeling human again,
but am still fairly wrecked.


drm/radeon spamming alloc_contig_range: [xxx, yyy) PFNs busy busy

2016-12-01 Thread Michal Hocko
On Thu 01-12-16 17:03:52, Michal Nazarewicz wrote:
> On Thu, Dec 01 2016, Michal Hocko wrote:
> > Let's also CC Marek
> >
> > On Thu 01-12-16 08:43:40, Vlastimil Babka wrote:
> >> On 12/01/2016 08:21 AM, Michal Hocko wrote:
> >> > Forgot to CC Joonsoo. The email thread starts more or less here
> >> > http://lkml.kernel.org/r/20161130092239.GD18437 at dhcp22.suse.cz
> >> > 
> >> > On Thu 01-12-16 08:15:07, Michal Hocko wrote:
> >> > > On Wed 30-11-16 20:19:03, Robin H. Johnson wrote:
> >> > > [...]
> >> > > > alloc_contig_range: [83f2a3, 83f2a4) PFNs busy
> >> > > 
> >> > > Huh, do I get it right that the request was for a _single_ page? Why do
> >> > > we need CMA for that?
> >> 
> >> Ugh, good point. I assumed that was just the PFNs that it failed to migrate
> >> away, but it seems that's indeed the whole requested range. Yeah sounds 
> >> some
> >> part of the dma-cma chain could be smarter and attempt CMA only for e.g.
> >> costly orders.
> >
> > Is there any reason why the DMA api doesn't try the page allocator first
> > before falling back to the CMA? I simply have a hard time to see why the
> > CMA should be used (and fragment) for small requests size.
> 
> There actually may be reasons to always go with CMA even if small
> regions are requested.  CMA areas may be defined to map to particular
> physical addresses and given device may require allocations from those
> addresses.  This may be more than just a matter of DMA address space.
> I cannot give you specific examples though and I might be talking
> nonsense.

I am not familiar with this code so I cannot really argue but a quick
look at rmem_cma_setup doesn't suggest any speicific placing or
anything...

-- 
Michal Hocko
SUSE Labs


drm/radeon spamming alloc_contig_range: [xxx, yyy) PFNs busy busy

2016-12-01 Thread Michal Nazarewicz
On Thu, Dec 01 2016, Michal Hocko wrote:
> Let's also CC Marek
>
> On Thu 01-12-16 08:43:40, Vlastimil Babka wrote:
>> On 12/01/2016 08:21 AM, Michal Hocko wrote:
>> > Forgot to CC Joonsoo. The email thread starts more or less here
>> > http://lkml.kernel.org/r/20161130092239.GD18437 at dhcp22.suse.cz
>> > 
>> > On Thu 01-12-16 08:15:07, Michal Hocko wrote:
>> > > On Wed 30-11-16 20:19:03, Robin H. Johnson wrote:
>> > > [...]
>> > > > alloc_contig_range: [83f2a3, 83f2a4) PFNs busy
>> > > 
>> > > Huh, do I get it right that the request was for a _single_ page? Why do
>> > > we need CMA for that?
>> 
>> Ugh, good point. I assumed that was just the PFNs that it failed to migrate
>> away, but it seems that's indeed the whole requested range. Yeah sounds some
>> part of the dma-cma chain could be smarter and attempt CMA only for e.g.
>> costly orders.
>
> Is there any reason why the DMA api doesn't try the page allocator first
> before falling back to the CMA? I simply have a hard time to see why the
> CMA should be used (and fragment) for small requests size.

There actually may be reasons to always go with CMA even if small
regions are requested.  CMA areas may be defined to map to particular
physical addresses and given device may require allocations from those
addresses.  This may be more than just a matter of DMA address space.
I cannot give you specific examples though and I might be talking
nonsense.

> -- 
> Michal Hocko
> SUSE Labs

-- 
Best regards
ミハウ “𝓶𝓲𝓷𝓪86” ナザレヴイツ
«If at first you don’t succeed, give up skydiving»


[PATCH] drm/i915/dsi: Do not clear DPOUNIT_CLOCK_GATE_DISABLE from vlv_init_display_clock_gating

2016-12-01 Thread Hans de Goede
On my Cherrytrail CUBE iwork8 Air tablet PIPE-A would get stuck on loading
i915 at boot 1 out of every 3 boots, resulting in a non functional LCD.
Once the i915 driver has successfully loaded, the panel can be disabled /
enabled without hitting this issue.

The getting stuck is caused by vlv_init_display_clock_gating() clearing
the DPOUNIT_CLOCK_GATE_DISABLE bit in DSPCLK_GATE_D when called from
chv_pipe_power_well_ops.enable() on driver load, while PIPE-A is enabled
driving the DSI LCD by the BIOS.

Clearing this bit while DSI is in use is a known issue and
intel_dsi_pre_enable() / intel_dsi_post_disable() already set / clear it
as appropriate.

This commit modifies vlv_init_display_clock_gating() to leave the
DPOUNIT_CLOCK_GATE_DISABLE bit alone fixing PIPE-A getting stuck.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=97330
Cc: stable at vger.kernel.org
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/intel_runtime_pm.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 356c662..b5ce7cb 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1039,7 +1039,18 @@ static bool vlv_power_well_enabled(struct 
drm_i915_private *dev_priv,

 static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
 {
-   I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
+   u32 val;
+
+   /*
+* When on driver load, PIPE A may be active and driving a DSI display.
+* Preserve DPOUNIT_CLOCK_GATE_DISABLE to avoid PIPE A getting stuck
+* (and never recovering) in this case. intel_dsi_post_disable() will
+* clear it when we turn off the display.
+*/
+   val = I915_READ(DSPCLK_GATE_D);
+   val &= DPOUNIT_CLOCK_GATE_DISABLE;
+   val |= VRHUNIT_CLOCK_GATE_DISABLE;
+   I915_WRITE(DSPCLK_GATE_D, val);

/*
 * Disable trickle feed and enable pnd deadline calculation
-- 
2.9.3



[PATCH v2] drm: Return -ENOTSUPP when called for KMS cap with a non-KMS driver

2016-12-01 Thread Michel Dänzer
From: Michel Dänzer 

This is an attempt to make the previous fix a bit more robust going
forward.

v2:
* Only allow DRM_CAP_TIMESTAMP_MONOTONIC with UMS drivers (Daniel
  Vetter, Alex Deucher)
* Different logic to keep DRM_CAP_TIMESTAMP_MONOTONIC separate from
  the other caps (Daniel Vetter)

Signed-off-by: Michel Dänzer 
---
 drivers/gpu/drm/drm_ioctl.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 71c3473..706d5aa 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -229,6 +229,17 @@ static int drm_getcap(struct drm_device *dev, void *data, 
struct drm_file *file_
struct drm_crtc *crtc;

req->value = 0;
+
+   /* Only one cap makes sense with a UMS driver: */
+   if (req->capability == DRM_CAP_TIMESTAMP_MONOTONIC) {
+   req->value = drm_timestamp_monotonic;
+   return 0;
+   }
+
+   /* Other caps only work with KMS drivers */
+   if (!drm_core_check_feature(dev, DRIVER_MODESET))
+   return -ENOTSUPP;
+
switch (req->capability) {
case DRM_CAP_DUMB_BUFFER:
if (dev->driver->dumb_create)
@@ -247,19 +258,14 @@ static int drm_getcap(struct drm_device *dev, void *data, 
struct drm_file *file_
req->value |= dev->driver->prime_fd_to_handle ? 
DRM_PRIME_CAP_IMPORT : 0;
req->value |= dev->driver->prime_handle_to_fd ? 
DRM_PRIME_CAP_EXPORT : 0;
break;
-   case DRM_CAP_TIMESTAMP_MONOTONIC:
-   req->value = drm_timestamp_monotonic;
-   break;
case DRM_CAP_ASYNC_PAGE_FLIP:
req->value = dev->mode_config.async_page_flip;
break;
case DRM_CAP_PAGE_FLIP_TARGET:
-   if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-   req->value = 1;
-   drm_for_each_crtc(crtc, dev) {
-   if (!crtc->funcs->page_flip_target)
-   req->value = 0;
-   }
+   req->value = 1;
+   drm_for_each_crtc(crtc, dev) {
+   if (!crtc->funcs->page_flip_target)
+   req->value = 0;
}
break;
case DRM_CAP_CURSOR_WIDTH:
-- 
2.10.2



[PATCH 2/2] drm: Return -ENOTSUPP when called for KMS cap with a non-KMS driver

2016-12-01 Thread Michel Dänzer
On 30/11/16 06:07 PM, Daniel Vetter wrote:
> On Wed, Nov 30, 2016 at 05:30:02PM +0900, Michel Dänzer wrote:
>> From: Michel Dänzer 
>>
>> This is an attempt to make the previous fix a bit more robust going
>> forward.
>>
>> Signed-off-by: Michel Dänzer 
>> ---
>>  drivers/gpu/drm/drm_ioctl.c | 23 +--
>>  1 file changed, 17 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>> index 71c3473..32f484b 100644
>> --- a/drivers/gpu/drm/drm_ioctl.c
>> +++ b/drivers/gpu/drm/drm_ioctl.c
>> @@ -229,6 +229,19 @@ static int drm_getcap(struct drm_device *dev, void 
>> *data, struct drm_file *file_
>>  struct drm_crtc *crtc;
>>  
>>  req->value = 0;
>> +
>> +/* Only allow non-KMS caps with non-KMS drivers */
>> +switch (req->capability) {
>> +case DRM_CAP_DUMB_BUFFER:
> 
> Dumb buffers are only meant to be used for kms drivers, should be
> disallowed too.
> 
>> +case DRM_CAP_VBLANK_HIGH_CRTC:
> 
> Might be good to have a comment here that we need to allow this for old
> ums?

This is effectively KMS-only as well, per Alex (thanks!).


>> +case DRM_CAP_PRIME:
>> +case DRM_CAP_TIMESTAMP_MONOTONIC:
> 
> This is pretty new, I don't think any of the old ums drivers was ever
> updated to use it. Should probably disallow it too.

DRM_CAP_TIMESTAMP_MONOTONIC is driver independent, I don't see why it
wouldn't work fine with UMS drivers. OTOH, I don't think DRM_CAP_PRIME
can work with UMS.


>> +break;
>> +default:
>> +if (!drm_core_check_feature(dev, DRIVER_MODESET))
>> +return -ENOTSUPP;
>> +}
> 
> And one code org bikeshed: I don't like the duplicated switch, could we
> instead split it it into two disjoint sets like this?
> 
>   switch (req->capability) {
>   case DRM_CAP_PRIME:
>   req->value |= dev->driver->prime_fd_to_handle ? 
> DRM_PRIME_CAP_IMPORT : 0;
>   req->value |= dev->driver->prime_handle_to_fd ? 
> DRM_PRIME_CAP_EXPORT : 0;
>   break;
>   ... all other non-modeset caps ...
>   }
> 
>   if (!drm_core_check_feature(dev, DRIVER_MODESET))
>   return -ENOTSUPP;
> 
>   switch (req->capability) {
>   ... handle remaining caps needed for DRIVER_MODSET ...
>   default:
>   return -EINVAL;
>   }
> 
> That way it would be a bit more obvious that people who add a new cap need
> to make a decision where to put it (and by default put it in the bottom
> pile).

Your pseudo-code wouldn't work correctly, but I get your idea. :)


v2 addressing review feedback coming up soon.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer


[PATCH v2] drm: Return -ENOTSUPP when called for KMS cap with a non-KMS driver

2016-12-01 Thread Daniel Vetter
On Thu, Dec 01, 2016 at 10:21:28AM -0500, Sean Paul wrote:
> On Thu, Dec 1, 2016 at 2:37 AM, Michel Dänzer  wrote:
> > From: Michel Dänzer 
> >
> > This is an attempt to make the previous fix a bit more robust going
> > forward.
> 
> It takes a bit of work to locate the "previous fix" now that it's gone
> through drm-misc-fixes. Can you update with a proper reference to the
> first patch?
> 
> Additionally, it's probably easiest if we hold off on merging this
> until your first patch finds its way into drm-misc-next.

I'll bother Dave for a backmerge as soon as 4.9/4.9-rc8 is out, and then
we can apply Michel's cleanup on top.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH v2 01/11] drm/vgem: Use ww_mutex_(un)lock even with a NULL context

2016-12-01 Thread Daniel Vetter
On Thu, Dec 01, 2016 at 02:18:04PM +, Chris Wilson wrote:
> On Thu, Dec 01, 2016 at 03:06:44PM +0100, Nicolai Hähnle wrote:
> > From: Nicolai Hähnle 
> > 
> > v2: use resv->lock instead of resv->lock.base (Christian König)
> > 
> > Cc: Peter Zijlstra 
> > Cc: Ingo Molnar 
> > Cc: Maarten Lankhorst 
> > Cc: Daniel Vetter 
> > Cc: Chris Wilson 
> > Cc: dri-devel at lists.freedesktop.org
> > Signed-off-by: Nicolai Hähnle 
> Reviewed-by: Chris Wilson 

Applied to drm-misc, thanks.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH] drm/drm_bridge: adjust bridge module's refcount

2016-12-01 Thread Daniel Vetter
On Thu, Dec 01, 2016 at 02:22:18PM +0100, Andrzej Hajda wrote:
> On 01.12.2016 08:18, Daniel Vetter wrote:
> > On Thu, Dec 01, 2016 at 08:07:29AM +0100, Andrzej Hajda wrote:
> >> On 30.11.2016 14:09, Daniel Vetter wrote:
> >>> On Wed, Nov 30, 2016 at 01:03:20PM +0200, Laurent Pinchart wrote:
>  On Wednesday 30 Nov 2016 11:55:20 Daniel Vetter wrote:
> > Why exactly do you want to hotplug encoders? Or bridges fwiw ... since 
> > at
> > least only making those hotpluggable will make the uabi story easier 
> > since
> > they're not exposed.
>  Ideally to avoid disabling the whole display engine when one encoder 
>  isn't 
>  available/operational. Right now we're waiting for all pieces to be 
>  available 
>  (using deferred probing or the component framework) before registering 
>  the DRM 
>  device. This means that if one bridge can't be probed successfully for 
>  any 
>  reason we'll end up having not display at all. This includes the case 
>  where 
>  the driver for the bridge is not available. If we could support dynamic 
>  hotplug of bridges, we could start with a display engine that supports a 
>  subset of the outputs, and add new outputs as they become operational.
> 
>  We have a similar issue when unbinding bridge devices from their driver. 
>  They 
>  obviously can't be used anymore, but we have no solution to handle that 
>  apart 
>  from unregistering the DRM device completely, as otherwise rebinding the 
>  bridge to the driver later can't be handled.
> >>> This all sounds pretty cool, but does anyone care? Like what's the
> >>> real-world use-case here? Some cosmic ray destroyed the bridge driver on
> >>> your android phone and now you want it to magically fall back to hdmi that
> >>> no one ever plugs in? Or someone misconfigures their kernel and gets
> >>> greeted with a black screen, instead of a ... black screen?
> >> Real use case is that we need to always load hdmi path drivers at phone
> >> startup just in case somebody will use it.
> >> This way we are wasting space and more importantly boot time, for code
> >> which won't be used by 99% users of phones.
> >> Putting them into modules an loading on MHL/HDMI cable plug-in would be
> >> more optimal, I guess.
> > Do we have numbers for this?
> 
> For number of HDMI/MHL users in mobiles, I have no stats :)
> For display boot delay due to deferring hdmi driver is 2.5-3.5 seconds
> on peach-pi board for example [1].

That sounds horrible. We load our entire driver in that time, and it has 3
hdmi ports. What exactly is that thing doing for 3 seconds?! Until we know
what's going on I'm not sure it's just a driver that has a dead-slow init
function ...

> [1]:
> https://storage.kernelci.org/ulfh/v4.9-rc7-120-g38cdf7e0bfee/arm-exynos_defconfig/lab-baylibre-seattle/boot-exynos5800-peach-pi.html
> 
> 
> >  What part of the overhead is the edid probing
> > and reading, which we probably should optimize either way ... optimize as
> > in make sure we never ever stall anything for edid reads.
> 
> As EDID probing should be performed only after detecting sink it seems
> irrelevant here.
> 
> >
> > And if you never load the hdmi driver, how do you know when to load it
> > because the user plugged in the cable?
> 
> Mobiles often have detection which cable is plugged in. However I am not
> sure if kernel sends such events to userspace,
> but this should be simple to do.

Well, to do that (at least with drm) you need the driver loaded, or at
least the stuff it supports registered.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH]i915: use WARN_ON_ONCE in intel_dp_aux_transfer

2016-12-01 Thread Dave Young
On 12/01/16 at 04:00pm, Dave Young wrote:
> On 11/30/16 at 03:25pm, Ville Syrjälä wrote:
> > On Thu, Nov 24, 2016 at 05:03:20PM +0800, Dave Young wrote:
> > > On 11/24/16 at 10:53am, Jani Nikula wrote:
> > > > On Thu, 24 Nov 2016, Dave Young  wrote:
> > > > > I see a lot of below warning:
> > > > 
> > > > No, we must not hide this under the carpet. There's a bug at fdo about
> > > > this, and we need to fix it.
> > > 
> > > It is not hiding it, just not repeating the warnings. But anyway I do
> > > not have strong opinion. I'm building my kernel with this patch until
> > > there is a real fix in upstream.
> > 
> > We already have a patch to reduce it a single WARN:
> > d4cb3fd9b548 ("drm/i915/dp: add lane_count check in 
> > intel_dp_check_link_status")
> 
> It works for me, thanks
> 
> > 
> > Do we need to get that backported to stable?
> 
> Personally I think it should but I'm not sure the policy of stable for i915 
> though.
> 

Hmm, I can not recall when I had such issue in which version of kernel
because I just pull and rebuild very often, so I should say I have no
idea .. 

> Thanks
> Dave


[PATCH 1/2] drm/i915/dsi: Fix swapping of MIPI_SEQ_DEASSERT_RESET / MIPI_SEQ_ASSERT_RESET

2016-12-01 Thread Hans de Goede
Hi,

On 29-11-16 14:06, Hans de Goede wrote:



> p.s.
>
> I'm also trying to come up with some patches which properly
> integrate pwm-lpss with the i915 driver instead of it
> throwing a "Failed to own the pwm chip" error. But as soon
> as I hook up things so that pwm_get() returns the pwm-lpss
> pwm0 I hit:
>
> https://bugs.freedesktop.org/show_bug.cgi?id=97330
>
> I get the same pipe-a stuck (or not seeing vblank irqs?)
> problems sometimes without the pwm-lpss driver in the loop
> but then only sometimes and with pwm-lpss I get this
> problem when loading the i915 driver most of the time
> (but not all the time).
>
> I've been debugging this a couple of evenings in a row
> now, but no luck sofar.

Ok, a couple of more evenings of debugging + working on
this today has finally resulted in me finding a fix :)

The problem is that on driver load we call
chv_pipe_power_well_ops.enable() which calls
vlv_init_display_clock_gating() which clears
the DPOUNIT_CLOCK_GATE_DISABLE bit in DSPCLK_GATE_D
while the DSI panel is being driven by PIPE-A, as
already documented in intel_dsi_pre_enable()
allowing the DPOUNIT to get gated while DSI
active will result in a stuck PIPE-A.

I've written a patch for this, I'll send this
right after this mail, and attach it to bug:
https://bugs.freedesktop.org/show_bug.cgi?id=97330

Which I believe is the same issue.

Regards,

Hans


[PATCH]i915: use WARN_ON_ONCE in intel_dp_aux_transfer

2016-12-01 Thread Dave Young
On 11/30/16 at 03:25pm, Ville Syrjälä wrote:
> On Thu, Nov 24, 2016 at 05:03:20PM +0800, Dave Young wrote:
> > On 11/24/16 at 10:53am, Jani Nikula wrote:
> > > On Thu, 24 Nov 2016, Dave Young  wrote:
> > > > I see a lot of below warning:
> > > 
> > > No, we must not hide this under the carpet. There's a bug at fdo about
> > > this, and we need to fix it.
> > 
> > It is not hiding it, just not repeating the warnings. But anyway I do
> > not have strong opinion. I'm building my kernel with this patch until
> > there is a real fix in upstream.
> 
> We already have a patch to reduce it a single WARN:
> d4cb3fd9b548 ("drm/i915/dp: add lane_count check in 
> intel_dp_check_link_status")

It works for me, thanks

> 
> Do we need to get that backported to stable?

Personally I think it should but I'm not sure the policy of stable for i915 
though.

Thanks
Dave


[PATCH v2 05/11] locking/ww_mutex: Add waiters in stamp order

2016-12-01 Thread Chris Wilson
On Thu, Dec 01, 2016 at 03:06:48PM +0100, Nicolai Hähnle wrote:
> @@ -677,15 +722,25 @@ __mutex_lock_common(struct mutex *lock, long state, 
> unsigned int subclass,
>   debug_mutex_lock_common(lock, );
>   debug_mutex_add_waiter(lock, , task);
>  
> - /* add waiting tasks to the end of the waitqueue (FIFO): */
> - list_add_tail(, >wait_list);
> + lock_contended(>dep_map, ip);
> +
> + if (!use_ww_ctx) {
> + /* add waiting tasks to the end of the waitqueue (FIFO): */
> + list_add_tail(, >wait_list);
> + } else {
> + /* Add in stamp order, waking up waiters that must back off. */
> + ret = __ww_mutex_add_waiter(, lock, ww_ctx);
> + if (ret)
> + goto err_early_backoff;
> +
> + waiter.ww_ctx = ww_ctx;
> + }
> +
>   waiter.task = task;

Would an unconditional waiter.ww_ctx = ww_ctx be chep enough? (Same
cacheline write and all that?)

Makes the above clearer in that you have

if (!ww_ctx) {
list_add_tail();
} else {
ret = __ww_mutex_add_waiter(); /* no need to handle !ww_ctx */
if (ret)
goto err_early_backoff;
}

waiter.ww_ctx = ww_ctx;
waiter.task = task;

>  
>   if (__mutex_waiter_is_first(lock, ))
>   __mutex_set_flag(lock, MUTEX_FLAG_WAITERS);
>  
> - lock_contended(>dep_map, ip);
> -
>   set_task_state(task, state);
>   for (;;) {
>   /*
> @@ -693,8 +748,12 @@ __mutex_lock_common(struct mutex *lock, long state, 
> unsigned int subclass,
>* mutex_unlock() handing the lock off to us, do a trylock
>* before testing the error conditions to make sure we pick up
>* the handoff.
> +  *
> +  * For w/w locks, we always need to do this even if we're not
> +  * currently the first waiter, because we may have been the
> +  * first waiter during the unlock.
>*/
> - if (__mutex_trylock(lock, first))
> + if (__mutex_trylock(lock, use_ww_ctx || first))

I'm not certain about the magic of first vs HANDOFF. Afaict, first ==
HANDOFF and this patch breaks that relationship. I think you need to add
bool handoff; as a separate tracker to first.

>   goto acquired;
>  
>   /*
> @@ -716,7 +775,20 @@ __mutex_lock_common(struct mutex *lock, long state, 
> unsigned int subclass,
>   spin_unlock_mutex(>wait_lock, flags);
>   schedule_preempt_disabled();
>  
> - if (!first && __mutex_waiter_is_first(lock, )) {
> + if (use_ww_ctx && ww_ctx) {
> + /*
> +  * Always re-check whether we're in first position. We
> +  * don't want to spin if another task with a lower
> +  * stamp has taken our position.
> +  *
> +  * We also may have to set the handoff flag again, if
> +  * our position at the head was temporarily taken away.

Comment makes sense.

Ah. Should this be just if (use_ww_ctx) { /* always recheck... */ ?
Except that !ww_ctx are never gazzumped in the list, so if they are
first, then they are always first.

Could you explain that as well (about why !ww_ctx is special here but
not above). And then it can even be reduced to if (ww_ctx) {} to match
the first chunk if the revision is acceptable.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[i.MX6 DRM IPUv3] Regression 4.9-rc5: greenish screen with YUV420 video

2016-12-01 Thread Philipp Zabel
Hi Krzysztof,

Am Donnerstag, den 17.11.2016, 10:43 +0100 schrieb Krzysztof Hałasa:
> Hi,
> 
> The following GStreamer pipeline causes screen to become green with
> v4.9-rc4+:
> 
> gst-launch-1.0 udpsrc uri=udp://239.1.2.2:5100 reuse=true 
> caps="application/x-rtp,media=(string)video,clock-rate=(int)9,encoding-name=(string)H264"
>  ! rtph264depay ! h264parse ! v4l2video1dec capture-io-mode=dmabuf ! kmssink 
> name=imx-drm sync=0
> 
> Reverting "drm/imx: ipuv3-plane: Skip setting u/vbo only when we don't
> need modeset", commit 81d553545a1510ff7c7c00cbc9b57d6172d411a4, fixes
> the problem.
> 
> Hardware is Gateworks Ventana GW5400, i.MX6Q, HDMI output, no X (console
> only).

I had already (accidentally) fixed this with 3fd8b292ae6b ("drm/imx:
ipuv3-plane: merge ipu_plane_atomic_set_base into atomic_update").

The bug is in this hunk in commit 81d553545a15:
 @@ -118,7 +117,7 @@ static void ipu_plane_atomic_set_base(struct ipu_plane 
*ipu_plane,
switch (fb->pixel_format) {
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
-   if (old_state->fb)
+   if (!drm_atomic_crtc_needs_modeset(crtc_state))
break;

/*

When the plane is first enabled, a modeset is not needed, so
drm_atomic_crtc_needs_modeset(crtc_state) is false and
ipu_plane_atomic_set_base then skipped the ubo/vbo setup.

When moving the code around in 3fd8b292ae6b I assumed that this
condition should never be true where the code ended up (as it was for
old_state->fb before), and I removed it.

regards
Philipp



[PATCH] drm: allow changing DPMS mode for non-CRTC displays

2016-12-01 Thread Marta Lofstedt
For non-CRTC displays, the drm_atomic_helper_connector_dpms
will always set the connector back the old DPMS state
before returning. This makes it impossible to change
DPMS state.

fixes: 0853695c3ba46f97dfc0b5885f7b7e640ca212dd

Signed-off-by: Marta Lofstedt 
---
 drivers/gpu/drm/drm_atomic_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 494680c..6a5acb9 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2885,8 +2885,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector 
*connector,
 fail:
if (ret == -EDEADLK)
goto backoff;
-
-   connector->dpms = old_mode;
+   if (ret != 0)
+   connector->dpms = old_mode;
drm_atomic_state_put(state);
return ret;

-- 
2.9.3



[PATCH libdrm v2 5/5] xf86drm: implement an OpenBSD specific drmGetDevice2

2016-12-01 Thread Jonathan Gray
DRI devices on OpenBSD are not in their own directory.  They reside in
/dev with a large number of statically generated /dev nodes.

Avoid stat'ing all of /dev on OpenBSD by implementing this custom path.

v2:
   - use drmGetMinorType to get node type
   - adapt to drmProcessPciDevice changes
   - verify drmParseSubsystemType type is PCI
   - add a comment describing why this was added

Signed-off-by: Jonathan Gray 
---
 xf86drm.c | 62 ++
 1 file changed, 62 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index ea24108..9981be4 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -3248,6 +3248,67 @@ drm_device_validate_flags(uint32_t flags)
  */
 int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
 {
+#ifdef __OpenBSD__
+/*
+ * DRI device nodes on OpenBSD are not in their own directory, they reside
+ * in /dev along with a large number of statically generated /dev nodes.
+ * Avoid stat'ing all of /dev needlessly by implementing this custom path.
+ */
+drmDevicePtr d;
+struct stat  sbuf;
+char node[PATH_MAX + 1];
+const char  *dev_name;
+int  node_type, subsystem_type;
+int  maj, min, n, ret;
+
+if (fd == -1 || device == NULL)
+return -EINVAL;
+
+if (fstat(fd, ))
+return -errno;
+
+maj = major(sbuf.st_rdev);
+min = minor(sbuf.st_rdev);
+
+if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+return -EINVAL;
+
+node_type = drmGetMinorType(min);
+if (node_type == -1)
+return -ENODEV;
+
+switch (node_type) {
+case DRM_NODE_PRIMARY:
+dev_name = DRM_DEV_NAME;
+break;
+case DRM_NODE_CONTROL:
+dev_name = DRM_CONTROL_DEV_NAME;
+break;
+case DRM_NODE_RENDER:
+dev_name = DRM_RENDER_DEV_NAME;
+break;
+default:
+return -EINVAL;
+};
+
+n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
+if (n == -1 || n >= PATH_MAX)
+  return -errno;
+if (stat(node, ))
+return -EINVAL;
+
+subsystem_type = drmParseSubsystemType(maj, min);
+if (subsystem_type != DRM_BUS_PCI)
+return -ENODEV;
+
+ret = drmProcessPciDevice(, node, node_type, maj, min, true, flags);
+if (ret)
+return ret;
+
+*device = d;
+
+return 0;
+#else
 drmDevicePtr *local_devices;
 drmDevicePtr d;
 DIR *sysdir;
@@ -3357,6 +3418,7 @@ free_devices:
 free_locals:
 free(local_devices);
 return ret;
+#endif
 }

 /**
-- 
2.10.2



[PATCH libdrm v2 4/5] xf86drm: implement drmParsePciBusInfo for OpenBSD

2016-12-01 Thread Jonathan Gray
Implement drmParsePciBusInfo for OpenBSD by using the new
DRM_IOCTL_GET_PCIINFO ioctl.

v2: use drmGetMinorType to get node type instead of always
using DRM_NODE_PRIMARY.

Signed-off-by: Jonathan Gray 
---
 xf86drm.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 6465953..ea24108 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2947,6 +2947,30 @@ static int drmParsePciBusInfo(int maj, int min, 
drmPciBusInfoPtr info)
 info->func = func;

 return 0;
+#elif defined(__OpenBSD__)
+struct drm_pciinfo pinfo;
+int fd, type;
+
+type = drmGetMinorType(min);
+if (type == -1)
+return -ENODEV;
+
+fd = drmOpenMinor(min, 0, type);
+if (fd < 0)
+return -errno;
+
+if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, )) {
+close(fd);
+return -errno;
+}
+close(fd);
+
+info->domain = pinfo.domain;
+info->bus = pinfo.bus;
+info->dev = pinfo.dev;
+info->func = pinfo.func;
+
+return 0;
 #else
 #warning "Missing implementation of drmParsePciBusInfo"
 return -EINVAL;
-- 
2.10.2



[PATCH libdrm v2 3/5] xf86drm: implement drmParsePciDeviceInfo for OpenBSD

2016-12-01 Thread Jonathan Gray
Implement drmParsePciDeviceInfo for OpenBSD by using the new
DRM_IOCTL_GET_PCIINFO ioctl.

v2: adapt to drmParsePciDeviceInfo changes and use drmOpenMinor

Signed-off-by: Jonathan Gray 
---
 xf86drm.c | 41 +
 1 file changed, 41 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 35c1fc4..6465953 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -102,6 +102,22 @@
 #define DRM_MAJOR 226 /* Linux */
 #endif

+#ifdef __OpenBSD__
+struct drm_pciinfo {
+   uint16_tdomain;
+   uint8_t bus;
+   uint8_t dev;
+   uint8_t func;
+   uint16_tvendor_id;
+   uint16_tdevice_id;
+   uint16_tsubvendor_id;
+   uint16_tsubdevice_id;
+   uint8_t revision_id;
+};
+
+#define DRM_IOCTL_GET_PCIINFO  DRM_IOR(0x15, struct drm_pciinfo)
+#endif
+
 #define DRM_MSG_VERBOSITY 3

 #define memclear(s) memset(, 0, sizeof(s))
@@ -3061,6 +3077,31 @@ static int drmParsePciDeviceInfo(int maj, int min,
 return parse_config_sysfs_file(maj, min, device);

 return 0;
+#elif defined(__OpenBSD__)
+struct drm_pciinfo pinfo;
+int fd, type;
+
+type = drmGetMinorType(min);
+if (type == -1)
+return -ENODEV;
+
+fd = drmOpenMinor(min, 0, type);
+if (fd < 0)
+return -errno;
+
+if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, )) {
+close(fd);
+return -errno;
+}
+close(fd);
+
+device->vendor_id = pinfo.vendor_id;
+device->device_id = pinfo.device_id;
+device->revision_id = pinfo.revision_id;
+device->subvendor_id = pinfo.subvendor_id;
+device->subdevice_id = pinfo.subdevice_id;
+
+return 0;
 #else
 #warning "Missing implementation of drmParsePciDeviceInfo"
 return -EINVAL;
-- 
2.10.2



[PATCH libdrm v2 2/5] xf86drm: implement drmParseSubsystemType for OpenBSD

2016-12-01 Thread Jonathan Gray
Implement drmParseSubsystemType for OpenBSD by always returning
DRM_BUS_PCI.  No non-pci drm drivers are in the kernel and this is
unlikely to change anytime soon as the existing ones aren't permissively
licensed.

Signed-off-by: Jonathan Gray 
---
 xf86drm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index f93ebc0..35c1fc4 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2887,6 +2887,8 @@ static int drmParseSubsystemType(int maj, int min)
 return DRM_BUS_PCI;

 return -EINVAL;
+#elif defined(__OpenBSD__)
+   return DRM_BUS_PCI;
 #else
 #warning "Missing implementation of drmParseSubsystemType"
 return -EINVAL;
-- 
2.10.2



[PATCH libdrm v2 1/5] xf86drm: implement drmGetMinorNameForFD for non-sysfs

2016-12-01 Thread Jonathan Gray
Implement drmGetMinorNameForFD for systems without sysfs by
adapting drm_get_device_name_for_fd() from the Mesa loader.

v2: use type parameter to select dev name instead of always
using DRM_DEV_NAME

Signed-off-by: Jonathan Gray 
---
 xf86drm.c | 35 ++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/xf86drm.c b/xf86drm.c
index f117716..f93ebc0 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2818,7 +2818,40 @@ static char *drmGetMinorNameForFD(int fd, int type)
 out_close_dir:
 closedir(sysdir);
 #else
-#warning "Missing implementation of drmGetMinorNameForFD"
+struct stat sbuf;
+char buf[PATH_MAX + 1];
+const char *dev_name;
+unsigned int maj, min;
+int n;
+
+if (fstat(fd, ))
+return NULL;
+
+maj = major(sbuf.st_rdev);
+min = minor(sbuf.st_rdev);
+
+if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+return NULL;
+
+switch (type) {
+case DRM_NODE_PRIMARY:
+dev_name = DRM_DEV_NAME;
+break;
+case DRM_NODE_CONTROL:
+dev_name = DRM_CONTROL_DEV_NAME;
+break;
+case DRM_NODE_RENDER:
+dev_name = DRM_RENDER_DEV_NAME;
+break;
+default:
+return NULL;
+};
+
+n = snprintf(buf, sizeof(buf), dev_name, DRM_DIR_NAME, min);
+if (n == -1 || n >= sizeof(buf))
+return NULL;
+
+return strdup(buf);
 #endif
 return NULL;
 }
-- 
2.10.2



drm/radeon spamming alloc_contig_range: [xxx, yyy) PFNs busy busy

2016-12-01 Thread Michal Hocko
Let's also CC Marek

On Thu 01-12-16 08:43:40, Vlastimil Babka wrote:
> On 12/01/2016 08:21 AM, Michal Hocko wrote:
> > Forgot to CC Joonsoo. The email thread starts more or less here
> > http://lkml.kernel.org/r/20161130092239.GD18437 at dhcp22.suse.cz
> > 
> > On Thu 01-12-16 08:15:07, Michal Hocko wrote:
> > > On Wed 30-11-16 20:19:03, Robin H. Johnson wrote:
> > > [...]
> > > > alloc_contig_range: [83f2a3, 83f2a4) PFNs busy
> > > 
> > > Huh, do I get it right that the request was for a _single_ page? Why do
> > > we need CMA for that?
> 
> Ugh, good point. I assumed that was just the PFNs that it failed to migrate
> away, but it seems that's indeed the whole requested range. Yeah sounds some
> part of the dma-cma chain could be smarter and attempt CMA only for e.g.
> costly orders.

Is there any reason why the DMA api doesn't try the page allocator first
before falling back to the CMA? I simply have a hard time to see why the
CMA should be used (and fragment) for small requests size.
-- 
Michal Hocko
SUSE Labs


[PATCH] drm/vmwgfx: Switch to mode_cmd2

2016-12-01 Thread Sinclair Yeh
One defect below otherwise:  Reviewed-by: Sinclair Yeh 

On Wed, Nov 30, 2016 at 06:00:04PM +0100, Daniel Vetter wrote:
> Surprisingly few changes needed to make it happen. Compile-tested
> only. The idea is that this replaces the 2 patches from Ville's big
> fb->format patch series as a prep patch. Only impact to later patches
> should be the one instace added in this patch where we look at
> fb->pixel_format (instead of fb->bpp and fb->depth), so minor
> adjustements in the cocci-generated patches needed.
> 
> Cc: ville.syrjala at linux.intel.com
> Cc: Laurent Pinchart 
> Cc: linux-graphics-maintainer at vmware.com
> Cc: Sinclair Yeh 
> Cc: Thomas Hellstrom 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_fb.c  |  18 +++---
>  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 116 
> +---
>  drivers/gpu/drm/vmwgfx/vmwgfx_kms.h |   2 +-
>  3 files changed, 52 insertions(+), 84 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> index d2d93959b119..4b1defc7aa6d 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> @@ -465,33 +465,33 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
>  
>  static int vmw_fb_kms_framebuffer(struct fb_info *info)
>  {
> - struct drm_mode_fb_cmd mode_cmd;
> + struct drm_mode_fb_cmd2 mode_cmd;
>   struct vmw_fb_par *par = info->par;
>   struct fb_var_screeninfo *var = >var;
>   struct drm_framebuffer *cur_fb;
>   struct vmw_framebuffer *vfb;
> - int ret = 0;
> + int ret = 0, depth;
>   size_t new_bo_size;
>  
> - ret = vmw_fb_compute_depth(var, _cmd.depth);
> + ret = vmw_fb_compute_depth(var, );
>   if (ret)
>   return ret;
>  
>   mode_cmd.width = var->xres;
>   mode_cmd.height = var->yres;
> - mode_cmd.bpp = var->bits_per_pixel;
> - mode_cmd.pitch = ((mode_cmd.bpp + 7) / 8) * mode_cmd.width;

mode_cmd.pitches[0] needs to be initialized before being used below.

Maybe something like:
mode_cmd.pitches[0] = ((var->bits_per_pixel + 7) / 8) * mode_cmd.width;

> + mode_cmd.pixel_format =
> + drm_mode_legacy_fb_format(var->bits_per_pixel,
> + ((var->bits_per_pixel + 7) / 8) * mode_cmd.width);
>  
>   cur_fb = par->set_fb;
>   if (cur_fb && cur_fb->width == mode_cmd.width &&
>   cur_fb->height == mode_cmd.height &&
> - cur_fb->bits_per_pixel == mode_cmd.bpp &&
> - cur_fb->depth == mode_cmd.depth &&
> - cur_fb->pitches[0] == mode_cmd.pitch)
> + cur_fb->pixel_format == mode_cmd.pixel_format &&
> + cur_fb->pitches[0] == mode_cmd.pitches[0])
>   return 0;
>  
>   /* Need new buffer object ? */
> - new_bo_size = (size_t) mode_cmd.pitch * (size_t) mode_cmd.height;
> + new_bo_size = (size_t) mode_cmd.pitches[0] * (size_t) mode_cmd.height;
>   ret = vmw_fb_kms_detach(par,
>   par->bo_size < new_bo_size ||
>   par->bo_size > 2*new_bo_size,
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> index e3f68cc9bb4b..e7daf59bac80 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> @@ -516,7 +516,7 @@ static const struct drm_framebuffer_funcs 
> vmw_framebuffer_surface_funcs = {
>  static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
>  struct vmw_surface *surface,
>  struct vmw_framebuffer **out,
> -const struct drm_mode_fb_cmd
> +const struct drm_mode_fb_cmd2
>  *mode_cmd,
>  bool is_dmabuf_proxy)
>  
> @@ -525,6 +525,7 @@ static int vmw_kms_new_framebuffer_surface(struct 
> vmw_private *dev_priv,
>   struct vmw_framebuffer_surface *vfbs;
>   enum SVGA3dSurfaceFormat format;
>   int ret;
> + struct drm_format_name_buf format_name;
>  
>   /* 3D is only supported on HWv8 and newer hosts */
>   if (dev_priv->active_display_unit == vmw_du_legacy)
> @@ -548,21 +549,22 @@ static int vmw_kms_new_framebuffer_surface(struct 
> vmw_private *dev_priv,
>   return -EINVAL;
>   }
>  
> - switch (mode_cmd->depth) {
> - case 32:
> + switch (mode_cmd->pixel_format) {
> + case DRM_FORMAT_ARGB:
>   format = SVGA3D_A8R8G8B8;
>   break;
> - case 24:
> + case DRM_FORMAT_XRGB:
>   format = SVGA3D_X8R8G8B8;
>   break;
> - case 16:
> + case DRM_FORMAT_RGB565:
>   format = SVGA3D_R5G6B5;
>   break;
> - case 15:
> + case DRM_FORMAT_XRGB1555:
>   format = SVGA3D_A1R5G5B5;
>   break;
>   default:
> -

[PATCH v2 11/11] [rfc] locking/ww_mutex: Always spin optimistically for the first waiter

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

Check the current owner's context once against our stamp. If our stamp is
lower, we continue to spin optimistically instead of backing off.

This is correct with respect to deadlock detection because while the
(owner, ww_ctx) pair may re-appear if the owner task manages to unlock
and re-acquire the lock while we're spinning, the context could only have
been re-initialized with an even higher stamp. We also still detect when
we have to back off for other waiters that join the list while we're
spinning.

But taking the wait_lock in mutex_spin_on_owner feels iffy, even if it is
done only once.

Median timings taken of a contention-heavy GPU workload:

Before:
real0m53.086s
user0m7.360s
sys 1m46.204s

After:
real0m52.577s
user0m7.544s
sys 1m49.200s

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 kernel/locking/mutex.c | 35 ---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 38d173c..9216239 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -378,6 +378,28 @@ bool mutex_spin_on_owner(struct mutex *lock, struct 
task_struct *owner,
 struct mutex_waiter *waiter)
 {
bool ret = true;
+   struct ww_acquire_ctx *owner_ww_ctx = NULL;
+
+   if (use_ww_ctx && ww_ctx && ww_ctx->acquired > 0) {
+   struct ww_mutex *ww;
+   unsigned long flags;
+
+   ww = container_of(lock, struct ww_mutex, base);
+
+   /*
+* Check the stamp of the current owner once. This allows us
+* to spin optimistically in the case where the current owner
+* has a higher stamp than us.
+*/
+   spin_lock_mutex(>wait_lock, flags);
+   owner_ww_ctx = ww->ctx;
+   if (owner_ww_ctx &&
+   __ww_mutex_stamp_after(ww_ctx, owner_ww_ctx)) {
+   spin_unlock_mutex(>wait_lock, flags);
+   return false;
+   }
+   spin_unlock_mutex(>wait_lock, flags);
+   }

rcu_read_lock();
while (__mutex_owner(lock) == owner) {
@@ -414,9 +436,16 @@ bool mutex_spin_on_owner(struct mutex *lock, struct 
task_struct *owner,
 * Check this in every inner iteration because we may
 * be racing against another thread's ww_mutex_lock.
 */
-   if (ww_ctx->acquired > 0 && READ_ONCE(ww->ctx)) {
-   ret = false;
-   break;
+   if (ww_ctx->acquired > 0) {
+   struct ww_acquire_ctx *current_ctx;
+
+   current_ctx = READ_ONCE(ww->ctx);
+
+   if (current_ctx &&
+   current_ctx != owner_ww_ctx) {
+   ret = false;
+   break;
+   }
}

/*
-- 
2.7.4



[PATCH v2 10/11] Documentation/locking/ww_mutex: Update the design document

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

Document the invariants we maintain for the wait list of ww_mutexes.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 Documentation/locking/ww-mutex-design.txt | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/Documentation/locking/ww-mutex-design.txt 
b/Documentation/locking/ww-mutex-design.txt
index 8a112dc..34c3a1b 100644
--- a/Documentation/locking/ww-mutex-design.txt
+++ b/Documentation/locking/ww-mutex-design.txt
@@ -309,11 +309,15 @@ Design:
   normal mutex locks, which are far more common. As such there is only a small
   increase in code size if wait/wound mutexes are not used.

+  We maintain the following invariants for the wait list:
+  (1) Waiters with an acquire context are sorted by stamp order; waiters
+  without an acquire context are interspersed in FIFO order.
+  (2) Among waiters with contexts, only the first one can have other locks
+  acquired already (ctx->acquired > 0). Note that this waiter may come
+  after other waiters without contexts in the list.
+
   In general, not much contention is expected. The locks are typically used to
-  serialize access to resources for devices. The only way to make wakeups
-  smarter would be at the cost of adding a field to struct mutex_waiter. This
-  would add overhead to all cases where normal mutexes are used, and
-  ww_mutexes are generally less performance sensitive.
+  serialize access to resources for devices.

 Lockdep:
   Special care has been taken to warn for as many cases of api abuse
-- 
2.7.4



[PATCH v2 09/11] locking/mutex: Initialize mutex_waiter::ww_ctx with poison when debugging

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

Help catch cases where mutex_lock is used directly on w/w mutexes, which
otherwise result in the w/w tasks reading uninitialized data.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 include/linux/poison.h | 1 +
 kernel/locking/mutex.c | 4 
 2 files changed, 5 insertions(+)

diff --git a/include/linux/poison.h b/include/linux/poison.h
index 51334ed..a395403 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -80,6 +80,7 @@
 /** kernel/mutexes **/
 #define MUTEX_DEBUG_INIT   0x11
 #define MUTEX_DEBUG_FREE   0x22
+#define MUTEX_POISON_WW_CTX((void *) 0x500 + POISON_POINTER_DELTA)

 /** lib/flex_array.c **/
 #define FLEX_ARRAY_FREE0x6c/* for use-after-free poisoning */
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 296605c..38d173c 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -794,6 +794,10 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
if (!use_ww_ctx) {
/* add waiting tasks to the end of the waitqueue (FIFO): */
list_add_tail(, >wait_list);
+
+#ifdef CONFIG_DEBUG_MUTEXES
+   waiter.ww_ctx = MUTEX_POISON_WW_CTX;
+#endif
} else {
/* Add in stamp order, waking up waiters that must back off. */
ret = __ww_mutex_add_waiter(, lock, ww_ctx);
-- 
2.7.4



[PATCH v2 08/11] locking/ww_mutex: Yield to other waiters from optimistic spin

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

Lock stealing is less beneficial for w/w mutexes since we may just end up
backing off if we stole from a thread with an earlier acquire stamp that
already holds another w/w mutex that we also need. So don't spin
optimistically unless we are sure that there is no other waiter that might
cause us to back off.

Median timings taken of a contention-heavy GPU workload:

Before:
real0m52.946s
user0m7.272s
sys 1m55.964s

After:
real0m53.086s
user0m7.360s
sys 1m46.204s

This particular workload still spends 20%-25% of CPU in mutex_spin_on_owner
according to perf, but my attempts to further reduce this spinning based on
various heuristics all lead to an increase in measured wall time despite
the decrease in sys time.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 kernel/locking/mutex.c | 48 ++--
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index d2ca447..296605c 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -374,7 +374,8 @@ ww_mutex_set_context_slowpath(struct ww_mutex *lock,
  */
 static noinline
 bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner,
-bool use_ww_ctx, struct ww_acquire_ctx *ww_ctx)
+bool use_ww_ctx, struct ww_acquire_ctx *ww_ctx,
+struct mutex_waiter *waiter)
 {
bool ret = true;

@@ -397,7 +398,7 @@ bool mutex_spin_on_owner(struct mutex *lock, struct 
task_struct *owner,
break;
}

-   if (use_ww_ctx && ww_ctx && ww_ctx->acquired > 0) {
+   if (use_ww_ctx && ww_ctx) {
struct ww_mutex *ww;

ww = container_of(lock, struct ww_mutex, base);
@@ -413,7 +414,30 @@ bool mutex_spin_on_owner(struct mutex *lock, struct 
task_struct *owner,
 * Check this in every inner iteration because we may
 * be racing against another thread's ww_mutex_lock.
 */
-   if (READ_ONCE(ww->ctx)) {
+   if (ww_ctx->acquired > 0 && READ_ONCE(ww->ctx)) {
+   ret = false;
+   break;
+   }
+
+   /*
+* If we aren't on the wait list yet, cancel the spin
+* if there are waiters. We want  to avoid stealing the
+* lock from a waiter with an earlier stamp, since the
+* other thread may already own a lock that we also
+* need.
+*/
+   if (!waiter &&
+   (atomic_long_read(>owner) &
+MUTEX_FLAG_WAITERS)) {
+   ret = false;
+   break;
+   }
+
+   /*
+* Similarly, stop spinning if we are no longer the
+* first waiter.
+*/
+   if (waiter && !__mutex_waiter_is_first(lock, waiter)) {
ret = false;
break;
}
@@ -479,7 +503,8 @@ static inline int mutex_can_spin_on_owner(struct mutex 
*lock)
  */
 static bool mutex_optimistic_spin(struct mutex *lock,
  struct ww_acquire_ctx *ww_ctx,
- const bool use_ww_ctx, const bool waiter)
+ const bool use_ww_ctx,
+ struct mutex_waiter *waiter)
 {
struct task_struct *task = current;

@@ -518,12 +543,12 @@ static bool mutex_optimistic_spin(struct mutex *lock,
}

if (!mutex_spin_on_owner(lock, owner, use_ww_ctx,
-ww_ctx))
+ww_ctx, waiter))
goto fail_unlock;
}

/* Try to acquire the mutex if it is unlocked. */
-   if (__mutex_trylock(lock, waiter))
+   if (__mutex_trylock(lock, waiter != NULL))
break;

/*
@@ -565,7 +590,8 @@ static bool mutex_optimistic_spin(struct mutex *lock,
 #else
 static bool mutex_optimistic_spin(struct mutex *lock,
  struct ww_acquire_ctx *ww_ctx,
- const bool use_ww_ctx, const bool waiter)
+ const bool use_ww_ctx,
+ struct mutex_waiter *waiter)
 {
  

[PATCH v2 07/11] locking/ww_mutex: Wake at most one waiter for back off when acquiring the lock

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

The wait list is sorted by stamp order, and the only waiting task that may
have to back off is the first waiter with a context.

The regular slow path does not have to wake any other tasks at all, since
all other waiters that would have to back off were either woken up when
the waiter was added to the list, or detected the condition before they
added themselves.

Median timings taken of a contention-heavy GPU workload:

Without this series:
real0m59.900s
user0m7.516s
sys 2m16.076s

With changes up to and including this patch:
real0m52.946s
user0m7.272s
sys 1m55.964s

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 kernel/locking/mutex.c | 58 +-
 1 file changed, 39 insertions(+), 19 deletions(-)

diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 01e9438..d2ca447 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -285,6 +285,35 @@ __ww_mutex_stamp_after(struct ww_acquire_ctx *a, struct 
ww_acquire_ctx *b)
 }

 /*
+ * Wake up any waiters that may have to back off when the lock is held by the
+ * given context.
+ *
+ * Due to the invariants on the wait list, this can only affect the first
+ * waiter with a context.
+ *
+ * Must be called with wait_lock held. The current task must not be on the
+ * wait list.
+ */
+static void __sched
+__ww_mutex_wakeup_for_backoff(struct mutex *lock, struct ww_acquire_ctx 
*ww_ctx)
+{
+   struct mutex_waiter *cur;
+
+   list_for_each_entry(cur, >wait_list, list) {
+   if (!cur->ww_ctx)
+   continue;
+
+   if (cur->ww_ctx->acquired > 0 &&
+   __ww_mutex_stamp_after(cur->ww_ctx, ww_ctx)) {
+   debug_mutex_wake_waiter(lock, cur);
+   wake_up_process(cur->task);
+   }
+
+   break;
+   }
+}
+
+/*
  * After acquiring lock with fastpath or when we lost out in contested
  * slowpath, set ctx and wake up any waiters so they can recheck.
  */
@@ -293,7 +322,6 @@ ww_mutex_set_context_fastpath(struct ww_mutex *lock,
   struct ww_acquire_ctx *ctx)
 {
unsigned long flags;
-   struct mutex_waiter *cur;

ww_mutex_lock_acquired(lock, ctx);

@@ -319,16 +347,15 @@ ww_mutex_set_context_fastpath(struct ww_mutex *lock,
 * so they can see the new lock->ctx.
 */
spin_lock_mutex(>base.wait_lock, flags);
-   list_for_each_entry(cur, >base.wait_list, list) {
-   debug_mutex_wake_waiter(>base, cur);
-   wake_up_process(cur->task);
-   }
+   __ww_mutex_wakeup_for_backoff(>base, ctx);
spin_unlock_mutex(>base.wait_lock, flags);
 }

 /*
- * After acquiring lock in the slowpath set ctx and wake up any
- * waiters so they can recheck.
+ * After acquiring lock in the slowpath set ctx.
+ *
+ * Unlike for the fast path, the caller ensures that waiters are woken up where
+ * necessary.
  *
  * Callers must hold the mutex wait_lock.
  */
@@ -336,19 +363,8 @@ static __always_inline void
 ww_mutex_set_context_slowpath(struct ww_mutex *lock,
  struct ww_acquire_ctx *ctx)
 {
-   struct mutex_waiter *cur;
-
ww_mutex_lock_acquired(lock, ctx);
lock->ctx = ctx;
-
-   /*
-* Give any possible sleeping processes the chance to wake up,
-* so they can recheck if they have to back off.
-*/
-   list_for_each_entry(cur, >base.wait_list, list) {
-   debug_mutex_wake_waiter(>base, cur);
-   wake_up_process(cur->task);
-   }
 }

 #ifdef CONFIG_MUTEX_SPIN_ON_OWNER
@@ -737,8 +753,12 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
/*
 * After waiting to acquire the wait_lock, try again.
 */
-   if (__mutex_trylock(lock, false))
+   if (__mutex_trylock(lock, false)) {
+   if (use_ww_ctx && ww_ctx)
+   __ww_mutex_wakeup_for_backoff(lock, ww_ctx);
+
goto skip_wait;
+   }

debug_mutex_lock_common(lock, );
debug_mutex_add_waiter(lock, , task);
-- 
2.7.4



[PATCH v2 06/11] locking/ww_mutex: Notify waiters that have to back off while adding tasks to wait list

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

While adding our task as a waiter, detect if another task should back off
because of us.

With this patch, we establish the invariant that the wait list contains
at most one (sleeping) waiter with ww_ctx->acquired > 0, and this waiter
will be the first waiter with a context.

Since only waiters with ww_ctx->acquired > 0 have to back off, this allows
us to be much more economical with wakeups.

v2: rebase on v2 of earlier patches

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 kernel/locking/mutex.c | 42 --
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index d63eebb..01e9438 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -609,23 +609,34 @@ void __sched ww_mutex_unlock(struct ww_mutex *lock)
 EXPORT_SYMBOL(ww_mutex_unlock);

 static inline int __sched
-__ww_mutex_lock_check_stamp(struct mutex *lock, struct ww_acquire_ctx *ctx)
+__ww_mutex_lock_check_stamp(struct mutex *lock, struct mutex_waiter *waiter,
+   struct ww_acquire_ctx *ctx)
 {
struct ww_mutex *ww = container_of(lock, struct ww_mutex, base);
struct ww_acquire_ctx *hold_ctx = READ_ONCE(ww->ctx);
+   struct mutex_waiter *cur;

-   if (!hold_ctx)
-   return 0;
+   if (hold_ctx && __ww_mutex_stamp_after(ctx, hold_ctx))
+   goto deadlock;

-   if (__ww_mutex_stamp_after(ctx, hold_ctx)) {
-#ifdef CONFIG_DEBUG_MUTEXES
-   DEBUG_LOCKS_WARN_ON(ctx->contending_lock);
-   ctx->contending_lock = ww;
-#endif
-   return -EDEADLK;
+   /*
+* If there is a waiter in front of us that has a context, then its
+* stamp is earlier than ours and we must back off.
+*/
+   cur = waiter;
+   list_for_each_entry_continue_reverse(cur, >wait_list, list) {
+   if (cur->ww_ctx)
+   goto deadlock;
}

return 0;
+
+deadlock:
+#ifdef CONFIG_DEBUG_MUTEXES
+   DEBUG_LOCKS_WARN_ON(ctx->contending_lock);
+   ctx->contending_lock = ww;
+#endif
+   return -EDEADLK;
 }

 static inline int __sched
@@ -666,6 +677,16 @@ __ww_mutex_add_waiter(struct mutex_waiter *waiter,
}

list_add_tail(>list, >list);
+
+   /*
+* Wake up the waiter so that it gets a chance to back
+* off.
+*/
+   if (cur->ww_ctx->acquired > 0) {
+   debug_mutex_wake_waiter(lock, cur);
+   wake_up_process(cur->task);
+   }
+
return 0;
}

@@ -767,7 +788,8 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
}

if (use_ww_ctx && ww_ctx && ww_ctx->acquired > 0) {
-   ret = __ww_mutex_lock_check_stamp(lock, ww_ctx);
+   ret = __ww_mutex_lock_check_stamp(lock, ,
+ ww_ctx);
if (ret)
goto err;
}
-- 
2.7.4



[PATCH v2 05/11] locking/ww_mutex: Add waiters in stamp order

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

Add regular waiters in stamp order. Keep adding waiters that have no
context in FIFO order and take care not to starve them.

While adding our task as a waiter, back off if we detect that there is a
waiter with a lower stamp in front of us.

Make sure to call lock_contended even when we back off early.

v2:
- rein in the indentation of __ww_mutex_add_waiter a bit
- set contending_lock in __ww_mutex_add_waiter (Chris Wilson)

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 include/linux/mutex.h  |  3 ++
 kernel/locking/mutex.c | 87 ++
 2 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index b97870f..118a3b6 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -20,6 +20,8 @@
 #include 
 #include 

+struct ww_acquire_ctx;
+
 /*
  * Simple, straightforward mutexes with strict semantics:
  *
@@ -75,6 +77,7 @@ static inline struct task_struct *__mutex_owner(struct mutex 
*lock)
 struct mutex_waiter {
struct list_headlist;
struct task_struct  *task;
+   struct ww_acquire_ctx   *ww_ctx;
 #ifdef CONFIG_DEBUG_MUTEXES
void*magic;
 #endif
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 585627f..d63eebb 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -628,6 +628,51 @@ __ww_mutex_lock_check_stamp(struct mutex *lock, struct 
ww_acquire_ctx *ctx)
return 0;
 }

+static inline int __sched
+__ww_mutex_add_waiter(struct mutex_waiter *waiter,
+ struct mutex *lock,
+ struct ww_acquire_ctx *ww_ctx)
+{
+   struct mutex_waiter *cur;
+
+   if (!ww_ctx) {
+   list_add_tail(>list, >wait_list);
+   return 0;
+   }
+
+   /*
+* Add the waiter before the first waiter with a higher stamp.
+* Waiters without a context are skipped to avoid starving
+* them.
+*/
+   list_for_each_entry(cur, >wait_list, list) {
+   if (!cur->ww_ctx)
+   continue;
+
+   if (__ww_mutex_stamp_after(ww_ctx, cur->ww_ctx)) {
+   /* Back off immediately if necessary. */
+   if (ww_ctx->acquired > 0) {
+#ifdef CONFIG_DEBUG_MUTEXES
+   struct ww_mutex *ww;
+
+   ww = container_of(lock, struct ww_mutex, base);
+   DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock);
+   ww_ctx->contending_lock = ww;
+#endif
+   return -EDEADLK;
+   }
+
+   continue;
+   }
+
+   list_add_tail(>list, >list);
+   return 0;
+   }
+
+   list_add_tail(>list, >wait_list);
+   return 0;
+}
+
 /*
  * Lock a mutex (possibly interruptible), slowpath:
  */
@@ -677,15 +722,25 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
debug_mutex_lock_common(lock, );
debug_mutex_add_waiter(lock, , task);

-   /* add waiting tasks to the end of the waitqueue (FIFO): */
-   list_add_tail(, >wait_list);
+   lock_contended(>dep_map, ip);
+
+   if (!use_ww_ctx) {
+   /* add waiting tasks to the end of the waitqueue (FIFO): */
+   list_add_tail(, >wait_list);
+   } else {
+   /* Add in stamp order, waking up waiters that must back off. */
+   ret = __ww_mutex_add_waiter(, lock, ww_ctx);
+   if (ret)
+   goto err_early_backoff;
+
+   waiter.ww_ctx = ww_ctx;
+   }
+
waiter.task = task;

if (__mutex_waiter_is_first(lock, ))
__mutex_set_flag(lock, MUTEX_FLAG_WAITERS);

-   lock_contended(>dep_map, ip);
-
set_task_state(task, state);
for (;;) {
/*
@@ -693,8 +748,12 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
 * mutex_unlock() handing the lock off to us, do a trylock
 * before testing the error conditions to make sure we pick up
 * the handoff.
+*
+* For w/w locks, we always need to do this even if we're not
+* currently the first waiter, because we may have been the
+* first waiter during the unlock.
 */
-   if (__mutex_trylock(lock, first))
+   if (__mutex_trylock(lock, use_ww_ctx || first))
goto acquired;

/*
@@ -716,7 +775,20 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
spin_unlock_mutex(>wait_lock, flags);
 

[PATCH v2 04/11] locking/ww_mutex: Set use_ww_ctx even when locking without a context

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

We will add a new field to struct mutex_waiter.  This field must be
initialized for all waiters if any waiter uses the ww_use_ctx path.

So there is a trade-off: Keep ww_mutex locking without a context on the
faster non-use_ww_ctx path, at the cost of adding the initialization to all
mutex locks (including non-ww_mutexes), or avoid the additional cost for
non-ww_mutex locks, at the cost of adding additional checks to the
use_ww_ctx path.

We take the latter choice.  It may be worth eliminating the users of
ww_mutex_lock(lock, NULL), but there are a lot of them.

Move the declaration of ww in __mutex_lock_common closer to its uses
because gcc otherwise (incorrectly) believes ww may be used without
initialization.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 include/linux/ww_mutex.h | 11 ++-
 kernel/locking/mutex.c   | 37 +
 2 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/include/linux/ww_mutex.h b/include/linux/ww_mutex.h
index 2bb5deb..a5960e5 100644
--- a/include/linux/ww_mutex.h
+++ b/include/linux/ww_mutex.h
@@ -222,11 +222,7 @@ extern int __must_check 
__ww_mutex_lock_interruptible(struct ww_mutex *lock,
  */
 static inline int ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx 
*ctx)
 {
-   if (ctx)
-   return __ww_mutex_lock(lock, ctx);
-
-   mutex_lock(>base);
-   return 0;
+   return __ww_mutex_lock(lock, ctx);
 }

 /**
@@ -262,10 +258,7 @@ static inline int ww_mutex_lock(struct ww_mutex *lock, 
struct ww_acquire_ctx *ct
 static inline int __must_check ww_mutex_lock_interruptible(struct ww_mutex 
*lock,
   struct 
ww_acquire_ctx *ctx)
 {
-   if (ctx)
-   return __ww_mutex_lock_interruptible(lock, ctx);
-   else
-   return mutex_lock_interruptible(>base);
+   return __ww_mutex_lock_interruptible(lock, ctx);
 }

 /**
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 200629a..585627f 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -381,7 +381,7 @@ bool mutex_spin_on_owner(struct mutex *lock, struct 
task_struct *owner,
break;
}

-   if (use_ww_ctx && ww_ctx->acquired > 0) {
+   if (use_ww_ctx && ww_ctx && ww_ctx->acquired > 0) {
struct ww_mutex *ww;

ww = container_of(lock, struct ww_mutex, base);
@@ -640,10 +640,11 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
struct mutex_waiter waiter;
unsigned long flags;
bool first = false;
-   struct ww_mutex *ww;
int ret;

-   if (use_ww_ctx) {
+   if (use_ww_ctx && ww_ctx) {
+   struct ww_mutex *ww;
+
ww = container_of(lock, struct ww_mutex, base);
if (unlikely(ww_ctx == READ_ONCE(ww->ctx)))
return -EALREADY;
@@ -656,8 +657,12 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx, false)) {
/* got the lock, yay! */
lock_acquired(>dep_map, ip);
-   if (use_ww_ctx)
+   if (use_ww_ctx && ww_ctx) {
+   struct ww_mutex *ww;
+
+   ww = container_of(lock, struct ww_mutex, base);
ww_mutex_set_context_fastpath(ww, ww_ctx);
+   }
preempt_enable();
return 0;
}
@@ -702,7 +707,7 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
goto err;
}

-   if (use_ww_ctx && ww_ctx->acquired > 0) {
+   if (use_ww_ctx && ww_ctx && ww_ctx->acquired > 0) {
ret = __ww_mutex_lock_check_stamp(lock, ww_ctx);
if (ret)
goto err;
@@ -742,8 +747,12 @@ __mutex_lock_common(struct mutex *lock, long state, 
unsigned int subclass,
/* got the lock - cleanup and rejoice! */
lock_acquired(>dep_map, ip);

-   if (use_ww_ctx)
+   if (use_ww_ctx && ww_ctx) {
+   struct ww_mutex *ww;
+
+   ww = container_of(lock, struct ww_mutex, base);
ww_mutex_set_context_slowpath(ww, ww_ctx);
+   }

spin_unlock_mutex(>wait_lock, flags);
preempt_enable();
@@ -830,8 +839,9 @@ __ww_mutex_lock(struct ww_mutex *lock, struct 
ww_acquire_ctx *ctx)

might_sleep();
ret =  __mutex_lock_common(>base, TASK_UNINTERRUPTIBLE,
-  0, >dep_map, _RET_IP_, ctx, 1);
-   if (!ret && ctx->acquired > 1)
+  0, 

[PATCH v2 03/11] locking/ww_mutex: Extract stamp comparison to __ww_mutex_stamp_after

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

The function will be re-used in subsequent patches.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 kernel/locking/mutex.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 0afa998..200629a 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -277,6 +277,13 @@ static __always_inline void ww_mutex_lock_acquired(struct 
ww_mutex *ww,
ww_ctx->acquired++;
 }

+static inline bool __sched
+__ww_mutex_stamp_after(struct ww_acquire_ctx *a, struct ww_acquire_ctx *b)
+{
+   return a->stamp - b->stamp <= LONG_MAX &&
+  (a->stamp != b->stamp || a > b);
+}
+
 /*
  * After acquiring lock with fastpath or when we lost out in contested
  * slowpath, set ctx and wake up any waiters so they can recheck.
@@ -610,8 +617,7 @@ __ww_mutex_lock_check_stamp(struct mutex *lock, struct 
ww_acquire_ctx *ctx)
if (!hold_ctx)
return 0;

-   if (ctx->stamp - hold_ctx->stamp <= LONG_MAX &&
-   (ctx->stamp != hold_ctx->stamp || ctx > hold_ctx)) {
+   if (__ww_mutex_stamp_after(ctx, hold_ctx)) {
 #ifdef CONFIG_DEBUG_MUTEXES
DEBUG_LOCKS_WARN_ON(ctx->contending_lock);
ctx->contending_lock = ww;
-- 
2.7.4



[PATCH v2 02/11] locking/ww_mutex: Re-check ww->ctx in the inner optimistic spin loop

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

In the following scenario, thread #1 should back off its attempt to lock
ww1 and unlock ww2 (assuming the acquire context stamps are ordered
accordingly).

Thread #0   Thread #1
-   -
successfully lock ww2
set ww1->base.owner
attempt to lock ww1
confirm ww1->ctx == NULL
enter mutex_spin_on_owner
set ww1->ctx

What was likely to happen previously is:

attempt to lock ww2
refuse to spin because
  ww2->ctx != NULL
schedule()
detect thread #0 is off CPU
stop optimistic spin
return -EDEADLK
unlock ww2
wakeup thread #0
lock ww2

Now, we are more likely to see:

detect ww1->ctx != NULL
stop optimistic spin
return -EDEADLK
unlock ww2
successfully lock ww2

... because thread #1 will stop its optimistic spin as soon as possible.

The whole scenario is quite unlikely, since it requires thread #1 to get
between thread #0 setting the owner and setting the ctx. But since we're
idling here anyway, the additional check is basically free.

Found by inspection.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 kernel/locking/mutex.c | 44 ++--
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 9b34961..0afa998 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -350,7 +350,8 @@ ww_mutex_set_context_slowpath(struct ww_mutex *lock,
  * access and not reliable.
  */
 static noinline
-bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner)
+bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner,
+bool use_ww_ctx, struct ww_acquire_ctx *ww_ctx)
 {
bool ret = true;

@@ -373,6 +374,28 @@ bool mutex_spin_on_owner(struct mutex *lock, struct 
task_struct *owner)
break;
}

+   if (use_ww_ctx && ww_ctx->acquired > 0) {
+   struct ww_mutex *ww;
+
+   ww = container_of(lock, struct ww_mutex, base);
+
+   /*
+* If ww->ctx is set the contents are undefined, only
+* by acquiring wait_lock there is a guarantee that
+* they are not invalid when reading.
+*
+* As such, when deadlock detection needs to be
+* performed the optimistic spinning cannot be done.
+*
+* Check this in every inner iteration because we may
+* be racing against another thread's ww_mutex_lock.
+*/
+   if (READ_ONCE(ww->ctx)) {
+   ret = false;
+   break;
+   }
+   }
+
cpu_relax();
}
rcu_read_unlock();
@@ -460,22 +483,6 @@ static bool mutex_optimistic_spin(struct mutex *lock,
for (;;) {
struct task_struct *owner;

-   if (use_ww_ctx && ww_ctx->acquired > 0) {
-   struct ww_mutex *ww;
-
-   ww = container_of(lock, struct ww_mutex, base);
-   /*
-* If ww->ctx is set the contents are undefined, only
-* by acquiring wait_lock there is a guarantee that
-* they are not invalid when reading.
-*
-* As such, when deadlock detection needs to be
-* performed the optimistic spinning cannot be done.
-*/
-   if (READ_ONCE(ww->ctx))
-   goto fail_unlock;
-   }
-
/*
 * If there's an owner, wait for it to either
 * release the lock or go to sleep.
@@ -487,7 +494,8 @@ static bool mutex_optimistic_spin(struct mutex *lock,
break;
}

-   if (!mutex_spin_on_owner(lock, owner))
+   if (!mutex_spin_on_owner(lock, owner, use_ww_ctx,
+ww_ctx))
goto fail_unlock;
}

-- 
2.7.4



[PATCH v2 01/11] drm/vgem: Use ww_mutex_(un)lock even with a NULL context

2016-12-01 Thread Nicolai Hähnle
From: Nicolai Hähnle 

v2: use resv->lock instead of resv->lock.base (Christian König)

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Maarten Lankhorst 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Nicolai Hähnle 
---
 drivers/gpu/drm/vgem/vgem_fence.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vgem/vgem_fence.c 
b/drivers/gpu/drm/vgem/vgem_fence.c
index 488909a..9cb00a5 100644
--- a/drivers/gpu/drm/vgem/vgem_fence.c
+++ b/drivers/gpu/drm/vgem/vgem_fence.c
@@ -191,12 +191,12 @@ int vgem_fence_attach_ioctl(struct drm_device *dev,

/* Expose the fence via the dma-buf */
ret = 0;
-   mutex_lock(>lock.base);
+   ww_mutex_lock(>lock, NULL);
if (arg->flags & VGEM_FENCE_WRITE)
reservation_object_add_excl_fence(resv, fence);
else if ((ret = reservation_object_reserve_shared(resv)) == 0)
reservation_object_add_shared_fence(resv, fence);
-   mutex_unlock(>lock.base);
+   ww_mutex_unlock(>lock);

/* Record the fence in our idr for later signaling */
if (ret == 0) {
-- 
2.7.4



[PATCH] drm/omap: fix primary-plane's possible_crtcs

2016-12-01 Thread Tomi Valkeinen
On 30/11/16 16:36, Laurent Pinchart wrote:
> Hi Tomi,
> 
> Thank you for the patch.
> 
> On Wednesday 30 Nov 2016 12:38:51 Tomi Valkeinen wrote:
>> We set the possible_crtc for all planes to "(1 << priv->num_crtcs) - 1",
>> which is fine as the HW planes can be used fro all crtcs. However, when
>> we're doing that, we are still incrementing 'num_crtcs', and we'll end
>> up with bad possible_crtcs, preventing the use of the primary planes.
>>
>> We should have all crtcs in 'possible_crtc', but apparently it's not as
>> easy to set as you would think. We create crtcs rather dynamically, and
>> when creating the primary planes, we don't know how many crtcs we're
>> going to have. This is mostly a problem with the way omapdrm creates
>> crtcs and planes, and how it connects those to display outputs.
>>
>> So, this patch fixes the problem the easy way, and sets the
>> possible_crtcs for primary planes only to the crtc in question, which in
>> practice should cover all normal use cases.
>>
>> Signed-off-by: Tomi Valkeinen 
>> ---
>>  drivers/gpu/drm/omapdrm/omap_plane.c | 8 +++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c
>> b/drivers/gpu/drm/omapdrm/omap_plane.c index 9c43cb481e62..fc1822870b26
>> 100644
>> --- a/drivers/gpu/drm/omapdrm/omap_plane.c
>> +++ b/drivers/gpu/drm/omapdrm/omap_plane.c
>> @@ -361,6 +361,7 @@ struct drm_plane *omap_plane_init(struct drm_device
>> *dev, struct omap_drm_private *priv = dev->dev_private;
>>  struct drm_plane *plane;
>>  struct omap_plane *omap_plane;
>> +unsigned long possible_crtcs;
>>  int ret;
>>
>>  DBG("%s: type=%d", plane_names[id], type);
>> @@ -381,7 +382,12 @@ struct drm_plane *omap_plane_init(struct drm_device
>> *dev, omap_plane->error_irq.irq = omap_plane_error_irq;
>>  omap_irq_register(dev, _plane->error_irq);
>>
>> -ret = drm_universal_plane_init(dev, plane, (1 << priv->num_crtcs) - 1,
>> +if (type == DRM_PLANE_TYPE_PRIMARY)
>> +possible_crtcs = 1 << id;
>> +else
>> +possible_crtcs = (1 << priv->num_crtcs) - 1;
> 
> The omap_modeset_init() function computes the number of CRTCs before creating 
> any plane with
> 
>   num_crtcs = min3(num_crtc, num_mgrs, num_ovls);
> 
> and the rest of the function then creates CRTCs, as far as I understand 
> always 
> up to num_crtcs. Can't we just use that value to compute possible_crtcs as (1 
> << num_crtcs ) - 1 ?

Yes, I think you're correct. It's not exactly obvious from the code =).
I'll change the patch to use the calculated num-crtcs.

 Tomi

-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20161201/8a3f93b0/attachment.sig>


[PATCH v2 03/11] locking/ww_mutex: Extract stamp comparison to __ww_mutex_stamp_after

2016-12-01 Thread Chris Wilson
On Thu, Dec 01, 2016 at 03:06:46PM +0100, Nicolai Hähnle wrote:
> From: Nicolai Hähnle 
> 
> The function will be re-used in subsequent patches.
> 
> Cc: Peter Zijlstra 
> Cc: Ingo Molnar 
> Cc: Maarten Lankhorst 
> Cc: Daniel Vetter 
> Cc: Chris Wilson 
> Cc: dri-devel at lists.freedesktop.org
> Signed-off-by: Nicolai Hähnle 
> ---
>  kernel/locking/mutex.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
> index 0afa998..200629a 100644
> --- a/kernel/locking/mutex.c
> +++ b/kernel/locking/mutex.c
> @@ -277,6 +277,13 @@ static __always_inline void 
> ww_mutex_lock_acquired(struct ww_mutex *ww,
>   ww_ctx->acquired++;
>  }
>  
> +static inline bool __sched
> +__ww_mutex_stamp_after(struct ww_acquire_ctx *a, struct ww_acquire_ctx *b)

Should it be ww_mutex_stamp or ww_acquire_stamp / ww_ctx_stamp?

Nothing else operates on the ww_acquire_ctx without a ww_mutex so it
might look a bit odd if it didn't use ww_mutex.

Patch only does what it says on tin, so
Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH v2 02/11] locking/ww_mutex: Re-check ww->ctx in the inner optimistic spin loop

2016-12-01 Thread Chris Wilson
On Thu, Dec 01, 2016 at 03:06:45PM +0100, Nicolai Hähnle wrote:
> From: Nicolai Hähnle 
> 
> In the following scenario, thread #1 should back off its attempt to lock
> ww1 and unlock ww2 (assuming the acquire context stamps are ordered
> accordingly).
> 
> Thread #0   Thread #1
> -   -
> successfully lock ww2
> set ww1->base.owner
> attempt to lock ww1
> confirm ww1->ctx == NULL
> enter mutex_spin_on_owner
> set ww1->ctx
> 
> What was likely to happen previously is:
> 
> attempt to lock ww2
> refuse to spin because
>   ww2->ctx != NULL
> schedule()
> detect thread #0 is off CPU
> stop optimistic spin
> return -EDEADLK
> unlock ww2
> wakeup thread #0
> lock ww2
> 
> Now, we are more likely to see:
> 
> detect ww1->ctx != NULL
> stop optimistic spin
> return -EDEADLK
> unlock ww2
> successfully lock ww2
> 
> ... because thread #1 will stop its optimistic spin as soon as possible.
> 
> The whole scenario is quite unlikely, since it requires thread #1 to get
> between thread #0 setting the owner and setting the ctx. But since we're
> idling here anyway, the additional check is basically free.
> 
> Found by inspection.

Similar question can be raised for can_spin_on_owner() as well. Is it
worth for a contending ww_mutex to enter the osq queue if we expect a
EDEADLK? It seems to boil down to how likely is the EDEADLK going to
evaporate if we wait for the owner to finish and unlock.

The patch looks reasonable, just a question of desirability.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH] drm/drm_bridge: adjust bridge module's refcount

2016-12-01 Thread Andrzej Hajda
On 01.12.2016 08:18, Daniel Vetter wrote:
> On Thu, Dec 01, 2016 at 08:07:29AM +0100, Andrzej Hajda wrote:
>> On 30.11.2016 14:09, Daniel Vetter wrote:
>>> On Wed, Nov 30, 2016 at 01:03:20PM +0200, Laurent Pinchart wrote:
 On Wednesday 30 Nov 2016 11:55:20 Daniel Vetter wrote:
> Why exactly do you want to hotplug encoders? Or bridges fwiw ... since at
> least only making those hotpluggable will make the uabi story easier since
> they're not exposed.
 Ideally to avoid disabling the whole display engine when one encoder isn't 
 available/operational. Right now we're waiting for all pieces to be 
 available 
 (using deferred probing or the component framework) before registering the 
 DRM 
 device. This means that if one bridge can't be probed successfully for any 
 reason we'll end up having not display at all. This includes the case 
 where 
 the driver for the bridge is not available. If we could support dynamic 
 hotplug of bridges, we could start with a display engine that supports a 
 subset of the outputs, and add new outputs as they become operational.

 We have a similar issue when unbinding bridge devices from their driver. 
 They 
 obviously can't be used anymore, but we have no solution to handle that 
 apart 
 from unregistering the DRM device completely, as otherwise rebinding the 
 bridge to the driver later can't be handled.
>>> This all sounds pretty cool, but does anyone care? Like what's the
>>> real-world use-case here? Some cosmic ray destroyed the bridge driver on
>>> your android phone and now you want it to magically fall back to hdmi that
>>> no one ever plugs in? Or someone misconfigures their kernel and gets
>>> greeted with a black screen, instead of a ... black screen?
>> Real use case is that we need to always load hdmi path drivers at phone
>> startup just in case somebody will use it.
>> This way we are wasting space and more importantly boot time, for code
>> which won't be used by 99% users of phones.
>> Putting them into modules an loading on MHL/HDMI cable plug-in would be
>> more optimal, I guess.
> Do we have numbers for this?

For number of HDMI/MHL users in mobiles, I have no stats :)
For display boot delay due to deferring hdmi driver is 2.5-3.5 seconds
on peach-pi board for example [1].

[1]:
https://storage.kernelci.org/ulfh/v4.9-rc7-120-g38cdf7e0bfee/arm-exynos_defconfig/lab-baylibre-seattle/boot-exynos5800-peach-pi.html


>  What part of the overhead is the edid probing
> and reading, which we probably should optimize either way ... optimize as
> in make sure we never ever stall anything for edid reads.

As EDID probing should be performed only after detecting sink it seems
irrelevant here.

>
> And if you never load the hdmi driver, how do you know when to load it
> because the user plugged in the cable?

Mobiles often have detection which cable is plugged in. However I am not
sure if kernel sends such events to userspace,
but this should be simple to do.

Regards
Andrzej



[PATCH v2 01/11] drm/vgem: Use ww_mutex_(un)lock even with a NULL context

2016-12-01 Thread Chris Wilson
On Thu, Dec 01, 2016 at 03:06:44PM +0100, Nicolai Hähnle wrote:
> From: Nicolai Hähnle 
> 
> v2: use resv->lock instead of resv->lock.base (Christian König)
> 
> Cc: Peter Zijlstra 
> Cc: Ingo Molnar 
> Cc: Maarten Lankhorst 
> Cc: Daniel Vetter 
> Cc: Chris Wilson 
> Cc: dri-devel at lists.freedesktop.org
> Signed-off-by: Nicolai Hähnle 
Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH] drm: allow changing DPMS mode for non-CRTC displays

2016-12-01 Thread Chris Wilson
On Thu, Dec 01, 2016 at 03:30:01PM +0200, Marta Lofstedt wrote:
> For non-CRTC displays,

A connector not attached to a CRTC works. It is the active connectors
that were broken.

> the drm_atomic_helper_connector_dpms
> will always set the connector back the old DPMS state
> before returning. This makes it impossible to change
> DPMS state.
> 
> fixes: 0853695c3ba46f97dfc0b5885f7b7e640ca212dd
> 
> Signed-off-by: Marta Lofstedt 
> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index 494680c..6a5acb9 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2885,8 +2885,8 @@ int drm_atomic_helper_connector_dpms(struct 
> drm_connector *connector,
>  fail:
>   if (ret == -EDEADLK)
>   goto backoff;
> -
> - connector->dpms = old_mode;
> + if (ret != 0)
> + connector->dpms = old_mode;

Patch however is correct.

Fix the subject line to reflect the impact correctly, amend the fixes
tag and add the appropriate CCs

Fixes: 0853695c3ba4 ("drm: Add reference counting to drm_atomic_state")
Cc: Chris Wilson 
Cc: Daniel Vetter 
Cc: Eric Engestrom 
Cc: Sean Paul 
Cc: dri-devel at lists.freedesktop.org
Cc: 

And mention if there was a testcase exercising the failure. If not
please suggest one.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 1/3] drm: Add a new connector atomic property for link status

2016-12-01 Thread Sean Paul
On Thu, Dec 1, 2016 at 1:58 PM, Manasi Navare  
wrote:
> Sean, could you please review this patch, I have tried to address
> all the comments from you.
>

Comments look good to me.

Reviewed-by: Sean Paul 

Sean

> Regards
> Manasi
>
> On Tue, Nov 29, 2016 at 11:30:31PM -0800, Manasi Navare wrote:
>> At the time userspace does setcrtc, we've already promised the mode
>> would work. The promise is based on the theoretical capabilities of
>> the link, but it's possible we can't reach this in practice. The DP
>> spec describes how the link should be reduced, but we can't reduce
>> the link below the requirements of the mode. Black screen follows.
>>
>> One idea would be to have setcrtc return a failure. However, it
>> already should not fail as the atomic checks have passed. It would
>> also conflict with the idea of making setcrtc asynchronous in the
>> future, returning before the actual mode setting and link training.
>>
>> Another idea is to train the link "upfront" at hotplug time, before
>> pruning the mode list, so that we can do the pruning based on
>> practical not theoretical capabilities. However, the changes for link
>> training are pretty drastic, all for the sake of error handling and
>> DP compliance, when the most common happy day scenario is the current
>> approach of link training at mode setting time, using the optimal
>> parameters for the mode. It is also not certain all hardware could do
>> this without the pipe on; not even all our hardware can do this. Some
>> of this can be solved, but not trivially.
>>
>> Both of the above ideas also fail to address link degradation *during*
>> operation.
>>
>> The solution is to add a new "link-status" connector property in order
>> to address link training failure in a way that:
>> a) changes the current happy day scenario as little as possible, to
>> avoid regressions, b) can be implemented the same way by all drm
>> drivers, c) is still opt-in for the drivers and userspace, and opting
>> out doesn't regress the user experience, d) doesn't prevent drivers
>> from implementing better or alternate approaches, possibly without
>> userspace involvement. And, of course, handles all the issues presented.
>> In the usual happy day scenario, this is always "good". If something
>> fails during or after a mode set, the kernel driver can set the link
>> status to "bad" and issue a hotplug uevent for userspace to have it
>> re-check the valid modes through GET_CONNECTOR IOCTL, and try modeset
>> again. If the theoretical capabilities of the link can't be reached,
>> the mode list is trimmed based on that.
>>
>> v4:
>> * Add comments in kernel-doc format (Daniel Vetter)
>> * Update the kernel-doc for link-status (Sean Paul)
>> v3:
>> * Fixed a build error (Jani Saarinen)
>> v2:
>> * Removed connector->link_status (Daniel Vetter)
>> * Set connector->state->link_status in 
>> drm_mode_connector_set_link_status_property
>> (Daniel Vetter)
>> * Set the connector_changed flag to true if connector->state->link_status 
>> changed.
>> * Reset link_status to GOOD in update_output_state (Daniel Vetter)
>> * Never allow userspace to set link status from Good To Bad (Daniel Vetter)
>>
>> Acked-by: Tony Cheng 
>> Acked-by: Harry Wentland 
>> Cc: Jani Nikula 
>> Cc: Daniel Vetter 
>> Cc: Ville Syrjala 
>> Cc: Chris Wilson 
>> Cc: Sean Paul 
>> Signed-off-by: Manasi Navare 
>> ---
>>  drivers/gpu/drm/drm_atomic.c| 10 +++
>>  drivers/gpu/drm/drm_atomic_helper.c |  8 ++
>>  drivers/gpu/drm/drm_connector.c | 54 
>> -
>>  include/drm/drm_connector.h | 19 +
>>  include/drm/drm_mode_config.h   |  5 
>>  include/uapi/drm/drm_mode.h |  4 +++
>>  6 files changed, 99 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> index 89737e4..990f013 100644
>> --- a/drivers/gpu/drm/drm_atomic.c
>> +++ b/drivers/gpu/drm/drm_atomic.c
>> @@ -1087,6 +1087,14 @@ int drm_atomic_connector_set_property(struct 
>> drm_connector *connector,
>>* now?) atomic writes to DPMS property:
>>*/
>>   return -EINVAL;
>> + } else if (property == config->link_status_property) {
>> + /* Never downgrade from GOOD to BAD on userspace's request 
>> here,
>> +  * only hw issues can do that.
>> +  */
>> + if (state->link_status == DRM_LINK_STATUS_GOOD)
>> + return 0;
>> + state->link_status = val;
>> + return 0;
>>   } else if (connector->funcs->atomic_set_property) {
>>   return connector->funcs->atomic_set_property(connector,
>>   state, property, val);
>> @@ -1135,6 +1143,8 @@ static void drm_atomic_connector_print_state(struct 
>> drm_printer *p,
>>   *val = (state->crtc) ? state->crtc->base.id : 0;
>>   } else if (property == config->dpms_property) {
>>   *val 

[linux-sunxi] Re: [PATCH v7 4/8] drm/sunxi: Add DT bindings documentation of Allwinner HDMI

2016-12-01 Thread Laurent Pinchart
On Thursday 01 Dec 2016 12:30:09 Jean-Francois Moine wrote:
> On Thu, 01 Dec 2016 12:41:20 +0200 Laurent Pinchart wrote:
> >>> If a DVI connector instead of a HDMI connector is soldered, how
> >>> should such a device tree be written?
> >> 
> >> Use a dvi-connector instead :)
> > 
> > The HDMI encoder DT node doesn't (and certainly shouldn't) report what
> > type of connector is mounted on the board. Having a connector node in DT
> > makes the connector type available to the system, allowing the DRM driver
> > to expose the right connector type to userspace (it would be confusing
> > for the user to report DRM_MODE_CONNECTOR_HDMIA for a DVI connector).
> 
> The connector type, HDMI or DVI, is known by the EDID.
> The user is not interested by the software indication of the connector
> type: (s)he knows it because (s)he connected him/herself the display
> device.

That's not correct. The connector type reported by DRM to userspace can be 
used as a hint to information the user about connectors. Displaying a "Please 
connect a monitor to the HDMI connector" is confusing when the system has a 
DVI connector.

> And the DRM driver does not do anything from the knowledge of the
> connector type in the DT. Only the EDID may tell if the display device
> may do audio streaming (direct HDMI with audio capability) or not
> (direct HDMI without audio, HDMI to DVI cable, DVI physical connector).

-- 
Regards,

Laurent Pinchart



[PATCH libdrm 4/5] xf86drm: introduce drmGetDevice[s]2

2016-12-01 Thread Emil Velikov
On 1 December 2016 at 03:56, Michel Dänzer  wrote:
> On 01/12/16 12:09 PM, Michel Dänzer wrote:
>> On 01/12/16 05:35 AM, Emil Velikov wrote:
>>> From: Emil Velikov 
>>>
>>> Relative to the original version, here one can provide a flags bitmask.
>>> Currently only DRM_DEVICE_IGNORE_PCI_REVISION is supported.
>>>
>>> Implementation detail:
>>> If it's set, we will only parse the separate sysfs files and we won't
>>> touch the config one. The latter awakes the device (causing delays)
>>> which is the core reason why this API was introduced.
>>>
>>> Cc: Michel Dänzer 
>>> Cc: Nicolai Hähnle 
>>> Cc: Mauro Santos 
>>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98502
>>> Signed-off-by: Emil Velikov 
>>> ---
>>> Michel, Nicolai any naming suggestions or input in general will be
>>> appreciated.
>>
>> It all looks good to me in general, thanks for doing this! I just have
>> a couple of minor suggestions for this patch which might make the code
>> clearer, feel free to take them or leave them. Either way, patches 3-5
>> are
>>
>> Reviewed-by: Michel Dänzer 
>
> On further thought, I wonder if maybe drmGetDevice[s]2 should default to
> not retrieving the PCI revision, unless a flag is set, say
> DRM_DEVICE_GET_PCI_REVISION? That would avoid unnecessarily using the
> config file if the caller forgets to set the flag even though it doesn't
> need the revision.
>
Not 100% sold on the reasoning (if someone forgets...) yet making the
revision opt-in (as opposed to opt-out) makes sense.

> Though in that case, maybe the revision_id field should also be set to
> 0xff without the flag, to avoid callers forgetting to set the flag and
> getting an incorrect but plausible(?) 0 for the revision.
>
All suggestions sound amazing, thank you !

Barring any objections, I'll re-spin the series and send one for Mesa
later on today.

Thanks again,
Emil


[PATCH] drm: Make the connector .detect() callback optional

2016-12-01 Thread Sean Paul
On Tue, Nov 29, 2016 at 4:09 PM, Laurent Pinchart
 wrote:
> Hi Sean,
>
> On Tuesday 29 Nov 2016 16:07:02 Sean Paul wrote:
>> On Tue, Nov 29, 2016 at 3:56 PM, Laurent Pinchart wrote:
>> > Many drivers (21 to be exact) create connectors that are always
>> > connected (for instance to an LVDS or DSI panel). Instead of forcing
>> > them to implement a dummy .detect() handler, make the callback optional
>> > and consider the connector as always connected in that case.
>>
>> I wonder if we should be a little bit smarter about this and default
>> connected only for built-in types (LVDS, edp, DSI), and return unknown
>> for others?
>
> I've deliberately decided not to change the behaviour of any driver in this
> patch to ease review and merge. We can change (a.k.a. improve :-)) the logic
> on top of this. Patches are welcome ;-)

Yeah, that's fair. I took a quick look to verify whether or not all of
the instances were already attached to a built-in, but that turned out
to be trickier than I anticipated.

I've merged it (with the Acks) to misc.

Thanks,

Sean

>
>> > Signed-off-by: Laurent Pinchart
>> > 
>> > ---
>> >
>> >  drivers/gpu/drm/amd/amdgpu/dce_virtual.c |  7 ---
>> >  drivers/gpu/drm/arc/arcpgu_sim.c |  7 ---
>> >  drivers/gpu/drm/ast/ast_mode.c   |  7 ---
>> >  drivers/gpu/drm/bochs/bochs_kms.c|  7 ---
>> >  drivers/gpu/drm/bridge/nxp-ptn3460.c |  7 ---
>> >  drivers/gpu/drm/bridge/parade-ps8622.c   |  7 ---
>> >  drivers/gpu/drm/bridge/tc358767.c|  7 ---
>> >  drivers/gpu/drm/cirrus/cirrus_mode.c |  7 ---
>> >  drivers/gpu/drm/drm_probe_helper.c   | 14 +++---
>> >  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c|  7 ---
>> >  drivers/gpu/drm/gma500/cdv_intel_lvds.c  | 14 --
>> >  drivers/gpu/drm/gma500/psb_intel_lvds.c  | 14 --
>> >  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c |  7 ---
>> >  drivers/gpu/drm/i915/intel_dsi.c |  7 ---
>> >  drivers/gpu/drm/imx/imx-ldb.c|  7 ---
>> >  drivers/gpu/drm/imx/imx-tve.c|  7 ---
>> >  drivers/gpu/drm/imx/parallel-display.c   |  7 ---
>> >  drivers/gpu/drm/mediatek/mtk_dsi.c   |  7 ---
>> >  drivers/gpu/drm/mgag200/mgag200_mode.c   |  7 ---
>> >  drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c|  7 ---
>> >  drivers/gpu/drm/rockchip/dw-mipi-dsi.c   |  7 ---
>> >  drivers/gpu/drm/shmobile/shmob_drm_crtc.c|  7 ---
>> >  drivers/gpu/drm/sti/sti_hda.c|  7 ---
>> >  drivers/gpu/drm/sun4i/sun4i_rgb.c|  7 ---
>> >  drivers/gpu/drm/sun4i/sun4i_tv.c |  7 ---
>> >  drivers/gpu/drm/tilcdc/tilcdc_panel.c|  8 
>> >  include/drm/drm_connector.h  |  3 +++
>> >  27 files changed, 14 insertions(+), 193 deletions(-)
>
> --
> Regards,
>
> Laurent Pinchart
>


[PATCH libdrm 4/5] xf86drm: introduce drmGetDevice[s]2

2016-12-01 Thread Michel Dänzer
On 01/12/16 12:09 PM, Michel Dänzer wrote:
> On 01/12/16 05:35 AM, Emil Velikov wrote:
>> From: Emil Velikov 
>>
>> Relative to the original version, here one can provide a flags bitmask.
>> Currently only DRM_DEVICE_IGNORE_PCI_REVISION is supported.
>>
>> Implementation detail:
>> If it's set, we will only parse the separate sysfs files and we won't
>> touch the config one. The latter awakes the device (causing delays)
>> which is the core reason why this API was introduced.
>>
>> Cc: Michel Dänzer 
>> Cc: Nicolai Hähnle 
>> Cc: Mauro Santos 
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98502
>> Signed-off-by: Emil Velikov 
>> ---
>> Michel, Nicolai any naming suggestions or input in general will be
>> appreciated.
> 
> It all looks good to me in general, thanks for doing this! I just have
> a couple of minor suggestions for this patch which might make the code
> clearer, feel free to take them or leave them. Either way, patches 3-5
> are
> 
> Reviewed-by: Michel Dänzer 

On further thought, I wonder if maybe drmGetDevice[s]2 should default to
not retrieving the PCI revision, unless a flag is set, say
DRM_DEVICE_GET_PCI_REVISION? That would avoid unnecessarily using the
config file if the caller forgets to set the flag even though it doesn't
need the revision.

Though in that case, maybe the revision_id field should also be set to
0xff without the flag, to avoid callers forgetting to set the flag and
getting an incorrect but plausible(?) 0 for the revision.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer


[PATCH v2 7/7] ARM: bcm/dt: Enable the VEC IP on all RaspeberryPi boards

2016-12-01 Thread Eric Anholt
Boris Brezillon  writes:

> Enable the VEC IP on all RaspeberryPi boards.

Typo in the subject and body, "Raspberry".  Don't worry about resending
for that, though.
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20161201/373b2a31/attachment-0001.sig>


[linux-sunxi] Re: [PATCH v7 4/8] drm/sunxi: Add DT bindings documentation of Allwinner HDMI

2016-12-01 Thread Laurent Pinchart
On Thursday 01 Dec 2016 09:55:20 Maxime Ripard wrote:
> On Thu, Dec 01, 2016 at 01:33:30AM +0800, Icenowy Zheng wrote:
> >>>  hdmi-out {
> >>>  compatible = "hdmi-connector";
> >>>  type = "a";
> >>>  /* I2C bus and GPIO references are made up for the
> >>> example */ ddc-i2c-bus = <>;
> >>>  hpd-gpios = < 7 GPIO_ACTIVE_HIGH>
> >> 
> >> the "hdmi-connector" is a big piece of software. It must handle a lot
> >> of more and more exotic connectors.
> >> So, I hope that you have written a "simple-hdmi-connector" which does
> >> nothing but setting the connector type.
> >> Where is it?
> > 
> > I suddenly thought about something...
> > 
> > If a DVI connector instead of a HDMI connector is soldered, how
> > should such a device tree be written?
> 
> Use a dvi-connector instead :)

The HDMI encoder DT node doesn't (and certainly shouldn't) report what type of 
connector is mounted on the board. Having a connector node in DT makes the 
connector type available to the system, allowing the DRM driver to expose the 
right connector type to userspace (it would be confusing for the user to 
report DRM_MODE_CONNECTOR_HDMIA for a DVI connector).

> > How about solder a HDMI-to-VGA bridge on the board? (Maybe there
> > should be "dumb-hdmi-dvi-bridge" and "dumb-hdmi-vga-bridge"
> > drivers?)
> 
> It probably wouldn't be dumb, but yeah, it would definitely be a
> bridge instead of the connector.

-- 
Regards,

Laurent Pinchart



[PATCH] drm/bridge: tc358767: don't warn if display side ASSR enable fails

2016-12-01 Thread Andrey Gusakov
Hi.

I'm fine with that change.

Acked-by:Andrey Gusakov 

On Thu, Dec 1, 2016 at 10:58 AM, Philipp Zabel  
wrote:
> Am Donnerstag, den 01.12.2016, 09:56 +0530 schrieb Archit Taneja:
>>
>> On 11/30/2016 05:18 PM, Lucas Stach wrote:
>> > ASSR is an optional feature, so it's a valid operating condition for
>> > the display to reject ASSR enable. Demote the warning to the debug
>> > level.
>>
>> Lgtm. Will pull it if Philipp or Andrey don't have any comments on it.
>
> No objections, this message is not helpful to a normal user.
>
> Acked-by: Philipp Zabel 
>
> regards
> Philipp
>


[Bug 107381] radeon VCE init error (-110) -- AMD/Intel Mars Hybrid Graphics

2016-12-01 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=107381

--- Comment #15 from Stratos Zolotas  ---
I'm on 4.8.10 and still is not fixed. I have two AMD GPUS (both Oland) and the
issue is appearing on both. So don't expect to see a fix on any released
kernel. Haven't tested any 4.9 pre-release yet.

01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Oland
XT [Radeon HD 8670 / R7 250/350]
02:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Oland
PRO [Radeon R7 240/340]

dmesg | egrep -i 'vce|error'
[3.297273] [drm] Found VCE firmware/feedback version 50.0.1 / 17!
[3.456641] radeon :01:00.0: failed VCE resume (-110).
[4.878397] [drm] Found VCE firmware/feedback version 50.0.1 / 17!
[4.985278] radeon :02:00.0: failed VCE resume (-110).

uname -a
Linux teras 4.8.10-1-default #1 SMP PREEMPT Mon Nov 21 13:50:28 UTC 2016
(d1ec066) x86_64 x86_64 x86_64 GNU/Linux

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[linux-sunxi] Re: [PATCH v7 4/8] drm/sunxi: Add DT bindings documentation of Allwinner HDMI

2016-12-01 Thread Jean-Francois Moine
On Thu, 01 Dec 2016 12:41:20 +0200
Laurent Pinchart  wrote:

> > > If a DVI connector instead of a HDMI connector is soldered, how
> > > should such a device tree be written?
> > 
> > Use a dvi-connector instead :)
> 
> The HDMI encoder DT node doesn't (and certainly shouldn't) report what type 
> of 
> connector is mounted on the board. Having a connector node in DT makes the 
> connector type available to the system, allowing the DRM driver to expose the 
> right connector type to userspace (it would be confusing for the user to 
> report DRM_MODE_CONNECTOR_HDMIA for a DVI connector).

The connector type, HDMI or DVI, is known by the EDID.
The user is not interested by the software indication of the connector
type: (s)he knows it because (s)he connected him/herself the display
device.
And the DRM driver does not do anything from the knowledge of the
connector type in the DT. Only the EDID may tell if the display device
may do audio streaming (direct HDMI with audio capability) or not
(direct HDMI without audio, HDMI to DVI cable, DVI physical connector).

-- 
Ken ar c'hentañ| ** Breizh ha Linux atav! **
Jef |   http://moinejf.free.fr/


[Bug 107381] radeon VCE init error (-110) -- AMD/Intel Mars Hybrid Graphics

2016-12-01 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=107381

Bhaskar  changed:

   What|Removed |Added

 CC||bha100710 at gmail.com

--- Comment #14 from Bhaskar  ---
This issue still does not seem to be fixed. My kernel version is
4.4.0-51-generic and the issue still occurs.

Here's the output of dmesg | egrep -i 'vce|error' :

[2.057617] [drm] Found VCE firmware/feedback version 40.2.2 / 15!
[2.271399] [drm] VCE initialized successfully.
[4.627532] kfd kfd: error getting iommu info. is the iommu enabled?
[4.627538] kfd kfd: Error initializing iommuv2 for device (1002:130a)
[4.627729] kfd kfd: device (1002:130a) NOT added due to errors
[4.752479] [drm] Found VCE firmware/feedback version 50.0.1 / 17!
[6.235140] radeon :01:00.0: VCE init error (-110).
[7.301364] [drm:radeon_acpi_init [radeon]] *ERROR* Cannot find a backlight
controller
[   20.220010] EXT4-fs (sda2): re-mounted. Opts: errors=remount-ro
[   31.605179] radeon :01:00.0: VCE init error (-110).
[   51.400194] radeon :01:00.0: VCE init error (-110).
[   74.917029] radeon :01:00.0: VCE init error (-110).



uname -a
Linux gublu 4.4.0-51-generic #72-Ubuntu SMP Thu Nov 24 18:29:54 UTC 2016 x86_64
x86_64 x86_64 GNU/Linux


sudo lspci | grep VGA
00:01.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI]
Kaveri [Radeon R6 Graphics]

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[Bug 98914] mesa-vdpau-drivers: breaks vdpau for mpeg2video

2016-12-01 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98914

--- Comment #5 from Jörg-Volker Peetz  ---
Meanwhile, I've tried version 13.0.0-1 from the debian snapshot archive. It
shows already the same regression for the vdpau hardware acceleration with
mpeg2video codec.
I've also cloned the mesa git repository. I'll try to bisect in the next days.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20161201/d94f3567/attachment.html>


[Bug 188321] i915: black screen after disconnecting HDMI monitor

2016-12-01 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=188321

Jani Nikula  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |INVALID

--- Comment #1 from Jani Nikula  ---
Please file drm/i915 bugs at
https://bugs.freedesktop.org/enter_bug.cgi?product=DRI=DRM/Intel

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[PATCH libdrm 4/5] xf86drm: introduce drmGetDevice[s]2

2016-12-01 Thread Michel Dänzer
On 01/12/16 05:35 AM, Emil Velikov wrote:
> From: Emil Velikov 
> 
> Relative to the original version, here one can provide a flags bitmask.
> Currently only DRM_DEVICE_IGNORE_PCI_REVISION is supported.
> 
> Implementation detail:
> If it's set, we will only parse the separate sysfs files and we won't
> touch the config one. The latter awakes the device (causing delays)
> which is the core reason why this API was introduced.
> 
> Cc: Michel Dänzer 
> Cc: Nicolai Hähnle 
> Cc: Mauro Santos 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98502
> Signed-off-by: Emil Velikov 
> ---
> Michel, Nicolai any naming suggestions or input in general will be
> appreciated.

It all looks good to me in general, thanks for doing this! I just have
a couple of minor suggestions for this patch which might make the code
clearer, feel free to take them or leave them. Either way, patches 3-5
are

Reviewed-by: Michel Dänzer 


> @@ -2963,7 +2964,7 @@ static int parse_separate_sysfs_files(int maj, int min,
>  FILE *fp;
>  int ret;
>  
> -for (unsigned i = 0; i < ARRAY_SIZE(attrs); i++) {
> +for (unsigned i = (0 + !!ignore_revision); i < ARRAY_SIZE(attrs); i++) {

for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) {


> diff --git a/xf86drm.h b/xf86drm.h
> index 4da6bd3..1c6ed36 100644
> --- a/xf86drm.h
> +++ b/xf86drm.h
> @@ -801,6 +801,10 @@ extern void drmFreeDevice(drmDevicePtr *device);
>  extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
>  extern void drmFreeDevices(drmDevicePtr devices[], int count);
>  
> +#define DRM_DEVICE_IGNORE_PCI_REVISION 0x0001

#define DRM_DEVICE_IGNORE_PCI_REVISION (1 << 0)

to make it clearer that flags will be separate bits, not enumeration values.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer


[PULL] drm-intel-fixes

2016-12-01 Thread Jani Nikula

Hi Dave, presumably final fixes for 4.9.

BR,
Jani.

The following changes since commit e5517c2a5a49ed5e99047008629f1cd60246ea0e:

  Linux 4.9-rc7 (2016-11-27 13:08:04 -0800)

are available in the git repository at:

  git://anongit.freedesktop.org/git/drm-intel tags/drm-intel-fixes-2016-12-01

for you to fetch changes up to e411072d5740a49cdc9d0713798c30440757e451:

  drm/i915: drop the struct_mutex when wedged or trying to reset (2016-11-30 
12:09:26 +0200)


Chris Wilson (1):
  drm/i915: Don't touch NULL sg on i915_gem_object_get_pages_gtt() error

Matthew Auld (1):
  drm/i915: drop the struct_mutex when wedged or trying to reset

 drivers/gpu/drm/i915/i915_gem.c  | 5 +++--
 drivers/gpu/drm/i915/intel_display.c | 3 ++-
 2 files changed, 5 insertions(+), 3 deletions(-)

-- 
Jani Nikula, Intel Open Source Technology Center


[RFC v3 1/3] fbmem: add default get_fb_unmapped_area function

2016-12-01 Thread Michel Dänzer
On 01/12/16 04:46 AM, Benjamin Gaignard wrote:
> 2016-11-30 20:39 GMT+01:00 Laurent Pinchart  ideasonboard.com>:
>> On Wednesday 30 Nov 2016 20:34:17 Benjamin Gaignard wrote:
>>> If HAVE_ARCH_FB_UNMAPPED_AREA is set and get_fb_unmapped_area
>>> function not defined in platform architecture let use a default function.
>>>
>>> Signed-off-by: Benjamin Gaignard 
>>> ---
>>>  drivers/video/fbdev/core/fbmem.c | 15 +++
>>>  1 file changed, 15 insertions(+)
>>>
>>> diff --git a/drivers/video/fbdev/core/fbmem.c
>>> b/drivers/video/fbdev/core/fbmem.c index 76c1ad9..54488ee 100644
>>> --- a/drivers/video/fbdev/core/fbmem.c
>>> +++ b/drivers/video/fbdev/core/fbmem.c
>>> @@ -1492,6 +1492,21 @@ static long fb_compat_ioctl(struct file *file,
>>> unsigned int cmd, return 0;
>>>  }
>>>
>>> +#if defined(HAVE_ARCH_FB_UNMAPPED_AREA) && !defined(get_fb_unmapped_area)
>>
>> I think I've asked this twice already, how is that possible ?
> 
> As you said before only sparc and blackfin architectures have define
> HAVE_ARCH_FB_UNMAPPED_AREA
> and get_fb_unmapped_area().
> For stm32f4 (ARMv7m) I plan to only add HAVE_ARCH_FB_UNMAPPED_AREA and
> use this default function

Note that the preprocessor only considers defined(get_fb_unmapped_area)
true if get_fb_unmapped_area is defined as a macro, not if it's a normal
function. Since AFAICT get_fb_unmapped_area is a normal function on
sparc and blackfin, this default function will be compiled on those
architectures as well.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer


How should we group related devices in DT ? (was Re: [PATCH v7 0/8] drm: sun8i: Add DE2 HDMI video support)

2016-12-01 Thread Laurent Pinchart
Hello,

On Thursday 01 Dec 2016 10:13:13 Maxime Ripard wrote:

[snip]

> The earlier Allwinner SoCs (with the old display engine), we had some
> SoCs with multiple instances of the display engine and TCON (the
> display engine roughly implementing the planes, the TCON the
> CRTC. Roughly.). However, those were sharing some encoders (HDMI,
> DSI) after that.
> 
> So we need to have a single DRM device taking care of the multiple
> display engines, which essentialy means that we have to decouple the
> DRM device from the display engine. This was done in the earlier
> designs using an additional node with a list of phandles to the
> display engines in the system, and obviously, I'd prefer to have some
> consistency and reuse the same thing.

I believe this problem isn't limited to sunxi and should be addressed in a 
more generic way. How should we describe in the device tree that multiple 
instances of a device unrelated from a control point of view are related at 
the hardware level ? There are multiple reasons why we need this, and here are 
a few.

- As described above, unrelated display controller instances that share 
encoders at their output need to be exposed to userspace as a single DRM 
device. This is also the case on Renesas platforms (where the display engines 
are independent except for the "small" detail that output routing is 
controlled through the first display engine).

- On Renesas platforms again a radio-related SPI receiver has multiple 
independent channels that each have their own registers, clocks and 
interrupts, but share the same physical clock and sync pins. They are used to 
receive multiple channels of the same data stream and must be exposed as a 
single V4L2 device to userspace. A generic DT binding RFC is available at 
http://www.spinics.net/lists/devicetree/msg152414.html.

> But the current approach doesn't work and will require some DT
> modifications if that case happens again, which we can't do because of
> the DT ABI.

-- 
Regards,

Laurent Pinchart



[pull] radeon and amdgpu drm-next-4.10

2016-12-01 Thread Alex Deucher
On Wed, Nov 23, 2016 at 3:40 PM, Alex Deucher  wrote:
> Hi Dave,
>
> More features for 4.10.  Highlights:
> - lots of code cleanup
> - lots of bug fixes
> - expose rpm based fan info via hwmon
> - lots of clock and powergating fixes
> - SI register header cleanup and conversion to common format used by newer 
> asics
>

Ping?

>
> The following changes since commit d8c1abd968f1c880ad8ce4ecf7df55489f8c69a1:
>
>   Merge tag 'zxdrm-4.10' of 
> git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into drm-next 
> (2016-11-11 10:09:13 +1000)
>
> are available in the git repository at:
>
>   git://people.freedesktop.org/~agd5f/linux drm-next-4.10
>
> for you to fetch changes up to e7b8243d3e0ace9f5130c3b5c3c52a50039a7501:
>
>   drm/amdgpu: drop is_display_hung from display funcs (2016-11-23 15:13:21 
> -0500)
>
> 
> Alex Deucher (4):
>   drm/amdgpu/sdma: fix typo in packet setup
>   drm/amdgpu/uvd: consolidate code for fetching addr from ctx
>   drm/amdgpu/uvd: reduce IB parsing overhead on UVD5+ (v2)
>   drm/amdgpu: drop is_display_hung from display funcs
>
> Christian König (7):
>   drm/amdgpu: disable the VRAM manager on special placements v2
>   drm/amdgpu: remove extra placement for AMDGPU_GEM_CREATE_NO_CPU_ACCESS
>   drm/amdgpu: remove amdgpu_irq_get_delayed
>   drm/amdgpu: fix amdgpu_fill_buffer (v2)
>   drm/amdgpu: fix error handling in amdgpu_bo_create_restricted
>   drm/amdgpu: improve AMDGPU_GEM_CREATE_VRAM_CLEARED handling (v2)
>   drm/amdgpu: use AMDGPU_GEM_CREATE_VRAM_CLEARED for VM PD/PTs (v2)
>
> Edward O'Callaghan (2):
>   amdgpu: Use dev_err() over vanilla printk() in vm_decode_fault()
>   amdgpu: Wrap dev_err() calls on vm faults with printk_ratelimit()
>
> Grazvydas Ignotas (2):
>   drm/amd/powerplay: export a function to read fan rpm
>   drm/amd/amdgpu: expose fan rpm though hwmon
>
> Huang Rui (4):
>   drm/amdgpu: cleanup amdgpu_cs_ioctl to make code logicality clear
>   drm/amdgpu: remove amdgpu_cs_handle_lockup
>   drm/amdgpu: cleanup unused iterator members for sdma v3
>   drm/amdgpu: cleanup unused iterator members for sdma v2.4
>
> Maruthi Srinivas Bayyavarapu (1):
>   drm/amdgpu: enable UVD clockgating in Polaris-10/11
>
> Monk Liu (1):
>   drm/amdgpu:impl vgt_flush for VI(V5)
>
> Ravikant B Sharma (1):
>   drm/amd/amdgpu : Fix NULL pointer comparison
>
> Rex Zhu (18):
>   drm/amd/powerplay: add new bit mask to ctrl clock stretch feature.
>   drm/amd/powerplay: make CAC feature controlled by module parameter.
>   drm/amdgpu/powerplay: pp module only enable smu when dpm disabled.
>   drm/amd/powerplay: use mask bit for deepsleep/power tune feature.
>   drm/amdgpu: use mask bit for deep sleep feature on dpm.
>   drm/amdgpu: delete duplicate module parameter.
>   drm/amd/powerplay: fix code style
>   drm/amd/powerplay: enable voltage control by default for dgpu.
>   drm/amd/powerplay: delete duplicate code in smu7_hwmgr.c
>   drm/amdgpu: refine uvd_4.2 clock gate sequence.
>   drm/amdgpu: not set bypass mode for uvd5.0/uvd6.0
>   drm/amd/powerplay: partial revert commit 01b0e7fb1.
>   drm/amdgpu: refine uvd 5.0 clock gate feature.
>   drm/amd/powerplay: add mask bit for fan control mode.
>   drm/amdgpu: always un-gate UVD REGS path.
>   drm/amdgpu: change log level to KERN_INFO in ci_dpm.c
>   drm/amdgpu: refine cz uvd clock gate logic.
>   drm/amdgpu: enable uvd mgcg for Fiji.
>
> Tom St Denis (8):
>   drm/amd/amdgpu: Clean up wave gfx7 helper
>   drm/amd/amdgpu: Clean up wave gfx8 helper
>   drm/amd/amdgpu: Introduction of SI registers (v2)
>   drm/amd/amdgpu: add SI defines/registers
>   drm/amd/amdgpu: port gfx6 over to new si headers (v2)
>   drm/amd/amdgpu: add wave reader to gfx v6
>   drm/amd/amdgpu:  Port GMC v6 driver to new SI headers (v2)
>   drm/amd/amdgpu: port of DCE v6 to new headers (v3)
>
> Trigger Huang (5):
>   drm/amdgpu: Add a ring type KIQ definition
>   drm/amdgpu:no gpu scheduler for KIQ
>   drm/amdgpu:bypass avfs event manager for sriov
>   drm/amd/powerplay:Tonga not to start SMC if SRIOV
>   drm/amdgpu: Disable DPM in virtualization
>
> jimqu (1):
>   drm/amdgpu: fix logic error for checking amdgpu_vram_page_split
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h| 5 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c   | 2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c |43 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h| 7 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|14 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  |39 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c| 9 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h   

[PATCH v7 0/8] drm: sun8i: Add DE2 HDMI video support

2016-12-01 Thread Laurent Pinchart
Hi Maxime,

On Thursday 01 Dec 2016 10:13:13 Maxime Ripard wrote:
> On Wed, Nov 30, 2016 at 12:12:55PM +0200, Laurent Pinchart wrote:
> >> More, it is not sure that the bridge/DW code would work with Allwinner's
> >> SoCs.
> > 
> > If it doesn't work and can't be made to work in a non-invasive way they it
> > should certainly not be used :-)
> 
> Even if the register layout is completely scrambled, as long as the
> bits themselves aren't (and by comparing the two drivers it looks like
> they haven't changed), you can easily deal with that using the
> regmap_fields, with the two implementations (the original one and the
> scrambled one) providing their register map that way, and the driver
> code using whatever has been provided.

Looking at https://linux-sunxi.org/DWC_HDMI_Controller#DWC_HDMI_Controller it 
seems that an address remapping function could be used.

> >> Eventually, I went the same way as omap/hdmi5: different driver.
> > 
> > I might try to fix that for OMAP5 at some point, we'll see.
> 
> For complex drivers that have already a driver written and a lot of
> testing that already happened, I don't think duplication is a smart
> move.
> 
> >>>   - And finally the fact that we can't have several display engine in
> >>> parallel, if needs be. This has happened in the past already on
> >>> Allwinner SoCs, so it's definitely something we should consider in
> >>> the DT bindings, since we can't break them.
> >> 
> >> IIRC, I proposed my driver before yours, and the DE2 is completely
> >> different from the other display engines.
> >> What you are telling is "add more code to already complex code and have
> >> a big driver for all SoCs in each kernels".
> >> I think it should be better to have small modules, each one treating
> >> specific hardware, and to let only the needed code in the kernel memory
> >> at startup time.
> >> 
> >>> Until those are fixed, I cannot see how this driver can be merged,
> >>> unfortunately.
> >> 
> >> No problem. I just wanted to help people by giving the job I did on the
> >> boards I have. My boards are working for almost one year, fine enough
> >> for I use them as daily desktop computers. I don't want to spend one
> >> more year for having my code in the Linux kernel: there are so much
> >> other exciting things to do...
> > 
> > And you're certainly welcome to contribute drivers to the kernel, that's
> > always appreciated. Of course, to ensure a reasonable level of quality and
> > consistency between drivers, the review process often requires changes to
> > be made to the code being submitted. When it comes to drivers I mostly
> > pay attention to DT bindings, userspace APIs and modification to common
> > code. Driver code itself, as long as it's reasonably clean and doesn't
> > impede development of other drivers or impact system security in an
> > adverse way, is still important but maybe slightly less so. I'll defer to
> > Maxime to come to an agreement on the multiple display engines in
> > parallel problem as I'm not familiar with it for the Allwinner platforms.
> 
> The earlier Allwinner SoCs (with the old display engine), we had some
> SoCs with multiple instances of the display engine and TCON (the
> display engine roughly implementing the planes, the TCON the
> CRTC. Roughly.). However, those were sharing some encoders (HDMI,
> DSI) after that.
> 
> So we need to have a single DRM device taking care of the multiple
> display engines, which essentialy means that we have to decouple the
> DRM device from the display engine. This was done in the earlier
> designs using an additional node with a list of phandles to the
> display engines in the system, and obviously, I'd prefer to have some
> consistency and reuse the same thing.
> 
> But the current approach doesn't work and will require some DT
> modifications if that case happens again, which we can't do because of
> the DT ABI.

-- 
Regards,

Laurent Pinchart



[RFCv2 PATCH 1/5] video: add HDMI state notifier support

2016-12-01 Thread Hans Verkuil
On 11/14/16 16:22, Hans Verkuil wrote:
> From: Hans Verkuil 
>
> Add support for HDMI hotplug and EDID notifiers, which is used to convey
> information from HDMI drivers to their CEC and audio counterparts.

I realized that the name 'HDMI notifier' isn't the best: the same mechanism
can be used with e.g. DisplayPort as well.

What would be a good alternative name?

"Video Notifier"?

Any objections to that? Or suggestions for a better name?

Regards,

Hans

>
> Based on an earlier version from Russell King:
>
> https://patchwork.kernel.org/patch/9277043/
>
> The hdmi_notifier is a reference counted object containing the HDMI state
> of an HDMI device.
>
> When a new notifier is registered the current state will be reported to
> that notifier at registration time.
>
> Signed-off-by: Hans Verkuil 
> ---
>  drivers/video/Kconfig |   3 +
>  drivers/video/Makefile|   1 +
>  drivers/video/hdmi-notifier.c | 136 
> ++
>  include/linux/hdmi-notifier.h |  43 +
>  4 files changed, 183 insertions(+)
>  create mode 100644 drivers/video/hdmi-notifier.c
>  create mode 100644 include/linux/hdmi-notifier.h
>
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 3c20af9..1ee7b9f 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -36,6 +36,9 @@ config VIDEOMODE_HELPERS
>  config HDMI
>   bool
>
> +config HDMI_NOTIFIERS
> + bool
> +
>  if VT
>   source "drivers/video/console/Kconfig"
>  endif
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index 9ad3c17..65f5649 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_VGASTATE)+= vgastate.o
>  obj-$(CONFIG_HDMI)+= hdmi.o
> +obj-$(CONFIG_HDMI_NOTIFIERS)  += hdmi-notifier.o
>
>  obj-$(CONFIG_VT)   += console/
>  obj-$(CONFIG_LOGO) += logo/
> diff --git a/drivers/video/hdmi-notifier.c b/drivers/video/hdmi-notifier.c
> new file mode 100644
> index 000..c2a4f1b
> --- /dev/null
> +++ b/drivers/video/hdmi-notifier.c
> @@ -0,0 +1,136 @@
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct hdmi_notifiers {
> + struct list_head head;
> + struct device *dev;
> + struct hdmi_notifier *n;
> +};
> +
> +static LIST_HEAD(hdmi_notifiers);
> +static DEFINE_MUTEX(hdmi_notifiers_lock);
> +
> +struct hdmi_notifier *hdmi_notifier_get(struct device *dev)
> +{
> + struct hdmi_notifier *n;
> +
> + mutex_lock(_notifiers_lock);
> + list_for_each_entry(n, _notifiers, head) {
> + if (n->dev == dev) {
> + mutex_unlock(_notifiers_lock);
> + kref_get(>kref);
> + return n;
> + }
> + }
> + n = kzalloc(sizeof(*n), GFP_KERNEL);
> + if (!n)
> + goto unlock;
> + mutex_init(>lock);
> + BLOCKING_INIT_NOTIFIER_HEAD(>notifiers);
> + kref_init(>kref);
> + list_add_tail(>head, _notifiers);
> +unlock:
> + mutex_unlock(_notifiers_lock);
> + return n;
> +}
> +EXPORT_SYMBOL_GPL(hdmi_notifier_get);
> +
> +static void hdmi_notifier_release(struct kref *kref)
> +{
> + struct hdmi_notifier *n =
> + container_of(kref, struct hdmi_notifier, kref);
> +
> + kfree(n->edid);
> + kfree(n);
> +}
> +
> +void hdmi_notifier_put(struct hdmi_notifier *n)
> +{
> + kref_put(>kref, hdmi_notifier_release);
> +}
> +EXPORT_SYMBOL_GPL(hdmi_notifier_put);
> +
> +int hdmi_notifier_register(struct hdmi_notifier *n, struct notifier_block 
> *nb)
> +{
> + int ret = blocking_notifier_chain_register(>notifiers, nb);
> +
> + if (ret)
> + return ret;
> + kref_get(>kref);
> + mutex_lock(>lock);
> + if (n->connected) {
> + blocking_notifier_call_chain(>notifiers, HDMI_CONNECTED, n);
> + if (n->edid_size)
> + blocking_notifier_call_chain(>notifiers, 
> HDMI_NEW_EDID, n);
> + if (n->has_eld)
> + blocking_notifier_call_chain(>notifiers, 
> HDMI_NEW_ELD, n);
> + }
> + mutex_unlock(>lock);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(hdmi_notifier_register);
> +
> +int hdmi_notifier_unregister(struct hdmi_notifier *n, struct notifier_block 
> *nb)
> +{
> + int ret = blocking_notifier_chain_unregister(>notifiers, nb);
> +
> + if (ret == 0)
> + hdmi_notifier_put(n);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(hdmi_notifier_unregister);
> +
> +void hdmi_event_connect(struct hdmi_notifier *n)
> +{
> + mutex_lock(>lock);
> + n->connected = true;
> + blocking_notifier_call_chain(>notifiers, HDMI_CONNECTED, n);
> + mutex_unlock(>lock);
> +}
> +EXPORT_SYMBOL_GPL(hdmi_event_connect);
> +
> +void hdmi_event_disconnect(struct hdmi_notifier *n)
> +{
> + mutex_lock(>lock);
> + n->connected = false;
> + n->has_eld = false;
> + n->edid_size = 0;
> + 

linux-next: problems fetching the drm-intel, etc trees

2016-12-01 Thread Daniel Stone
Hi guys,  



On Nov 30 2016, at 10:49 pm, Rob Clark  wrote:  

> yeah, {cgit,anongit}.fd.o have been having problems all day.. (the ssh  
git urls for folks who have push access work fine).. although it has  
worked for me a couple times today, given enough time.

>

> (not sure if we have github/etc mirrors somewhere? I do have a github  
clone of mesa which is up to date as of ~10min ago.. I could do the  
same for other git trees if someone somewhere is stuck)


Sorry about this, it is quite bad. I think having mirrors for the key DRM
trees on GitHub is a good idea though, and I can get to setting that up.
Stephen, you need DRM (airlied), drm-misc, drm-panel, drm-intel, drm-tegra,
drm-exynos and drm-msm, right?



Though, whilst you're at it, I noticed that the drm-misc tree needs updating:
it's now at git://anongit.freedesktop.org/drm/drm-misc, rather than a branch
of drm-intel.



Cheers,

Daniel

-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20161201/4e2e493a/attachment.html>


  1   2   >