[Intel-gfx] [RFC 4/6] drm/i915: Add i915 perf event for Haswell OA unit

2015-09-29 Thread kbuild test robot
Hi Robert,

[auto build test results on v4.3-rc3 -- if it's inappropriate base, please 
ignore]

config: i386-defconfig (attached as .config)
reproduce:
  git checkout a1d59679ae8f3e7e7659e9723ae3fc69af2532e6
  # save the attached .config to linux build tree
  make ARCH=i386 

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/i915/i915_perf.c: In function 'append_oa_sample':
>> drivers/gpu/drm/i915/i915_perf.c:199:2: warning: #warning "fixme: extract 
>> context ID from OA reports" [-Wcpp]
#warning "fixme: extract context ID from OA reports"
 ^
>> drivers/gpu/drm/i915/i915_perf.c:205:2: warning: #warning "fixme: extract 
>> timestamp from OA reports" [-Wcpp]
#warning "fixme: extract timestamp from OA reports"
 ^
   drivers/gpu/drm/i915/i915_perf.c: In function 'append_oa_status':
>> drivers/gpu/drm/i915/i915_perf.c:155:2: warning: ignoring return value of 
>> 'copy_to_user', declared with attribute warn_unused_result [-Wunused-result]
 copy_to_user(read_state->buf, , sizeof(header));
 ^
   drivers/gpu/drm/i915/i915_perf.c: In function 'append_oa_sample':
   drivers/gpu/drm/i915/i915_perf.c:195:2: warning: ignoring return value of 
'copy_to_user', declared with attribute warn_unused_result [-Wunused-result]
 copy_to_user(read_state->buf, , sizeof(header));
 ^
   drivers/gpu/drm/i915/i915_perf.c:200:3: warning: ignoring return value of 
'copy_to_user', declared with attribute warn_unused_result [-Wunused-result]
  copy_to_user(read_state->buf, _ctx_id, 4);
  ^
   drivers/gpu/drm/i915/i915_perf.c:206:3: warning: ignoring return value of 
'copy_to_user', declared with attribute warn_unused_result [-Wunused-result]
  copy_to_user(read_state->buf, _timestamp, 4);
  ^
   drivers/gpu/drm/i915/i915_perf.c:211:3: warning: ignoring return value of 
'copy_to_user', declared with attribute warn_unused_result [-Wunused-result]
  copy_to_user(read_state->buf, report, report_size);
  ^

vim +199 drivers/gpu/drm/i915/i915_perf.c

   149  {
   150  struct drm_i915_perf_event_header header = { type, 0, 
sizeof(header) };
   151  
   152  if ((read_state->count - read_state->read) < header.size)
   153  return false;
   154  
 > 155  copy_to_user(read_state->buf, , sizeof(header));
   156  
   157  read_state->buf += sizeof(header);
   158  read_state->read += header.size;
   159  
   160  return true;
   161  }
   162  
   163  static bool append_oa_sample(struct i915_perf_event *event,
   164   struct i915_perf_read_state *read_state,
   165   const u8 *report)
   166  {
   167  struct drm_i915_private *dev_priv = event->dev_priv;
   168  int report_size = dev_priv->perf.oa.oa_buffer.format_size;
   169  struct drm_i915_perf_event_header header;
   170  u32 sample_flags = event->sample_flags;
   171  u32 dummy_ctx_id = 0;
   172  u32 dummy_timestamp = 0;
   173  
   174  header.type = DRM_I915_PERF_RECORD_SAMPLE;
   175  header.misc = 0;
   176  header.size = sizeof(header);
   177  
   178  
   179  /* XXX: could pre-compute this when opening the event... */
   180  
   181  if (sample_flags & I915_PERF_SAMPLE_CTXID)
   182  header.size += 4;
   183  
   184  if (sample_flags & I915_PERF_SAMPLE_TIMESTAMP)
   185  header.size += 4;
   186  
   187  if (sample_flags & I915_PERF_SAMPLE_OA_REPORT)
   188  header.size += report_size;
   189  
   190  
   191  if ((read_state->count - read_state->read) < header.size)
   192  return false;
   193  
   194  
   195  copy_to_user(read_state->buf, , sizeof(header));
   196  read_state->buf += sizeof(header);
   197  
   198  if (sample_flags & I915_PERF_SAMPLE_CTXID) {
 > 199  #warning "fixme: extract context ID from OA reports"
   200  copy_to_user(read_state->buf, _ctx_id, 4);
   201  read_state->buf += 4;
   202  }
   203  
   204  if (sample_flags & I915_PERF_SAMPLE_TIMESTAMP) {
 > 205  #warning "fixme: extract timestamp from OA reports"
   206  copy_to_user(read_state->buf, _timestamp, 4);
   207  read_state->buf += 4;
   208  }

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
-- next part --
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 23761 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150929/d423ad00/attachment-0001.obj>


[Bug 84500] [radeonsi] radeon 0000:01:00.0: Packet0 not allowed!

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=84500

--- Comment #54 from Chernovsky Oleg  ---

> Great! You are the guy who also did the fan control patches aren't you?

Yep, that's me, thanks!
I also stalkered Michel Dänzer for explanations of GTT and VMM at some time :)

> As first step please try to catch an apitrace of it.
> 
> If that doesn't work and you still want to get your hands dirty with the
> code again contact me by mail (christian.koenig at amd.com) and we can discuss
> how to dig deeper into this issue.
> 
> Best regards,
> Christian.

Will do on weekend and mail you about results.

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


[Bug 90263] GPU card fans run full speed at all times

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=90263

--- Comment #20 from Chernovsky Oleg  ---
(In reply to Todd from comment #19)
> St. Petersburg USA or Russia?

Russia.

P.S. If you're thinking about parcel, forget it, post service here is horrible.
I asked local LUG for PITCAIRN GPU last time and can do it once more for BARTS.

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


[Bug 92184] Many piglit assertion failures in radeon_unmap_renderbuffer

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92184

Bug ID: 92184
   Summary: Many piglit assertion failures in
radeon_unmap_renderbuffer
   Product: Mesa
   Version: git
  Hardware: Other
OS: All
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/DRI/R100
  Assignee: dri-devel at lists.freedesktop.org
  Reporter: idr at freedesktop.org
QA Contact: dri-devel at lists.freedesktop.org

While doing other things, I noticed quite a few piglit tests crashing with

radeon_fbo.c:454: radeon_unmap_renderbuffer: Assertion `ok' failed.

This occurs when r100_blit fails.  Just skimming the code, there are a LOT of
reasons that r100_blit could return false, so it seems like there should be
some fallback path.  Some (perhaps all?) of the failures also log

WRITE DOMAIN RELOC FAILURE 0x1 6 4

Some tests that fail in this manner are:

bin/fbo-depthstencil copypixels default_fb -auto
bin/stencil-drawpixels -auto
bin/texsubimage -auto
bin/tex3d-depth1 -auto -fbo

There are many others.  On my last run there were 39 crashes (out of 1072 tests
not skipped), and most of those seem to be this assertion.

If it matters, this was on:

Linux grundgetta.home 4.1.6-201.fc22.x86_64 #1 SMP Fri Sep 4 17:49:24 UTC 2015
x86_64 x86_64 x86_64 GNU/Linux

00:01.0 PCI bridge [0604]: Intel Corporation 82865G/PE/P AGP Bridge [8086:2571]
(rev 02)
01:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc.
[AMD/ATI] RV200 [Radeon 7500/7500 LE] [1002:5157]

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


[regression] [git pull] drm for 4.3

2015-09-29 Thread da...@codemonkey.org.uk
On Thu, Sep 24, 2015 at 04:26:28PM +0300, Jani Nikula wrote:
 > On Thu, 24 Sep 2015, "davej at codemonkey.org.uk"  codemonkey.org.uk> wrote:
 > > On Wed, Sep 23, 2015 at 11:07:56AM +, Lankhorst, Maarten wrote:
 > >  > Hey,
 > >  > 
 > >  > Dave Jones schreef op di 22-09-2015 om 21:49 [-0400]:
 > >  > > On Tue, Sep 22, 2015 at 09:15:58AM -0700, Matt Roper wrote:
 > >  > >  > On Tue, Sep 22, 2015 at 05:13:55PM +0200, Daniel Vetter wrote:
 > >  > >  > > On Tue, Sep 22, 2015 at 08:00:17AM -0700, Jesse Barnes wrote:
 > >  > >  > > > Cc'ing Maarten and Matt; I'm guessing this may be related to 
 > > one of
 > >  > >  > > > their recent patches.
 > >  > >  > 
 > >  > >  > Sounds like this showed up before my recent work, but I think I 
 > > might
 > >  > >  > have seen similar problems while working on atomic watermarks; the
 > >  > >  > issues I was seeing were because the initial hardware readout could
 > >  > >  > leave primary->visible set to true even when the CRTC was off.  My
 > >  > >  > series (which is still under development) contains this patch to 
 > > fix
 > >  > >  > that:
 > >  > >  > 
 > >  > >  > http://patchwork.freedesktop.org/patch/59564/
 > >  > >  > 
 > >  > >  > Does applying that help with the problems reported here?
 > >  > > 
 > >  > > No difference at all for me.
 > >  > Looks like a (reopened) dup of 91952?
 > >  > 
 > >  > Can you apply "[PATCH] drm/i915: Add primary plane to mask if it's
 > >  > visible", and get me the results?
 > >
 > > This doesn't apply on top of Linus' current tree.
 > > If you let me know what it's dependant on, I'll do a build with
 > > those patches tomorrow.
 > 
 > It's now part of the drm-intel-fixes pull request [1], maybe it's
 > easiest to pull that in? Just four commits on top of
 > v4.3-rc2. Alternatively pick it up from our repo [2].

The warning on boot seems to be gone as of rc3, but I can now trigger this 
pretty easily..

WARNING: CPU: 2 PID: 28911 at drivers/gpu/drm/drm_atomic.c:889 
drm_atomic_get_property+0x244/0x2d0()
CPU: 2 PID: 28911 Comm: trinity-c313 Not tainted 4.3.0-rc3-think+ #14
 0379 8801a1377c88 8e35d5ec 
 8801a1377cc0 8e07a862 880500b392b8 880500a13008
 880500b39290 8804fe3806d8 88003fa45668 8801a1377cd0
Call Trace:
 [] dump_stack+0x4e/0x82
 [] warn_slowpath_common+0x82/0xc0
 [] warn_slowpath_null+0x1a/0x20
 [] drm_atomic_get_property+0x244/0x2d0
 [] drm_object_property_get_value+0x6c/0x70
 [] dpms_show+0x2f/0x70
 [] dev_attr_show+0x20/0x50
 [] ? sysfs_file_ops+0x41/0x60
 [] sysfs_kf_seq_show+0xb7/0x110
 [] kernfs_seq_show+0x26/0x30
 [] seq_read+0xe6/0x430
 [] kernfs_fop_read+0x127/0x170
 [] ? mutex_lock_nested+0x26b/0x3f0
 [] __vfs_read+0x28/0xe0
 [] ? mutex_lock_nested+0x287/0x3f0
 [] ? __fdget_pos+0x49/0x50
 [] ? __fdget_pos+0x49/0x50
 [] vfs_read+0x86/0x130
 [] SyS_read+0x49/0xb0
 [] entry_SYSCALL_64_fastpath+0x12/0x6f
---[ end trace e053063c697a1355 ]---

 887 case DRM_MODE_OBJECT_CONNECTOR: {
 888 struct drm_connector *connector = obj_to_connector(obj);
 889 
WARN_ON(!drm_modeset_is_locked(>mode_config.connection_mutex));
 890 ret = drm_atomic_connector_get_property(connector,
 891 connector->state, property, val);
 892 break;
 893 }



[Bug 91278] Tonga GPU lock/reset fail with Unigine Valley

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=91278

--- Comment #16 from Mathias Tillman  ---
(In reply to Alex Deucher from comment #15)
> These patches may help:
> http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150928/302380.html
> http://lists.freedesktop.org/archives/mesa-dev/2015-September/095718.html
Afraid not, applied both of them and it still hangs. One interesting thing is
that I was using mesa from the oibaf ppa which compiles against llvm 3.6. While
using that I haven't been able to replay my apitrace of valley once - it always
hangs before it finishes. However, I compiled mesa against llvm 3.7 (one
compiled from source with the patch, and one from llvm's apt repository) and
3.8, and it gets much further now - I've been able to replay the trace three
times without a hang, though it does ultimately hang unfortunately.

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


[PATCH 11/11] drm/i2c: tda998x: clean up after struct tda998x_priv2 removal

2015-09-29 Thread Russell King
We can now kill a number of glue functions which were sitting between
the common tda998x code and the drm encoder/connector methods.  This
results in slightly cleaner code.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 80 +++
 1 file changed, 22 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 8bca9155ee18..896b6aaf8c4d 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -54,6 +54,12 @@ struct tda998x_priv {
struct drm_connector connector;
 };

+#define conn_to_tda998x_priv(x) \
+   container_of(x, struct tda998x_priv, connector)
+
+#define enc_to_tda998x_priv(x) \
+   container_of(x, struct tda998x_priv, encoder)
+
 /* The TDA9988 series of devices use a paged register scheme.. to simplify
  * things we encode the page # in upper bits of the register #.  To read/
  * write a given register, we need to make sure CURPAGE register is set
@@ -562,7 +568,7 @@ tda998x_reset(struct tda998x_priv *priv)
  * trying to read EDID data.
  *
  * However, tda998x_encoder_get_modes() may be called at any moment
- * after tda998x_encoder_detect() indicates that we are connected, so
+ * after tda998x_connector_detect() indicates that we are connected, so
  * we need to delay probing modes in tda998x_encoder_get_modes() after
  * we have seen a HPD inactive->active transition.  This code implements
  * that delay.
@@ -816,8 +822,10 @@ static void tda998x_encoder_set_config(struct tda998x_priv 
*priv,
priv->params = *p;
 }

-static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
+static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
 {
+   struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
+
/* we only care about on or off: */
if (mode != DRM_MODE_DPMS_ON)
mode = DRM_MODE_DPMS_OFF;
@@ -867,8 +875,8 @@ tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
return true;
 }

-static int tda998x_encoder_mode_valid(struct tda998x_priv *priv,
- struct drm_display_mode *mode)
+static int tda998x_connector_mode_valid(struct drm_connector *connector,
+   struct drm_display_mode *mode)
 {
if (mode->clock > 15)
return MODE_CLOCK_HIGH;
@@ -880,10 +888,11 @@ static int tda998x_encoder_mode_valid(struct tda998x_priv 
*priv,
 }

 static void
-tda998x_encoder_mode_set(struct tda998x_priv *priv,
+tda998x_encoder_mode_set(struct drm_encoder *encoder,
 struct drm_display_mode *mode,
 struct drm_display_mode *adjusted_mode)
 {
+   struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
u16 ref_pix, ref_line, n_pix, n_line;
u16 hs_pix_s, hs_pix_e;
u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e;
@@ -1071,8 +1080,9 @@ tda998x_encoder_mode_set(struct tda998x_priv *priv,
 }

 static enum drm_connector_status
-tda998x_encoder_detect(struct tda998x_priv *priv)
+tda998x_connector_detect(struct drm_connector *connector, bool force)
 {
+   struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
u8 val = cec_read(priv, REG_CEC_RXSHPDLEV);

return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected :
@@ -1135,10 +1145,9 @@ static int read_edid_block(void *data, u8 *buf, unsigned 
int blk, size_t length)
return 0;
 }

-static int
-tda998x_encoder_get_modes(struct tda998x_priv *priv,
- struct drm_connector *connector)
+static int tda998x_connector_get_modes(struct drm_connector *connector)
 {
+   struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
struct edid *edid;
int n;

@@ -1330,46 +1339,24 @@ static int tda998x_create(struct i2c_client *client, 
struct tda998x_priv *priv)
return -ENXIO;
 }

-#define conn_to_tda998x_priv(x) \
-   container_of(x, struct tda998x_priv, connector);
-
-#define enc_to_tda998x_priv(x) \
-   container_of(x, struct tda998x_priv, encoder);
-
-static void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode)
-{
-   struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
-
-   tda998x_encoder_dpms(priv, mode);
-}
-
 static void tda998x_encoder_prepare(struct drm_encoder *encoder)
 {
-   tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_OFF);
+   tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 }

 static void tda998x_encoder_commit(struct drm_encoder *encoder)
 {
-   tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static void tda998x_encoder2_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
-   struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
-
-   

[PATCH 10/11] drm/i2c: tda998x: kill struct tda998x_priv2

2015-09-29 Thread Russell King
Kill the redundant tda998x_priv2 structure now that its only member is
the struct tda998x_priv.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 80 +++
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index a2a463cec244..8bca9155ee18 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1330,21 +1330,17 @@ static int tda998x_create(struct i2c_client *client, 
struct tda998x_priv *priv)
return -ENXIO;
 }

-struct tda998x_priv2 {
-   struct tda998x_priv base;
-};
-
-#define conn_to_tda998x_priv2(x) \
-   container_of(x, struct tda998x_priv2, base.connector);
+#define conn_to_tda998x_priv(x) \
+   container_of(x, struct tda998x_priv, connector);

-#define enc_to_tda998x_priv2(x) \
-   container_of(x, struct tda998x_priv2, base.encoder);
+#define enc_to_tda998x_priv(x) \
+   container_of(x, struct tda998x_priv, encoder);

 static void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode)
 {
-   struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
+   struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);

-   tda998x_encoder_dpms(>base, mode);
+   tda998x_encoder_dpms(priv, mode);
 }

 static void tda998x_encoder_prepare(struct drm_encoder *encoder)
@@ -1361,9 +1357,9 @@ static void tda998x_encoder2_mode_set(struct drm_encoder 
*encoder,
  struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode)
 {
-   struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
+   struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);

-   tda998x_encoder_mode_set(>base, mode, adjusted_mode);
+   tda998x_encoder_mode_set(priv, mode, adjusted_mode);
 }

 static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = {
@@ -1378,9 +1374,9 @@ static const struct drm_encoder_helper_funcs 
tda998x_encoder_helper_funcs = {

 static void tda998x_encoder_destroy(struct drm_encoder *encoder)
 {
-   struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
+   struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);

-   tda998x_destroy(>base);
+   tda998x_destroy(priv);
drm_encoder_cleanup(encoder);
 }

@@ -1390,25 +1386,25 @@ static const struct drm_encoder_funcs 
tda998x_encoder_funcs = {

 static int tda998x_connector_get_modes(struct drm_connector *connector)
 {
-   struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+   struct tda998x_priv *priv = conn_to_tda998x_priv(connector);

-   return tda998x_encoder_get_modes(>base, connector);
+   return tda998x_encoder_get_modes(priv, connector);
 }

 static int tda998x_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+   struct tda998x_priv *priv = conn_to_tda998x_priv(connector);

-   return tda998x_encoder_mode_valid(>base, mode);
+   return tda998x_encoder_mode_valid(priv, mode);
 }

 static struct drm_encoder *
 tda998x_connector_best_encoder(struct drm_connector *connector)
 {
-   struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+   struct tda998x_priv *priv = conn_to_tda998x_priv(connector);

-   return >base.encoder;
+   return >encoder;
 }

 static
@@ -1421,9 +1417,9 @@ const struct drm_connector_helper_funcs 
tda998x_connector_helper_funcs = {
 static enum drm_connector_status
 tda998x_connector_detect(struct drm_connector *connector, bool force)
 {
-   struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+   struct tda998x_priv *priv = conn_to_tda998x_priv(connector);

-   return tda998x_encoder_detect(>base);
+   return tda998x_encoder_detect(priv);
 }

 static void tda998x_connector_destroy(struct drm_connector *connector)
@@ -1444,7 +1440,7 @@ static int tda998x_bind(struct device *dev, struct device 
*master, void *data)
struct tda998x_encoder_params *params = dev->platform_data;
struct i2c_client *client = to_i2c_client(dev);
struct drm_device *drm = data;
-   struct tda998x_priv2 *priv;
+   struct tda998x_priv *priv;
u32 crtcs = 0;
int ret;

@@ -1463,58 +1459,58 @@ static int tda998x_bind(struct device *dev, struct 
device *master, void *data)
crtcs = 1 << 0;
}

-   priv->base.connector.interlace_allowed = 1;
-   priv->base.encoder.possible_crtcs = crtcs;
+   priv->connector.interlace_allowed = 1;
+   priv->encoder.possible_crtcs = crtcs;

-   ret = tda998x_create(client, >base);
+   ret = tda998x_create(client, priv);
if (ret)
return ret;

if (!dev->of_node && params)
-   

[PATCH 09/11] drm/i2c: tda998x: move connector into struct tda998x_priv

2015-09-29 Thread Russell King
Move the DRM connector structure into struct tda998x_priv from the old
struct tda998x_priv2.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index e30a2a8c2a3c..a2a463cec244 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -51,6 +51,7 @@ struct tda998x_priv {
bool edid_delay_active;

struct drm_encoder encoder;
+   struct drm_connector connector;
 };

 /* The TDA9988 series of devices use a paged register scheme.. to simplify
@@ -1331,11 +1332,10 @@ static int tda998x_create(struct i2c_client *client, 
struct tda998x_priv *priv)

 struct tda998x_priv2 {
struct tda998x_priv base;
-   struct drm_connector connector;
 };

 #define conn_to_tda998x_priv2(x) \
-   container_of(x, struct tda998x_priv2, connector);
+   container_of(x, struct tda998x_priv2, base.connector);

 #define enc_to_tda998x_priv2(x) \
container_of(x, struct tda998x_priv2, base.encoder);
@@ -1463,7 +1463,7 @@ static int tda998x_bind(struct device *dev, struct device 
*master, void *data)
crtcs = 1 << 0;
}

-   priv->connector.interlace_allowed = 1;
+   priv->base.connector.interlace_allowed = 1;
priv->base.encoder.possible_crtcs = crtcs;

ret = tda998x_create(client, >base);
@@ -1473,7 +1473,7 @@ static int tda998x_bind(struct device *dev, struct device 
*master, void *data)
if (!dev->of_node && params)
tda998x_encoder_set_config(>base, params);

-   tda998x_encoder_set_polling(>base, >connector);
+   tda998x_encoder_set_polling(>base, >base.connector);

drm_encoder_helper_add(>base.encoder, 
_encoder_helper_funcs);
ret = drm_encoder_init(drm, >base.encoder, _encoder_funcs,
@@ -1481,25 +1481,25 @@ static int tda998x_bind(struct device *dev, struct 
device *master, void *data)
if (ret)
goto err_encoder;

-   drm_connector_helper_add(>connector,
+   drm_connector_helper_add(>base.connector,
 _connector_helper_funcs);
-   ret = drm_connector_init(drm, >connector,
+   ret = drm_connector_init(drm, >base.connector,
 _connector_funcs,
 DRM_MODE_CONNECTOR_HDMIA);
if (ret)
goto err_connector;

-   ret = drm_connector_register(>connector);
+   ret = drm_connector_register(>base.connector);
if (ret)
goto err_sysfs;

-   priv->connector.encoder = >base.encoder;
-   drm_mode_connector_attach_encoder(>connector, 
>base.encoder);
+   priv->base.connector.encoder = >base.encoder;
+   drm_mode_connector_attach_encoder(>base.connector, 
>base.encoder);

return 0;

 err_sysfs:
-   drm_connector_cleanup(>connector);
+   drm_connector_cleanup(>base.connector);
 err_connector:
drm_encoder_cleanup(>base.encoder);
 err_encoder:
@@ -1512,7 +1512,7 @@ static void tda998x_unbind(struct device *dev, struct 
device *master,
 {
struct tda998x_priv2 *priv = dev_get_drvdata(dev);

-   drm_connector_cleanup(>connector);
+   drm_connector_cleanup(>base.connector);
drm_encoder_cleanup(>base.encoder);
tda998x_destroy(>base);
 }
-- 
2.1.0



[PATCH 08/11] drm/i2c: tda998x: remove encoder pointer

2015-09-29 Thread Russell King
Remove the encoder pointer from struct tda998x_priv, moving the encoder
itself from struct tda998x_priv2 here.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 25 -
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 883025d35f87..e30a2a8c2a3c 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -44,12 +44,13 @@ struct tda998x_priv {

wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
-   struct drm_encoder *encoder;

struct work_struct detect_work;
struct timer_list edid_delay_timer;
wait_queue_head_t edid_delay_waitq;
bool edid_delay_active;
+
+   struct drm_encoder encoder;
 };

 /* The TDA9988 series of devices use a paged register scheme.. to simplify
@@ -594,7 +595,7 @@ static void tda998x_detect_work(struct work_struct *work)
 {
struct tda998x_priv *priv =
container_of(work, struct tda998x_priv, detect_work);
-   struct drm_device *dev = priv->encoder->dev;
+   struct drm_device *dev = priv->encoder.dev;

if (dev)
drm_kms_helper_hotplug_event(dev);
@@ -1330,7 +1331,6 @@ static int tda998x_create(struct i2c_client *client, 
struct tda998x_priv *priv)

 struct tda998x_priv2 {
struct tda998x_priv base;
-   struct drm_encoder encoder;
struct drm_connector connector;
 };

@@ -1338,7 +1338,7 @@ struct tda998x_priv2 {
container_of(x, struct tda998x_priv2, connector);

 #define enc_to_tda998x_priv2(x) \
-   container_of(x, struct tda998x_priv2, encoder);
+   container_of(x, struct tda998x_priv2, base.encoder);

 static void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode)
 {
@@ -1408,7 +1408,7 @@ tda998x_connector_best_encoder(struct drm_connector 
*connector)
 {
struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);

-   return >encoder;
+   return >base.encoder;
 }

 static
@@ -1463,9 +1463,8 @@ static int tda998x_bind(struct device *dev, struct device 
*master, void *data)
crtcs = 1 << 0;
}

-   priv->base.encoder = >encoder;
priv->connector.interlace_allowed = 1;
-   priv->encoder.possible_crtcs = crtcs;
+   priv->base.encoder.possible_crtcs = crtcs;

ret = tda998x_create(client, >base);
if (ret)
@@ -1476,8 +1475,8 @@ static int tda998x_bind(struct device *dev, struct device 
*master, void *data)

tda998x_encoder_set_polling(>base, >connector);

-   drm_encoder_helper_add(>encoder, _encoder_helper_funcs);
-   ret = drm_encoder_init(drm, >encoder, _encoder_funcs,
+   drm_encoder_helper_add(>base.encoder, 
_encoder_helper_funcs);
+   ret = drm_encoder_init(drm, >base.encoder, _encoder_funcs,
   DRM_MODE_ENCODER_TMDS);
if (ret)
goto err_encoder;
@@ -1494,15 +1493,15 @@ static int tda998x_bind(struct device *dev, struct 
device *master, void *data)
if (ret)
goto err_sysfs;

-   priv->connector.encoder = >encoder;
-   drm_mode_connector_attach_encoder(>connector, >encoder);
+   priv->connector.encoder = >base.encoder;
+   drm_mode_connector_attach_encoder(>connector, 
>base.encoder);

return 0;

 err_sysfs:
drm_connector_cleanup(>connector);
 err_connector:
-   drm_encoder_cleanup(>encoder);
+   drm_encoder_cleanup(>base.encoder);
 err_encoder:
tda998x_destroy(>base);
return ret;
@@ -1514,7 +1513,7 @@ static void tda998x_unbind(struct device *dev, struct 
device *master,
struct tda998x_priv2 *priv = dev_get_drvdata(dev);

drm_connector_cleanup(>connector);
-   drm_encoder_cleanup(>encoder);
+   drm_encoder_cleanup(>base.encoder);
tda998x_destroy(>base);
 }

-- 
2.1.0



[PATCH 07/11] drm/i2c: tda998x: remove DRM slave encoder support

2015-09-29 Thread Russell King
Remove the DRM slave encoder compatibility from the TDA998x driver.  We
now use the component helpers to manage the binding of DRM sub-drivers.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 146 +++---
 1 file changed, 8 insertions(+), 138 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 1c6fc245514f..883025d35f87 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -23,7 +23,6 @@

 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -53,8 +52,6 @@ struct tda998x_priv {
bool edid_delay_active;
 };

-#define to_tda998x_priv(x)  ((struct tda998x_priv 
*)to_encoder_slave(x)->slave_priv)
-
 /* The TDA9988 series of devices use a paged register scheme.. to simplify
  * things we encode the page # in upper bits of the register #.  To read/
  * write a given register, we need to make sure CURPAGE register is set
@@ -1182,16 +1179,6 @@ static void tda998x_encoder_set_polling(struct 
tda998x_priv *priv,
DRM_CONNECTOR_POLL_DISCONNECT;
 }

-static int
-tda998x_encoder_set_property(struct drm_encoder *encoder,
-   struct drm_connector *connector,
-   struct drm_property *property,
-   uint64_t val)
-{
-   DBG("");
-   return 0;
-}
-
 static void tda998x_destroy(struct tda998x_priv *priv)
 {
/* disable all IRQs and free the IRQ handler */
@@ -1207,78 +1194,6 @@ static void tda998x_destroy(struct tda998x_priv *priv)
i2c_unregister_device(priv->cec);
 }

-/* Slave encoder support */
-
-static void
-tda998x_encoder_slave_set_config(struct drm_encoder *encoder, void *params)
-{
-   tda998x_encoder_set_config(to_tda998x_priv(encoder), params);
-}
-
-static void tda998x_encoder_slave_destroy(struct drm_encoder *encoder)
-{
-   struct tda998x_priv *priv = to_tda998x_priv(encoder);
-
-   tda998x_destroy(priv);
-   drm_i2c_encoder_destroy(encoder);
-   kfree(priv);
-}
-
-static void tda998x_encoder_slave_dpms(struct drm_encoder *encoder, int mode)
-{
-   tda998x_encoder_dpms(to_tda998x_priv(encoder), mode);
-}
-
-static int tda998x_encoder_slave_mode_valid(struct drm_encoder *encoder,
-   struct drm_display_mode *mode)
-{
-   return tda998x_encoder_mode_valid(to_tda998x_priv(encoder), mode);
-}
-
-static void
-tda998x_encoder_slave_mode_set(struct drm_encoder *encoder,
-  struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode)
-{
-   tda998x_encoder_mode_set(to_tda998x_priv(encoder), mode, adjusted_mode);
-}
-
-static enum drm_connector_status
-tda998x_encoder_slave_detect(struct drm_encoder *encoder,
-struct drm_connector *connector)
-{
-   return tda998x_encoder_detect(to_tda998x_priv(encoder));
-}
-
-static int tda998x_encoder_slave_get_modes(struct drm_encoder *encoder,
-  struct drm_connector *connector)
-{
-   return tda998x_encoder_get_modes(to_tda998x_priv(encoder), connector);
-}
-
-static int
-tda998x_encoder_slave_create_resources(struct drm_encoder *encoder,
-  struct drm_connector *connector)
-{
-   tda998x_encoder_set_polling(to_tda998x_priv(encoder), connector);
-   return 0;
-}
-
-static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = {
-   .set_config = tda998x_encoder_slave_set_config,
-   .destroy = tda998x_encoder_slave_destroy,
-   .dpms = tda998x_encoder_slave_dpms,
-   .save = tda998x_encoder_save,
-   .restore = tda998x_encoder_restore,
-   .mode_fixup = tda998x_encoder_mode_fixup,
-   .mode_valid = tda998x_encoder_slave_mode_valid,
-   .mode_set = tda998x_encoder_slave_mode_set,
-   .detect = tda998x_encoder_slave_detect,
-   .get_modes = tda998x_encoder_slave_get_modes,
-   .create_resources = tda998x_encoder_slave_create_resources,
-   .set_property = tda998x_encoder_set_property,
-};
-
 /* I2C driver functions */

 static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
@@ -1413,31 +1328,6 @@ static int tda998x_create(struct i2c_client *client, 
struct tda998x_priv *priv)
return -ENXIO;
 }

-static int tda998x_encoder_init(struct i2c_client *client,
-   struct drm_device *dev,
-   struct drm_encoder_slave *encoder_slave)
-{
-   struct tda998x_priv *priv;
-   int ret;
-
-   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-   if (!priv)
-   return -ENOMEM;
-
-   priv->encoder = _slave->base;
-
-   ret = tda998x_create(client, priv);
-   if (ret) {
-   kfree(priv);
-   return ret;
-   }
-
-   

[PATCH 06/11] drm/i2c: tda998x: use more HDMI helpers

2015-09-29 Thread Russell King
Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 71 +--
 1 file changed, 31 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 1285fb354813..1c6fc245514f 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -640,66 +640,57 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
return IRQ_RETVAL(handled);
 }

-static u8 tda998x_cksum(u8 *buf, size_t bytes)
-{
-   int sum = 0;
-
-   while (bytes--)
-   sum -= *buf++;
-   return sum;
-}
-
-#define HB(x) (x)
-#define PB(x) (HB(2) + 1 + (x))
-
 static void
 tda998x_write_if(struct tda998x_priv *priv, u8 bit, u16 addr,
-u8 *buf, size_t size)
+union hdmi_infoframe *frame)
 {
+   u8 buf[32];
+   ssize_t len;
+
+   len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
+   if (len < 0) {
+   dev_err(>hdmi->dev,
+   "hdmi_infoframe_pack() type=0x%02x failed: %zd\n",
+   frame->any.type, len);
+   return;
+   }
+
reg_clear(priv, REG_DIP_IF_FLAGS, bit);
-   reg_write_range(priv, addr, buf, size);
+   reg_write_range(priv, addr, buf, len);
reg_set(priv, REG_DIP_IF_FLAGS, bit);
 }

 static void
 tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p)
 {
-   u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1];
+   union hdmi_infoframe frame;
+
+   hdmi_audio_infoframe_init();

-   memset(buf, 0, sizeof(buf));
-   buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO;
-   buf[HB(1)] = 0x01;
-   buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE;
-   buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */
-   buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */
-   buf[PB(4)] = p->audio_frame[4];
-   buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */
+   frame.audio.channels = p->audio_frame[1] & 0x07;
+   frame.audio.channel_allocation = p->audio_frame[4];
+   frame.audio.level_shift_value = (p->audio_frame[5] & 0x78) >> 3;
+   frame.audio.downmix_inhibit = (p->audio_frame[5] & 0x80) >> 7;

-   buf[PB(0)] = tda998x_cksum(buf, sizeof(buf));
+   /*
+* L-PCM and IEC61937 compressed audio shall always set sample
+* frequency to "refer to stream".  For others, see the HDMI
+* specification.
+*/
+   frame.audio.sample_frequency = (p->audio_frame[2] & 0x1c) >> 2;

-   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf,
-sizeof(buf));
+   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, );
 }

 static void
 tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
 {
-   struct hdmi_avi_infoframe frame;
-   u8 buf[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
-   ssize_t len;
-
-   drm_hdmi_avi_infoframe_from_display_mode(, mode);
+   union hdmi_infoframe frame;

-   frame.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
-
-   len = hdmi_avi_infoframe_pack(, buf, sizeof(buf));
-   if (len < 0) {
-   dev_err(>hdmi->dev,
-   "hdmi_avi_infoframe_pack() failed: %zd\n", len);
-   return;
-   }
+   drm_hdmi_avi_infoframe_from_display_mode(, mode);
+   frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;

-   tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, len);
+   tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, );
 }

 static void tda998x_audio_mute(struct tda998x_priv *priv, bool on)
-- 
2.1.0



[PATCH 05/11] drm/i2c: tda998x: handle all outstanding interrupts

2015-09-29 Thread Russell King
As reading the interrupt registers clears the outstanding interrupts, we
must process all received interrupts to avoid dropping any.  Rearrange
the code to achieve this, and properly check for a HPD interrupt from
the CEC_RXSHPDINT register.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 6d6aaadc0d2f..1285fb354813 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -330,6 +330,8 @@ struct tda998x_priv {
 # define CEC_FRO_IM_CLK_CTRL_FRO_DIV   (1 << 0)
 #define REG_CEC_RXSHPDINTENA 0xfc/* read/write */
 #define REG_CEC_RXSHPDINT0xfd/* read */
+# define CEC_RXSHPDINT_RXSENS BIT(0)
+# define CEC_RXSHPDINT_HPDBIT(1)
 #define REG_CEC_RXSHPDLEV 0xfe/* read */
 # define CEC_RXSHPDLEV_RXSENS (1 << 0)
 # define CEC_RXSHPDLEV_HPD(1 << 1)
@@ -619,11 +621,8 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
DRM_DEBUG_DRIVER(
"tda irq sta %02x cec %02x lvl %02x f0 %02x f1 %02x f2 %02x\n",
sta, cec, lvl, flag0, flag1, flag2);
-   if ((flag2 & INT_FLAGS_2_EDID_BLK_RD) && priv->wq_edid_wait) {
-   priv->wq_edid_wait = 0;
-   wake_up(>wq_edid);
-   handled = true;
-   } else if (cec != 0) {  /* HPD change */
+
+   if (cec & CEC_RXSHPDINT_HPD) {
if (lvl & CEC_RXSHPDLEV_HPD)
tda998x_edid_delay_start(priv);
else
@@ -631,6 +630,13 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)

handled = true;
}
+
+   if ((flag2 & INT_FLAGS_2_EDID_BLK_RD) && priv->wq_edid_wait) {
+   priv->wq_edid_wait = 0;
+   wake_up(>wq_edid);
+   handled = true;
+   }
+
return IRQ_RETVAL(handled);
 }

-- 
2.1.0



[PATCH 04/11] drm/i2c: tda998x: convert to u8/u16/u32 types

2015-09-29 Thread Russell King
C99 types are against the style of the Linux kernel.  Convert to using
Linus-friendly types.  See https://lwn.net/Articles/113367/ for more
information.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 74 +++
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index a53696fd8938..6d6aaadc0d2f 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -34,8 +34,8 @@ struct tda998x_priv {
struct i2c_client *cec;
struct i2c_client *hdmi;
struct mutex mutex;
-   uint16_t rev;
-   uint8_t current_page;
+   u16 rev;
+   u8 current_page;
int dpms;
bool is_hdmi_sink;
u8 vip_cntrl_0;
@@ -349,10 +349,10 @@ struct tda998x_priv {
 #define TDA19988  0x0301

 static void
-cec_write(struct tda998x_priv *priv, uint16_t addr, uint8_t val)
+cec_write(struct tda998x_priv *priv, u16 addr, u8 val)
 {
struct i2c_client *client = priv->cec;
-   uint8_t buf[] = {addr, val};
+   u8 buf[] = {addr, val};
int ret;

ret = i2c_master_send(client, buf, sizeof(buf));
@@ -360,11 +360,11 @@ cec_write(struct tda998x_priv *priv, uint16_t addr, 
uint8_t val)
dev_err(>dev, "Error %d writing to cec:0x%x\n", ret, 
addr);
 }

-static uint8_t
-cec_read(struct tda998x_priv *priv, uint8_t addr)
+static u8
+cec_read(struct tda998x_priv *priv, u8 addr)
 {
struct i2c_client *client = priv->cec;
-   uint8_t val;
+   u8 val;
int ret;

ret = i2c_master_send(client, , sizeof(addr));
@@ -383,11 +383,11 @@ cec_read(struct tda998x_priv *priv, uint8_t addr)
 }

 static int
-set_page(struct tda998x_priv *priv, uint16_t reg)
+set_page(struct tda998x_priv *priv, u16 reg)
 {
if (REG2PAGE(reg) != priv->current_page) {
struct i2c_client *client = priv->hdmi;
-   uint8_t buf[] = {
+   u8 buf[] = {
REG_CURPAGE, REG2PAGE(reg)
};
int ret = i2c_master_send(client, buf, sizeof(buf));
@@ -403,10 +403,10 @@ set_page(struct tda998x_priv *priv, uint16_t reg)
 }

 static int
-reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt)
+reg_read_range(struct tda998x_priv *priv, u16 reg, char *buf, int cnt)
 {
struct i2c_client *client = priv->hdmi;
-   uint8_t addr = REG2ADDR(reg);
+   u8 addr = REG2ADDR(reg);
int ret;

mutex_lock(>mutex);
@@ -432,10 +432,10 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, 
char *buf, int cnt)
 }

 static void
-reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt)
+reg_write_range(struct tda998x_priv *priv, u16 reg, u8 *p, int cnt)
 {
struct i2c_client *client = priv->hdmi;
-   uint8_t buf[cnt+1];
+   u8 buf[cnt+1];
int ret;

buf[0] = REG2ADDR(reg);
@@ -454,9 +454,9 @@ reg_write_range(struct tda998x_priv *priv, uint16_t reg, 
uint8_t *p, int cnt)
 }

 static int
-reg_read(struct tda998x_priv *priv, uint16_t reg)
+reg_read(struct tda998x_priv *priv, u16 reg)
 {
-   uint8_t val = 0;
+   u8 val = 0;
int ret;

ret = reg_read_range(priv, reg, , sizeof(val));
@@ -466,10 +466,10 @@ reg_read(struct tda998x_priv *priv, uint16_t reg)
 }

 static void
-reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val)
+reg_write(struct tda998x_priv *priv, u16 reg, u8 val)
 {
struct i2c_client *client = priv->hdmi;
-   uint8_t buf[] = {REG2ADDR(reg), val};
+   u8 buf[] = {REG2ADDR(reg), val};
int ret;

mutex_lock(>mutex);
@@ -485,10 +485,10 @@ reg_write(struct tda998x_priv *priv, uint16_t reg, 
uint8_t val)
 }

 static void
-reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val)
+reg_write16(struct tda998x_priv *priv, u16 reg, u16 val)
 {
struct i2c_client *client = priv->hdmi;
-   uint8_t buf[] = {REG2ADDR(reg), val >> 8, val};
+   u8 buf[] = {REG2ADDR(reg), val >> 8, val};
int ret;

mutex_lock(>mutex);
@@ -504,7 +504,7 @@ reg_write16(struct tda998x_priv *priv, uint16_t reg, 
uint16_t val)
 }

 static void
-reg_set(struct tda998x_priv *priv, uint16_t reg, uint8_t val)
+reg_set(struct tda998x_priv *priv, u16 reg, u8 val)
 {
int old_val;

@@ -514,7 +514,7 @@ reg_set(struct tda998x_priv *priv, uint16_t reg, uint8_t 
val)
 }

 static void
-reg_clear(struct tda998x_priv *priv, uint16_t reg, uint8_t val)
+reg_clear(struct tda998x_priv *priv, u16 reg, u8 val)
 {
int old_val;

@@ -634,7 +634,7 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
return IRQ_RETVAL(handled);
 }

-static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes)
+static u8 tda998x_cksum(u8 *buf, size_t bytes)
 {
int sum = 0;

@@ -647,8 +647,8 @@ static uint8_t 

[PATCH 03/11] drm/i2c: tda998x: re-implement "Fix EDID read timeout on HDMI connect"

2015-09-29 Thread Russell King
Commit 6833d26ef823 ("drm: tda998x: Fix EDID read timeout on HDMI
connect") used a weak scheme to try and delay reading EDID on a HDMI
connect event.  It is weak because delaying the notification of a
hotplug event does not stop userspace from trying to read the EDID
within the 100ms delay.

The solution provided here solves this issue:
* When a HDMI connection event is detected, mark a blocking flag for
  EDID reads, and start a timer for the delay.
* If an EDID read is attempted, and the blocking flag is set, wait
  for the blocking flag to clear.
* When the timer expires, clear the blocking flag and wake any thread
  waiting for the EDID read.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 80 +--
 1 file changed, 68 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index ad3ce3479edf..a53696fd8938 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -34,7 +34,6 @@ struct tda998x_priv {
struct i2c_client *cec;
struct i2c_client *hdmi;
struct mutex mutex;
-   struct delayed_work dwork;
uint16_t rev;
uint8_t current_page;
int dpms;
@@ -47,6 +46,11 @@ struct tda998x_priv {
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
+
+   struct work_struct detect_work;
+   struct timer_list edid_delay_timer;
+   wait_queue_head_t edid_delay_waitq;
+   bool edid_delay_active;
 };

 #define to_tda998x_priv(x)  ((struct tda998x_priv 
*)to_encoder_slave(x)->slave_priv)
@@ -551,15 +555,50 @@ tda998x_reset(struct tda998x_priv *priv)
reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24);
 }

-/* handle HDMI connect/disconnect */
-static void tda998x_hpd(struct work_struct *work)
+/*
+ * The TDA998x has a problem when trying to read the EDID close to a
+ * HPD assertion: it needs a delay of 100ms to avoid timing out while
+ * trying to read EDID data.
+ *
+ * However, tda998x_encoder_get_modes() may be called at any moment
+ * after tda998x_encoder_detect() indicates that we are connected, so
+ * we need to delay probing modes in tda998x_encoder_get_modes() after
+ * we have seen a HPD inactive->active transition.  This code implements
+ * that delay.
+ */
+static void tda998x_edid_delay_done(unsigned long data)
+{
+   struct tda998x_priv *priv = (struct tda998x_priv *)data;
+
+   priv->edid_delay_active = false;
+   wake_up(>edid_delay_waitq);
+   schedule_work(>detect_work);
+}
+
+static void tda998x_edid_delay_start(struct tda998x_priv *priv)
+{
+   priv->edid_delay_active = true;
+   mod_timer(>edid_delay_timer, jiffies + HZ/10);
+}
+
+static int tda998x_edid_delay_wait(struct tda998x_priv *priv)
+{
+   return wait_event_killable(priv->edid_delay_waitq, 
!priv->edid_delay_active);
+}
+
+/*
+ * We need to run the KMS hotplug event helper outside of our threaded
+ * interrupt routine as this can call back into our get_modes method,
+ * which will want to make use of interrupts.
+ */
+static void tda998x_detect_work(struct work_struct *work)
 {
-   struct delayed_work *dwork = to_delayed_work(work);
struct tda998x_priv *priv =
-   container_of(dwork, struct tda998x_priv, dwork);
+   container_of(work, struct tda998x_priv, detect_work);
+   struct drm_device *dev = priv->encoder->dev;

-   if (priv->encoder->dev)
-   drm_kms_helper_hotplug_event(priv->encoder->dev);
+   if (dev)
+   drm_kms_helper_hotplug_event(dev);
 }

 /*
@@ -585,7 +624,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
wake_up(>wq_edid);
handled = true;
} else if (cec != 0) {  /* HPD change */
-   schedule_delayed_work(>dwork, HZ/10);
+   if (lvl & CEC_RXSHPDLEV_HPD)
+   tda998x_edid_delay_start(priv);
+   else
+   schedule_work(>detect_work);
+
handled = true;
}
return IRQ_RETVAL(handled);
@@ -1103,6 +1146,14 @@ tda998x_encoder_get_modes(struct tda998x_priv *priv,
struct edid *edid;
int n;

+   /*
+* If we get killed while waiting for the HPD timeout, return
+* no modes found: we are not in a restartable path, so we
+* can't handle signals gracefully.
+*/
+   if (tda998x_edid_delay_wait(priv))
+   return 0;
+
if (priv->rev == TDA19988)
reg_clear(priv, REG_TX4, TX4_PD_RAM);

@@ -1149,10 +1200,12 @@ static void tda998x_destroy(struct tda998x_priv *priv)
/* disable all IRQs and free the IRQ handler */
cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
-   if (priv->hdmi->irq) {
+
+   if 

[PATCH 02/11] drm/i2c: tda998x: report whether we actually handled the IRQ

2015-09-29 Thread Russell King
Rather than always reporting that the interrupt was handled, we should
report whether we did handle the interrupt.  Arrange to report IRQ_NONE
for cases where we found nothing to do.

This allows us to (eventually) recover from stuck-IRQ problems, rather
than causing the kernel to solidly lock up.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index d8e97085f866..ad3ce3479edf 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -569,6 +569,7 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
 {
struct tda998x_priv *priv = data;
u8 sta, cec, lvl, flag0, flag1, flag2;
+   bool handled = false;

sta = cec_read(priv, REG_CEC_INTSTATUS);
cec = cec_read(priv, REG_CEC_RXSHPDINT);
@@ -582,10 +583,12 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
if ((flag2 & INT_FLAGS_2_EDID_BLK_RD) && priv->wq_edid_wait) {
priv->wq_edid_wait = 0;
wake_up(>wq_edid);
+   handled = true;
} else if (cec != 0) {  /* HPD change */
schedule_delayed_work(>dwork, HZ/10);
+   handled = true;
}
-   return IRQ_HANDLED;
+   return IRQ_RETVAL(handled);
 }

 static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes)
-- 
2.1.0



[PATCH 01/11] drm/i2c: tda998x: remove useless NULL checks

2015-09-29 Thread Russell King
There is no way 'priv' can be NULL in tda998x_irq_thread() - this can
only happen if request_threaded_irq() was passed a NULL priv pointer,
and we would have crashed long before then if that was the case.

We also always ensure that priv->encoder is correctly setup, which
must have been initialised prior to the interrupt being claimed, so we
can remove this check as well.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 424228be79ae..d8e97085f866 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -558,7 +558,7 @@ static void tda998x_hpd(struct work_struct *work)
struct tda998x_priv *priv =
container_of(dwork, struct tda998x_priv, dwork);

-   if (priv->encoder && priv->encoder->dev)
+   if (priv->encoder->dev)
drm_kms_helper_hotplug_event(priv->encoder->dev);
 }

@@ -570,8 +570,6 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
struct tda998x_priv *priv = data;
u8 sta, cec, lvl, flag0, flag1, flag2;

-   if (!priv)
-   return IRQ_HANDLED;
sta = cec_read(priv, REG_CEC_INTSTATUS);
cec = cec_read(priv, REG_CEC_RXSHPDINT);
lvl = cec_read(priv, REG_CEC_RXSHPDLEV);
-- 
2.1.0



[PATCH 00/11] tda998x updates

2015-09-29 Thread Russell King - ARM Linux
Hi,

Here's my currently queued TDA998x development work for 4.4.

* Remove some useless NULL checks here variables can't be NULL.
* Return IRQ_HANDLED only if we handled the IRQ, otherwise return
  IRQ_NONE.  This avoids locking the system up if the IRQ gets stuck.
* Re-implement a previous patch "Fix EDID read timeout on HDMI connect"
  to be much more reliable: an attempt to read the EDID may come in
  while we're delaying the HPD detect event, violating the critical
  pause.
* Use Linux types rather than C99 types.
* Handle all outstanding interrupts, rather than only the first
  interrupt that we discover pending.
* Use more helpers from drivers/video/hdmi.c - this removes our own
  infoframe checksumming code.
* Remove DRM slave encoder support (which I think no one is using
  anymore.)  This allows other tidy-ups, removing the abstractions
  to allow slave encoder support to co-exist with component support.

 drivers/gpu/drm/i2c/tda998x_drv.c | 487 +++---
 1 file changed, 185 insertions(+), 302 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.


[PATCH 20/20] drm/armada: move frame wait wakeup into plane work

2015-09-29 Thread Russell King
Move the wakeup for the frame wait into the armada plane work, to
ensure that it is woken up every time we run a work.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 418dbfad4271..cebcab560626 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -201,6 +201,8 @@ static void armada_drm_plane_work_run(struct armada_crtc 
*dcrtc,
work->fn(dcrtc, plane, work);
drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
}
+
+   wake_up(>frame_wait);
 }

 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
@@ -415,7 +417,6 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, 
u32 stat)
if (ovl_plane) {
struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
armada_drm_plane_work_run(dcrtc, plane);
-   wake_up(>frame_wait);
}

if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
@@ -449,7 +450,6 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, 
u32 stat)
if (stat & GRA_FRAME_IRQ) {
struct armada_plane *plane = 
drm_to_armada_plane(dcrtc->crtc.primary);
armada_drm_plane_work_run(dcrtc, plane);
-   wake_up(>frame_wait);
}
 }

-- 
2.1.0



[PATCH 19/20] drm/armada: convert overlay plane vbl worker to a armada plane worker

2015-09-29 Thread Russell King
Convert the overlay plane to use the generic armada plane worker
infrastructure which is shared with the primary plane.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c| 48 +
 drivers/gpu/drm/armada/armada_crtc.h| 20 ++
 drivers/gpu/drm/armada/armada_overlay.c | 27 +--
 3 files changed, 26 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 0c1a1524f5d5..418dbfad4271 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -226,44 +226,15 @@ int armada_drm_plane_work_wait(struct armada_plane 
*plane, long timeout)
return wait_event_timeout(plane->frame_wait, !plane->work, timeout);
 }

-void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
-   struct armada_vbl_event *evt)
+struct armada_plane_work *armada_drm_plane_work_cancel(
+   struct armada_crtc *dcrtc, struct armada_plane *plane)
 {
-   unsigned long flags;
-   bool not_on_list;
-
-   WARN_ON(drm_vblank_get(dcrtc->crtc.dev, dcrtc->num));
-
-   spin_lock_irqsave(>irq_lock, flags);
-   not_on_list = list_empty(>node);
-   if (not_on_list)
-   list_add_tail(>node, >vbl_list);
-   spin_unlock_irqrestore(>irq_lock, flags);
+   struct armada_plane_work *work = xchg(>work, NULL);

-   if (!not_on_list)
+   if (work)
drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-}

-void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
-   struct armada_vbl_event *evt)
-{
-   spin_lock_irq(>irq_lock);
-   if (!list_empty(>node)) {
-   list_del_init(>node);
-   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-   }
-   spin_unlock_irq(>irq_lock);
-}
-
-static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
-{
-   struct armada_vbl_event *e, *n;
-
-   list_for_each_entry_safe(e, n, >vbl_list, node) {
-   list_del_init(>node);
-   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-   e->fn(dcrtc, e->data);
-   }
+   return work;
 }

 static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
@@ -429,6 +400,7 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc 
*crtc,
 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
void __iomem *base = dcrtc->base;
+   struct drm_plane *ovl_plane;

if (stat & DMA_FF_UNDERFLOW)
DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
@@ -439,7 +411,12 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, 
u32 stat)
drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);

spin_lock(>irq_lock);
-   armada_drm_vbl_event_run(dcrtc);
+   ovl_plane = dcrtc->plane;
+   if (ovl_plane) {
+   struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
+   armada_drm_plane_work_run(dcrtc, plane);
+   wake_up(>frame_wait);
+   }

if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
@@ -1188,7 +1165,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, 
struct device *dev,
dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
spin_lock_init(>irq_lock);
dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
-   INIT_LIST_HEAD(>vbl_list);

/* Initialize some registers which we don't otherwise set */
writel_relaxed(0x0001, dcrtc->base + LCD_CFG_SCLK_DIV);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h 
b/drivers/gpu/drm/armada/armada_crtc.h
index aaad5ab78673..04fdd22d483b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -52,6 +52,8 @@ int armada_drm_plane_init(struct armada_plane *plane);
 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
struct armada_plane *plane, struct armada_plane_work *work);
 int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
+struct armada_plane_work *armada_drm_plane_work_cancel(
+   struct armada_crtc *dcrtc, struct armada_plane *plane);

 struct armada_crtc {
struct drm_crtc crtc;
@@ -87,27 +89,9 @@ struct armada_crtc {

spinlock_t  irq_lock;
uint32_tirq_ena;
-   struct list_headvbl_list;
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)

-struct armada_vbl_event {
-   struct list_headnode;
-   void*data;
-   void(*fn)(struct armada_crtc *, void *);
-};
-
-void armada_drm_vbl_event_add(struct armada_crtc *,
-   struct armada_vbl_event *);
-void armada_drm_vbl_event_remove(struct armada_crtc *,
-   struct armada_vbl_event *);
-#define armada_drm_vbl_event_init(_e, _f, _d) do { \
-   struct 

[PATCH 18/20] drm/armada: move CRTC flip work to primary plane work

2015-09-29 Thread Russell King
Add a plane work implementation, and move the CRTC framebuffer flip
work to it for the primary plane.  The idea is to have a common
plane work implementation for both the primary and overlay planes.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 102 ---
 drivers/gpu/drm/armada/armada_crtc.h |  15 --
 2 files changed, 70 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 46d932bc7678..0c1a1524f5d5 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -20,6 +20,7 @@
 #include "armada_hw.h"

 struct armada_frame_work {
+   struct armada_plane_work work;
struct drm_pending_vblank_event *event;
struct armada_regs regs[4];
struct drm_framebuffer *old_fb;
@@ -190,6 +191,41 @@ static unsigned armada_drm_crtc_calc_fb(struct 
drm_framebuffer *fb,
return i;
 }

+static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
+   struct armada_plane *plane)
+{
+   struct armada_plane_work *work = xchg(>work, NULL);
+
+   /* Handle any pending frame work. */
+   if (work) {
+   work->fn(dcrtc, plane, work);
+   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+   }
+}
+
+int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
+   struct armada_plane *plane, struct armada_plane_work *work)
+{
+   int ret;
+
+   ret = drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
+   if (ret) {
+   DRM_ERROR("failed to acquire vblank counter\n");
+   return ret;
+   }
+
+   ret = cmpxchg(>work, NULL, work) ? -EBUSY : 0;
+   if (ret)
+   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+
+   return ret;
+}
+
+int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout)
+{
+   return wait_event_timeout(plane->frame_wait, !plane->work, timeout);
+}
+
 void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
struct armada_vbl_event *evt)
 {
@@ -233,44 +269,31 @@ static void armada_drm_vbl_event_run(struct armada_crtc 
*dcrtc)
 static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
struct armada_frame_work *work)
 {
-   struct drm_device *dev = dcrtc->crtc.dev;
-   int ret;
+   struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);

-   ret = drm_vblank_get(dev, dcrtc->num);
-   if (ret) {
-   DRM_ERROR("failed to acquire vblank counter\n");
-   return ret;
-   }
-
-   if (cmpxchg(>frame_work, NULL, work)) {
-   drm_vblank_put(dev, dcrtc->num);
-   ret = -EBUSY;
-   }
-
-   return ret;
+   return armada_drm_plane_work_queue(dcrtc, plane, >work);
 }

 static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
-   struct armada_frame_work *work)
+   struct armada_plane *plane, struct armada_plane_work *work)
 {
+   struct armada_frame_work *fwork = container_of(work, struct 
armada_frame_work, work);
struct drm_device *dev = dcrtc->crtc.dev;
unsigned long flags;

spin_lock_irqsave(>irq_lock, flags);
-   armada_drm_crtc_update_regs(dcrtc, work->regs);
+   armada_drm_crtc_update_regs(dcrtc, fwork->regs);
spin_unlock_irqrestore(>irq_lock, flags);

-   if (work->event) {
+   if (fwork->event) {
spin_lock_irqsave(>event_lock, flags);
-   drm_send_vblank_event(dev, dcrtc->num, work->event);
+   drm_send_vblank_event(dev, dcrtc->num, fwork->event);
spin_unlock_irqrestore(>event_lock, flags);
}

-   drm_vblank_put(dev, dcrtc->num);
-
/* Finally, queue the process-half of the cleanup. */
-   __armada_drm_queue_unref_work(dcrtc->crtc.dev, work->old_fb);
-   kfree(work);
+   __armada_drm_queue_unref_work(dcrtc->crtc.dev, fwork->old_fb);
+   kfree(fwork);
 }

 static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
@@ -290,6 +313,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc 
*dcrtc,
work = kmalloc(sizeof(*work), GFP_KERNEL);
if (work) {
int i = 0;
+   work->work.fn = armada_drm_crtc_complete_frame_work;
work->event = NULL;
work->old_fb = fb;
armada_reg_queue_end(work->regs, i);
@@ -310,18 +334,14 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc 
*dcrtc,

 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 {
-   struct armada_frame_work *work;
+   struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);

/*
 * Tell the DRM core that vblank IRQs aren't going to happen for
 * a while.  This cleans up any pending vblank events for us.
 */
drm_crtc_vblank_off(>crtc);
-
-   /* Handle any pending 

[PATCH 17/20] drm/armada: move frame wait into armada_frame

2015-09-29 Thread Russell King
Both the CRTC and overlay frames have their own wait queues.  It would
make more sense if these were part of the plane - the primary plane for
the CRTC and overlay plane for the overlay.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c| 22 ++
 drivers/gpu/drm/armada/armada_crtc.h|  4 +++-
 drivers/gpu/drm/armada/armada_overlay.c | 12 
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index e3e6f81593c0..46d932bc7678 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -455,7 +455,7 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, 
u32 stat)
if (work)
armada_drm_crtc_complete_frame_work(dcrtc, work);

-   wake_up(>frame_wait);
+   wake_up(_to_armada_plane(dcrtc->crtc.primary)->frame_wait);
}
 }

@@ -571,7 +571,8 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
adj->crtc_vtotal, tm, bm);

/* Wait for pending flips to complete */
-   wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
+   wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait,
+  !dcrtc->frame_work);

drm_crtc_vblank_off(crtc);

@@ -688,7 +689,8 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc 
*crtc, int x, int y,
armada_reg_queue_end(regs, i);

/* Wait for pending flips to complete */
-   wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
+   wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait,
+  !dcrtc->frame_work);

/* Take a reference to the new fb as we're using it */
drm_framebuffer_reference(crtc->primary->fb);
@@ -1096,6 +1098,13 @@ static const struct drm_plane_funcs 
armada_primary_plane_funcs = {
.destroy= drm_primary_helper_destroy,
 };

+int armada_drm_plane_init(struct armada_plane *plane)
+{
+   init_waitqueue_head(>frame_wait);
+
+   return 0;
+}
+
 static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
{ CSC_AUTO,"Auto" },
{ CSC_YUV_CCIR601, "CCIR601" },
@@ -1166,7 +1175,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, 
struct device *dev,
spin_lock_init(>irq_lock);
dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
INIT_LIST_HEAD(>vbl_list);
-   init_waitqueue_head(>frame_wait);

/* Initialize some registers which we don't otherwise set */
writel_relaxed(0x0001, dcrtc->base + LCD_CFG_SCLK_DIV);
@@ -1208,6 +1216,12 @@ static int armada_drm_crtc_create(struct drm_device 
*drm, struct device *dev,
if (!primary)
return -ENOMEM;

+   ret = armada_drm_plane_init(primary);
+   if (ret) {
+   kfree(primary);
+   return ret;
+   }
+
ret = drm_universal_plane_init(drm, >base, 0,
   _primary_plane_funcs,
   armada_primary_formats,
diff --git a/drivers/gpu/drm/armada/armada_crtc.h 
b/drivers/gpu/drm/armada/armada_crtc.h
index 500ce0f43f64..3ec5101e13f7 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -36,9 +36,12 @@ struct armada_variant;

 struct armada_plane {
struct drm_planebase;
+   wait_queue_head_t   frame_wait;
 };
 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)

+int armada_drm_plane_init(struct armada_plane *plane);
+
 struct armada_crtc {
struct drm_crtc crtc;
const struct armada_variant *variant;
@@ -71,7 +74,6 @@ struct armada_crtc {
uint32_tdumb_ctrl;
uint32_tspu_iopad_ctrl;

-   wait_queue_head_t   frame_wait;
struct armada_frame_work *frame_work;

spinlock_t  irq_lock;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 6ec42eb85981..9a5bab765085 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -39,7 +39,6 @@ struct armada_ovl_plane {
struct {
struct armada_vbl_event update;
struct armada_regs regs[13];
-   wait_queue_head_t wait;
} vbl;
struct armada_ovl_plane_properties prop;
 };
@@ -90,7 +89,7 @@ static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, 
void *data)
armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
armada_ovl_retire_fb(dplane, NULL);

-   wake_up(>vbl.wait);
+   wake_up(>base.frame_wait);
 }

 static int
@@ -163,7 +162,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
   dcrtc->base + LCD_SPU_SRAM_PARA1);
}

-   

[PATCH 16/20] drm/armada: move the locking for armada_drm_vbl_event_remove()

2015-09-29 Thread Russell King
Move the locking for armada_drm_vbl_event_remove() into itself, which
makes this function symmetrical with armada_drm_vbl_event_add().

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c| 2 ++
 drivers/gpu/drm/armada/armada_overlay.c | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 89decc5bdcd4..e3e6f81593c0 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -211,10 +211,12 @@ void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
 void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
struct armada_vbl_event *evt)
 {
+   spin_lock_irq(>irq_lock);
if (!list_empty(>node)) {
list_del_init(>node);
drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
}
+   spin_unlock_irq(>irq_lock);
 }

 static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index e7e020d4372a..6ec42eb85981 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -273,9 +273,7 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
dcrtc = drm_to_armada_crtc(dplane->base.base.crtc);
dcrtc->plane = NULL;

-   spin_lock_irq(>irq_lock);
armada_drm_vbl_event_remove(dcrtc, >vbl.update);
-   spin_unlock_irq(>irq_lock);

dplane->ctrl0 = 0;

-- 
2.1.0



[PATCH 15/20] drm/armada: move the update of dplane->ctrl0 out of spinlock

2015-09-29 Thread Russell King
It is not necessary to write dplane->ctrl0 under the CRTC spinlock, as
this is only accessed under process context where the DRM locks will
protect us instead.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_overlay.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 9686d79335a0..e7e020d4372a 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -275,9 +275,10 @@ static int armada_ovl_plane_disable(struct drm_plane 
*plane)

spin_lock_irq(>irq_lock);
armada_drm_vbl_event_remove(dcrtc, >vbl.update);
-   dplane->ctrl0 = 0;
spin_unlock_irq(>irq_lock);

+   dplane->ctrl0 = 0;
+
armada_drm_crtc_plane_disable(dcrtc, plane);

fb = xchg(>old_fb, NULL);
-- 
2.1.0



[PATCH 14/20] drm/armada: move write to dma_ctrl0 to armada_drm_crtc_plane_disable()

2015-09-29 Thread Russell King
Move the write to clear the DMA enable bit, and augment it with clearing
the graphics enable bit for the primary plane.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c| 12 ++--
 drivers/gpu/drm/armada/armada_overlay.c |  1 -
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 007fc5d3eb54..89decc5bdcd4 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -703,7 +703,7 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc 
*crtc, int x, int y,
 void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
struct drm_plane *plane)
 {
-   u32 sram_para1;
+   u32 sram_para1, dma_ctrl0_mask;

/*
 * Drop our reference on any framebuffer attached to this plane.
@@ -719,9 +719,17 @@ void armada_drm_crtc_plane_disable(struct armada_crtc 
*dcrtc,
sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;

/* Power down most RAMs and FIFOs if this is the primary plane */
-   if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+   if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
sram_para1 |= CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
  CFG_PDWN32x32 | CFG_PDWN64x66;
+   dma_ctrl0_mask = CFG_GRA_ENA;
+   } else {
+   dma_ctrl0_mask = CFG_DMA_ENA;
+   }
+
+   spin_lock_irq(>irq_lock);
+   armada_updatel(0, dma_ctrl0_mask, dcrtc->base + LCD_SPU_DMA_CTRL0);
+   spin_unlock_irq(>irq_lock);

armada_updatel(sram_para1, 0, dcrtc->base + LCD_SPU_SRAM_PARA1);
 }
diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 1032f9b3d5f1..9686d79335a0 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -275,7 +275,6 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)

spin_lock_irq(>irq_lock);
armada_drm_vbl_event_remove(dcrtc, >vbl.update);
-   armada_updatel(0, CFG_DMA_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
dplane->ctrl0 = 0;
spin_unlock_irq(>irq_lock);

-- 
2.1.0



[PATCH 13/20] drm/armada: provide a common helper to disable a plane

2015-09-29 Thread Russell King
Provide a common helper to disable either the overlay or the primary
plane.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c| 33 +++--
 drivers/gpu/drm/armada/armada_crtc.h|  3 +++
 drivers/gpu/drm/armada/armada_overlay.c |  7 +--
 3 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index f146fcf6b274..007fc5d3eb54 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -700,18 +700,39 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc 
*crtc, int x, int y,
return 0;
 }

+void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
+   struct drm_plane *plane)
+{
+   u32 sram_para1;
+
+   /*
+* Drop our reference on any framebuffer attached to this plane.
+* We don't need to NULL this out as drm_plane_force_disable(),
+* and __setplane_internal() will do so for an overlay plane, and
+* __drm_helper_disable_unused_functions() will do so for the
+* primary plane.
+*/
+   if (plane->fb)
+   drm_framebuffer_unreference(plane->fb);
+
+   /* Power down the Y/U/V FIFOs */
+   sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
+
+   /* Power down most RAMs and FIFOs if this is the primary plane */
+   if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+   sram_para1 |= CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
+ CFG_PDWN32x32 | CFG_PDWN64x66;
+
+   armada_updatel(sram_para1, 0, dcrtc->base + LCD_SPU_SRAM_PARA1);
+}
+
 /* The mode_config.mutex will be held for this call */
 static void armada_drm_crtc_disable(struct drm_crtc *crtc)
 {
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);

armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-   armada_drm_crtc_finish_fb(dcrtc, crtc->primary->fb, true);
-
-   /* Power down most RAMs and FIFOs */
-   writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
-  CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
-  CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
+   armada_drm_crtc_plane_disable(dcrtc, crtc->primary);
 }

 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
diff --git a/drivers/gpu/drm/armada/armada_crtc.h 
b/drivers/gpu/drm/armada/armada_crtc.h
index 549b5f538266..500ce0f43f64 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -103,6 +103,9 @@ void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
 void armada_drm_crtc_enable_irq(struct armada_crtc *, u32);
 void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);

+void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
+   struct drm_plane *plane);
+
 extern struct platform_driver armada_lcd_platform_driver;

 #endif
diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index e5a5b73a08cb..1032f9b3d5f1 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -279,12 +279,7 @@ static int armada_ovl_plane_disable(struct drm_plane 
*plane)
dplane->ctrl0 = 0;
spin_unlock_irq(>irq_lock);

-   /* Power down the Y/U/V FIFOs */
-   armada_updatel(CFG_PDWN16x66 | CFG_PDWN32x66, 0,
-  dcrtc->base + LCD_SPU_SRAM_PARA1);
-
-   if (plane->fb)
-   drm_framebuffer_unreference(plane->fb);
+   armada_drm_crtc_plane_disable(dcrtc, plane);

fb = xchg(>old_fb, NULL);
if (fb)
-- 
2.1.0



[PATCH 12/20] drm/armada: allocate primary plane ourselves

2015-09-29 Thread Russell King
Allocate our own primary plane as an armada_plane.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index b96b77b61337..f146fcf6b274 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1059,6 +1059,12 @@ static struct drm_crtc_funcs armada_crtc_funcs = {
.set_property   = armada_drm_crtc_set_property,
 };

+static const struct drm_plane_funcs armada_primary_plane_funcs = {
+   .update_plane   = drm_primary_helper_update,
+   .disable_plane  = drm_primary_helper_disable,
+   .destroy= drm_primary_helper_destroy,
+};
+
 static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
{ CSC_AUTO,"Auto" },
{ CSC_YUV_CCIR601, "CCIR601" },
@@ -1097,7 +1103,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, 
struct device *dev,
 {
struct armada_private *priv = drm->dev_private;
struct armada_crtc *dcrtc;
-   struct drm_plane *primary;
+   struct armada_plane *primary;
void __iomem *base;
int ret;

@@ -1167,12 +1173,21 @@ static int armada_drm_crtc_create(struct drm_device 
*drm, struct device *dev,

dcrtc->crtc.port = port;

-   primary = drm_primary_helper_create_plane(drm, armada_primary_formats,
-   ARRAY_SIZE(armada_primary_formats));
+   primary = kzalloc(sizeof(*primary), GFP_KERNEL);
if (!primary)
return -ENOMEM;

-   ret = drm_crtc_init_with_planes(drm, >crtc, primary, NULL,
+   ret = drm_universal_plane_init(drm, >base, 0,
+  _primary_plane_funcs,
+  armada_primary_formats,
+  ARRAY_SIZE(armada_primary_formats),
+  DRM_PLANE_TYPE_PRIMARY);
+   if (ret) {
+   kfree(primary);
+   return ret;
+   }
+
+   ret = drm_crtc_init_with_planes(drm, >crtc, >base, NULL,
_crtc_funcs);
if (ret)
goto err_crtc_init;
@@ -1187,7 +1202,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, 
struct device *dev,
return armada_overlay_plane_create(drm, 1 << dcrtc->num);

 err_crtc_init:
-   primary->funcs->destroy(primary);
+   primary->base.funcs->destroy(>base);
return ret;
 }

-- 
2.1.0



[PATCH 11/20] drm/armada: add primary plane creation

2015-09-29 Thread Russell King
Use drm_primary_helper_create_plane() to create our primary plane, and
register the CRTC with drm_crtc_init_with_planes().  This enables the
primary plane to be initialised with the supported format information.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 5d627646601e..b96b77b61337 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -33,6 +33,23 @@ enum csc_mode {
CSC_RGB_STUDIO = 2,
 };

+static const uint32_t armada_primary_formats[] = {
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_VYUY,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_ABGR1555,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_BGR565,
+};
+
 /*
  * A note about interlacing.  Let's consider HDMI 1920x1080i.
  * The timing parameters we have from X are:
@@ -1080,6 +1097,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, 
struct device *dev,
 {
struct armada_private *priv = drm->dev_private;
struct armada_crtc *dcrtc;
+   struct drm_plane *primary;
void __iomem *base;
int ret;

@@ -1148,7 +1166,17 @@ static int armada_drm_crtc_create(struct drm_device 
*drm, struct device *dev,
priv->dcrtc[dcrtc->num] = dcrtc;

dcrtc->crtc.port = port;
-   drm_crtc_init(drm, >crtc, _crtc_funcs);
+
+   primary = drm_primary_helper_create_plane(drm, armada_primary_formats,
+   ARRAY_SIZE(armada_primary_formats));
+   if (!primary)
+   return -ENOMEM;
+
+   ret = drm_crtc_init_with_planes(drm, >crtc, primary, NULL,
+   _crtc_funcs);
+   if (ret)
+   goto err_crtc_init;
+
drm_crtc_helper_add(>crtc, _crtc_helper_funcs);

drm_object_attach_property(>crtc.base, priv->csc_yuv_prop,
@@ -1157,6 +1185,10 @@ static int armada_drm_crtc_create(struct drm_device 
*drm, struct device *dev,
   dcrtc->csc_rgb_mode);

return armada_overlay_plane_create(drm, 1 << dcrtc->num);
+
+err_crtc_init:
+   primary->funcs->destroy(primary);
+   return ret;
 }

 static int
-- 
2.1.0



[PATCH 10/20] drm/armada: introduce generic armada_plane struct

2015-09-29 Thread Russell King
Introduce a generic armada_plane struct which will eventually be used
for both the primary and overlay planes.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.h|  5 +
 drivers/gpu/drm/armada/armada_overlay.c | 17 +
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.h 
b/drivers/gpu/drm/armada/armada_crtc.h
index a86243ef4a51..549b5f538266 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -34,6 +34,11 @@ struct armada_regs {
 struct armada_frame_work;
 struct armada_variant;

+struct armada_plane {
+   struct drm_planebase;
+};
+#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
+
 struct armada_crtc {
struct drm_crtc crtc;
const struct armada_variant *variant;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 4609ae8de042..e5a5b73a08cb 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -30,7 +30,7 @@ struct armada_ovl_plane_properties {
 };

 struct armada_ovl_plane {
-   struct drm_plane base;
+   struct armada_plane base;
struct drm_framebuffer *old_fb;
uint32_t src_hw;
uint32_t dst_hw;
@@ -43,7 +43,8 @@ struct armada_ovl_plane {
} vbl;
struct armada_ovl_plane_properties prop;
 };
-#define drm_to_armada_ovl_plane(p) container_of(p, struct armada_ovl_plane, 
base)
+#define drm_to_armada_ovl_plane(p) \
+   container_of(p, struct armada_ovl_plane, base.base)


 static void
@@ -266,10 +267,10 @@ static int armada_ovl_plane_disable(struct drm_plane 
*plane)
struct drm_framebuffer *fb;
struct armada_crtc *dcrtc;

-   if (!dplane->base.crtc)
+   if (!dplane->base.base.crtc)
return 0;

-   dcrtc = drm_to_armada_crtc(dplane->base.crtc);
+   dcrtc = drm_to_armada_crtc(dplane->base.base.crtc);
dcrtc->plane = NULL;

spin_lock_irq(>irq_lock);
@@ -362,9 +363,9 @@ static int armada_ovl_plane_set_property(struct drm_plane 
*plane,
update_attr = true;
}

-   if (update_attr && dplane->base.crtc)
+   if (update_attr && dplane->base.base.crtc)
armada_ovl_update_attr(>prop,
-  drm_to_armada_crtc(dplane->base.crtc));
+  
drm_to_armada_crtc(dplane->base.base.crtc));

return 0;
 }
@@ -461,7 +462,7 @@ int armada_overlay_plane_create(struct drm_device *dev, 
unsigned long crtcs)
armada_drm_vbl_event_init(>vbl.update, armada_ovl_plane_vbl,
  dplane);

-   ret = drm_universal_plane_init(dev, >base, crtcs,
+   ret = drm_universal_plane_init(dev, >base.base, crtcs,
   _ovl_plane_funcs,
   armada_ovl_formats,
   ARRAY_SIZE(armada_ovl_formats),
@@ -479,7 +480,7 @@ int armada_overlay_plane_create(struct drm_device *dev, 
unsigned long crtcs)
dplane->prop.contrast = 0x4000;
dplane->prop.saturation = 0x4000;

-   mobj = >base.base;
+   mobj = >base.base.base;
drm_object_attach_property(mobj, priv->colorkey_prop,
   0x0101fe);
drm_object_attach_property(mobj, priv->colorkey_min_prop,
-- 
2.1.0



[PATCH 09/20] drm/armada: update armada overlay to use drm_universal_plane_init()

2015-09-29 Thread Russell King
Use the new drm_universal_plane_init() rather than the legacy
drm_plane_init().

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_overlay.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 8738b590abc2..4609ae8de042 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -461,9 +461,11 @@ int armada_overlay_plane_create(struct drm_device *dev, 
unsigned long crtcs)
armada_drm_vbl_event_init(>vbl.update, armada_ovl_plane_vbl,
  dplane);

-   drm_plane_init(dev, >base, crtcs, _ovl_plane_funcs,
-  armada_ovl_formats, ARRAY_SIZE(armada_ovl_formats),
-  false);
+   ret = drm_universal_plane_init(dev, >base, crtcs,
+  _ovl_plane_funcs,
+  armada_ovl_formats,
+  ARRAY_SIZE(armada_ovl_formats),
+  DRM_PLANE_TYPE_OVERLAY);
if (ret) {
kfree(dplane);
return ret;
-- 
2.1.0



[PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb

2015-09-29 Thread Russell King
Rather than using a spinlock, use xchg() to atomically update
dplane->old_fb.  This allows us to eliminate dplane->lock.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_overlay.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 093c2d4f2b79..8738b590abc2 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -31,7 +31,6 @@ struct armada_ovl_plane_properties {

 struct armada_ovl_plane {
struct drm_plane base;
-   spinlock_t lock;
struct drm_framebuffer *old_fb;
uint32_t src_hw;
uint32_t dst_hw;
@@ -76,13 +75,10 @@ static void armada_ovl_retire_fb(struct armada_ovl_plane 
*dplane,
 {
struct drm_framebuffer *old_fb;

-   spin_lock(>lock);
-   old_fb = dplane->old_fb;
-   dplane->old_fb = fb;
-   spin_unlock(>lock);
+   old_fb = xchg(>old_fb, fb);

if (old_fb)
-   armada_drm_queue_unref_work(dplane->base.dev, old_fb);
+   armada_drm_queue_unref_work(dplane->base.base.dev, old_fb);
 }

 /* === Plane support === */
@@ -289,10 +285,7 @@ static int armada_ovl_plane_disable(struct drm_plane 
*plane)
if (plane->fb)
drm_framebuffer_unreference(plane->fb);

-   spin_lock_irq(>lock);
-   fb = dplane->old_fb;
-   dplane->old_fb = NULL;
-   spin_unlock_irq(>lock);
+   fb = xchg(>old_fb, NULL);
if (fb)
drm_framebuffer_unreference(fb);

@@ -464,7 +457,6 @@ int armada_overlay_plane_create(struct drm_device *dev, 
unsigned long crtcs)
if (!dplane)
return -ENOMEM;

-   spin_lock_init(>lock);
init_waitqueue_head(>vbl.wait);
armada_drm_vbl_event_init(>vbl.update, armada_ovl_plane_vbl,
  dplane);
-- 
2.1.0



[PATCH 07/20] drm/armada: factor out retirement of old fb

2015-09-29 Thread Russell King
We have two identical places in the overlay code which retire the drm
framebuffer.  Factor these out into a common function.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_overlay.c | 37 +++--
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 9393a15183e2..093c2d4f2b79 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -71,21 +71,27 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties 
*prop,
spin_unlock_irq(>irq_lock);
 }

+static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
+   struct drm_framebuffer *fb)
+{
+   struct drm_framebuffer *old_fb;
+
+   spin_lock(>lock);
+   old_fb = dplane->old_fb;
+   dplane->old_fb = fb;
+   spin_unlock(>lock);
+
+   if (old_fb)
+   armada_drm_queue_unref_work(dplane->base.dev, old_fb);
+}
+
 /* === Plane support === */
 static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data)
 {
struct armada_ovl_plane *dplane = data;
-   struct drm_framebuffer *fb;

armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
-
-   spin_lock(>lock);
-   fb = dplane->old_fb;
-   dplane->old_fb = NULL;
-   spin_unlock(>lock);
-
-   if (fb)
-   armada_drm_queue_unref_work(dcrtc->crtc.dev, fb);
+   armada_ovl_retire_fb(dplane, NULL);

wake_up(>vbl.wait);
 }
@@ -175,17 +181,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
 */
drm_framebuffer_reference(fb);

-   if (plane->fb) {
-   struct drm_framebuffer *older_fb;
-
-   spin_lock_irq(>lock);
-   older_fb = dplane->old_fb;
-   dplane->old_fb = plane->fb;
-   spin_unlock_irq(>lock);
-   if (older_fb)
-   armada_drm_queue_unref_work(dcrtc->crtc.dev,
-   older_fb);
-   }
+   if (plane->fb)
+   armada_ovl_retire_fb(dplane, plane->fb);

src_y = src.y1 >> 16;
src_x = src.x1 >> 16;
-- 
2.1.0



[PATCH 06/20] drm/armada: rename overlay identifiers

2015-09-29 Thread Russell King
Include an _ovl infix into the overlay identifiers to separate them from
the primary plane.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_overlay.c | 55 ++---
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index e939faba7fcc..9393a15183e2 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -16,7 +16,7 @@
 #include 
 #include "armada_ioctlP.h"

-struct armada_plane_properties {
+struct armada_ovl_plane_properties {
uint32_t colorkey_yr;
uint32_t colorkey_ug;
uint32_t colorkey_vb;
@@ -29,7 +29,7 @@ struct armada_plane_properties {
uint32_t colorkey_mode;
 };

-struct armada_plane {
+struct armada_ovl_plane {
struct drm_plane base;
spinlock_t lock;
struct drm_framebuffer *old_fb;
@@ -42,13 +42,13 @@ struct armada_plane {
struct armada_regs regs[13];
wait_queue_head_t wait;
} vbl;
-   struct armada_plane_properties prop;
+   struct armada_ovl_plane_properties prop;
 };
-#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
+#define drm_to_armada_ovl_plane(p) container_of(p, struct armada_ovl_plane, 
base)


 static void
-armada_ovl_update_attr(struct armada_plane_properties *prop,
+armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
struct armada_crtc *dcrtc)
 {
writel_relaxed(prop->colorkey_yr, dcrtc->base + LCD_SPU_COLORKEY_Y);
@@ -72,9 +72,9 @@ armada_ovl_update_attr(struct armada_plane_properties *prop,
 }

 /* === Plane support === */
-static void armada_plane_vbl(struct armada_crtc *dcrtc, void *data)
+static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data)
 {
-   struct armada_plane *dplane = data;
+   struct armada_ovl_plane *dplane = data;
struct drm_framebuffer *fb;

armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
@@ -91,12 +91,12 @@ static void armada_plane_vbl(struct armada_crtc *dcrtc, 
void *data)
 }

 static int
-armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
+armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
 {
-   struct armada_plane *dplane = drm_to_armada_plane(plane);
+   struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
struct drm_rect src = {
.x1 = src_x,
@@ -267,9 +267,9 @@ armada_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
return 0;
 }

-static int armada_plane_disable(struct drm_plane *plane)
+static int armada_ovl_plane_disable(struct drm_plane *plane)
 {
-   struct armada_plane *dplane = drm_to_armada_plane(plane);
+   struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
struct drm_framebuffer *fb;
struct armada_crtc *dcrtc;

@@ -302,20 +302,20 @@ static int armada_plane_disable(struct drm_plane *plane)
return 0;
 }

-static void armada_plane_destroy(struct drm_plane *plane)
+static void armada_ovl_plane_destroy(struct drm_plane *plane)
 {
-   struct armada_plane *dplane = drm_to_armada_plane(plane);
+   struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);

drm_plane_cleanup(plane);

kfree(dplane);
 }

-static int armada_plane_set_property(struct drm_plane *plane,
+static int armada_ovl_plane_set_property(struct drm_plane *plane,
struct drm_property *property, uint64_t val)
 {
struct armada_private *priv = plane->dev->dev_private;
-   struct armada_plane *dplane = drm_to_armada_plane(plane);
+   struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
bool update_attr = false;

if (property == priv->colorkey_prop) {
@@ -379,14 +379,14 @@ static int armada_plane_set_property(struct drm_plane 
*plane,
return 0;
 }

-static const struct drm_plane_funcs armada_plane_funcs = {
-   .update_plane   = armada_plane_update,
-   .disable_plane  = armada_plane_disable,
-   .destroy= armada_plane_destroy,
-   .set_property   = armada_plane_set_property,
+static const struct drm_plane_funcs armada_ovl_plane_funcs = {
+   .update_plane   = armada_ovl_plane_update,
+   .disable_plane  = armada_ovl_plane_disable,
+   .destroy= armada_ovl_plane_destroy,
+   .set_property   = armada_ovl_plane_set_property,
 };

-static const uint32_t armada_formats[] = {
+static const uint32_t armada_ovl_formats[] = {
DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV,
DRM_FORMAT_YUV420,
@@ -456,7 +456,7 @@ int armada_overlay_plane_create(struct drm_device *dev, 

[PATCH 05/20] drm/armada: redo locking and atomics for armada_drm_crtc_complete_frame_work()

2015-09-29 Thread Russell King
We can do better with armada_drm_crtc_complete_frame_work() - we can
avoid taking the event lock unless a call to drm_send_vblank_event()
is required, and using cmpxchg() and xchg(), we can eliminate the
locking around dcrtc->frame_work entirely.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 53 
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 8c43ecc19c15..5d627646601e 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -215,7 +215,6 @@ static int armada_drm_crtc_queue_frame_work(struct 
armada_crtc *dcrtc,
struct armada_frame_work *work)
 {
struct drm_device *dev = dcrtc->crtc.dev;
-   unsigned long flags;
int ret;

ret = drm_vblank_get(dev, dcrtc->num);
@@ -224,30 +223,29 @@ static int armada_drm_crtc_queue_frame_work(struct 
armada_crtc *dcrtc,
return ret;
}

-   spin_lock_irqsave(>event_lock, flags);
-   if (!dcrtc->frame_work)
-   dcrtc->frame_work = work;
-   else
-   ret = -EBUSY;
-   spin_unlock_irqrestore(>event_lock, flags);
-
-   if (ret)
+   if (cmpxchg(>frame_work, NULL, work)) {
drm_vblank_put(dev, dcrtc->num);
+   ret = -EBUSY;
+   }

return ret;
 }

-static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc)
+static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
+   struct armada_frame_work *work)
 {
struct drm_device *dev = dcrtc->crtc.dev;
-   struct armada_frame_work *work = dcrtc->frame_work;
-
-   dcrtc->frame_work = NULL;
+   unsigned long flags;

+   spin_lock_irqsave(>irq_lock, flags);
armada_drm_crtc_update_regs(dcrtc, work->regs);
+   spin_unlock_irqrestore(>irq_lock, flags);

-   if (work->event)
+   if (work->event) {
+   spin_lock_irqsave(>event_lock, flags);
drm_send_vblank_event(dev, dcrtc->num, work->event);
+   spin_unlock_irqrestore(>event_lock, flags);
+   }

drm_vblank_put(dev, dcrtc->num);

@@ -293,7 +291,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc 
*dcrtc,

 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 {
-   struct drm_device *dev = dcrtc->crtc.dev;
+   struct armada_frame_work *work;

/*
 * Tell the DRM core that vblank IRQs aren't going to happen for
@@ -302,10 +300,9 @@ static void armada_drm_vblank_off(struct armada_crtc 
*dcrtc)
drm_crtc_vblank_off(>crtc);

/* Handle any pending flip event. */
-   spin_lock_irq(>event_lock);
-   if (dcrtc->frame_work)
-   armada_drm_crtc_complete_frame_work(dcrtc);
-   spin_unlock_irq(>event_lock);
+   work = xchg(>frame_work, NULL);
+   if (work)
+   armada_drm_crtc_complete_frame_work(dcrtc, work);
 }

 void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
@@ -434,12 +431,10 @@ static void armada_drm_crtc_irq(struct armada_crtc 
*dcrtc, u32 stat)
spin_unlock(>irq_lock);

if (stat & GRA_FRAME_IRQ) {
-   struct drm_device *dev = dcrtc->crtc.dev;
+   struct armada_frame_work *work = xchg(>frame_work, NULL);

-   spin_lock(>event_lock);
-   if (dcrtc->frame_work)
-   armada_drm_crtc_complete_frame_work(dcrtc);
-   spin_unlock(>event_lock);
+   if (work)
+   armada_drm_crtc_complete_frame_work(dcrtc, work);

wake_up(>frame_wait);
}
@@ -957,8 +952,6 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 {
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
struct armada_frame_work *work;
-   struct drm_device *dev = crtc->dev;
-   unsigned long flags;
unsigned i;
int ret;

@@ -1004,10 +997,10 @@ static int armada_drm_crtc_page_flip(struct drm_crtc 
*crtc,
 * interrupt, so complete it now.
 */
if (dpms_blanked(dcrtc->dpms)) {
-   spin_lock_irqsave(>event_lock, flags);
-   if (dcrtc->frame_work)
-   armada_drm_crtc_complete_frame_work(dcrtc);
-   spin_unlock_irqrestore(>event_lock, flags);
+   struct armada_frame_work *work = xchg(>frame_work, NULL);
+
+   if (work)
+   armada_drm_crtc_complete_frame_work(dcrtc, work);
}

return 0;
-- 
2.1.0



[PATCH 04/20] drm/armada: disable CRTC clock during DPMS

2015-09-29 Thread Russell King
When the CRTC is in low power mode, it isn't running, and so there's
no point keeping the CRTC clock enabled.  Disable the CRTC clock during
DPMS.

We need to re-enable it in the mode_set callback to ensure that the
variant's compute_clock() continues to see its clock in the expected
state (enabled).

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index bbf5ff785cd2..8c43ecc19c15 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -325,7 +325,11 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, 
int dpms)

if (dcrtc->dpms != dpms) {
dcrtc->dpms = dpms;
+   if (!IS_ERR(dcrtc->clk) && !dpms_blanked(dpms))
+   WARN_ON(clk_prepare_enable(dcrtc->clk));
armada_drm_crtc_update(dcrtc);
+   if (!IS_ERR(dcrtc->clk) && dpms_blanked(dpms))
+   clk_disable_unprepare(dcrtc->clk);
if (dpms_blanked(dpms))
armada_drm_vblank_off(dcrtc);
else
@@ -563,6 +567,13 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
}

+   /*
+* If we are blanked, we would have disabled the clock.  Re-enable
+* it so that compute_clock() does the right thing.
+*/
+   if (!IS_ERR(dcrtc->clk) && dpms_blanked(dcrtc->dpms))
+   WARN_ON(clk_prepare_enable(dcrtc->clk));
+
/* Now compute the divider for real */
dcrtc->variant->compute_clock(dcrtc, adj, );

-- 
2.1.0



[PATCH 03/20] drm/armada: use drm_plane_force_disable() to disable the overlay plane

2015-09-29 Thread Russell King
Use drm_plane_force_disable() to disable the overlay plane on a mode_set
rather than coding this ourselves.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 418594b19d1d..bbf5ff785cd2 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -348,17 +348,11 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
/*
 * If we have an overlay plane associated with this CRTC, disable
 * it before the modeset to avoid its coordinates being outside
-* the new mode parameters.  DRM doesn't provide help with this.
+* the new mode parameters.
 */
plane = dcrtc->plane;
-   if (plane) {
-   struct drm_framebuffer *fb = plane->fb;
-
-   plane->funcs->disable_plane(plane);
-   plane->fb = NULL;
-   plane->crtc = NULL;
-   drm_framebuffer_unreference(fb);
-   }
+   if (plane)
+   drm_plane_force_disable(plane);
 }

 /* The mode_config.mutex will be held for this call */
-- 
2.1.0



[PATCH 02/20] drm/armada: move vbl code into armada_crtc

2015-09-29 Thread Russell King
Our vblank event code belongs in armada_crtc.c rather than the core of
the driver.  Move it there.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/armada_crtc.c | 46 ++--
 drivers/gpu/drm/armada/armada_crtc.h | 17 +
 drivers/gpu/drm/armada/armada_drm.h  | 16 -
 drivers/gpu/drm/armada/armada_drv.c  | 23 --
 4 files changed, 56 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index c7374a3ec67a..418594b19d1d 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -173,6 +173,44 @@ static unsigned armada_drm_crtc_calc_fb(struct 
drm_framebuffer *fb,
return i;
 }

+void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
+   struct armada_vbl_event *evt)
+{
+   unsigned long flags;
+   bool not_on_list;
+
+   WARN_ON(drm_vblank_get(dcrtc->crtc.dev, dcrtc->num));
+
+   spin_lock_irqsave(>irq_lock, flags);
+   not_on_list = list_empty(>node);
+   if (not_on_list)
+   list_add_tail(>node, >vbl_list);
+   spin_unlock_irqrestore(>irq_lock, flags);
+
+   if (!not_on_list)
+   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+}
+
+void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
+   struct armada_vbl_event *evt)
+{
+   if (!list_empty(>node)) {
+   list_del_init(>node);
+   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+   }
+}
+
+static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
+{
+   struct armada_vbl_event *e, *n;
+
+   list_for_each_entry_safe(e, n, >vbl_list, node) {
+   list_del_init(>node);
+   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+   e->fn(dcrtc, e->data);
+   }
+}
+
 static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
struct armada_frame_work *work)
 {
@@ -356,7 +394,6 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc 
*crtc,

 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
-   struct armada_vbl_event *e, *n;
void __iomem *base = dcrtc->base;

if (stat & DMA_FF_UNDERFLOW)
@@ -368,12 +405,7 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, 
u32 stat)
drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);

spin_lock(>irq_lock);
-
-   list_for_each_entry_safe(e, n, >vbl_list, node) {
-   list_del_init(>node);
-   drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-   e->fn(dcrtc, e->data);
-   }
+   armada_drm_vbl_event_run(dcrtc);

if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
diff --git a/drivers/gpu/drm/armada/armada_crtc.h 
b/drivers/gpu/drm/armada/armada_crtc.h
index a13469f5d72b..a86243ef4a51 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -75,6 +75,23 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)

+struct armada_vbl_event {
+   struct list_headnode;
+   void*data;
+   void(*fn)(struct armada_crtc *, void *);
+};
+
+void armada_drm_vbl_event_add(struct armada_crtc *,
+   struct armada_vbl_event *);
+void armada_drm_vbl_event_remove(struct armada_crtc *,
+   struct armada_vbl_event *);
+#define armada_drm_vbl_event_init(_e, _f, _d) do { \
+   struct armada_vbl_event *__e = _e;  \
+   INIT_LIST_HEAD(&__e->node); \
+   __e->data = _d; \
+   __e->fn = _f;   \
+} while (0)
+
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
diff --git a/drivers/gpu/drm/armada/armada_drm.h 
b/drivers/gpu/drm/armada/armada_drm.h
index 5f6aef0dca59..4df6f2af2b21 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -37,22 +37,6 @@ static inline uint32_t armada_pitch(uint32_t width, uint32_t 
bpp)
return ALIGN(pitch, 128);
 }

-struct armada_vbl_event {
-   struct list_headnode;
-   void*data;
-   void(*fn)(struct armada_crtc *, void *);
-};
-void armada_drm_vbl_event_add(struct armada_crtc *,
-   struct armada_vbl_event *);
-void armada_drm_vbl_event_remove(struct armada_crtc *,
-   struct armada_vbl_event *);
-#define armada_drm_vbl_event_init(_e, _f, _d) do { \
-   struct armada_vbl_event *__e = _e;  \
-   INIT_LIST_HEAD(&__e->node); \
-   __e->data = _d; \
-   __e->fn = _f;

[PATCH 01/20] drm/armada: remove non-component support

2015-09-29 Thread Russell King
Now that the transition of TDA998x to the component helpers is complete,
remove the non-componentised support from the Armada DRM driver.  All
outputs are expected to use the component helpers from now on.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/armada/Kconfig |   9 ---
 drivers/gpu/drm/armada/Makefile|   3 +-
 drivers/gpu/drm/armada/armada_crtc.c   |   2 +-
 drivers/gpu/drm/armada/armada_crtc.h   |   4 -
 drivers/gpu/drm/armada/armada_drv.c| 125 -
 drivers/gpu/drm/armada/armada_output.c | 142 -
 drivers/gpu/drm/armada/armada_output.h |  33 
 drivers/gpu/drm/armada/armada_slave.c  | 139 
 drivers/gpu/drm/armada/armada_slave.h  |  26 --
 9 files changed, 19 insertions(+), 464 deletions(-)
 delete mode 100644 drivers/gpu/drm/armada/armada_output.c
 delete mode 100644 drivers/gpu/drm/armada/armada_output.h
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.c
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.h

diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig
index 50ae88ad4d76..eb773e9af313 100644
--- a/drivers/gpu/drm/armada/Kconfig
+++ b/drivers/gpu/drm/armada/Kconfig
@@ -14,12 +14,3 @@ config DRM_ARMADA
  This driver provides no built-in acceleration; acceleration is
  performed by other IP found on the SoC.  This driver provides
  kernel mode setting and buffer management to userspace.
-
-config DRM_ARMADA_TDA1998X
-   bool "Support TDA1998X HDMI output"
-   depends on DRM_ARMADA != n
-   depends on I2C && DRM_I2C_NXP_TDA998X = y
-   default y
-   help
- Support the TDA1998x HDMI output device found on the Solid-Run
- CuBox.
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
index d6f43e06150a..ffd673615772 100644
--- a/drivers/gpu/drm/armada/Makefile
+++ b/drivers/gpu/drm/armada/Makefile
@@ -1,6 +1,5 @@
 armada-y   := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
-  armada_gem.o armada_output.o armada_overlay.o \
-  armada_slave.o
+  armada_gem.o armada_overlay.o
 armada-y   += armada_510.o
 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 01ffe9bffe38..c7374a3ec67a 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1044,7 +1044,7 @@ static int armada_drm_crtc_create_properties(struct 
drm_device *dev)
return 0;
 }

-int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
+static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
struct resource *res, int irq, const struct armada_variant *variant,
struct device_node *port)
 {
diff --git a/drivers/gpu/drm/armada/armada_crtc.h 
b/drivers/gpu/drm/armada/armada_crtc.h
index 98102a5a9af5..a13469f5d72b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -75,10 +75,6 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)

-struct device_node;
-int armada_drm_crtc_create(struct drm_device *, struct device *,
-   struct resource *, int, const struct armada_variant *,
-   struct device_node *);
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
diff --git a/drivers/gpu/drm/armada/armada_drv.c 
b/drivers/gpu/drm/armada/armada_drv.c
index 225034b74cda..b373cf9b2f65 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -18,47 +18,6 @@
 #include 
 #include "armada_ioctlP.h"

-#ifdef CONFIG_DRM_ARMADA_TDA1998X
-#include 
-#include "armada_slave.h"
-
-static struct tda998x_encoder_params params = {
-   /* With 0x24, there is no translation between vp_out and int_vp
-   FB  LCD out PinsVIP Int Vp
-   R:23:16 R:7:0   VPC7:0  7:0 7:0[R]
-   G:15:8  G:15:8  VPB7:0  23:16   23:16[G]
-   B:7:0   B:23:16 VPA7:0  15:815:8[B]
-   */
-   .swap_a = 2,
-   .swap_b = 3,
-   .swap_c = 4,
-   .swap_d = 5,
-   .swap_e = 0,
-   .swap_f = 1,
-   .audio_cfg = BIT(2),
-   .audio_frame[1] = 1,
-   .audio_format = AFMT_SPDIF,
-   .audio_sample_rate = 44100,
-};
-
-static const struct armada_drm_slave_config tda19988_config = {
-   .i2c_adapter_id = 0,
-   .crtcs = 1 << 0, /* Only LCD0 at the moment */
-   .polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT,
-   .interlace_allowed = true,
-   .info = {
-   .type = "tda998x",
-   .addr = 0x70,
-   .platform_data = ,
-   },
-};
-#endif
-

[PATCH 00/20] Armada DRM updates for 4.4

2015-09-29 Thread Russell King - ARM Linux
Here are my queued changes for the Armada DRM driver, for the upcoming
4.4 merge window.

These changes are about updating the driver to some of the more recent
DRM APIs, and removing the non-component support now that has
stabilised.  This results in all of armada_output and armada_slave
being removed, resulting in 460 lines of code removed from that change
alone.

Other changes include:

* moving more towards supporting DRM planes in a more generic way,
  thereby reducing the duplication between the primary and overlay
  planes.
* locking cleanups, more like locking removal, prefering inherently
  atomic operations (eg, xchg) instead of spinlocking.  This ultimately
  results in simpler and faster code.

I've been running these patches for a while and haven't noticed any ill
effects.

Posted for comment, if nothing is forthcoming, I'll send a pull request
to David in a week or so's time.  These patches are against v4.2, but
rebase to 4.3-rc3 without any fuss.

 drivers/gpu/drm/armada/Kconfig  |   9 --
 drivers/gpu/drm/armada/Makefile |   3 +-
 drivers/gpu/drm/armada/armada_crtc.c| 258 +++-
 drivers/gpu/drm/armada/armada_crtc.h|  34 +++--
 drivers/gpu/drm/armada/armada_drm.h |  16 --
 drivers/gpu/drm/armada/armada_drv.c | 148 +++---
 drivers/gpu/drm/armada/armada_output.c  | 142 --
 drivers/gpu/drm/armada/armada_output.h  |  33 
 drivers/gpu/drm/armada/armada_overlay.c | 147 +-
 drivers/gpu/drm/armada/armada_slave.c   | 139 -
 drivers/gpu/drm/armada/armada_slave.h   |  26 
 11 files changed, 297 insertions(+), 658 deletions(-)
 delete mode 100644 drivers/gpu/drm/armada/armada_output.c
 delete mode 100644 drivers/gpu/drm/armada/armada_output.h
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.c
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.h

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.


[Intel-gfx] [PATCH i-g-t] tests: Adding kms_dp_aux_dev test.

2015-09-29 Thread Ville Syrjälä
On Tue, Sep 29, 2015 at 10:53:02AM +0300, Jani Nikula wrote:
> On Tue, 29 Sep 2015, Rafael Antognolli  wrote:
> > This new test makes some basic testing on the proposed drm_dp_aux_dev
> > interface. If the feature is enabled and the drm_dp_aux_dev class is
> > present, it will check for available DP aux channels and test them for:
> > - basic seek to 0 and read 1 byte
> > - seek to the last address and read, to confirm 0 is returned
> > - seek one more byte and confirm that EINVAL is returned
> > - try to read 64 bytes when at 8 bytes from the end of the
> > address space
> > - try to read 64 bytes at the address 0.
> >
> > So far, no write checks are done.
> 
> Side note, it would be useful to have a tool under tools/ to
> read/write/dump DPCD registers.

dd could be used thanks to the use of standard syscalls, but something
a bit easier might be interesting too.

What I'd like to have is a DPCD decoder, so we could just grab
the entire thing and make it human readable.

> 
> On the one hand, I think it would be trivial to bolt this into the
> intel_reg tool. One could add a dpcd "port" (kind of like namespace) and
> all of it would work very nicely. Everything is there already.
> 
> On the other hand, this perhaps should be a standalone tool, as it's
> driver agnostic stuff. But it would mean quite a bit of code
> duplication, and we might end up with the mess we had before intel_reg -
> lots of tools for various things with slightly different feature sets,
> yet all of them doing roughly the same thing.
> 
> BR,
> Jani.
> 
> 
> >
> > Signed-off-by: Rafael Antognolli 
> > ---
> >  tests/.gitignore   |   1 +
> >  tests/Makefile.sources |   1 +
> >  tests/kms_dp_aux_dev.c | 134 
> > +
> >  3 files changed, 136 insertions(+)
> >  create mode 100644 tests/kms_dp_aux_dev.c
> >
> > diff --git a/tests/.gitignore b/tests/.gitignore
> > index dc8bb53..efdad75 100644
> > --- a/tests/.gitignore
> > +++ b/tests/.gitignore
> > @@ -127,6 +127,7 @@ kms_3d
> >  kms_addfb_basic
> >  kms_crtc_background_color
> >  kms_cursor_crc
> > +kms_dp_aux_dev
> >  kms_draw_crc
> >  kms_fbc_crc
> >  kms_fbcon_fbt
> > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > index 2e2e088..dc07737 100644
> > --- a/tests/Makefile.sources
> > +++ b/tests/Makefile.sources
> > @@ -64,6 +64,7 @@ TESTS_progs_M = \
> > gem_write_read_ring_switch \
> > kms_addfb_basic \
> > kms_cursor_crc \
> > +   kms_dp_aux_dev \
> > kms_draw_crc \
> > kms_fbc_crc \
> > kms_fbcon_fbt \
> > diff --git a/tests/kms_dp_aux_dev.c b/tests/kms_dp_aux_dev.c
> > new file mode 100644
> > index 000..aab8c95
> > --- /dev/null
> > +++ b/tests/kms_dp_aux_dev.c
> > @@ -0,0 +1,134 @@
> > +/*
> > + * Copyright © 2015 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the 
> > "Software"),
> > + * to deal in the Software without restriction, including without 
> > limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the 
> > next
> > + * paragraph) shall be included in all copies or substantial portions of 
> > the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
> > OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
> > OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> > DEALINGS
> > + * IN THE SOFTWARE.
> > + */
> > +
> > +/** @file kms_dp_aux_dev.c
> > + *
> > + * This is a test of functionality of drm_dp_aux_dev.
> > + */
> > +
> > +#include "igt.h"
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +#define DRM_DP_AUX_SYSFS_PATH "/sys/class/drm_dp_aux_dev"
> > +
> > +IGT_TEST_DESCRIPTION("Test of drm_aux_dev nodes.");
> > +
> > +static void drm_dp_aux_test(const char *devname)
> > +{
> > +   char basedir[] = "/dev/";
> > +   char name[256 + sizeof(basedir)];
> > +   off_t address;
> > +   uint8_t buf;
> > +   uint8_t bigbuf[64];
> > +   int fd;
> > +
> > +   ssize_t res;
> > +
> > +   snprintf(name, sizeof(name), "%s%s", basedir, devname);
> > +   igt_info("Running test on %s\n", name);
> > + 
> > +   /* Check if this DP aux channel is connected before continuing tests */
> > +   fd = open(name, O_RDONLY);
> > +   igt_assert_lte(0, fd);
> > +   

[PATCH] drm/rockchip: vop: Correct enabled clocks during setup

2015-09-29 Thread Yakir Yang


On 09/29/2015 05:55 PM, Yakir Yang wrote:
>
>
> On 09/29/2015 05:28 PM, Sjoerd Simons wrote:
>> When doing the initial setup both the hclk and the aclk need to be
>> enabled otherwise the board will simply hang. This only occurs when
>> building the vop driver as a module, when its built-in the initial setup

Hmm... My previous test was built-in the vop driver, and just notice that
you say problem only occurred when building the vop driver as module.
That's to say my test was wrong, so I try to do the right things.

But I found that vop driver module and rockchipdrm driver module in
dependency cycles, here are the build message:
 depmod: ERROR: Found 2 modules in dependency cycles!
 depmod: ERROR: Cycle detected: rockchip_drm_vop -> rockchipdrm -> 
rockchip_drm_vop
 Makefile:1054: recipe for target '_modinst_post' failed

And past my Makefile:
vop-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o 
rockchip_drm_gem.o
obj-m = rockchip_drm_vop.o vop.o

Very like to know how you handle this dependency cycles :)

Thanks,
- Yakir

>> happens to run before the clock framework shuts of unused clocks
>> (including the aclk).
>>
>> While there also switch to doing prepare and enable in one step rather
>> then separate steps to reduce the amount of code required.
>>
>> Signed-off-by: Sjoerd Simons 
>
> Looks good and test on chromeos-3.14 tree, no problem, so
>
> Tested-by: Yakir Yang 
>
>> ---
>>
>>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 
>> +++--
>>   1 file changed, 14 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
>> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>> index 5d8ae5e..48719df 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>> @@ -1575,32 +1575,25 @@ static int vop_initial(struct vop *vop)
>>   return PTR_ERR(vop->dclk);
>>   }
>>   -ret = clk_prepare(vop->hclk);
>> -if (ret < 0) {
>> -dev_err(vop->dev, "failed to prepare hclk\n");
>> -return ret;
>> -}
>> -
>>   ret = clk_prepare(vop->dclk);
>>   if (ret < 0) {
>>   dev_err(vop->dev, "failed to prepare dclk\n");
>> -goto err_unprepare_hclk;
>> +return ret;
>>   }
>>   -ret = clk_prepare(vop->aclk);
>> +/* Enable both the hclk and aclk to setup the vop */
>> +ret = clk_prepare_enable(vop->hclk);
>>   if (ret < 0) {
>> -dev_err(vop->dev, "failed to prepare aclk\n");
>> +dev_err(vop->dev, "failed to prepare/enable hclk\n");
>>   goto err_unprepare_dclk;
>>   }
>>   -/*
>> - * enable hclk, so that we can config vop register.
>> - */
>> -ret = clk_enable(vop->hclk);
>> +ret = clk_prepare_enable(vop->aclk);
>>   if (ret < 0) {
>> -dev_err(vop->dev, "failed to prepare aclk\n");
>> -goto err_unprepare_aclk;
>> +dev_err(vop->dev, "failed to prepare/enable aclk\n");
>> +goto err_disable_hclk;
>>   }
>> +
>>   /*
>>* do hclk_reset, reset all vop registers.
>>*/
>> @@ -1608,7 +1601,7 @@ static int vop_initial(struct vop *vop)
>>   if (IS_ERR(ahb_rst)) {
>>   dev_err(vop->dev, "failed to get ahb reset\n");
>>   ret = PTR_ERR(ahb_rst);
>> -goto err_disable_hclk;
>> +goto err_disable_aclk;
>>   }
>>   reset_control_assert(ahb_rst);
>>   usleep_range(10, 20);
>> @@ -1634,26 +1627,25 @@ static int vop_initial(struct vop *vop)
>>   if (IS_ERR(vop->dclk_rst)) {
>>   dev_err(vop->dev, "failed to get dclk reset\n");
>>   ret = PTR_ERR(vop->dclk_rst);
>> -goto err_unprepare_aclk;
>> +goto err_disable_aclk;
>>   }
>>   reset_control_assert(vop->dclk_rst);
>>   usleep_range(10, 20);
>>   reset_control_deassert(vop->dclk_rst);
>> clk_disable(vop->hclk);
>> +clk_disable(vop->aclk);
>> vop->is_enabled = false;
>> return 0;
>>   +err_disable_aclk:
>> +clk_disable_unprepare(vop->aclk);
>>   err_disable_hclk:
>> -clk_disable(vop->hclk);
>> -err_unprepare_aclk:
>> -clk_unprepare(vop->aclk);
>> +clk_disable_unprepare(vop->hclk);
>>   err_unprepare_dclk:
>>   clk_unprepare(vop->dclk);
>> -err_unprepare_hclk:
>> -clk_unprepare(vop->hclk);
>>   return ret;
>>   }
>




[PATCH v4 1/2] drm/dp: Store the drm_connector device pointer on the helper.

2015-09-29 Thread Daniel Vetter
On Tue, Sep 29, 2015 at 05:27:33PM +0200, Lukas Wunner wrote:
> Hi Daniel,
> 
> On Tue, Sep 29, 2015 at 05:04:03PM +0200, Daniel Vetter wrote:
> > On Tue, Sep 29, 2015 at 02:49:20PM +0200, Lukas Wunner wrote:
> > > On Mon, Sep 28, 2015 at 04:45:35PM -0700, Rafael Antognolli wrote:
> > > > This is useful to determine which connector owns this AUX channel.
> > > 
> > > WTF? I posted a patch in August which does exactly that:
> > > http://lists.freedesktop.org/archives/dri-devel/2015-August/088172.html
> > > 
> > > Can also be pulled in from this git repo:
> > > https://github.com/l1k/linux/commit/b78b38d53fc0fc4fa0f6acf699b0fcad56ec1fe6
> > > 
> > > My patch has the advantage that it updates all the drivers which use
> > > drm_dp_aux to fill that attribute. Yours only updates i915.
> > > 
> > > Daniel Vetter criticized storing a drm_connector pointer in drm_dp_aux,
> > > quote:
> > > 
> > > "That will also clear up the confusion with drm_dp_aux, adding a
> > > drm_connector there feels wrong since not every dp_aux line has a
> > > connector (e.g. for dp mst). If we can lift this relation out into drivers
> > > (where this is known) that seems cleaner."
> > > 
> > > So now Intel itself does precisely what Daniel criticized? Confusing!
> > > 
> > > Source:
> > > http://lists.freedesktop.org/archives/dri-devel/2015-August/089108.html
> > 
> > Critism is still valid, and thinking about this again a cleaner solution
> > would be to just have a correct parent/child relationship in the device
> > hirarchy. I.e. add a struct device *parent to the aux channel structure
> > which should point to the right connector.
> 
> We already have that:
> 
> struct drm_dp_aux {
>   const char *name;
>   struct i2c_adapter ddc;
>   struct device *dev; <---
>   struct mutex hw_mutex;
>   ssize_t (*transfer)(struct drm_dp_aux *aux,
>   struct drm_dp_aux_msg *msg);
>   unsigned i2c_nack_count, i2c_defer_count;
> };
> 
> What Rafael is struggling with is that you cannot unambiguously
> get from drm_dp_aux->dev to the drm_connector. (The drm_device
> may have multiple drm_connectors with type
> DRM_MODE_CONNECTOR_DisplayPort.)

What I meant to say is that we don't need that, if instead of filling in
the overall dev in dp_aux->dev we fill in the connector sysfs device
thing. The we have proper nesting, like with i2c buses. And then there's
no need for a connector property in sysfs to show that link (which should
be done with a proper sysfs link anyway).
-Daniel

> 
> > 
> > Thanks for pointing out that I missed properly delayering this.
> > -Daniel
> > 
> > > 
> > > 
> > > Best regards,
> > > 
> > > Lukas
> > > 
> > > 
> > > > 
> > > > Signed-off-by: Rafael Antognolli 
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_dp.c | 1 +
> > > >  include/drm/drm_dp_helper.h | 1 +
> > > >  2 files changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_dp.c 
> > > > b/drivers/gpu/drm/i915/intel_dp.c
> > > > index 77f7330..f90439d 100644
> > > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > > @@ -1079,6 +1079,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, 
> > > > struct intel_connector *connector)
> > > >  
> > > > intel_dp->aux.name = name;
> > > > intel_dp->aux.dev = dev->dev;
> > > > +   intel_dp->aux.connector = connector->base.kdev;
> > > > intel_dp->aux.transfer = intel_dp_aux_transfer;
> > > >  
> > > > DRM_DEBUG_KMS("registering %s bus for %s\n", name,
> > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > > index 9ec4716..e009b5d 100644
> > > > --- a/include/drm/drm_dp_helper.h
> > > > +++ b/include/drm/drm_dp_helper.h
> > > > @@ -702,6 +702,7 @@ struct drm_dp_aux {
> > > > const char *name;
> > > > struct i2c_adapter ddc;
> > > > struct device *dev;
> > > > +   struct device *connector;
> > > > struct mutex hw_mutex;
> > > > ssize_t (*transfer)(struct drm_dp_aux *aux,
> > > > struct drm_dp_aux_msg *msg);
> > > > -- 
> > > > 2.4.3
> > > > 
> > > > ___
> > > > dri-devel mailing list
> > > > dri-devel at lists.freedesktop.org
> > > > http://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch

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


[PATCH] drm/rockchip: vop: Correct enabled clocks during setup

2015-09-29 Thread Mark yao
Hi Sjoerd
 We double check this problem, yes, board will hang if aclk is disabled
when setting vop register.

 Acked-by: Mark Yao 

Thanks for this fix.

On 2015年09月29日 17:28, Sjoerd Simons wrote:
> When doing the initial setup both the hclk and the aclk need to be
> enabled otherwise the board will simply hang. This only occurs when
> building the vop driver as a module, when its built-in the initial setup
> happens to run before the clock framework shuts of unused clocks
> (including the aclk).
>
> While there also switch to doing prepare and enable in one step rather
> then separate steps to reduce the amount of code required.
>
> Signed-off-by: Sjoerd Simons 
>
> ---
>
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 
> +++--
>   1 file changed, 14 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 5d8ae5e..48719df 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -1575,32 +1575,25 @@ static int vop_initial(struct vop *vop)
>   return PTR_ERR(vop->dclk);
>   }
>   
> - ret = clk_prepare(vop->hclk);
> - if (ret < 0) {
> - dev_err(vop->dev, "failed to prepare hclk\n");
> - return ret;
> - }
> -
>   ret = clk_prepare(vop->dclk);
>   if (ret < 0) {
>   dev_err(vop->dev, "failed to prepare dclk\n");
> - goto err_unprepare_hclk;
> + return ret;
>   }
>   
> - ret = clk_prepare(vop->aclk);
> + /* Enable both the hclk and aclk to setup the vop */
> + ret = clk_prepare_enable(vop->hclk);
>   if (ret < 0) {
> - dev_err(vop->dev, "failed to prepare aclk\n");
> + dev_err(vop->dev, "failed to prepare/enable hclk\n");
>   goto err_unprepare_dclk;
>   }
>   
> - /*
> -  * enable hclk, so that we can config vop register.
> -  */
> - ret = clk_enable(vop->hclk);
> + ret = clk_prepare_enable(vop->aclk);
>   if (ret < 0) {
> - dev_err(vop->dev, "failed to prepare aclk\n");
> - goto err_unprepare_aclk;
> + dev_err(vop->dev, "failed to prepare/enable aclk\n");
> + goto err_disable_hclk;
>   }
> +
>   /*
>* do hclk_reset, reset all vop registers.
>*/
> @@ -1608,7 +1601,7 @@ static int vop_initial(struct vop *vop)
>   if (IS_ERR(ahb_rst)) {
>   dev_err(vop->dev, "failed to get ahb reset\n");
>   ret = PTR_ERR(ahb_rst);
> - goto err_disable_hclk;
> + goto err_disable_aclk;
>   }
>   reset_control_assert(ahb_rst);
>   usleep_range(10, 20);
> @@ -1634,26 +1627,25 @@ static int vop_initial(struct vop *vop)
>   if (IS_ERR(vop->dclk_rst)) {
>   dev_err(vop->dev, "failed to get dclk reset\n");
>   ret = PTR_ERR(vop->dclk_rst);
> - goto err_unprepare_aclk;
> + goto err_disable_aclk;
>   }
>   reset_control_assert(vop->dclk_rst);
>   usleep_range(10, 20);
>   reset_control_deassert(vop->dclk_rst);
>   
>   clk_disable(vop->hclk);
> + clk_disable(vop->aclk);
>   
>   vop->is_enabled = false;
>   
>   return 0;
>   
> +err_disable_aclk:
> + clk_disable_unprepare(vop->aclk);
>   err_disable_hclk:
> - clk_disable(vop->hclk);
> -err_unprepare_aclk:
> - clk_unprepare(vop->aclk);
> + clk_disable_unprepare(vop->hclk);
>   err_unprepare_dclk:
>   clk_unprepare(vop->dclk);
> -err_unprepare_hclk:
> - clk_unprepare(vop->hclk);
>   return ret;
>   }
>   


-- 
ï¼­ark Yao




[PATCH 3/3] drm/exynos: remove unused mode_fixup() code

2015-09-29 Thread Gustavo Padovan
From: Gustavo Padovan 

CRTC's mode_fixup() isn't used anymore in exynos, remove it.

Signed-off-by: Gustavo Padovan 
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c | 15 ---
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |  4 
 2 files changed, 19 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 0872aa2f..ed28823 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -41,20 +41,6 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
exynos_crtc->ops->disable(exynos_crtc);
 }

-static bool
-exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
-{
-   struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
-
-   if (exynos_crtc->ops->mode_fixup)
-   return exynos_crtc->ops->mode_fixup(exynos_crtc, mode,
-   adjusted_mode);
-
-   return true;
-}
-
 static void
 exynos_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
@@ -99,7 +85,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
 static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
.enable = exynos_drm_crtc_enable,
.disable= exynos_drm_crtc_disable,
-   .mode_fixup = exynos_drm_crtc_mode_fixup,
.mode_set_nofb  = exynos_drm_crtc_mode_set_nofb,
.atomic_begin   = exynos_crtc_atomic_begin,
.atomic_flush   = exynos_crtc_atomic_flush,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index b7ba21d..6c717ba 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -82,7 +82,6 @@ struct exynos_drm_plane {
  *
  * @enable: enable the device
  * @disable: disable the device
- * @mode_fixup: fix mode data before applying it
  * @commit: set current hw specific display mode to hw.
  * @enable_vblank: specific driver callback for enabling vblank interrupt.
  * @disable_vblank: specific driver callback for disabling vblank interrupt.
@@ -103,9 +102,6 @@ struct exynos_drm_crtc;
 struct exynos_drm_crtc_ops {
void (*enable)(struct exynos_drm_crtc *crtc);
void (*disable)(struct exynos_drm_crtc *crtc);
-   bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode);
void (*commit)(struct exynos_drm_crtc *crtc);
int (*enable_vblank)(struct exynos_drm_crtc *crtc);
void (*disable_vblank)(struct exynos_drm_crtc *crtc);
-- 
2.1.0



[PATCH 2/3] drm/exynos: remove decon_mode_fixup()

2015-09-29 Thread Gustavo Padovan
From: Gustavo Padovan 

The only thing mode_fixup was doing was set the adjusted_mode->vrefresh to
60, but it already has the value of 60 when the decon_mode_fixup() is
called. That means this call is actually pointless and can be removed.

Signed-off-by: Gustavo Padovan 

---
This is untested as I don't have any decon device, but I assume the
behaviour is similar to FIMD and it that case, I'm proposing the
the removal in decon_mode_fixup() as well.
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index cbdb78e..e6cbaca 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -37,7 +37,6 @@
  * DECON stands for Display and Enhancement controller.
  */

-#define DECON_DEFAULT_FRAMERATE 60
 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128

 #define WINDOWS_NR 2
@@ -165,16 +164,6 @@ static u32 decon_calc_clkdiv(struct decon_context *ctx,
return (clkdiv < 0x100) ? clkdiv : 0xff;
 }

-static bool decon_mode_fixup(struct exynos_drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
-{
-   if (adjusted_mode->vrefresh == 0)
-   adjusted_mode->vrefresh = DECON_DEFAULT_FRAMERATE;
-
-   return true;
-}
-
 static void decon_commit(struct exynos_drm_crtc *crtc)
 {
struct decon_context *ctx = crtc->ctx;
@@ -637,7 +626,6 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
 static const struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable = decon_enable,
.disable = decon_disable,
-   .mode_fixup = decon_mode_fixup,
.commit = decon_commit,
.enable_vblank = decon_enable_vblank,
.disable_vblank = decon_disable_vblank,
-- 
2.1.0



[PATCH 1/3] drm/exynos: remove fimd_mode_fixup()

2015-09-29 Thread Gustavo Padovan
From: Gustavo Padovan 

The only thing mode_fixup was doing was set the adjusted_mode->vrefresh to
60, but it already has the value of 60 when the fimd_mode_fixup() is
called. That means this call is actually pointless and can be removed.

Signed-off-by: Gustavo Padovan 
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 750a9e6..03ad549 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -41,7 +41,6 @@
  * CPU Interface.
  */

-#define FIMD_DEFAULT_FRAMERATE 60
 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128

 /* position control register for hardware window 0, 2 ~ 4.*/
@@ -377,16 +376,6 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
return (clkdiv < 0x100) ? clkdiv : 0xff;
 }

-static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
-{
-   if (adjusted_mode->vrefresh == 0)
-   adjusted_mode->vrefresh = FIMD_DEFAULT_FRAMERATE;
-
-   return true;
-}
-
 static void fimd_commit(struct exynos_drm_crtc *crtc)
 {
struct fimd_context *ctx = crtc->ctx;
@@ -888,7 +877,6 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc 
*crtc, bool enable)
 static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
.enable = fimd_enable,
.disable = fimd_disable,
-   .mode_fixup = fimd_mode_fixup,
.commit = fimd_commit,
.enable_vblank = fimd_enable_vblank,
.disable_vblank = fimd_disable_vblank,
-- 
2.1.0



[PATCH] drm/rockchip: vop: Correct enabled clocks during setup

2015-09-29 Thread Yakir Yang


On 09/29/2015 05:28 PM, Sjoerd Simons wrote:
> When doing the initial setup both the hclk and the aclk need to be
> enabled otherwise the board will simply hang. This only occurs when
> building the vop driver as a module, when its built-in the initial setup
> happens to run before the clock framework shuts of unused clocks
> (including the aclk).
>
> While there also switch to doing prepare and enable in one step rather
> then separate steps to reduce the amount of code required.
>
> Signed-off-by: Sjoerd Simons 

Looks good and test on chromeos-3.14 tree, no problem, so

Tested-by: Yakir Yang 

> ---
>
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 
> +++--
>   1 file changed, 14 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 5d8ae5e..48719df 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -1575,32 +1575,25 @@ static int vop_initial(struct vop *vop)
>   return PTR_ERR(vop->dclk);
>   }
>   
> - ret = clk_prepare(vop->hclk);
> - if (ret < 0) {
> - dev_err(vop->dev, "failed to prepare hclk\n");
> - return ret;
> - }
> -
>   ret = clk_prepare(vop->dclk);
>   if (ret < 0) {
>   dev_err(vop->dev, "failed to prepare dclk\n");
> - goto err_unprepare_hclk;
> + return ret;
>   }
>   
> - ret = clk_prepare(vop->aclk);
> + /* Enable both the hclk and aclk to setup the vop */
> + ret = clk_prepare_enable(vop->hclk);
>   if (ret < 0) {
> - dev_err(vop->dev, "failed to prepare aclk\n");
> + dev_err(vop->dev, "failed to prepare/enable hclk\n");
>   goto err_unprepare_dclk;
>   }
>   
> - /*
> -  * enable hclk, so that we can config vop register.
> -  */
> - ret = clk_enable(vop->hclk);
> + ret = clk_prepare_enable(vop->aclk);
>   if (ret < 0) {
> - dev_err(vop->dev, "failed to prepare aclk\n");
> - goto err_unprepare_aclk;
> + dev_err(vop->dev, "failed to prepare/enable aclk\n");
> + goto err_disable_hclk;
>   }
> +
>   /*
>* do hclk_reset, reset all vop registers.
>*/
> @@ -1608,7 +1601,7 @@ static int vop_initial(struct vop *vop)
>   if (IS_ERR(ahb_rst)) {
>   dev_err(vop->dev, "failed to get ahb reset\n");
>   ret = PTR_ERR(ahb_rst);
> - goto err_disable_hclk;
> + goto err_disable_aclk;
>   }
>   reset_control_assert(ahb_rst);
>   usleep_range(10, 20);
> @@ -1634,26 +1627,25 @@ static int vop_initial(struct vop *vop)
>   if (IS_ERR(vop->dclk_rst)) {
>   dev_err(vop->dev, "failed to get dclk reset\n");
>   ret = PTR_ERR(vop->dclk_rst);
> - goto err_unprepare_aclk;
> + goto err_disable_aclk;
>   }
>   reset_control_assert(vop->dclk_rst);
>   usleep_range(10, 20);
>   reset_control_deassert(vop->dclk_rst);
>   
>   clk_disable(vop->hclk);
> + clk_disable(vop->aclk);
>   
>   vop->is_enabled = false;
>   
>   return 0;
>   
> +err_disable_aclk:
> + clk_disable_unprepare(vop->aclk);
>   err_disable_hclk:
> - clk_disable(vop->hclk);
> -err_unprepare_aclk:
> - clk_unprepare(vop->aclk);
> + clk_disable_unprepare(vop->hclk);
>   err_unprepare_dclk:
>   clk_unprepare(vop->dclk);
> -err_unprepare_hclk:
> - clk_unprepare(vop->hclk);
>   return ret;
>   }
>   




[PATCH 4/6] qcom-scm: add ocmem support

2015-09-29 Thread Rob Clark
On Tue, Sep 29, 2015 at 5:38 PM, Stephen Boyd  wrote:
> On 09/29, Rob Clark wrote:
>> diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
>> index c1e4325..e1ac97f 100644
>> --- a/drivers/firmware/qcom_scm-32.c
>> +++ b/drivers/firmware/qcom_scm-32.c
>> @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, 
>> u32 req_cnt, u32 *resp)
>>   req, req_cnt * sizeof(*req), resp, sizeof(*resp));
>>  }
>>
>> +int __qcom_scm_ocmem_secure_cfg(unsigned sec_id)
>> +{
>> + int ret, scm_ret = 0;
>> + struct msm_scm_sec_cfg {
>
> We've left these as anonymous structs for things like
> qcom_scm_set_boot_addr(), maybe we should do the same here.
>
>> + __le32 id;
>> + __le32 spare;
>
> Also, the iommu driver would use this API and it uses this
> "spare" element, so perhaps this whole function should be renamed
> to be more generic and take two values. Downstream the function
> is called scm_restore_sec_cfg, so maybe something similar.  And
> the service id is MP for "memory protection", so
> QCOM_SCM_OCMEM_SECURE_SVC could be QCOM_SCM_MEMORY_PROTECTION?

heh,

#define SCM_SVC_MP0xC
#define IOMMU_SECURE_CFG2

vs.

#define OCMEM_SECURE_SVC_ID 12
#define OCMEM_SECURE_CFG_ID 0x2

that wasn't obscure at all!

Maybe then there is a better name than spare?  Looks like downstream
iommu calls it cb_num?

BR,
-R


> Otherwise this patch looks good.
>
>> + } cfg;
>> +
>> + cfg.id = cpu_to_le32(sec_id);
>> +
>> + ret = qcom_scm_call(QCOM_SCM_OCMEM_SECURE_SVC, 
>> QCOM_SCM_OCMEM_SECURE_CFG,
>> + , sizeof(cfg), _ret, sizeof(scm_ret));
>> +
>> + if (ret || scm_ret)
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project


[PATCH v4 1/2] drm/dp: Store the drm_connector device pointer on the helper.

2015-09-29 Thread Lukas Wunner
Hi Daniel,

On Tue, Sep 29, 2015 at 05:04:03PM +0200, Daniel Vetter wrote:
> On Tue, Sep 29, 2015 at 02:49:20PM +0200, Lukas Wunner wrote:
> > On Mon, Sep 28, 2015 at 04:45:35PM -0700, Rafael Antognolli wrote:
> > > This is useful to determine which connector owns this AUX channel.
> > 
> > WTF? I posted a patch in August which does exactly that:
> > http://lists.freedesktop.org/archives/dri-devel/2015-August/088172.html
> > 
> > Can also be pulled in from this git repo:
> > https://github.com/l1k/linux/commit/b78b38d53fc0fc4fa0f6acf699b0fcad56ec1fe6
> > 
> > My patch has the advantage that it updates all the drivers which use
> > drm_dp_aux to fill that attribute. Yours only updates i915.
> > 
> > Daniel Vetter criticized storing a drm_connector pointer in drm_dp_aux,
> > quote:
> > 
> > "That will also clear up the confusion with drm_dp_aux, adding a
> > drm_connector there feels wrong since not every dp_aux line has a
> > connector (e.g. for dp mst). If we can lift this relation out into drivers
> > (where this is known) that seems cleaner."
> > 
> > So now Intel itself does precisely what Daniel criticized? Confusing!
> > 
> > Source:
> > http://lists.freedesktop.org/archives/dri-devel/2015-August/089108.html
> 
> Critism is still valid, and thinking about this again a cleaner solution
> would be to just have a correct parent/child relationship in the device
> hirarchy. I.e. add a struct device *parent to the aux channel structure
> which should point to the right connector.

We already have that:

struct drm_dp_aux {
const char *name;
struct i2c_adapter ddc;
struct device *dev; <---
struct mutex hw_mutex;
ssize_t (*transfer)(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg);
unsigned i2c_nack_count, i2c_defer_count;
};

What Rafael is struggling with is that you cannot unambiguously
get from drm_dp_aux->dev to the drm_connector. (The drm_device
may have multiple drm_connectors with type
DRM_MODE_CONNECTOR_DisplayPort.)

> 
> Thanks for pointing out that I missed properly delayering this.
> -Daniel
> 
> > 
> > 
> > Best regards,
> > 
> > Lukas
> > 
> > 
> > > 
> > > Signed-off-by: Rafael Antognolli 
> > > ---
> > >  drivers/gpu/drm/i915/intel_dp.c | 1 +
> > >  include/drm/drm_dp_helper.h | 1 +
> > >  2 files changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c 
> > > b/drivers/gpu/drm/i915/intel_dp.c
> > > index 77f7330..f90439d 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > @@ -1079,6 +1079,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct 
> > > intel_connector *connector)
> > >  
> > >   intel_dp->aux.name = name;
> > >   intel_dp->aux.dev = dev->dev;
> > > + intel_dp->aux.connector = connector->base.kdev;
> > >   intel_dp->aux.transfer = intel_dp_aux_transfer;
> > >  
> > >   DRM_DEBUG_KMS("registering %s bus for %s\n", name,
> > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > index 9ec4716..e009b5d 100644
> > > --- a/include/drm/drm_dp_helper.h
> > > +++ b/include/drm/drm_dp_helper.h
> > > @@ -702,6 +702,7 @@ struct drm_dp_aux {
> > >   const char *name;
> > >   struct i2c_adapter ddc;
> > >   struct device *dev;
> > > + struct device *connector;
> > >   struct mutex hw_mutex;
> > >   ssize_t (*transfer)(struct drm_dp_aux *aux,
> > >   struct drm_dp_aux_msg *msg);
> > > -- 
> > > 2.4.3
> > > 
> > > ___
> > > dri-devel mailing list
> > > dri-devel at lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch


[PATCH 07/12] drm/amdgpu: implement cgs gpu memory callbacks

2015-09-29 Thread Daniel Vetter
On Tue, Sep 29, 2015 at 02:39:49PM +0200, Christian König wrote:
> On 29.09.2015 13:40, Daniel Vetter wrote:
> >On Thu, Jul 09, 2015 at 12:21:06PM -0400, Alex Deucher wrote:
> >>From: Chunming Zhou 
> >>
> >>This implements the cgs interface for allocating
> >>GPU memory.
> >>
> >>Reviewed-by: Jammy Zhou 
> >I don't see that review anywhere on a m-l ... where is it?
> 
> Jammy reviewed the stuff internally before we made it public, that's why you
> can't find it.
> 
> >
> >I stumbled over this patch because it adds a new dev->struct_mutex user
> >(that should be a big warning sign) and then I somehow unrolled some giant
> >chain of wtfs. Either I'm completely missing what this is used for or it
> >probably should get reworked asap.
> 
> The CGS functions aren't used at the moment because none of the components
> depending on them made it into the kernel, but we wanted to keep it so that
> we can get reviews on the general idea and if necessary rework it.
> 
> In general it's an abstraction layer of device driver dependent functions
> which enables us to share more code internally.
> 
> We worked quite hard on trying to avoid the OS abstraction trap with this,
> but if you think this still won't work feel free to object.

The bit that made me look really is the import_gpu_mem thing, which seems
to partially reinvent drm_prime.c. Given how tricky importing and
import-caching is I'd really like to see that gone (and Alex said on irc
he'd be ok with that).

The other stuff seems a lot more benign. For the irq abstraction
specifically it might be worth looking at the irq_chip stuff linux core
has, which is what's used to virtualize/abstract irq routing and handling.
But for that stuff it's a balance thing really how much you reinvent
wheels internally in the driver (e.g. i915 has it's own power_well stuff
which is pretty much just powerdomains reinvented, with less features).

But really I can't tell without the users whether I'd expect this to be
hurt longterm or not for you ;-) But the import stuff is hurt for me since
you noodle around in drm internals. And specifically I'd like to make
modern drivers completely struct_mutex free with the goal to untangle the
last hold-outs of that lock in the drm core.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[Intel-gfx] [RFC 4/6] drm/i915: Add i915 perf event for Haswell OA unit

2015-09-29 Thread Peter Zijlstra
On Tue, Sep 29, 2015 at 10:55:39PM +0800, kbuild test robot wrote:
> Hi Robert,
> 
> [auto build test results on v4.3-rc3 -- if it's inappropriate base, please 
> ignore]
> 
> config: i386-defconfig (attached as .config)
> reproduce:
>   git checkout a1d59679ae8f3e7e7659e9723ae3fc69af2532e6
>   # save the attached .config to linux build tree
>   make ARCH=i386 
> 
> All warnings (new ones prefixed by >>):
> 

@Wu, hehe, another series pattern to match ;-)



[PATCH v4 2/2] drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers.

2015-09-29 Thread Rafael Antognolli
Thanks Ville for the review, I'm addressing all the issues but have some
questions on the ones mentioned below:

On Tue, Sep 29, 2015 at 05:09:23PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 28, 2015 at 04:45:36PM -0700, Rafael Antognolli wrote:
> > This module is heavily based on i2c-dev. Once loaded, it provides one
> > dev node per DP AUX channel, named drm_dp_auxN, where N is an integer.
> > 
> > It's possible to know which connector owns this aux channel by looking
> > at the respective sysfs /sys/class/drm_aux_dev/drm_dp_auxN/connector, if
> > the connector device pointer was correctly set in the aux helper struct.
> > 
> > Two main operations are provided on the registers read and write. The
> > address of the register to be read or written is given using lseek. The
> > seek position is updated upon read or write.
> > 
> > Signed-off-by: Rafael Antognolli 
> > ---
> >  drivers/gpu/drm/Kconfig  |   8 +
> >  drivers/gpu/drm/Makefile |   1 +
> >  drivers/gpu/drm/drm_dp_aux_dev.c | 357 
> > +++
> >  drivers/gpu/drm/drm_dp_helper.c  |   5 +
> >  include/drm/drm_dp_aux_dev.h |  50 ++
> >  5 files changed, 421 insertions(+)
> >  create mode 100644 drivers/gpu/drm/drm_dp_aux_dev.c
> >  create mode 100644 include/drm/drm_dp_aux_dev.h
> > 
> > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> > index 1a0a8df..64fa0f4 100644
> > --- a/drivers/gpu/drm/Kconfig
> > +++ b/drivers/gpu/drm/Kconfig
> > @@ -25,6 +25,14 @@ config DRM_MIPI_DSI
> > bool
> > depends on DRM
> >  
> > +config DRM_DP_AUX_CHARDEV
> > +   bool "DRM DP AUX Interface"
> > +   depends on DRM
> > +   help
> > + Choose this option to enable a /dev/drm_dp_auxN node that allows to
> > + read and write values to arbitrary DPCD registers on the DP aux
> > + channel.
> > +
> >  config DRM_KMS_HELPER
> > tristate
> > depends on DRM
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index 45e7719..e5ae7f0 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -25,6 +25,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o 
> > drm_probe_helper.o \
> >  drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
> >  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
> >  drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
> > +drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
> >  
> >  obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
> >  
> > diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c 
> > b/drivers/gpu/drm/drm_dp_aux_dev.c
> > new file mode 100644
> > index 000..e337081
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_dp_aux_dev.c
> > @@ -0,0 +1,357 @@
> > +/*
> > + * Copyright © 2015 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the 
> > "Software"),
> > + * to deal in the Software without restriction, including without 
> > limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the 
> > next
> > + * paragraph) shall be included in all copies or substantial portions of 
> > the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
> > OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
> > OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> > DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + * Authors:
> > + *Rafael Antognolli 
> > + *
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +struct drm_dp_aux_dev {
> > +   struct list_head list;
> > +   unsigned index;
> > +   struct drm_dp_aux *aux;
> > +   struct device *dev;
> > +};
> > +
> > +#define DRM_AUX_MINORS 256
> > +static int aux_max_offset = 1 << 20;
> 
> People seem to prefer defines for such things.
> 
> > +static int drm_dp_aux_dev_count = 0;
> > +static LIST_HEAD(drm_dp_aux_dev_list);
> > +static DEFINE_SPINLOCK(drm_dp_aux_dev_list_lock);
> > +
> > +static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
> > +{
> > +   struct drm_dp_aux_dev *aux_dev;
> > +
> > +   spin_lock(_dp_aux_dev_list_lock);
> > +   list_for_each_entry(aux_dev, _dp_aux_dev_list, list) {
> > +   if (aux_dev->index == index)

[PATCH v4 2/2] drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers.

2015-09-29 Thread Ville Syrjälä
On Mon, Sep 28, 2015 at 04:45:36PM -0700, Rafael Antognolli wrote:
> This module is heavily based on i2c-dev. Once loaded, it provides one
> dev node per DP AUX channel, named drm_dp_auxN, where N is an integer.
> 
> It's possible to know which connector owns this aux channel by looking
> at the respective sysfs /sys/class/drm_aux_dev/drm_dp_auxN/connector, if
> the connector device pointer was correctly set in the aux helper struct.
> 
> Two main operations are provided on the registers read and write. The
> address of the register to be read or written is given using lseek. The
> seek position is updated upon read or write.
> 
> Signed-off-by: Rafael Antognolli 
> ---
>  drivers/gpu/drm/Kconfig  |   8 +
>  drivers/gpu/drm/Makefile |   1 +
>  drivers/gpu/drm/drm_dp_aux_dev.c | 357 
> +++
>  drivers/gpu/drm/drm_dp_helper.c  |   5 +
>  include/drm/drm_dp_aux_dev.h |  50 ++
>  5 files changed, 421 insertions(+)
>  create mode 100644 drivers/gpu/drm/drm_dp_aux_dev.c
>  create mode 100644 include/drm/drm_dp_aux_dev.h
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 1a0a8df..64fa0f4 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -25,6 +25,14 @@ config DRM_MIPI_DSI
>   bool
>   depends on DRM
>  
> +config DRM_DP_AUX_CHARDEV
> + bool "DRM DP AUX Interface"
> + depends on DRM
> + help
> +   Choose this option to enable a /dev/drm_dp_auxN node that allows to
> +   read and write values to arbitrary DPCD registers on the DP aux
> +   channel.
> +
>  config DRM_KMS_HELPER
>   tristate
>   depends on DRM
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 45e7719..e5ae7f0 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -25,6 +25,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o 
> drm_probe_helper.o \
>  drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
>  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
>  drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
> +drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
>  
>  obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
>  
> diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c 
> b/drivers/gpu/drm/drm_dp_aux_dev.c
> new file mode 100644
> index 000..e337081
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_dp_aux_dev.c
> @@ -0,0 +1,357 @@
> +/*
> + * Copyright © 2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + *Rafael Antognolli 
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct drm_dp_aux_dev {
> + struct list_head list;
> + unsigned index;
> + struct drm_dp_aux *aux;
> + struct device *dev;
> +};
> +
> +#define DRM_AUX_MINORS   256
> +static int aux_max_offset = 1 << 20;

People seem to prefer defines for such things.

> +static int drm_dp_aux_dev_count = 0;
> +static LIST_HEAD(drm_dp_aux_dev_list);
> +static DEFINE_SPINLOCK(drm_dp_aux_dev_list_lock);
> +
> +static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
> +{
> + struct drm_dp_aux_dev *aux_dev;
> +
> + spin_lock(_dp_aux_dev_list_lock);
> + list_for_each_entry(aux_dev, _dp_aux_dev_list, list) {
> + if (aux_dev->index == index)
> + goto found;
> + }
> +
> + aux_dev = NULL;
> +found:
> + spin_unlock(_dp_aux_dev_list_lock);
> + return aux_dev;
> +}
> +
> +static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux 
> *aux)
> +{
> + struct drm_dp_aux_dev *aux_dev;
> +
> + spin_lock(_dp_aux_dev_list_lock);
> + list_for_each_entry(aux_dev, _dp_aux_dev_list, list) {
> + 

[PATCH v4 1/2] drm/dp: Store the drm_connector device pointer on the helper.

2015-09-29 Thread Daniel Vetter
On Tue, Sep 29, 2015 at 02:49:20PM +0200, Lukas Wunner wrote:
> Hi Rafael,
> 
> On Mon, Sep 28, 2015 at 04:45:35PM -0700, Rafael Antognolli wrote:
> > This is useful to determine which connector owns this AUX channel.
> 
> WTF? I posted a patch in August which does exactly that:
> http://lists.freedesktop.org/archives/dri-devel/2015-August/088172.html
> 
> Can also be pulled in from this git repo:
> https://github.com/l1k/linux/commit/b78b38d53fc0fc4fa0f6acf699b0fcad56ec1fe6
> 
> My patch has the advantage that it updates all the drivers which use
> drm_dp_aux to fill that attribute. Yours only updates i915.
> 
> Daniel Vetter criticized storing a drm_connector pointer in drm_dp_aux,
> quote:
> 
> "That will also clear up the confusion with drm_dp_aux, adding a
> drm_connector there feels wrong since not every dp_aux line has a
> connector (e.g. for dp mst). If we can lift this relation out into drivers
> (where this is known) that seems cleaner."
> 
> So now Intel itself does precisely what Daniel criticized? Confusing!
> 
> Source:
> http://lists.freedesktop.org/archives/dri-devel/2015-August/089108.html

Critism is still valid, and thinking about this again a cleaner solution
would be to just have a correct parent/child relationship in the device
hirarchy. I.e. add a struct device *parent to the aux channel structure
which should point to the right connector.

Thanks for pointing out that I missed properly delayering this.
-Daniel

> 
> 
> Best regards,
> 
> Lukas
> 
> 
> > 
> > Signed-off-by: Rafael Antognolli 
> > ---
> >  drivers/gpu/drm/i915/intel_dp.c | 1 +
> >  include/drm/drm_dp_helper.h | 1 +
> >  2 files changed, 2 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c 
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index 77f7330..f90439d 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -1079,6 +1079,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct 
> > intel_connector *connector)
> >  
> > intel_dp->aux.name = name;
> > intel_dp->aux.dev = dev->dev;
> > +   intel_dp->aux.connector = connector->base.kdev;
> > intel_dp->aux.transfer = intel_dp_aux_transfer;
> >  
> > DRM_DEBUG_KMS("registering %s bus for %s\n", name,
> > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > index 9ec4716..e009b5d 100644
> > --- a/include/drm/drm_dp_helper.h
> > +++ b/include/drm/drm_dp_helper.h
> > @@ -702,6 +702,7 @@ struct drm_dp_aux {
> > const char *name;
> > struct i2c_adapter ddc;
> > struct device *dev;
> > +   struct device *connector;
> > struct mutex hw_mutex;
> > ssize_t (*transfer)(struct drm_dp_aux *aux,
> > struct drm_dp_aux_msg *msg);
> > -- 
> > 2.4.3
> > 
> > ___
> > dri-devel mailing list
> > dri-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/dri-devel

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


[RFC 3/5] ASoC: codec: hdmi drm codec driver

2015-09-29 Thread Jyri Sarha
On 09/25/15 18:50, Arnaud Pouliquen wrote:
> Hello Jyri,
>
> Yes using or not DRM bridge we should be able to have a common
> implementation
>
> Please find,my answer belows
>
> BR,
> Arnaud
>
> On 09/25/2015 04:11 PM, Jyri Sarha wrote:
>> Despite my earlier comment this implementation and the related HW is
>> quite similar in all significant aspects to the patch set posted couple
>> of days ago [1] for Beaglebone-Black HDMI audio.
>>
>> [1] http://permalink.gmane.org/gmane.linux.alsa.devel/144144
> yes i trying to align my dev on it. to match with your development.
> Aim for me is to reuse it and adapt it using a DRM bridge interface.
> i hope to provide a V2 next week.
>>
>> I have not yet gotten to bottom of drm-side audio bride part, but I am
>> working on it. Bellow is couple of early comments to the ASoC part.
>>
>> Best regards,
>> Jyri
>>
>> On 09/21/15 16:19, Arnaud Pouliquen wrote:
>>> +
>>> +static int st_hdmi_dai_probe(struct snd_soc_dai *dai)
>>> +{
>>> +struct hdmi_drm_dai_data *priv;
>>> +
>>> +dev_err(dai->dev, "%s: enter\n", __func__);
>>> +priv = devm_kzalloc(dai->dev, sizeof(*priv), GFP_KERNEL);
>>> +
>>> +priv->bridge = of_drm_find_bridge(dai->dev->of_node);
>>> +
>>> +dev_err(dai->dev, "%s: bridge %p\n", __func__, priv->bridge);
>>> +
>>> +snd_soc_dai_set_drvdata(dai, priv);
>>> +
>>
>> The call above overwrites the private data pointer of the drivers that
>> registering the codec. This hardly works in general.
>>
>> A separate platform driver - with this already merged patch [2] - that I
>> use with my patch-set solves this issue quite nicely.
>>
>> [2] http://lists.freedesktop.org/archives/dri-devel/2015-May/083517.html
> Yes same dev,(but no crash...?).i need to define sub node.
>>> +return 0;
>>> +}here are several important callbacks missing here
>>> +
>>> +static const struct snd_soc_dai_ops hdmi_drm_codec_ops = {
>>> +.prepare =  hdmi_drm_dai_prepare,
>>> +.trigger = hdmi_drm_dai_trigger,
>>> +};
>>
>>
>> At least set_daifmt() and hw_params() callbacks should be defined before
>> this could be generally usable. HDMI encoders do not usually support too
>> many daifmts, but the driver should be able the check that the selected
>> format is supported. But as you said this not complete code yet.
> I'm trying to match codec ops with following DRM audio bridge ops,
> that is similar to the existing drm_bridge_funcs structure.

I am not yet too familiar with drm way of doing things. My code is 
trying to follow the way how ALSA does things. I tried to survive with 
as few callback as possible, but if you think more is needed I can add 
those if there is a corresponding callback in ALSA.

> struct drm_audio_bridge_funcs {
>  void (*disable)(struct drm_bridge *bridge);

There is no such thing in my HDMI codec. However, there is digital_mute 
callback that is used by alsa before the streams are shut down to avoid 
undesired pops and clicks.

>  void (*post_disable)(struct drm_bridge *bridge);

Post_disable should map more or less directly to audio_shutdown() in my 
code.

>  void (*pre_enable)(struct drm_bridge *bridge);

audio_startup() and hw_params() should both be called at pre_enable() 
phase.

>  void (*enable)(struct drm_bridge *bridge);

... or one could see hw_params() to map to enable. And there is 
digital_mute which is toggled by ALSA at this phase.

>  int  (*mode_set)(struct drm_bridge *bridge,
>  struct hdmi_audio_mode *mode);

Actually hw_params() does pretty much the same thing as set_mode(), but 
it should be called after audio_startup() has been called.

>  uint8_t *(*mode_get)(struct drm_bridge *bridge); /*return eld*/
> };

For this there is get_eld() in my HDMI codec code.

> audio parameters should be part of struct hdmi_audio_mode that contains
> audio configurations ( info frame,iec, format, clk...)
>
>

BTW, the HDMI codec is made in such a way that one can get by with only 
hw_params() and audio_shutdown(). In such an implementation hw_params() 
sets the HDMI encoder ready for receiving i2s or spdif from CPU DAI and 
audio_shutdown() disables the audio stream.

Best regards,
Jyri


WARNING: CPU: 4 PID: 863 at include/drm/drm_crtc.h:1577 drm_helper_choose_encoder_dpms+0x88/0x90() - evildoer found and neutralized

2015-09-29 Thread Jiang Liu
   if (dev->power.runtime_status == RPM_SUSPENDING)
> + return true;
> +#endif
> +
> + return false;
> +}
> +
>  static int pirq_enable_irq(struct pci_dev *dev)
>  {
>   u8 pin = 0;
> @@ -1258,7 +1270,8 @@ static int pirq_enable_irq(struct pci_dev *dev)
>  
>  static void pirq_disable_irq(struct pci_dev *dev)
>  {
> - if (io_apic_assign_pci_irqs && pci_has_managed_irq(dev)) {
> + if (io_apic_assign_pci_irqs && !mp_should_keep_irq(>dev) &&
> + dev->irq_managed && dev->irq) {
>   mp_unmap_irq(dev->irq);
>   pci_reset_managed_irq(dev);
>   }
> diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
> index 6da0f9beab19..d8a3f49a960c 100644
> --- a/drivers/acpi/pci_irq.c
> +++ b/drivers/acpi/pci_irq.c
> @@ -479,6 +479,14 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
>   if (!pin || !pci_has_managed_irq(dev))
>   return;
>  
> + /* Keep IOAPIC pin configuration when suspending */
> + if (dev->dev.power.is_prepared)
> + return;
> +#ifdef   CONFIG_PM
> + if (dev->dev.power.runtime_status == RPM_SUSPENDING)
> + return;
> +#endif
> +
>   entry = acpi_pci_irq_lookup(dev, pin);
>   if (!entry)
>   return;
> 
-- next part --
A non-text attachment was scrubbed...
Name: 0001-Gather-debug-info.patch
Type: text/x-patch
Size: 4983 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150929/c2df64ff/attachment-0001.bin>


[Intel-gfx] [PATCH 2/3] drm/sysfs: Grab lock for edid/modes_show

2015-09-29 Thread Julia Lawall
Maybe line 294 should become an unlock and should be moved under 295?

julia

On Tue, 29 Sep 2015, kbuild test robot wrote:

> CC: kbuild-all at 01.org
> In-Reply-To: <1443513993-5228-2-git-send-email-daniel.vetter at ffwll.ch>
> TO: Daniel Vetter 
> CC: DRI Development 
> CC: Daniel Vetter , Intel Graphics Development 
> 
>
> Hi Daniel,
>
> [auto build test results on v4.3-rc3 -- if it's inappropriate base, please 
> ignore]
>
> :: branch date: 2 hours ago
> :: commit date: 2 hours ago
>
> >> drivers/gpu/drm/drm_sysfs.c:277:1-11: second lock on line 294
> --
> >> drivers/gpu/drm/drm_sysfs.c:297:1-7: preceding lock on line 277
>
> git remote add linux-review 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> git remote update linux-review
> git checkout 0a4b5f2c3380cb718d25f3ecf7af6cbbc4a7bced
> vim +277 drivers/gpu/drm/drm_sysfs.c
>
> f453ba04 Dave Airlie   2008-11-07  271struct device *connector_dev = 
> container_of(kobj, struct device, kobj);
> f453ba04 Dave Airlie   2008-11-07  272struct drm_connector *connector 
> = to_drm_connector(connector_dev);
> f453ba04 Dave Airlie   2008-11-07  273unsigned char *edid;
> f453ba04 Dave Airlie   2008-11-07  274size_t size;
> 0a4b5f2c Daniel Vetter 2015-09-29  275ssize_t ret = 0;
> f453ba04 Dave Airlie   2008-11-07  276
> 0a4b5f2c Daniel Vetter 2015-09-29 @277
> mutex_lock(>dev->mode_config.mutex);
> f453ba04 Dave Airlie   2008-11-07  278if (!connector->edid_blob_ptr)
> 0a4b5f2c Daniel Vetter 2015-09-29  279goto unlock;
> f453ba04 Dave Airlie   2008-11-07  280
> f453ba04 Dave Airlie   2008-11-07  281edid = 
> connector->edid_blob_ptr->data;
> f453ba04 Dave Airlie   2008-11-07  282size = 
> connector->edid_blob_ptr->length;
> f453ba04 Dave Airlie   2008-11-07  283if (!edid)
> 0a4b5f2c Daniel Vetter 2015-09-29  284goto unlock;
> f453ba04 Dave Airlie   2008-11-07  285
> f453ba04 Dave Airlie   2008-11-07  286if (off >= size)
> 0a4b5f2c Daniel Vetter 2015-09-29  287goto unlock;
> f453ba04 Dave Airlie   2008-11-07  288
> f453ba04 Dave Airlie   2008-11-07  289if (off + count > size)
> f453ba04 Dave Airlie   2008-11-07  290count = size - off;
> f453ba04 Dave Airlie   2008-11-07  291memcpy(buf, edid + off, count);
> f453ba04 Dave Airlie   2008-11-07  292
> 0a4b5f2c Daniel Vetter 2015-09-29  293ret = count;
> 0a4b5f2c Daniel Vetter 2015-09-29 @294
> mutex_lock(>dev->mode_config.mutex);
> 0a4b5f2c Daniel Vetter 2015-09-29  295  unlock:
> 0a4b5f2c Daniel Vetter 2015-09-29  296
> 0a4b5f2c Daniel Vetter 2015-09-29 @297return ret;
> f453ba04 Dave Airlie   2008-11-07  298  }
> f453ba04 Dave Airlie   2008-11-07  299
> f453ba04 Dave Airlie   2008-11-07  300  static ssize_t modes_show(struct 
> device *device,
>
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation
>


[PATCH] CHROMIUM: drm: bridge/dw_hdmi: Eliminate unused cable_plugin

2015-09-29 Thread Russell King - ARM Linux
On Tue, Sep 29, 2015 at 01:07:25PM +0200, Thierry Reding wrote:
> On Fri, Sep 25, 2015 at 10:29:51AM +0200, Philipp Zabel wrote:
> > Am Montag, den 21.09.2015, 15:15 +0100 schrieb Russell King - ARM Linux:
> > > On Mon, Sep 21, 2015 at 11:51:06AM +0200, Thierry Reding wrote:
> > > > On Wed, Sep 16, 2015 at 01:41:38PM -0700, Douglas Anderson wrote:
> > > > > There's a member in 'struct dw_hdmi' called cable_plugin.  It's never
> > > > > set to anything anywhere so thus is always false.  There's a bit of 
> > > > > code
> > > > > checking it, but since it's always false this must be dead code.
> > > > > Eliminate it.
> > > > > 
> > > > > Note: if someone wants to figure out the intention of the original 
> > > > > code
> > > > > and implement whatever feature / fix was needed then we can drop this
> > > > > patch.  The 'cable_plugin' member has been unused since the code was
> > > > > first added in (9aaf880 imx-drm: Add mx6 hdmi transmitter support).
> > > > > 
> > > > > Signed-off-by: Douglas Anderson 
> > > > > ---
> > > > >  drivers/gpu/drm/bridge/dw_hdmi.c | 9 -
> > > > >  1 file changed, 9 deletions(-)
> > > > 
> > > > Except for the CHROMIUM: prefix this looks good to me:
> > > > 
> > > > Reviewed-by: Thierry Reding 
> > 
> > This seems to be similar to Sascha's "drm: bridge/dw_hdmi: remove unused
> > code" patch, except that the hdmi_disable_overflow_interrupts function
> > could be removed too.
> > 
> > > > Russell, do you have patches to this driver queued for v4.4 and plan to
> > > > pick this up into your tree or should I take it?
> > > 
> > > My current patch stack for imx-drm related stuff looks like this at
> > > present:
> > >
> > > drm: bridge/dw_hdmi: place PHY into low power mode when disabled
> > > drm: bridge/dw_hdmi: start of support for pixel doubled modes
> > > drm: bridge/dw_hdmi: remove CEC engine register definitions
> > > drm: bridge/dw_hdmi-cec: add Designware HDMI CEC driver
> > > cec: add HDMI CEC input driver
> > > cec: add HDMI CEC core driver
> > > drm: bridge/dw_hdmi: replace CTS calculation for the ACR
> > > drm: bridge/dw_hdmi: remove ratio support from ACR code
> > > drm: bridge/dw_hdmi: adjust pixel clock values in N calculation
> > > drm: bridge/dw_hdmi: avoid being recursive in N calculation
> > > drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes
> > > drm: bridge/dw_hdmi-ahb-audio: basic support for multi-channel PCM audio
> > > drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
> > > drm: bridge/dw_hdmi-ahb-audio: add audio driver
> > > drm: bridge/dw_hdmi: improve HDMI enable/disable handling
> > > drm: bridge/dw_hdmi: add connector mode forcing
> > > drm: bridge/dw_hdmi: add support for interlaced video modes
> > > gpu: imx: fix support for interlaced modes
> > > gpu: imx: simplify sync polarity setting
> > > 
> > > I haven't yet decided what, if anything, from that stack I'm going to
> > > try to get into the next merge window.  Given the lack of interest last
> > > time I posted these patches, I'm loosing interest myself in trying to
> > > get them merged, especially ones which are getting on for being 2 years
> > > old.
> > 
> > I'm still very interested to see at least the "gpu: imx: fix support for
> > interlaced modes" and "gpu: imx: simplify sync polarity setting" merged.
> > May I take them into the imx-drm tree separately?
> 
> The "gpu: imx:" patches sound like they are standalone, so taking them
> through the imx-drm tree would be the easiest.

Taking just those screws up the rest of the series, as I previously
explained:

> On Thu, Aug 27, 2015 at 10:39:12AM +0200, Philipp Zabel wrote:
> > Unfortunately these timings are completely different from what Freescale
> > came up with for the TV Encoder on i.MX5, but the code we have currently
> > in mainline doesn't work for that either. I suppose I'll follow up with
> > a patch that adds yet another sync counter setup for the i.MX5/TVE case.
> >
> > I'd like to take the two ipu-v3 patches, making a few small changes on
> > this one:
> 
> Please don't split the series up.  The reason it's a series is because
> there's interdependencies between the patches.

Have you acked my patch set sent in August, after I relied saying that
the series needs to be kept together?

Philipp sent a tested-by, but that was about the only attributation
I received from posting the set, so I only sent David what I was fully
happy to send at the time.  I'm willing to send:

drm: bridge/dw_hdmi: improve HDMI enable/disable handling
drm: bridge/dw_hdmi: add connector mode forcing
drm: bridge/dw_hdmi: add support for interlaced video modes
gpu: imx: fix support for interlaced modes
gpu: imx: simplify sync polarity setting

now, which are patches 3, 4, 5, 11 and 12 from the original 12 patch
series.

The actual audio patches I think need to be held _even_ longer, because
it's unclear what's happening with ALSA in regard to HDMI audio.  There's
also the need to sort out what's going on with CEC (thanks to the late

[PATCH] drm: fix missing modeset lock from sysfs path

2015-09-29 Thread Jani Nikula
On Mon, 28 Sep 2015, Jens Axboe  wrote:
> Hi,
>
> Running 4.3-rc on a new laptop, and I notice that I get these whenever
> powertop --auto-tune is run:
>
> [14954.927920] [ cut here ]
> [14954.927926] WARNING: CPU: 1 PID: 14297 at drivers/gpu/drm/drm_atomic.c:889 
> drm_atomic_get_property+0x232/0x2b0()
> [14954.927927] Modules linked in: msr drbg ctr ccm cmac uvcvideo hid_generic 
> videobuf2_vmalloc videobuf2_memops videobuf2_core v4l2_common videodev usbhid 
> btusb btintel arc4 iwlmvm mac80211 joydev snd_hda_codec_realtek 
> snd_hda_codec_generic x86_pkg_temp_thermal snd_hda_codec_hdmi 
> intel_powerclamp kvm_intel dell_laptop dell_wmi dcdbas snd_hda_intel 
> hid_multitouch kvm sparse_keymap iwlwifi snd_hda_codec snd_hwdep snd_hda_core 
> aesni_intel aes_x86_64 glue_helper ehci_pci lrw gf128mul xhci_pci ablk_helper 
> cfg80211 cryptd xhci_hcd ehci_hcd snd_pcm int3403_thermal snd_seq_midi bnep 
> snd_seq_midi_event rfcomm snd_rawmidi bluetooth snd_seq snd_timer 
> snd_seq_device processor_thermal_device snd intel_soc_dts_iosf iosf_mbi 
> i2c_hid hid i2c_designware_platform i2c_designware_core int3402_thermal 
> int3400_thermal int340x_thermal_zone acpi_thermal_rel soundcore binfmt_misc 
> nls_iso8859_1 nls_cp437 fuse vfat fat
> [14954.927963] CPU: 1 PID: 14297 Comm: powertop Tainted: G U  W   
> 4.3.0-rc3+ #177
> [14954.927964] Hardware name: Dell Inc. XPS 13 9343/0310JH, BIOS A05 
> 07/14/2015
> [14954.927965]  81a7c2db 8800032e3c88 812923a9 
> 
> [14954.927967]  8800032e3cc0 81050aa6 880215577028 
> 88021551df80
> [14954.927968]  880215577000 880133e2ea80 88020ea59000 
> 8800032e3cd0
> [14954.927970] Call Trace:
> [14954.927974]  [] dump_stack+0x4b/0x72
> [14954.927976]  [] warn_slowpath_common+0x86/0xc0
> [14954.927978]  [] warn_slowpath_null+0x1a/0x20
> [14954.927980]  [] drm_atomic_get_property+0x232/0x2b0
> [14954.927982]  [] drm_object_property_get_value+0x6c/0x70
> [14954.927984]  [] dpms_show+0x2f/0x70
> [14954.927987]  [] dev_attr_show+0x20/0x50
> [14954.927989]  [] sysfs_kf_seq_show+0xa3/0x140
> [14954.927990]  [] kernfs_seq_show+0x20/0x30
> [14954.927993]  [] seq_read+0xcd/0x370
> [14954.927994]  [] kernfs_fop_read+0x107/0x160
> [14954.927996]  [] __vfs_read+0x28/0xd0
> [14954.927999]  [] ? security_file_permission+0xa3/0xc0
> [14954.928001]  [] ? rw_verify_area+0x53/0xf0
> [14954.928002]  [] vfs_read+0x86/0x130
> [14954.928004]  [] SyS_read+0x46/0xa0
> [14954.928007]  [] entry_SYSCALL_64_fastpath+0x12/0x6a
> [14954.928008] ---[ end trace b1d297c2aeff3470 ]---
>
> Looks like we're missing a modeset lock/unlock around the property
> retrieval from the sysfs path. Below patch works for me.

Daniel's alternative at

http://mid.gmane.org/1443513413-28873-1-git-send-email-daniel.vetter at ffwll.ch

>
> Signed-off-by: Jens Axboe 
>
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index 0f6cd33b531f..2b62166f6b2a 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -239,9 +239,12 @@ static ssize_t dpms_show(struct device *device,
>   uint64_t dpms_status;
>   int ret;
>  
> + drm_modeset_lock(>mode_config.connection_mutex, NULL);
>   ret = drm_object_property_get_value(>base,
>   dev->mode_config.dpms_property,
>   _status);
> + drm_modeset_unlock(>mode_config.connection_mutex);
> +
>   if (ret)
>   return 0;
>  
>
> -- 
> Jens Axboe
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Jani Nikula, Intel Open Source Technology Center


[PATCH] drm: Fix locking for sysfs dpms file

2015-09-29 Thread Jani Nikula
On Tue, 29 Sep 2015, Daniel Vetter  wrote:
> With atomic drivers we need to make sure that (at least in general)
> property reads hold the right locks. But the legacy dpms property is
> special and can be read locklessly. Since userspace loves to just
> randomly look at that all the time (like with "status") do that.
>
> To make it clear that we play tricks use the READ_ONCE compiler
> barrier (and also for paranoia).
>
> Note that there's not really anything bad going on since even with the
> new atomic paths we eventually end up not chasing any pointers (and
> hence possibly freed memory and other fun stuff). The locking WARNING
> has been added in
>
> commit 88a48e297b3a3bac6022c03babfb038f1a886cea
> Author: Rob Clark 
> Date:   Thu Dec 18 16:01:50 2014 -0500
>
> drm: add atomic properties
>
> but since drivers are converting not everyone will have seen this from
> the start.
>
> Jens reported this and submitted a patch to just grab the
> mode_config.connection_mutex, but we can do a bit better.
>
> v2: Remove unused variables I failed to git add for real.
>

Reference: http://mid.gmane.org/20150928194822.GA3930 at kernel.dk

> Reported-by: Jens Axboe 
> Cc: Jens Axboe 
> Cc: Rob Clark 
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_sysfs.c | 12 +++-
>  1 file changed, 3 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index f08873f6489c..615b7e667320 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -230,18 +230,12 @@ static ssize_t dpms_show(struct device *device,
>  char *buf)
>  {
>   struct drm_connector *connector = to_drm_connector(device);
> - struct drm_device *dev = connector->dev;
> - uint64_t dpms_status;
> - int ret;
> + int dpms;
>  
> - ret = drm_object_property_get_value(>base,
> - dev->mode_config.dpms_property,
> - _status);
> - if (ret)
> - return 0;
> + dpms = READ_ONCE(connector->dpms);
>  
>   return snprintf(buf, PAGE_SIZE, "%s\n",
> - drm_get_dpms_name((int)dpms_status));
> + drm_get_dpms_name(dpms));
>  }
>  
>  static ssize_t enabled_show(struct device *device,
> -- 
> 2.5.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Jani Nikula, Intel Open Source Technology Center


[PATCH] drm/doc: Update docs about device instance setup

2015-09-29 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Monday 28 September 2015 21:46:35 Daniel Vetter wrote:
> ->load is deprecated, bus functions are deprecated and everyone
> should use drm_dev_alloc
> 
> So update the .tmpl (and pull a bunch of the overview docs into the
> sourcecode to increase chances that it'll stay in sync in the future)
> and add notes to functions which are deprecated. I didn't bother to
> clean up and document the unload sequence similarly since that one is
> still a bit a mess: drm_dev_unregister does way too much,
> drm_unplug_dev does what _unregister should be doing but then has the
> complication of promising something it doesn't actually do (it doesn't
> unplug existing open fds for instance, only prevents new ones).
> 
> Motivated since I don't want to hunt every new driver for usage of
> drm_platform_init any more ;-)
> 
> v2: Reword the deprecation note for ->load a bit, using Laurent's
> suggestion as an example (but making the wording a bit stronger even).
> Fix spelling in commit message.
> 
> Cc: Laurent Pinchart 
> Cc: David Herrmann 
> Acked-by: David Herrmann 
> Signed-off-by: Daniel Vetter 
> ---
>  Documentation/DocBook/drm.tmpl | 99 +++
>  drivers/gpu/drm/drm_drv.c  | 55 +--
>  drivers/gpu/drm/drm_pci.c  | 11 +
>  drivers/gpu/drm/drm_platform.c |  3 ++
>  4 files changed, 83 insertions(+), 85 deletions(-)
> 
> diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
> index 5395cde6905e..6d24ebb97cda 100644
> --- a/Documentation/DocBook/drm.tmpl
> +++ b/Documentation/DocBook/drm.tmpl
> @@ -138,14 +138,10 @@
>  
>At the core of every DRM driver is a
> drm_driver structure. Drivers typically statically
> initialize a drm_driver structure, -  and then pass it to one of the
> drm_*_init() functions -  to register it with the
> DRM subsystem.
> -
> -
> -  Newer drivers that no longer require a
> drm_bus -  structure can alternatively use the
> low-level device initialization and -  registration functions such as
> drm_dev_alloc() and - 
> drm_dev_register() directly.
> +  and then pass it to drm_dev_alloc() to allocate
> a +  device instance. After the device instance is fully initialized it
> can be +  registered (which makes it accessible from userspace) using +
>  drm_dev_register().
>  
>  
>The drm_driver structure contains static
> @@ -296,83 +292,12 @@ char *date;
>
>  
>  
> -  Device Registration
> -  
> -A number of functions are provided to help with device
> registration. -The functions deal with PCI and platform devices,
> respectively. -  
> -!Edrivers/gpu/drm/drm_pci.c
> -!Edrivers/gpu/drm/drm_platform.c
> -  
> -New drivers that no longer rely on the services provided by the
> -drm_bus structure can call the low-level
> -device registration functions directly. The
> -drm_dev_alloc() function can be used to
> allocate -and initialize a new drm_device
> structure. -Drivers will typically want to perform some additional
> setup on this -structure, such as allocating driver-specific data
> and storing a -pointer to it in the DRM device's
> dev_private -field. Drivers should also
> set the device's unique name using the -   
> drm_dev_set_unique() function. After it has been -
>set up a device can be registered with the DRM subsystem by calling -   
> drm_dev_register(). This will cause the device to
> -be exposed to userspace and will call the driver's
> -.load() implementation. When a device is
> -removed, the DRM device can safely be unregistered and freed by
> calling -drm_dev_unregister() followed by a
> call to -drm_dev_unref().
> -  
> +  Device Instance and Driver Handling
> +!Pdrivers/gpu/drm/drm_drv.c driver instance overview
>  !Edrivers/gpu/drm/drm_drv.c
>  
>  
>Driver Load
> -  
> -The load method is the driver and device
> -initialization entry point. The method is responsible for
> allocating and -  initializing driver private data, performing resource
> allocation and -  mapping (e.g. acquiring
> -clocks, mapping registers or allocating command buffers),
> initializing -the memory manager ( linkend="drm-memory-management"/>), installing -the IRQ handler
> (), setting up -vertical
> blanking handling (), mode -  setting
> () and initial output
> - configuration ().
> -  
> -  
> -If compatibility is a concern (e.g. with drivers converted over
> from -User Mode Setting to Kernel Mode Setting), care must be taken
> to prevent -device initialization and control that is incompatible
> with currently -active userspace drivers. For instance, if user
> level mode setting -drivers are in 

[PATCH 07/12] drm/amdgpu: implement cgs gpu memory callbacks

2015-09-29 Thread Alex Deucher
On Tue, Sep 29, 2015 at 4:10 PM, Dave Airlie  wrote:
> On 30 September 2015 at 01:41, Alex Deucher  wrote:
>> On Tue, Sep 29, 2015 at 11:20 AM, Daniel Vetter  wrote:
>>> On Tue, Sep 29, 2015 at 02:39:49PM +0200, Christian König wrote:
 On 29.09.2015 13:40, Daniel Vetter wrote:
 >On Thu, Jul 09, 2015 at 12:21:06PM -0400, Alex Deucher wrote:
 >>From: Chunming Zhou 
 >>
 >>This implements the cgs interface for allocating
 >>GPU memory.
 >>
 >>Reviewed-by: Jammy Zhou 
 >I don't see that review anywhere on a m-l ... where is it?

 Jammy reviewed the stuff internally before we made it public, that's why 
 you
 can't find it.
>
> Can we get these reviews done publically? it's kinda hard to know how
> well someone
> reviewed things if we have no external copy. Like did Jammy a) read
> the patch, and
> slap Reviewed-by on it, or did he b) comment on some whitespace issues
> and slap R-b
> on it, or c) did he suggest a bunch of changes and those changes were
> made and a new
> version was produced and he r-b'ed that etc.
>

We are pushing for that and making steady progress, but things are
slow to move internally.

>>> The other stuff seems a lot more benign. For the irq abstraction
>>> specifically it might be worth looking at the irq_chip stuff linux core
>>> has, which is what's used to virtualize/abstract irq routing and handling.
>>> But for that stuff it's a balance thing really how much you reinvent
>>> wheels internally in the driver (e.g. i915 has it's own power_well stuff
>>> which is pretty much just powerdomains reinvented, with less features).
>>>
>>
>> I think that's one of the hardest things in the kernel: finding out if
>> a solution already exists or not.  We implemented our own version of
>> mfd for our ACP audio block driver.  Upon upsteaming we were alerted
>> to mfd's existence and we converted the driver to use mfd.  At the end
>> of the day it was a lot of work for minimal gain, at least from a
>> functionality perspective.  I wish we had known about it sooner.  I'll
>> take a look at the irq_chip stuff.  Thanks for the heads up!
>
> You say for minimal gain, but this is pretty much going to keep happening
> to you with the development model you have chosen, get used to rewriting
> things you consider finished and reviewed. I've said it before so I'll use 
> this
> to reiterate, your patches are only starting the process when you post them,
> all the internal stuff you do is nice and all but it could all be done
> externally
> if you guys weren't so stuck on internal IP review. Otherwise you
> should be taking
> into account that this overhead will continue to exist in all your 
> development,
> and adjust schedules to suit.

We do take that into account as evidenced by the multiple revisions of
the ACP patch set for example.  We know there may be a delta between
short term deliverables and what eventually goes upstream and we take
that into account.  That doesn't change the overall amount of work
involved.  The fact is we didn't know about mfd so we didn't use it.
I don't see how we could have avoided rewriting it if we didn't know
about it in the first place.  When we sent the patches out, we found
out about it and made the appropriate changes.  My point was just that
we aren't the only ones this happens to.

Alex


[PATCH] drm/doc: Update docs about device instance setup

2015-09-29 Thread Daniel Vetter
On Tue, Sep 29, 2015 at 04:28:15PM +0300, Laurent Pinchart wrote:
> Hi Daniel,
> 
> Thank you for the patch.
> 
> On Monday 28 September 2015 21:46:35 Daniel Vetter wrote:
> > ->load is deprecated, bus functions are deprecated and everyone
> > should use drm_dev_alloc
> > 
> > So update the .tmpl (and pull a bunch of the overview docs into the
> > sourcecode to increase chances that it'll stay in sync in the future)
> > and add notes to functions which are deprecated. I didn't bother to
> > clean up and document the unload sequence similarly since that one is
> > still a bit a mess: drm_dev_unregister does way too much,
> > drm_unplug_dev does what _unregister should be doing but then has the
> > complication of promising something it doesn't actually do (it doesn't
> > unplug existing open fds for instance, only prevents new ones).
> > 
> > Motivated since I don't want to hunt every new driver for usage of
> > drm_platform_init any more ;-)
> > 
> > v2: Reword the deprecation note for ->load a bit, using Laurent's
> > suggestion as an example (but making the wording a bit stronger even).
> > Fix spelling in commit message.
> > 
> > Cc: Laurent Pinchart 
> > Cc: David Herrmann 
> > Acked-by: David Herrmann 
> > Signed-off-by: Daniel Vetter 
> > ---
> >  Documentation/DocBook/drm.tmpl | 99 +++
> >  drivers/gpu/drm/drm_drv.c  | 55 +--
> >  drivers/gpu/drm/drm_pci.c  | 11 +
> >  drivers/gpu/drm/drm_platform.c |  3 ++
> >  4 files changed, 83 insertions(+), 85 deletions(-)
> > 
> > diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
> > index 5395cde6905e..6d24ebb97cda 100644
> > --- a/Documentation/DocBook/drm.tmpl
> > +++ b/Documentation/DocBook/drm.tmpl
> > @@ -138,14 +138,10 @@
> >  
> >At the core of every DRM driver is a
> > drm_driver structure. Drivers typically statically
> > initialize a drm_driver structure, -  and then pass it to one of the
> > drm_*_init() functions -  to register it with the
> > DRM subsystem.
> > -
> > -
> > -  Newer drivers that no longer require a
> > drm_bus -  structure can alternatively use the
> > low-level device initialization and -  registration functions such as
> > drm_dev_alloc() and - 
> > drm_dev_register() directly.
> > +  and then pass it to drm_dev_alloc() to allocate
> > a +  device instance. After the device instance is fully initialized it
> > can be +  registered (which makes it accessible from userspace) using +
> >  drm_dev_register().
> >  
> >  
> >The drm_driver structure contains static
> > @@ -296,83 +292,12 @@ char *date;
> >
> >  
> >  
> > -  Device Registration
> > -  
> > -A number of functions are provided to help with device
> > registration. -The functions deal with PCI and platform devices,
> > respectively. -  
> > -!Edrivers/gpu/drm/drm_pci.c
> > -!Edrivers/gpu/drm/drm_platform.c
> > -  
> > -New drivers that no longer rely on the services provided by the
> > -drm_bus structure can call the low-level
> > -device registration functions directly. The
> > -drm_dev_alloc() function can be used to
> > allocate -and initialize a new drm_device
> > structure. -Drivers will typically want to perform some additional
> > setup on this -structure, such as allocating driver-specific data
> > and storing a -pointer to it in the DRM device's
> > dev_private -field. Drivers should also
> > set the device's unique name using the -   
> > drm_dev_set_unique() function. After it has been -
> >set up a device can be registered with the DRM subsystem by calling -   
> > drm_dev_register(). This will cause the device to
> > -be exposed to userspace and will call the driver's
> > -.load() implementation. When a device is
> > -removed, the DRM device can safely be unregistered and freed by
> > calling -drm_dev_unregister() followed by a
> > call to -drm_dev_unref().
> > -  
> > +  Device Instance and Driver Handling
> > +!Pdrivers/gpu/drm/drm_drv.c driver instance overview
> >  !Edrivers/gpu/drm/drm_drv.c
> >  
> >  
> >Driver Load
> > -  
> > -The load method is the driver and device
> > -initialization entry point. The method is responsible for
> > allocating and -initializing driver private data, performing resource
> > allocation and -mapping (e.g. acquiring
> > -clocks, mapping registers or allocating command buffers),
> > initializing -the memory manager ( > linkend="drm-memory-management"/>), installing -the IRQ handler
> > (), setting up -vertical
> > blanking handling (), mode -setting
> > () and initial output
> > -   configuration ().
> > -  
> > -  
> > -If compatibility is a concern (e.g. with drivers 

[Bug 105051] Radeon sets max_brightness to -1, breaking GNOME backlight control on Macbook Pro mid-2015 11,5

2015-09-29 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=105051

--- Comment #7 from Alex Deucher  ---
Perhaps the radeon driver should just not attempt to register a backlight
interface on Macs since they seem to use the gmux for backlight control.  Some
one with more knowledge of mac hw should probably comment on how they should be
handled.

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


[PATCH 6/6] drm/msm: add OCMEM driver

2015-09-29 Thread Rob Clark
For now, since the GPU is the only upstream consumer, just stuff this
into drm/msm.  Eventually if we have other consumers, we'll have to
split this out and make the allocation less hard coded.  But I'll punt
on that until I better understand the non-gpu uses-cases (and whether
the allocation *really* needs to be as complicated as it is in the
downstream driver).

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/Makefile  |   3 +-
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c |  19 +-
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c |  19 +-
 drivers/gpu/drm/msm/msm_drv.c |   2 +
 drivers/gpu/drm/msm/msm_gpu.h |   3 +
 drivers/gpu/drm/msm/ocmem/ocmem.c | 399 ++
 drivers/gpu/drm/msm/ocmem/ocmem.h |  46 
 7 files changed, 463 insertions(+), 28 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 0a543eb..8ddf6fa 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -48,7 +48,8 @@ msm-y := \
msm_iommu.o \
msm_perf.o \
msm_rd.o \
-   msm_ringbuffer.o
+   msm_ringbuffer.o \
+   ocmem/ocmem.o

 msm-$(CONFIG_DRM_MSM_FBDEV) += msm_fbdev.o
 msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index ca29688..2a8bf4c 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -17,10 +17,7 @@
  * this program.  If not, see .
  */

-#ifdef CONFIG_MSM_OCMEM
-#  include 
-#endif
-
+#include "ocmem/ocmem.h"
 #include "a3xx_gpu.h"

 #define A3XX_INT0_MASK \
@@ -322,10 +319,8 @@ static void a3xx_destroy(struct msm_gpu *gpu)

adreno_gpu_cleanup(adreno_gpu);

-#ifdef CONFIG_MSM_OCMEM
-   if (a3xx_gpu->ocmem_base)
+   if (a3xx_gpu->ocmem_hdl)
ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl);
-#endif

kfree(a3xx_gpu);
 }
@@ -539,6 +534,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
struct msm_gpu *gpu;
struct msm_drm_private *priv = dev->dev_private;
struct platform_device *pdev = priv->gpu_pdev;
+   struct ocmem_buf *ocmem_hdl;
int ret;

if (!pdev) {
@@ -569,18 +565,13 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
goto fail;

/* if needed, allocate gmem: */
-   if (adreno_is_a330(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-   /* TODO this is different/missing upstream: */
-   struct ocmem_buf *ocmem_hdl =
-   ocmem_allocate(OCMEM_GRAPHICS, 
adreno_gpu->gmem);
-
+   ocmem_hdl = ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
+   if (!IS_ERR(ocmem_hdl)) {
a3xx_gpu->ocmem_hdl = ocmem_hdl;
a3xx_gpu->ocmem_base = ocmem_hdl->addr;
adreno_gpu->gmem = ocmem_hdl->len;
DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
a3xx_gpu->ocmem_base);
-#endif
}

if (!gpu->mmu) {
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index a53f1be..17f084d 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -10,10 +10,9 @@
  * GNU General Public License for more details.
  *
  */
+
+#include "ocmem/ocmem.h"
 #include "a4xx_gpu.h"
-#ifdef CONFIG_MSM_OCMEM
-#  include 
-#endif

 #define A4XX_INT0_MASK \
(A4XX_INT0_RBBM_AHB_ERROR |\
@@ -289,10 +288,8 @@ static void a4xx_destroy(struct msm_gpu *gpu)

adreno_gpu_cleanup(adreno_gpu);

-#ifdef CONFIG_MSM_OCMEM
-   if (a4xx_gpu->ocmem_base)
+   if (a4xx_gpu->ocmem_hdl)
ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl);
-#endif

kfree(a4xx_gpu);
 }
@@ -538,6 +535,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
struct msm_gpu *gpu;
struct msm_drm_private *priv = dev->dev_private;
struct platform_device *pdev = priv->gpu_pdev;
+   struct ocmem_buf *ocmem_hdl;
int ret;

if (!pdev) {
@@ -568,18 +566,13 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
goto fail;

/* if needed, allocate gmem: */
-   if (adreno_is_a4xx(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-   /* TODO this is different/missing upstream: */
-   struct ocmem_buf *ocmem_hdl =
-   ocmem_allocate(OCMEM_GRAPHICS, 
adreno_gpu->gmem);
-
+   ocmem_hdl = ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
+   if (!IS_ERR(ocmem_hdl)) {
a4xx_gpu->ocmem_hdl = ocmem_hdl;
a4xx_gpu->ocmem_base = ocmem_hdl->addr;
adreno_gpu->gmem = ocmem_hdl->len;
DBG("using %dK of OCMEM at 0x%08x", 

[PATCH 5/6] drm/msm: update generated headers

2015-09-29 Thread Rob Clark
Update generated headers to pull in OCMEM register definitions.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/a2xx.xml.h  |   9 +-
 drivers/gpu/drm/msm/adreno/a3xx.xml.h  |  27 --
 drivers/gpu/drm/msm/adreno/a4xx.xml.h  |  15 ++--
 drivers/gpu/drm/msm/adreno/adreno_common.xml.h |  13 ++-
 drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h|   9 +-
 drivers/gpu/drm/msm/dsi/dsi.xml.h  |   4 +-
 drivers/gpu/drm/msm/dsi/mmss_cc.xml.h  |   4 +-
 drivers/gpu/drm/msm/dsi/sfpb.xml.h |   4 +-
 drivers/gpu/drm/msm/edp/edp.xml.h  |   4 +-
 drivers/gpu/drm/msm/hdmi/hdmi.xml.h|   4 +-
 drivers/gpu/drm/msm/hdmi/qfprom.xml.h  |   4 +-
 drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h|   4 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h|  82 +-
 drivers/gpu/drm/msm/mdp/mdp_common.xml.h   |  11 ++-
 drivers/gpu/drm/msm/ocmem/ocmem.xml.h  | 113 +
 15 files changed, 267 insertions(+), 40 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.xml.h

diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h 
b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
index 0261f0d..9e2aceb 100644
--- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
@@ -8,13 +8,14 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git

 The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml   (
364 bytes, from 2015-05-20 20:03:07)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml   (
398 bytes, from 2015-09-24 17:25:31)
 - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml  (   
1453 bytes, from 2015-05-20 20:03:07)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml  (  
32901 bytes, from 2015-05-20 20:03:14)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml (  
10551 bytes, from 2015-05-20 20:03:14)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml (  
10755 bytes, from 2015-09-14 20:46:55)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml(  
14968 bytes, from 2015-05-20 20:12:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml  (  
67120 bytes, from 2015-08-14 23:22:03)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml  (  
63785 bytes, from 2015-08-14 18:27:06)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml  (  
67771 bytes, from 2015-09-14 20:46:55)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml  (  
63970 bytes, from 2015-09-14 20:50:12)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml (   
1773 bytes, from 2015-09-24 17:30:00)

 Copyright (C) 2013-2015 by the following authors:
 - Rob Clark  (robclark)
diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h 
b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
index 48d1337..97dc1c6 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
@@ -8,13 +8,14 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git

 The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml   (
364 bytes, from 2015-05-20 20:03:07)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml   (
398 bytes, from 2015-09-24 17:25:31)
 - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml  (   
1453 bytes, from 2015-05-20 20:03:07)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml  (  
32901 bytes, from 2015-05-20 20:03:14)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml (  
10551 bytes, from 2015-05-20 20:03:14)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml (  
10755 bytes, from 2015-09-14 20:46:55)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml(  
14968 bytes, from 2015-05-20 20:12:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml  (  
67120 bytes, from 2015-08-14 23:22:03)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml  (  
63785 bytes, from 2015-08-14 18:27:06)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml  (  
67771 bytes, from 2015-09-14 20:46:55)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml  (  
63970 bytes, from 2015-09-14 20:50:12)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml (   
1773 bytes, from 2015-09-24 17:30:00)

 Copyright (C) 2013-2015 by the following authors:
 - Rob Clark  (robclark)
@@ -280,6 +281,8 @@ enum a3xx_rb_blend_opcode {
 enum a3xx_intp_mode {
SMOOTH = 0,
FLAT = 1,
+   ZERO = 2,
+   ONE = 3,
 };

 enum a3xx_repl_mode {
@@ 

[PATCH 4/6] qcom-scm: add ocmem support

2015-09-29 Thread Rob Clark
Add interfaces needed for configuring OCMEM.

Signed-off-by: Rob Clark 
---
 drivers/firmware/qcom_scm-32.c | 53 
 drivers/firmware/qcom_scm-64.c | 16 +++
 drivers/firmware/qcom_scm.c| 61 ++
 drivers/firmware/qcom_scm.h| 12 +
 include/linux/qcom_scm.h   |  7 +
 5 files changed, 149 insertions(+)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index c1e4325..e1ac97f 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 
req_cnt, u32 *resp)
req, req_cnt * sizeof(*req), resp, sizeof(*resp));
 }

+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id)
+{
+   int ret, scm_ret = 0;
+   struct msm_scm_sec_cfg {
+   __le32 id;
+   __le32 spare;
+   } cfg;
+
+   cfg.id = cpu_to_le32(sec_id);
+
+   ret = qcom_scm_call(QCOM_SCM_OCMEM_SECURE_SVC, 
QCOM_SCM_OCMEM_SECURE_CFG,
+   , sizeof(cfg), _ret, sizeof(scm_ret));
+
+   if (ret || scm_ret)
+   return ret ? ret : -EINVAL;
+
+   return 0;
+}
+
+int __qcom_scm_ocmem_lock(u32 id, u32 offset, u32 size, u32 mode)
+{
+   struct ocmem_tz_lock {
+   __le32 id;
+   __le32 offset;
+   __le32 size;
+   __le32 mode;
+   } request;
+
+   request.id = cpu_to_le32(id);
+   request.offset = cpu_to_le32(offset);
+   request.size   = cpu_to_le32(size);
+   request.mode   = cpu_to_le32(mode);
+
+   return qcom_scm_call(QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD,
+   , sizeof(request), NULL, 0);
+}
+
+int __qcom_scm_ocmem_unlock(u32 id, u32 offset, u32 size)
+{
+   struct ocmem_tz_unlock {
+   __le32 id;
+   __le32 offset;
+   __le32 size;
+   } request;
+
+   request.id = cpu_to_le32(id);
+   request.offset = cpu_to_le32(offset);
+   request.size   = cpu_to_le32(size);
+
+   return qcom_scm_call(QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD,
+   , sizeof(request), NULL, 0);
+}
+
 bool __qcom_scm_pas_supported(u32 peripheral)
 {
__le32 out;
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index e64fd92..ef5c59e 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -62,6 +62,22 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 
req_cnt, u32 *resp)
return -ENOTSUPP;
 }

+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id)
+{
+   return -ENOTSUPP;
+}
+
+int __qcom_scm_ocmem_lock(uint32_t id, uint32_t offset, uint32_t size,
+   uint32_t mode)
+{
+   return -ENOTSUPP;
+}
+
+int __qcom_scm_ocmem_unlock(uint32_t id, uint32_t offset, uint32_t size)
+{
+   return -ENOTSUPP;
+}
+
 bool __qcom_scm_pas_supported(u32 peripheral)
 {
return false;
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 118df0a..83a6b77 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -154,6 +154,67 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 
req_cnt, u32 *resp)
 EXPORT_SYMBOL(qcom_scm_hdcp_req);

 /**
+ * qcom_scm_ocmem_secure_available() - Check if secure environment supports
+ * OCMEM.
+ *
+ * Return true if OCMEM secure interface is supported, false if not.
+ */
+bool qcom_scm_ocmem_secure_available(void)
+{
+   return __qcom_scm_is_call_available(QCOM_SCM_OCMEM_SECURE_SVC,
+   QCOM_SCM_OCMEM_SECURE_CFG);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_secure_available);
+
+/**
+ * qcom_scm_ocmem_secure_cfg() - call OCMEM secure cfg interface
+ */
+int qcom_scm_ocmem_secure_cfg(unsigned sec_id)
+{
+   return __qcom_scm_ocmem_secure_cfg(sec_id);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_secure_cfg);
+
+/**
+ * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available
+ */
+bool qcom_scm_ocmem_lock_available(void)
+{
+   return __qcom_scm_is_call_available(QCOM_SCM_OCMEM_SVC,
+   QCOM_SCM_OCMEM_LOCK_CMD);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_lock_available);
+
+/**
+ * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM
+ * region to the specified initiator
+ *
+ * @id: tz initiator id
+ * @offset: OCMEM offset
+ * @size:   OCMEM size
+ * @mode:   access mode (WIDE/NARROW)
+ */
+int qcom_scm_ocmem_lock(u32 id, u32 offset, u32 size, u32 mode)
+{
+   return __qcom_scm_ocmem_lock(id, offset, size, mode);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_lock);
+
+/**
+ * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM
+ * region from the specified initiator
+ *
+ * @id: tz initiator id
+ * @offset: OCMEM offset
+ * @size:   OCMEM size
+ */
+int qcom_scm_ocmem_unlock(u32 id, u32 offset, u32 size)
+{
+   return __qcom_scm_ocmem_unlock(id, offset, 

[PATCH 3/6] qcom-scm: add missing prototype for qcom_scm_is_available()

2015-09-29 Thread Rob Clark
Signed-off-by: Rob Clark 
---
 include/linux/qcom_scm.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index c536b70..e407c0a 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -26,6 +26,8 @@ struct qcom_scm_hdcp_req {
u32 val;
 };

+extern bool qcom_scm_is_available(void);
+
 extern bool qcom_scm_hdcp_available(void);
 extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
u32 *resp);
-- 
2.4.3



[PATCH 2/6] qcom-scm: fix header compile errors

2015-09-29 Thread Rob Clark
Add missing #include for types.h to have u32, etc.  And fwd declare
'struct cpumask'.

Signed-off-by: Rob Clark 
---
 include/linux/qcom_scm.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index 46d41e4..c536b70 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -13,8 +13,11 @@
 #ifndef __QCOM_SCM_H
 #define __QCOM_SCM_H

-extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
-extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
+#include 
+
+struct cpumask;
+extern int qcom_scm_set_cold_boot_addr(void *entry, const struct cpumask 
*cpus);
+extern int qcom_scm_set_warm_boot_addr(void *entry, const struct cpumask 
*cpus);

 #define QCOM_SCM_HDCP_MAX_REQ_CNT  5

-- 
2.4.3



[PATCH 1/6] qcom-scm: fix endianess issue in __qcom_scm_is_call_available

2015-09-29 Thread Rob Clark
Signed-off-by: Rob Clark 
---
 drivers/firmware/qcom_scm-32.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index e9c306b..c1e4325 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -480,15 +480,15 @@ void __qcom_scm_cpu_power_down(u32 flags)
 int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
 {
int ret;
-   u32 svc_cmd = (svc_id << 10) | cmd_id;
-   u32 ret_val = 0;
+   __le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id);
+   __le32 ret_val = 0;

ret = qcom_scm_call(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, _cmd,
sizeof(svc_cmd), _val, sizeof(ret_val));
if (ret)
return ret;

-   return ret_val;
+   return le32_to_cpu(ret_val);
 }

 int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
-- 
2.4.3



[PATCH 0/6] Add OCMEM support (v2)

2015-09-29 Thread Rob Clark
Updates for review comments, plus a couple misc qcom-scm fixes

>From original cover-letter:

For devices such as 8x74 and 8084, which have a separate OCMEM block
used by the GPU (and some other devices), rather than an internal GMEM
block inside the GPU, we need a driver to power up and configure OCMEM
in order to get the GPU working.

This patchset implements a vastly simplified version of the downstream
vendor kernel's OCMEM driver.  Currently it is just enough to enable
the GPU.  But we can worry about other OCMEM users when they have up-
stream drivers.

The first patch adds support for the necessary scm interfaces, for the
parts of the OCMEM configuration that must be done from secure mode.
The second patch can be dropped, as so far this doesn't seem needed for
the GPU (I'm just sending the patch now so it can be found later if it
turns out to be needed).

The remaining two patches add the OCMEM driver inside drm/msm.  If we
eventually have other upstream OCMEM users, this would need to be split
out.  But that should not effect DT bindings, etc, so that is something
that can easily be done later when the need arises.

Rob Clark (6):
  qcom-scm: fix endianess issue in __qcom_scm_is_call_available
  qcom-scm: fix header compile errors
  qcom-scm: add missing prototype for qcom_scm_is_available()
  qcom-scm: add ocmem support
  drm/msm: update generated headers
  drm/msm: add OCMEM driver

 drivers/firmware/qcom_scm-32.c |  59 +++-
 drivers/firmware/qcom_scm-64.c |  16 +
 drivers/firmware/qcom_scm.c|  61 
 drivers/firmware/qcom_scm.h|  12 +
 drivers/gpu/drm/msm/Makefile   |   3 +-
 drivers/gpu/drm/msm/adreno/a2xx.xml.h  |   9 +-
 drivers/gpu/drm/msm/adreno/a3xx.xml.h  |  27 +-
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c  |  19 +-
 drivers/gpu/drm/msm/adreno/a4xx.xml.h  |  15 +-
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c  |  19 +-
 drivers/gpu/drm/msm/adreno/adreno_common.xml.h |  13 +-
 drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h|   9 +-
 drivers/gpu/drm/msm/dsi/dsi.xml.h  |   4 +-
 drivers/gpu/drm/msm/dsi/mmss_cc.xml.h  |   4 +-
 drivers/gpu/drm/msm/dsi/sfpb.xml.h |   4 +-
 drivers/gpu/drm/msm/edp/edp.xml.h  |   4 +-
 drivers/gpu/drm/msm/hdmi/hdmi.xml.h|   4 +-
 drivers/gpu/drm/msm/hdmi/qfprom.xml.h  |   4 +-
 drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h|   4 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h|  82 -
 drivers/gpu/drm/msm/mdp/mdp_common.xml.h   |  11 +-
 drivers/gpu/drm/msm/msm_drv.c  |   2 +
 drivers/gpu/drm/msm/msm_gpu.h  |   3 +
 drivers/gpu/drm/msm/ocmem/ocmem.c  | 399 +
 drivers/gpu/drm/msm/ocmem/ocmem.h  |  46 +++
 drivers/gpu/drm/msm/ocmem/ocmem.xml.h  | 113 +++
 include/linux/qcom_scm.h   |  16 +-
 27 files changed, 889 insertions(+), 73 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.xml.h

-- 
2.4.3



[Bug 91278] Tonga GPU lock/reset fail with Unigine Valley

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=91278

--- Comment #15 from Alex Deucher  ---
These patches may help:
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150928/302380.html
http://lists.freedesktop.org/archives/mesa-dev/2015-September/095718.html

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


[RFC 6/6] drm/i915: add oa_event_min_timer_exponent sysctl

2015-09-29 Thread Robert Bragg
The minimal sampling period is now configurable via a
dev.i915.oa_event_min_timer_exponent sysctl parameter.

Following the precedent set by perf, the default is the minimum that
won't (on its own) exceed the default kernel.perf_event_max_sample_rate
default of 10 samples/s.

Signed-off-by: Robert Bragg 
---
 drivers/gpu/drm/i915/i915_perf.c | 37 -
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index ab82857..5ef7d92 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -42,6 +42,23 @@ static u32 i915_perf_event_paranoid = true;

 #define OA_EXPONENT_MAX 0x3f

+/* for sysctl proc_dointvec_minmax of i915_oa_event_min_timer_exponent */
+static int zero;
+static int oa_exponent_max = OA_EXPONENT_MAX;
+
+/* Theoretically we can program the OA unit to sample every 160ns but don't
+ * allow that by default unless root...
+ *
+ * The period is derived from the exponent as:
+ *
+ *   period = 80ns * 2^(exponent + 1)
+ *
+ * Referring to perf's kernel.perf_event_max_sample_rate for a precedent
+ * (10 by default); with an OA exponent of 6 we get a period of 10.240
+ * microseconds - just under 10Hz
+ */
+static u32 i915_oa_event_min_timer_exponent = 6;
+
 static struct i915_oa_format hsw_oa_formats[I915_OA_FORMAT_MAX] = {
[I915_OA_FORMAT_A13]= { 0, 64 },
[I915_OA_FORMAT_A29]= { 1, 128 },
@@ -674,15 +691,8 @@ static int i915_oa_event_init(struct i915_perf_event 
*event,
if (period_exponent > OA_EXPONENT_MAX)
return -EINVAL;

-   /* Theoretically we can program the OA unit to sample every
-* 160ns but don't allow that by default unless root...
-*
-* Referring to perf's kernel.perf_event_max_sample_rate for
-* a precedent (10 by default); with an OA exponent of
-* 6 we get a period of 10.240 microseconds -just under
-* 10Hz
-*/
-   if (period_exponent < 6 && !capable(CAP_SYS_ADMIN)) {
+   if (period_exponent < i915_oa_event_min_timer_exponent &&
+   !capable(CAP_SYS_ADMIN)) {
DRM_ERROR("Sampling period too high without root 
privileges\n");
return -EACCES;
}
@@ -1113,6 +1123,15 @@ static struct ctl_table oa_table[] = {
 .mode = 0644,
 .proc_handler = proc_dointvec,
 },
+   {
+.procname = "oa_event_min_timer_exponent",
+.data = _oa_event_min_timer_exponent,
+.maxlen = sizeof(i915_oa_event_min_timer_exponent),
+.mode = 0644,
+.proc_handler = proc_dointvec_minmax,
+.extra1 = ,
+.extra2 = _exponent_max,
+},
{}
 };

-- 
2.5.2



[RFC 5/6] drm/i915: Add dev.i915.perf_event_paranoid sysctl option

2015-09-29 Thread Robert Bragg
Consistent with the kernel.perf_event_paranoid sysctl option that can
allow non-root users to access system wide cpu metrics, this can
optionally allow non-root users to access system wide OA counter metrics
from Gen graphics hardware.

Signed-off-by: Robert Bragg 
---
 drivers/gpu/drm/i915/i915_perf.c | 46 +++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index bc1c4d1..ab82857 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -38,6 +38,8 @@
 #define POLL_FREQUENCY 200
 #define POLL_PERIOD max_t(u64, 1, NSEC_PER_SEC / POLL_FREQUENCY)

+static u32 i915_perf_event_paranoid = true;
+
 #define OA_EXPONENT_MAX 0x3f

 static struct i915_oa_format hsw_oa_formats[I915_OA_FORMAT_MAX] = {
@@ -1016,7 +1018,13 @@ int i915_perf_open_ioctl_locked(struct drm_device *dev, 
void *data,
}
}

-   if (!specific_ctx && !capable(CAP_SYS_ADMIN)) {
+   /* Similar to perf's kernel.perf_paranoid_cpu sysctl option
+* we check a dev.i915.perf_event_paranoid sysctl option
+* to determine if it's ok to access system wide OA counters
+* without CAP_SYS_ADMIN privileges.
+*/
+   if (!specific_ctx &&
+   i915_perf_event_paranoid && !capable(CAP_SYS_ADMIN)) {
DRM_ERROR("Insufficient privileges to open perf event\n");
ret = -EACCES;
goto err_ctx;
@@ -1096,6 +1104,38 @@ int i915_perf_open_ioctl(struct drm_device *dev, void 
*data,
return ret;
 }

+
+static struct ctl_table oa_table[] = {
+   {
+.procname = "perf_event_paranoid",
+.data = _perf_event_paranoid,
+.maxlen = sizeof(i915_perf_event_paranoid),
+.mode = 0644,
+.proc_handler = proc_dointvec,
+},
+   {}
+};
+
+static struct ctl_table i915_root[] = {
+   {
+.procname = "i915",
+.maxlen = 0,
+.mode = 0555,
+.child = oa_table,
+},
+   {}
+};
+
+static struct ctl_table dev_root[] = {
+   {
+.procname = "dev",
+.maxlen = 0,
+.mode = 0555,
+.child = i915_root,
+},
+   {}
+};
+
 void i915_perf_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
@@ -1103,6 +1143,8 @@ void i915_perf_init(struct drm_device *dev)
if (!IS_HASWELL(dev))
return;

+   dev_priv->perf.sysctl_header = register_sysctl_table(dev_root);
+
hrtimer_init(_priv->perf.oa.poll_check_timer,
 CLOCK_MONOTONIC, HRTIMER_MODE_REL);
dev_priv->perf.oa.poll_check_timer.function = poll_check_timer_cb;
@@ -1132,6 +1174,8 @@ void i915_perf_fini(struct drm_device *dev)
if (!dev_priv->perf.initialized)
return;

+   unregister_sysctl_table(dev_priv->perf.sysctl_header);
+
dev_priv->perf.oa.ops.init_oa_buffer = NULL;

dev_priv->perf.initialized = false;
-- 
2.5.2



[RFC 4/6] drm/i915: Add i915 perf event for Haswell OA unit

2015-09-29 Thread Robert Bragg
Gen graphics hardware can be set up to periodically write snapshots of
performance counters into a circular buffer via its Observation
Architecture and this patch exposes that capability to userspace via the
i915 perf interface.

Cc: Chris Wilson 
Signed-off-by: Robert Bragg 
Signed-off-by: Zhenyu Wang 
---
 drivers/gpu/drm/i915/i915_drv.h |  57 +++
 drivers/gpu/drm/i915/i915_gem_context.c |  23 +-
 drivers/gpu/drm/i915/i915_perf.c| 697 +++-
 drivers/gpu/drm/i915/i915_reg.h | 338 
 include/uapi/drm/i915_drm.h |  63 +++
 5 files changed, 1171 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0cb36d9..d6db816 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1694,6 +1694,11 @@ struct i915_execbuffer_params {
struct drm_i915_gem_request *request;
 };

+struct i915_oa_format {
+   u32 format;
+   int size;
+};
+
 struct i915_oa_reg {
u32 addr;
u32 value;
@@ -1760,6 +1765,20 @@ struct i915_perf_event {
void (*destroy)(struct i915_perf_event *event);
 };

+struct i915_oa_ops {
+   void (*init_oa_buffer)(struct drm_i915_private *dev_priv);
+   void (*enable_metric_set)(struct drm_i915_private *dev_priv);
+   void (*disable_metric_set)(struct drm_i915_private *dev_priv);
+   void (*oa_enable)(struct drm_i915_private *dev_priv);
+   void (*oa_disable)(struct drm_i915_private *dev_priv);
+   void (*update_oacontrol)(struct drm_i915_private *dev_priv);
+   void (*update_specific_hw_ctx_id)(struct drm_i915_private *dev_priv,
+ u32 ctx_id);
+   void (*read)(struct i915_perf_event *event,
+struct i915_perf_read_state *read_state);
+   bool (*oa_buffer_is_empty)(struct drm_i915_private *dev_priv);
+};
+
 struct drm_i915_private {
struct drm_device *dev;
struct kmem_cache *objects;
@@ -1996,7 +2015,43 @@ struct drm_i915_private {

struct {
bool initialized;
+
struct mutex lock;
+
+   struct ctl_table_header *sysctl_header;
+
+   struct {
+   struct i915_perf_event *exclusive_event;
+
+   u32 specific_ctx_id;
+
+   struct hrtimer poll_check_timer;
+   wait_queue_head_t poll_wq;
+
+   bool periodic;
+   u32 period_exponent;
+
+   u32 metrics_set;
+
+   const struct i915_oa_reg *mux_regs;
+   int mux_regs_len;
+   const struct i915_oa_reg *b_counter_regs;
+   int b_counter_regs_len;
+
+   struct {
+   struct drm_i915_gem_object *obj;
+   u32 gtt_offset;
+   u8 *addr;
+   u32 head;
+   u32 tail;
+   int format;
+   int format_size;
+   } oa_buffer;
+
+   struct i915_oa_ops ops;
+   const struct i915_oa_format *oa_formats;
+   } oa;
+
struct list_head events;
} perf;

@@ -3204,6 +3259,8 @@ int i915_gem_context_setparam_ioctl(struct drm_device 
*dev, void *data,

 int i915_perf_open_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file);
+void i915_oa_context_pin_notify(struct drm_i915_private *dev_priv,
+   struct intel_context *context);

 /* i915_gem_evict.c */
 int __must_check i915_gem_evict_something(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 8e893b3..3c4419c 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -133,6 +133,23 @@ static int get_context_size(struct drm_device *dev)
return ret;
 }

+static int i915_gem_context_pin_state(struct drm_device *dev,
+ struct intel_context *ctx)
+{
+   int ret;
+
+   BUG_ON(!mutex_is_locked(>struct_mutex));
+
+   ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,
+   get_context_alignment(dev), 0);
+   if (ret)
+   return ret;
+
+   i915_oa_context_pin_notify(dev->dev_private, ctx);
+
+   return 0;
+}
+
 void i915_gem_context_free(struct kref *ctx_ref)
 {
struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
@@ -258,8 +275,7 @@ i915_gem_create_context(struct drm_device *dev,
 * be available. To avoid this we always pin the default
 * context.
 */
-   ret = 

[RFC 3/6] drm/i915: Add static '3D' Haswell OA unit config

2015-09-29 Thread Robert Bragg
Adds a static OA unit, MUX + B Counter configuration for basic '3D'
metrics on Haswell. This is autogenerated from an internal XML
description of metric sets.

Signed-off-by: Robert Bragg 
---
 drivers/gpu/drm/i915/Makefile  |  3 +-
 drivers/gpu/drm/i915/i915_drv.h|  5 ++
 drivers/gpu/drm/i915/i915_oa_hsw.c | 98 ++
 drivers/gpu/drm/i915/i915_oa_hsw.h | 36 ++
 4 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/i915_oa_hsw.c
 create mode 100644 drivers/gpu/drm/i915/i915_oa_hsw.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 5485495..5b1c688 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -94,7 +94,8 @@ i915-y += dvo_ch7017.o \
 i915-y += i915_vgpu.o

 # perf code
-i915-y += i915_perf.o
+i915-y += i915_perf.o \
+ i915_oa_hsw.o

 # legacy horrors
 i915-y += i915_dma.o
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c16c9e5..0cb36d9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1694,6 +1694,11 @@ struct i915_execbuffer_params {
struct drm_i915_gem_request *request;
 };

+struct i915_oa_reg {
+   u32 addr;
+   u32 value;
+};
+
 struct i915_perf_read_state {
int count;
ssize_t read;
diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c 
b/drivers/gpu/drm/i915/i915_oa_hsw.c
new file mode 100644
index 000..187bade
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
@@ -0,0 +1,98 @@
+/*
+ * Autogenerated file, DO NOT EDIT manually!
+ *
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "i915_drv.h"
+
+const struct i915_oa_reg i915_oa_3d_b_counter_config_hsw[] = {
+   { 0x2724, 0x0080 },
+   { 0x2720, 0x },
+   { 0x2714, 0x0080 },
+   { 0x2710, 0x },
+};
+const int i915_oa_3d_b_counter_config_hsw_len = 4;
+
+const struct i915_oa_reg i915_oa_3d_mux_config_hsw[] = {
+   { 0x253A4, 0x0160 },
+   { 0x25440, 0x0010 },
+   { 0x25128, 0x },
+   { 0x2691C, 0x0800 },
+   { 0x26AA0, 0x0150 },
+   { 0x26B9C, 0x6000 },
+   { 0x2791C, 0x0800 },
+   { 0x27AA0, 0x0150 },
+   { 0x27B9C, 0x6000 },
+   { 0x2641C, 0x0400 },
+   { 0x25380, 0x0010 },
+   { 0x2538C, 0x },
+   { 0x25384, 0x0800 },
+   { 0x25400, 0x0004 },
+   { 0x2540C, 0x06029000 },
+   { 0x25410, 0x0002 },
+   { 0x25404, 0x5C30 },
+   { 0x25100, 0x0016 },
+   { 0x25110, 0x0400 },
+   { 0x25104, 0x },
+   { 0x26804, 0x1211 },
+   { 0x26884, 0x0100 },
+   { 0x26900, 0x0002 },
+   { 0x26908, 0x0070 },
+   { 0x26904, 0x },
+   { 0x26984, 0x1022 },
+   { 0x26A04, 0x0011 },
+   { 0x26A80, 0x0006 },
+   { 0x26A88, 0x0C02 },
+   { 0x26A84, 0x },
+   { 0x26B04, 0x1000 },
+   { 0x26B80, 0x0002 },
+   { 0x26B8C, 0x0007 },
+   { 0x26B84, 0x },
+   { 0x27804, 0x4844 },
+   { 0x27884, 0x0400 },
+   { 0x27900, 0x0002 },
+   { 0x27908, 0x0E00 },
+   { 0x27904, 0x },
+   { 0x27984, 0x4088 },
+   { 0x27A04, 0x0044 },
+   { 0x27A80, 0x0006 },
+   { 0x27A88, 0x00018040 },
+   { 0x27A84, 0x },
+   { 0x27B04, 0x4000 },
+   { 0x27B80, 0x0002 },
+   { 0x27B8C, 0x00E0 },
+   { 0x27B84, 0x },
+   { 0x26104, 0x },
+   { 0x26184, 0x0C00 },
+   { 0x26284, 0x0400 },
+   { 0x26304, 0x0400 },
+   { 0x26400, 0x0002 },
+   { 0x26410, 0x00A0 },
+   { 0x26404, 0x },
+   { 0x25420, 0x04108020 },

[RFC 2/6] drm/i915: rename OACONTROL GEN7_OACONTROL

2015-09-29 Thread Robert Bragg
OACONTROL changes quite a bit for gen8, with some bits split out into a
per-context OACTXCONTROL register

Signed-off-by: Robert Bragg 
---
 drivers/gpu/drm/i915/i915_cmd_parser.c | 4 ++--
 drivers/gpu/drm/i915/i915_reg.h| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c 
b/drivers/gpu/drm/i915/i915_cmd_parser.c
index 237ff68..d769436 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -439,7 +439,7 @@ static const struct drm_i915_reg_descriptor 
gen7_render_regs[] = {
REG64(CL_PRIMITIVES_COUNT),
REG64(PS_INVOCATION_COUNT),
REG64(PS_DEPTH_COUNT),
-   REG32(OACONTROL), /* Only allowed for LRI and SRM. See below. */
+   REG32(GEN7_OACONTROL), /* Only allowed for LRI and SRM. See below. */
REG64(MI_PREDICATE_SRC0),
REG64(MI_PREDICATE_SRC1),
REG32(GEN7_3DPRIM_END_OFFSET),
@@ -1020,7 +1020,7 @@ static bool check_cmd(const struct intel_engine_cs *ring,
 * to the register. Hence, limit OACONTROL writes to
 * only MI_LOAD_REGISTER_IMM commands.
 */
-   if (reg_addr == OACONTROL) {
+   if (reg_addr == GEN7_OACONTROL) {
if (desc->cmd.value == MI_LOAD_REGISTER_MEM(1)) 
{
DRM_DEBUG_DRIVER("CMD: Rejected LRM to 
OACONTROL\n");
return false;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1fa0554..2e488e8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -536,7 +536,7 @@
 #define GEN7_3DPRIM_START_INSTANCE  0x243C
 #define GEN7_3DPRIM_BASE_VERTEX 0x2440

-#define OACONTROL 0x2360
+#define GEN7_OACONTROL 0x2360

 #define _GEN7_PIPEA_DE_LOAD_SL 0x70068
 #define _GEN7_PIPEB_DE_LOAD_SL 0x71068
-- 
2.5.2



[RFC 1/6] drm/i915: Add i915 perf infrastructure

2015-09-29 Thread Robert Bragg
This adds a DRM_IOCTL_I915_PERF_OPEN ioctl comparable to perf_event_open
that opens a file descriptor for an event source.

Based on our initial experience aiming to use the core perf
infrastructure, this interface is inspired by perf, but focused on
exposing metrics about work running on Gen graphics instead a CPU.

One notable difference is that it doesn't support mmaping a circular
buffer of samples into userspace. The currently planned use cases
require an internal buffering that forces at least one copy of data
which can be neatly hidden in a read() based interface.

No specific event types are supported yet so perf_event_open can currently
only get as far as returning EINVAL for an unknown event type.

Signed-off-by: Robert Bragg 
---
 drivers/gpu/drm/i915/Makefile|   3 +
 drivers/gpu/drm/i915/i915_dma.c  |   7 +
 drivers/gpu/drm/i915/i915_drv.h  |  74 +++
 drivers/gpu/drm/i915/i915_perf.c | 447 +++
 include/uapi/drm/i915_drm.h  |  62 ++
 5 files changed, 593 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/i915_perf.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 44d290a..5485495 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -93,6 +93,9 @@ i915-y += dvo_ch7017.o \
 # virtual gpu code
 i915-y += i915_vgpu.o

+# perf code
+i915-y += i915_perf.o
+
 # legacy horrors
 i915-y += i915_dma.o

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2193cc2..0424e8c 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -841,6 +841,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long 
flags)
mutex_init(_priv->modeset_restore_lock);
mutex_init(_priv->csr_lock);

+   /* Must at least be initialized before trying to pin any context
+* which i915_perf hooks into.
+*/
+   i915_perf_init(dev);
+
intel_pm_setup(dev);

intel_display_crc_init(dev);
@@ -1090,6 +1095,7 @@ int i915_driver_unload(struct drm_device *dev)
return ret;
}

+   i915_perf_fini(dev);
intel_power_domains_fini(dev_priv);

intel_gpu_ips_teardown();
@@ -1280,6 +1286,7 @@ const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, 
DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, 
i915_gem_context_getparam_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, 
i915_gem_context_setparam_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, 
DRM_UNLOCKED|DRM_RENDER_ALLOW),
 };

 int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e0f3f05..c16c9e5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1694,6 +1694,67 @@ struct i915_execbuffer_params {
struct drm_i915_gem_request *request;
 };

+struct i915_perf_read_state {
+   int count;
+   ssize_t read;
+   char __user *buf;
+};
+
+struct i915_perf_event {
+   struct drm_i915_private *dev_priv;
+
+   struct list_head link;
+
+   u32 sample_flags;
+
+   struct intel_context *ctx;
+   bool enabled;
+
+   /* Enables the collection of HW events, either in response to
+* I915_PERF_IOCTL_ENABLE or implicitly called when event is
+* opened without I915_PERF_FLAG_DISABLED */
+   void (*enable)(struct i915_perf_event *event);
+
+   /* Disables the collection of HW events, either in response to
+* I915_PERF_IOCTL_DISABLE or implicitly called before
+* destroying the event. */
+   void (*disable)(struct i915_perf_event *event);
+
+   /* Return: true if any i915 perf records are ready to read()
+* for this event */
+   bool (*can_read)(struct i915_perf_event *event);
+
+   /* Call poll_wait, passing a wait queue that will be woken
+* once there is something to ready to read() for the event */
+   void (*poll_wait)(struct i915_perf_event *event,
+ struct file *file,
+ poll_table *wait);
+
+   /* For handling a blocking read, wait until there is something
+* to ready to read() for the event. E.g. wait on the same
+* wait queue that would be passed to poll_wait() until
+* ->can_read() returns true (if its safe to call ->can_read()
+* without the i915 perf lock held). */
+   int (*wait_unlocked)(struct i915_perf_event *event);
+
+   /* Copy as many buffered i915 perf samples and records for
+* this event to userspace as will fit in the given buffer.
+*
+* Only write complete records.
+*
+* read_state->count is the length of read_state->buf
+*
+* Update read_state->read 

[RFC 0/6] Non perf based Gen Graphics OA unit driver

2015-09-29 Thread Robert Bragg
After some recent progress enabling the Observation Architecture unit
for Gen8+, we can hopefully paint a fairly complete picture of the
requirements for supporting the unit from Haswell to Skylake and so
I'm looking again at the challenges in upstreaming this work.

Considering this, it looked like it could be worthwhile experimenting
with a non-perf based driver for the OA unit and I'm hoping to explain
why and how it went as well as request some feedback on whether we
should aim to move forward without perf.

Besides the patches forwarded here, a branch can be found for reference
here:

  https://github.com/rib/linux - wip/rib/oa-without-perf branch

I created corresponding branches for Mesa and GPU Top to test this here
(same branch names):

  https://github.com/rib/mesa
  https://github.com/rib/gputop

Here I've only included the patches up to an initial Haswell driver,
although the wip/rib/oa-without-perf branch on github includes support
for Gen8+. Please let me know if it would be helpful to forward more.

At this point I have two drivers at feature parity; one based on perf,
one not. Technically they're very similar and the patches are split to
hopefully be quite comparable. My latest perf-based work is under
wip/rib/oa-next branches in the above repos.


So, these are the concerns I have a.t.m about upstreaming this work:


- We're bridging two complex architectures

To review this work I think it will be relevant to have a good
general familiarity with Gen graphics (e.g. thinking about the OA
unit's interaction with the command streamer and execlist
scheduling) as well as our userspace architecture and how we're
consuming OA data within Mesa to implement the
INTEL_performance_query extension.

On the flip side here, its necessary to understand the perf
userspace interface (for most this is hidden by tools so the details
aren't common knowledge) as well as the internal design, considering
that the PMU we're looking at seems to break several current design
assumptions. I can only claim a limited familiarity with perf's
design, just as a result of this work.


- Limited documentation for the OA unit:

Not unique to the OA unit but I think having a driver that extends
outside of the graphics stack, into the core perf infrastructure
probably requires more comprehensive HW + graphics stack
documentation for non drm/i915 developers.  Earlier RFC discussions
were hampered somewhat by limited documentation.  Improved
documentation is always desirable, but of course it can also take a
significant amount of time and effort while some key aspects
(notably the PRMs) aren't directly under my control.


- The current OA PMU driver breaks some significant design assumptions.

Existing perf pmus are used for profiling work on a cpu and we're
introducing the idea of _IS_DEVICE pmus with different security
implications, the need to fake cpu-related data (such as user/kernel
registers) to fit with perf's current design, and adding _DEVICE
records as a way to forward device-specific status records.

The OA unit writes reports of counters into a circular buffer,
without involvement from the CPU, making our PMU driver the first of
a kind.

Given the way we periodically forward data from the OA buffer to
perf's buffer, these bursts of sample writes look to perf like we're
sampling too fast and so it throttles us.

Perf supports groups of counters and allows those to be read via
transactions internally but transactions currently seem designed to
be explicitly initiated from the cpu (say in response to a userspace
read()) and while we could pull a report out of the OA buffer we
can't trigger a report from the cpu on demand.

Related to being report based; the OA counters are configured in HW
as a set while perf generally expects counter configurations to be
orthogonal. Although counters can be associated with a group leader
as they are opened, there's no clear precedent for being able to
provide group-wide configuration attributes and no obvious solution
as yet that's expected to be acceptable to upstream and meets our
userspace needs. We currently avoid using perf's grouping feature
and forward OA reports to userspace via perf's 'raw' sample field.
This suits our userspace well considering how coupled the counters
are when dealing with normalizing. It would be inconvenient to split
counters up into separate events, only to require userspace to
recombine them. For Mesa it's also convenient to be forwarded raw,
periodic reports for combining with the raw reports it captures
using MI_REPORT_PERF_COUNT commands.

Related to counter orthogonality; we can't time share the OA unit,
while event scheduling is a central design idea within perf for
allowing userspace to open + enable more events than can be
configured 

[PATCH 4/6] qcom-scm: add ocmem support

2015-09-29 Thread Stephen Boyd
On 09/29, Rob Clark wrote:
> On Tue, Sep 29, 2015 at 5:38 PM, Stephen Boyd  wrote:
> > On 09/29, Rob Clark wrote:
> >> diff --git a/drivers/firmware/qcom_scm-32.c 
> >> b/drivers/firmware/qcom_scm-32.c
> >> index c1e4325..e1ac97f 100644
> >> --- a/drivers/firmware/qcom_scm-32.c
> >> +++ b/drivers/firmware/qcom_scm-32.c
> >> @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req 
> >> *req, u32 req_cnt, u32 *resp)
> >>   req, req_cnt * sizeof(*req), resp, sizeof(*resp));
> >>  }
> >>
> >> +int __qcom_scm_ocmem_secure_cfg(unsigned sec_id)
> >> +{
> >> + int ret, scm_ret = 0;
> >> + struct msm_scm_sec_cfg {
> >
> > We've left these as anonymous structs for things like
> > qcom_scm_set_boot_addr(), maybe we should do the same here.
> >
> >> + __le32 id;
> >> + __le32 spare;
> >
> > Also, the iommu driver would use this API and it uses this
> > "spare" element, so perhaps this whole function should be renamed
> > to be more generic and take two values. Downstream the function
> > is called scm_restore_sec_cfg, so maybe something similar.  And
> > the service id is MP for "memory protection", so
> > QCOM_SCM_OCMEM_SECURE_SVC could be QCOM_SCM_MEMORY_PROTECTION?
> 
> heh,
> 
> #define SCM_SVC_MP0xC
> #define IOMMU_SECURE_CFG2
> 
> vs.
> 
> #define OCMEM_SECURE_SVC_ID 12
> #define OCMEM_SECURE_CFG_ID 0x2
> 
> that wasn't obscure at all!

:)

> 
> Maybe then there is a better name than spare?  Looks like downstream
> iommu calls it cb_num?

Yeah I think that's the only use to indicate which context bank
it is. Maybe we can have a single id configure API and a special
iommu context bank API that both funnel into the same private two
number API. Otherwise we have a bunch of callers passing 0 for
the second argument because they don't care.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


[PATCH] drm/gma500: fix double freeing

2015-09-29 Thread Patrik Jakobsson
On Thu, Sep 24, 2015 at 5:57 PM, Sudip Mukherjee
 wrote:
> On Wed, Sep 09, 2015 at 06:20:40PM +0530, Sudip Mukherjee wrote:
>> If backing->stolen is true then we were freeing backing by calling
>> psb_gtt_free_range() but we called it again after unlocking the mutex.
>> Lets make it NULL after freeing in psb_gtt_free_range() and check for
>> NULL before calling the function for the second time.
>>
>> Signed-off-by: Sudip Mukherjee 
>> ---
> Hi Patrik,
> A gentle ping.
>
> regards
> sudip

Hi, sorry for the late reply.

Why are we freeing the range twice in the first case?

-Patrik


[PATCH] drm/radeon: Restore LCD backlight level on resume (>= R5xx)

2015-09-29 Thread Alex Deucher
On Mon, Sep 28, 2015 at 5:16 AM, Michel Dänzer  wrote:
> From: Michel Dänzer 
>
> Instead of only enabling the backlight (which seems to set it to max
> brightness), just re-set the current backlight level, which also takes
> care of enabling the backlight if necessary.
>
> Only the radeon_atom_encoder_dpms_dig part tested on a Kaveri laptop,
> the radeon_atom_encoder_dpms_avivo part is only compile tested.
>
> Cc: stable at vger.kernel.org
> Signed-off-by: Michel Dänzer 

Applied and committed a similar fix for amdgpu.

Thanks!

Alex

> ---
>  drivers/gpu/drm/radeon/atombios_encoders.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c 
> b/drivers/gpu/drm/radeon/atombios_encoders.c
> index c387259..65adb9c 100644
> --- a/drivers/gpu/drm/radeon/atombios_encoders.c
> +++ b/drivers/gpu/drm/radeon/atombios_encoders.c
> @@ -1624,8 +1624,9 @@ radeon_atom_encoder_dpms_avivo(struct drm_encoder 
> *encoder, int mode)
> } else
> atom_execute_table(rdev->mode_info.atom_context, 
> index, (uint32_t *));
> if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
> -   args.ucAction = ATOM_LCD_BLON;
> -   atom_execute_table(rdev->mode_info.atom_context, 
> index, (uint32_t *));
> +   struct radeon_encoder_atom_dig *dig = 
> radeon_encoder->enc_priv;
> +
> +   atombios_set_backlight_level(radeon_encoder, 
> dig->backlight_level);
> }
> break;
> case DRM_MODE_DPMS_STANDBY:
> @@ -1706,8 +1707,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder 
> *encoder, int mode)
> atombios_dig_encoder_setup(encoder, 
> ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
> }
> if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
> -   atombios_dig_transmitter_setup(encoder,
> -  
> ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
> +   atombios_set_backlight_level(radeon_encoder, 
> dig->backlight_level);
> if (ext_encoder)
> atombios_external_encoder_setup(encoder, ext_encoder, 
> ATOM_ENABLE);
> break;
> --
> 2.5.0
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 1/2] drm/dp: Store the drm_connector device pointer on the helper.

2015-09-29 Thread Lukas Wunner
Hi Rafael,

On Mon, Sep 28, 2015 at 04:45:35PM -0700, Rafael Antognolli wrote:
> This is useful to determine which connector owns this AUX channel.

WTF? I posted a patch in August which does exactly that:
http://lists.freedesktop.org/archives/dri-devel/2015-August/088172.html

Can also be pulled in from this git repo:
https://github.com/l1k/linux/commit/b78b38d53fc0fc4fa0f6acf699b0fcad56ec1fe6

My patch has the advantage that it updates all the drivers which use
drm_dp_aux to fill that attribute. Yours only updates i915.

Daniel Vetter criticized storing a drm_connector pointer in drm_dp_aux,
quote:

"That will also clear up the confusion with drm_dp_aux, adding a
drm_connector there feels wrong since not every dp_aux line has a
connector (e.g. for dp mst). If we can lift this relation out into drivers
(where this is known) that seems cleaner."

So now Intel itself does precisely what Daniel criticized? Confusing!

Source:
http://lists.freedesktop.org/archives/dri-devel/2015-August/089108.html


Best regards,

Lukas


> 
> Signed-off-by: Rafael Antognolli 
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 1 +
>  include/drm/drm_dp_helper.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 77f7330..f90439d 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1079,6 +1079,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct 
> intel_connector *connector)
>  
>   intel_dp->aux.name = name;
>   intel_dp->aux.dev = dev->dev;
> + intel_dp->aux.connector = connector->base.kdev;
>   intel_dp->aux.transfer = intel_dp_aux_transfer;
>  
>   DRM_DEBUG_KMS("registering %s bus for %s\n", name,
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 9ec4716..e009b5d 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -702,6 +702,7 @@ struct drm_dp_aux {
>   const char *name;
>   struct i2c_adapter ddc;
>   struct device *dev;
> + struct device *connector;
>   struct mutex hw_mutex;
>   ssize_t (*transfer)(struct drm_dp_aux *aux,
>   struct drm_dp_aux_msg *msg);
> -- 
> 2.4.3
> 
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 07/12] drm/amdgpu: implement cgs gpu memory callbacks

2015-09-29 Thread Christian König
On 29.09.2015 13:40, Daniel Vetter wrote:
> On Thu, Jul 09, 2015 at 12:21:06PM -0400, Alex Deucher wrote:
>> From: Chunming Zhou 
>>
>> This implements the cgs interface for allocating
>> GPU memory.
>>
>> Reviewed-by: Jammy Zhou 
> I don't see that review anywhere on a m-l ... where is it?

Jammy reviewed the stuff internally before we made it public, that's why 
you can't find it.

>
> I stumbled over this patch because it adds a new dev->struct_mutex user
> (that should be a big warning sign) and then I somehow unrolled some giant
> chain of wtfs. Either I'm completely missing what this is used for or it
> probably should get reworked asap.

The CGS functions aren't used at the moment because none of the 
components depending on them made it into the kernel, but we wanted to 
keep it so that we can get reviews on the general idea and if necessary 
rework it.

In general it's an abstraction layer of device driver dependent 
functions which enables us to share more code internally.

We worked quite hard on trying to avoid the OS abstraction trap with 
this, but if you think this still won't work feel free to object.

Regards,
Christian.

> -Daniel
>
>> Signed-off-by: Chunming Zhou 
>> Signed-off-by: Alex Deucher 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 238 
>> ++--
>>   1 file changed, 226 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
>> index c1ee39e..ac0f124 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
>> @@ -21,7 +21,11 @@
>>*
>>*
>>*/
>> +#include 
>> +#include 
>>   #include 
>> +#include 
>> +#include 
>>   #include "amdgpu.h"
>>   #include "cgs_linux.h"
>>   #include "atom.h"
>> @@ -39,6 +43,30 @@ static int amdgpu_cgs_gpu_mem_info(void *cgs_device, enum 
>> cgs_gpu_mem_type type,
>> uint64_t *mc_start, uint64_t *mc_size,
>> uint64_t *mem_size)
>>   {
>> +CGS_FUNC_ADEV;
>> +switch(type) {
>> +case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
>> +case CGS_GPU_MEM_TYPE__VISIBLE_FB:
>> +*mc_start = 0;
>> +*mc_size = adev->mc.visible_vram_size;
>> +*mem_size = adev->mc.visible_vram_size - adev->vram_pin_size;
>> +break;
>> +case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
>> +case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
>> +*mc_start = adev->mc.visible_vram_size;
>> +*mc_size = adev->mc.real_vram_size - adev->mc.visible_vram_size;
>> +*mem_size = *mc_size;
>> +break;
>> +case CGS_GPU_MEM_TYPE__GART_CACHEABLE:
>> +case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE:
>> +*mc_start = adev->mc.gtt_start;
>> +*mc_size = adev->mc.gtt_size;
>> +*mem_size = adev->mc.gtt_size - adev->gart_pin_size;
>> +break;
>> +default:
>> +return -EINVAL;
>> +}
>> +
>>  return 0;
>>   }
>>   
>> @@ -47,11 +75,43 @@ static int amdgpu_cgs_gmap_kmem(void *cgs_device, void 
>> *kmem,
>>  uint64_t min_offset, uint64_t max_offset,
>>  cgs_handle_t *kmem_handle, uint64_t *mcaddr)
>>   {
>> -return 0;
>> +CGS_FUNC_ADEV;
>> +int ret;
>> +struct amdgpu_bo *bo;
>> +struct page *kmem_page = vmalloc_to_page(kmem);
>> +int npages = ALIGN(size, PAGE_SIZE) >> PAGE_SHIFT;
>> +
>> +struct sg_table *sg = drm_prime_pages_to_sg(_page, npages);
>> +ret = amdgpu_bo_create(adev, size, PAGE_SIZE, false,
>> +   AMDGPU_GEM_DOMAIN_GTT, 0, sg, );
>> +if (ret)
>> +return ret;
>> +ret = amdgpu_bo_reserve(bo, false);
>> +if (unlikely(ret != 0))
>> +return ret;
>> +
>> +/* pin buffer into GTT */
>> +ret = amdgpu_bo_pin_restricted(bo, AMDGPU_GEM_DOMAIN_GTT,
>> +   min_offset, max_offset, mcaddr);
>> +amdgpu_bo_unreserve(bo);
>> +
>> +*kmem_handle = (cgs_handle_t)bo;
>> +return ret;
>>   }
>>   
>>   static int amdgpu_cgs_gunmap_kmem(void *cgs_device, cgs_handle_t 
>> kmem_handle)
>>   {
>> +struct amdgpu_bo *obj = (struct amdgpu_bo *)kmem_handle;
>> +
>> +if (obj) {
>> +int r = amdgpu_bo_reserve(obj, false);
>> +if (likely(r == 0)) {
>> +amdgpu_bo_unpin(obj);
>> +amdgpu_bo_unreserve(obj);
>> +}
>> +amdgpu_bo_unref();
>> +
>> +}
>>  return 0;
>>   }
>>   
>> @@ -61,46 +121,200 @@ static int amdgpu_cgs_alloc_gpu_mem(void *cgs_device,
>>  uint64_t min_offset, uint64_t max_offset,
>>  cgs_handle_t *handle)
>>   {
>> -return 0;
>> +CGS_FUNC_ADEV;
>> +uint16_t flags = 0;
>> +int ret = 0;
>> +uint32_t domain = 0;
>> +struct amdgpu_bo *obj;
>> +

[PATCH 4/6] qcom-scm: add ocmem support

2015-09-29 Thread Stephen Boyd
On 09/29, Rob Clark wrote:
> diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
> index c1e4325..e1ac97f 100644
> --- a/drivers/firmware/qcom_scm-32.c
> +++ b/drivers/firmware/qcom_scm-32.c
> @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, 
> u32 req_cnt, u32 *resp)
>   req, req_cnt * sizeof(*req), resp, sizeof(*resp));
>  }
>  
> +int __qcom_scm_ocmem_secure_cfg(unsigned sec_id)
> +{
> + int ret, scm_ret = 0;
> + struct msm_scm_sec_cfg {

We've left these as anonymous structs for things like
qcom_scm_set_boot_addr(), maybe we should do the same here.

> + __le32 id;
> + __le32 spare;

Also, the iommu driver would use this API and it uses this
"spare" element, so perhaps this whole function should be renamed
to be more generic and take two values. Downstream the function
is called scm_restore_sec_cfg, so maybe something similar.  And
the service id is MP for "memory protection", so
QCOM_SCM_OCMEM_SECURE_SVC could be QCOM_SCM_MEMORY_PROTECTION?

Otherwise this patch looks good.

> + } cfg;
> +
> + cfg.id = cpu_to_le32(sec_id);
> +
> + ret = qcom_scm_call(QCOM_SCM_OCMEM_SECURE_SVC, 
> QCOM_SCM_OCMEM_SECURE_CFG,
> + , sizeof(cfg), _ret, sizeof(scm_ret));
> +
> + if (ret || scm_ret)

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


[PATCH 2/6] qcom-scm: fix header compile errors

2015-09-29 Thread Stephen Boyd
On 09/29, Rob Clark wrote:
> Add missing #include for types.h to have u32, etc.  And fwd declare
> 'struct cpumask'.
> 
> Signed-off-by: Rob Clark 
> ---

We should change the arguments for the implementation too.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


[PATCH 1/6] qcom-scm: fix endianess issue in __qcom_scm_is_call_available

2015-09-29 Thread Stephen Boyd
On 09/29, Rob Clark wrote:
> Signed-off-by: Rob Clark 
> ---

Reviewed-by: Stephen Boyd 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


[PATCH] drm/rockchip: vop: Correct enabled clocks during setup

2015-09-29 Thread Sjoerd Simons
On Tue, 2015-09-29 at 18:58 +0800, Yakir Yang wrote:
> 
> On 09/29/2015 05:55 PM, Yakir Yang wrote:
> > 
> > 
> > On 09/29/2015 05:28 PM, Sjoerd Simons wrote:
> > > When doing the initial setup both the hclk and the aclk need to
> > > be
> > > enabled otherwise the board will simply hang. This only occurs
> > > when
> > > building the vop driver as a module, when its built-in the
> > > initial setup
> 
> Hmm... My previous test was built-in the vop driver, and just notice
> that
> you say problem only occurred when building the vop driver as module.
> That's to say my test was wrong, so I try to do the right things.
> 
> But I found that vop driver module and rockchipdrm driver module in
> dependency cycles, here are the build message:
>  depmod: ERROR: Found 2 modules in dependency cycles!


I've only tested with mainline which doesn't seem to have that issue?
So can't easily help you there unfortunately.


> Thanks,
> - Yakir
> 
> > > happens to run before the clock framework shuts of unused clocks
> > > (including the aclk).
> > > 
> > > While there also switch to doing prepare and enable in one step
> > > rather
> > > then separate steps to reduce the amount of code required.
> > > 
> > > Signed-off-by: Sjoerd Simons 
> > 
> > Looks good and test on chromeos-3.14 tree, no problem, so
> > 
> > Tested-by: Yakir Yang 
> > 
> > > ---
> > > 
> > >   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 
> > > +++--
> > >   1 file changed, 14 insertions(+), 22 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> > > b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > > index 5d8ae5e..48719df 100644
> > > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > > @@ -1575,32 +1575,25 @@ static int vop_initial(struct vop *vop)
> > >   return PTR_ERR(vop->dclk);
> > >   }
> > >   -ret = clk_prepare(vop->hclk);
> > > -if (ret < 0) {
> > > -dev_err(vop->dev, "failed to prepare hclk\n");
> > > -return ret;
> > > -}
> > > -
> > >   ret = clk_prepare(vop->dclk);
> > >   if (ret < 0) {
> > >   dev_err(vop->dev, "failed to prepare dclk\n");
> > > -goto err_unprepare_hclk;
> > > +return ret;
> > >   }
> > >   -ret = clk_prepare(vop->aclk);
> > > +/* Enable both the hclk and aclk to setup the vop */
> > > +ret = clk_prepare_enable(vop->hclk);
> > >   if (ret < 0) {
> > > -dev_err(vop->dev, "failed to prepare aclk\n");
> > > +dev_err(vop->dev, "failed to prepare/enable hclk\n");
> > >   goto err_unprepare_dclk;
> > >   }
> > >   -/*
> > > - * enable hclk, so that we can config vop register.
> > > - */
> > > -ret = clk_enable(vop->hclk);
> > > +ret = clk_prepare_enable(vop->aclk);
> > >   if (ret < 0) {
> > > -dev_err(vop->dev, "failed to prepare aclk\n");
> > > -goto err_unprepare_aclk;
> > > +dev_err(vop->dev, "failed to prepare/enable aclk\n");
> > > +goto err_disable_hclk;
> > >   }
> > > +
> > >   /*
> > >* do hclk_reset, reset all vop registers.
> > >*/
> > > @@ -1608,7 +1601,7 @@ static int vop_initial(struct vop *vop)
> > >   if (IS_ERR(ahb_rst)) {
> > >   dev_err(vop->dev, "failed to get ahb reset\n");
> > >   ret = PTR_ERR(ahb_rst);
> > > -goto err_disable_hclk;
> > > +goto err_disable_aclk;
> > >   }
> > >   reset_control_assert(ahb_rst);
> > >   usleep_range(10, 20);
> > > @@ -1634,26 +1627,25 @@ static int vop_initial(struct vop *vop)
> > >   if (IS_ERR(vop->dclk_rst)) {
> > >   dev_err(vop->dev, "failed to get dclk reset\n");
> > >   ret = PTR_ERR(vop->dclk_rst);
> > > -goto err_unprepare_aclk;
> > > +goto err_disable_aclk;
> > >   }
> > >   reset_control_assert(vop->dclk_rst);
> > >   usleep_range(10, 20);
> > >   reset_control_deassert(vop->dclk_rst);
> > > clk_disable(vop->hclk);
> > > +clk_disable(vop->aclk);
> > > vop->is_enabled = false;
> > > return 0;
> > >   +err_disable_aclk:
> > > +clk_disable_unprepare(vop->aclk);
> > >   err_disable_hclk:
> > > -clk_disable(vop->hclk);
> > > -err_unprepare_aclk:
> > > -clk_unprepare(vop->aclk);
> > > +clk_disable_unprepare(vop->hclk);
> > >   err_unprepare_dclk:
> > >   clk_unprepare(vop->dclk);
> > > -err_unprepare_hclk:
> > > -clk_unprepare(vop->hclk);
> > >   return ret;
> > >   }
> > 
> 
> 

-- 
Sjoerd Simons
Collabora Ltd.


[patch] drm/amdgpu: signedness bug in amdgpu_cs_parser_init()

2015-09-29 Thread Alex Deucher
On Fri, Sep 25, 2015 at 7:36 AM, Dan Carpenter  
wrote:
> The "i" variable should be signed or it leads to a crash in the error
> handling code.
>
> Fixes: 1d263474c441 ('drm/amdgpu: unwind properly in amdgpu_cs_parser_init()')
> Signed-off-by: Dan Carpenter 

Applied.  thanks!

Alex

>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index 749420f..cb3c274 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -156,7 +156,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, 
> void *data)
> uint64_t *chunk_array_user;
> uint64_t *chunk_array;
> struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
> -   unsigned size, i;
> +   unsigned size;
> +   int i;
> int ret;
>
> if (cs->in.num_chunks == 0)
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 07/12] drm/amdgpu: implement cgs gpu memory callbacks

2015-09-29 Thread Daniel Vetter
On Thu, Jul 09, 2015 at 12:21:06PM -0400, Alex Deucher wrote:
> From: Chunming Zhou 
> 
> This implements the cgs interface for allocating
> GPU memory.
> 
> Reviewed-by: Jammy Zhou 

I don't see that review anywhere on a m-l ... where is it?

I stumbled over this patch because it adds a new dev->struct_mutex user
(that should be a big warning sign) and then I somehow unrolled some giant
chain of wtfs. Either I'm completely missing what this is used for or it
probably should get reworked asap.
-Daniel

> Signed-off-by: Chunming Zhou 
> Signed-off-by: Alex Deucher 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 238 
> ++--
>  1 file changed, 226 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> index c1ee39e..ac0f124 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> @@ -21,7 +21,11 @@
>   *
>   *
>   */
> +#include 
> +#include 
>  #include 
> +#include 
> +#include 
>  #include "amdgpu.h"
>  #include "cgs_linux.h"
>  #include "atom.h"
> @@ -39,6 +43,30 @@ static int amdgpu_cgs_gpu_mem_info(void *cgs_device, enum 
> cgs_gpu_mem_type type,
>  uint64_t *mc_start, uint64_t *mc_size,
>  uint64_t *mem_size)
>  {
> + CGS_FUNC_ADEV;
> + switch(type) {
> + case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
> + case CGS_GPU_MEM_TYPE__VISIBLE_FB:
> + *mc_start = 0;
> + *mc_size = adev->mc.visible_vram_size;
> + *mem_size = adev->mc.visible_vram_size - adev->vram_pin_size;
> + break;
> + case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
> + case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
> + *mc_start = adev->mc.visible_vram_size;
> + *mc_size = adev->mc.real_vram_size - adev->mc.visible_vram_size;
> + *mem_size = *mc_size;
> + break;
> + case CGS_GPU_MEM_TYPE__GART_CACHEABLE:
> + case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE:
> + *mc_start = adev->mc.gtt_start;
> + *mc_size = adev->mc.gtt_size;
> + *mem_size = adev->mc.gtt_size - adev->gart_pin_size;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
>   return 0;
>  }
>  
> @@ -47,11 +75,43 @@ static int amdgpu_cgs_gmap_kmem(void *cgs_device, void 
> *kmem,
>   uint64_t min_offset, uint64_t max_offset,
>   cgs_handle_t *kmem_handle, uint64_t *mcaddr)
>  {
> - return 0;
> + CGS_FUNC_ADEV;
> + int ret;
> + struct amdgpu_bo *bo;
> + struct page *kmem_page = vmalloc_to_page(kmem);
> + int npages = ALIGN(size, PAGE_SIZE) >> PAGE_SHIFT;
> +
> + struct sg_table *sg = drm_prime_pages_to_sg(_page, npages);
> + ret = amdgpu_bo_create(adev, size, PAGE_SIZE, false,
> +AMDGPU_GEM_DOMAIN_GTT, 0, sg, );
> + if (ret)
> + return ret;
> + ret = amdgpu_bo_reserve(bo, false);
> + if (unlikely(ret != 0))
> + return ret;
> +
> + /* pin buffer into GTT */
> + ret = amdgpu_bo_pin_restricted(bo, AMDGPU_GEM_DOMAIN_GTT,
> +min_offset, max_offset, mcaddr);
> + amdgpu_bo_unreserve(bo);
> +
> + *kmem_handle = (cgs_handle_t)bo;
> + return ret;
>  }
>  
>  static int amdgpu_cgs_gunmap_kmem(void *cgs_device, cgs_handle_t kmem_handle)
>  {
> + struct amdgpu_bo *obj = (struct amdgpu_bo *)kmem_handle;
> +
> + if (obj) {
> + int r = amdgpu_bo_reserve(obj, false);
> + if (likely(r == 0)) {
> + amdgpu_bo_unpin(obj);
> + amdgpu_bo_unreserve(obj);
> + }
> + amdgpu_bo_unref();
> +
> + }
>   return 0;
>  }
>  
> @@ -61,46 +121,200 @@ static int amdgpu_cgs_alloc_gpu_mem(void *cgs_device,
>   uint64_t min_offset, uint64_t max_offset,
>   cgs_handle_t *handle)
>  {
> - return 0;
> + CGS_FUNC_ADEV;
> + uint16_t flags = 0;
> + int ret = 0;
> + uint32_t domain = 0;
> + struct amdgpu_bo *obj;
> + struct ttm_placement placement;
> + struct ttm_place place;
> +
> + if (min_offset > max_offset) {
> + BUG_ON(1);
> + return -EINVAL;
> + }
> +
> + /* fail if the alignment is not a power of 2 */
> + if (((align != 1) && (align & (align - 1)))
> + || size == 0 || align == 0)
> + return -EINVAL;
> +
> +
> + switch(type) {
> + case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
> + case CGS_GPU_MEM_TYPE__VISIBLE_FB:
> + flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
> + domain = AMDGPU_GEM_DOMAIN_VRAM;
> + if (max_offset > adev->mc.real_vram_size)
> + return -EINVAL;
> + place.fpfn = min_offset 

[PATCH] CHROMIUM: drm: bridge/dw_hdmi: Eliminate unused cable_plugin

2015-09-29 Thread Thierry Reding
On Fri, Sep 25, 2015 at 10:29:51AM +0200, Philipp Zabel wrote:
> Am Montag, den 21.09.2015, 15:15 +0100 schrieb Russell King - ARM Linux:
> > On Mon, Sep 21, 2015 at 11:51:06AM +0200, Thierry Reding wrote:
> > > On Wed, Sep 16, 2015 at 01:41:38PM -0700, Douglas Anderson wrote:
> > > > There's a member in 'struct dw_hdmi' called cable_plugin.  It's never
> > > > set to anything anywhere so thus is always false.  There's a bit of code
> > > > checking it, but since it's always false this must be dead code.
> > > > Eliminate it.
> > > > 
> > > > Note: if someone wants to figure out the intention of the original code
> > > > and implement whatever feature / fix was needed then we can drop this
> > > > patch.  The 'cable_plugin' member has been unused since the code was
> > > > first added in (9aaf880 imx-drm: Add mx6 hdmi transmitter support).
> > > > 
> > > > Signed-off-by: Douglas Anderson 
> > > > ---
> > > >  drivers/gpu/drm/bridge/dw_hdmi.c | 9 -
> > > >  1 file changed, 9 deletions(-)
> > > 
> > > Except for the CHROMIUM: prefix this looks good to me:
> > > 
> > > Reviewed-by: Thierry Reding 
> 
> This seems to be similar to Sascha's "drm: bridge/dw_hdmi: remove unused
> code" patch, except that the hdmi_disable_overflow_interrupts function
> could be removed too.
> 
> > > Russell, do you have patches to this driver queued for v4.4 and plan to
> > > pick this up into your tree or should I take it?
> > 
> > My current patch stack for imx-drm related stuff looks like this at
> > present:
> >
> > drm: bridge/dw_hdmi: place PHY into low power mode when disabled
> > drm: bridge/dw_hdmi: start of support for pixel doubled modes
> > drm: bridge/dw_hdmi: remove CEC engine register definitions
> > drm: bridge/dw_hdmi-cec: add Designware HDMI CEC driver
> > cec: add HDMI CEC input driver
> > cec: add HDMI CEC core driver
> > drm: bridge/dw_hdmi: replace CTS calculation for the ACR
> > drm: bridge/dw_hdmi: remove ratio support from ACR code
> > drm: bridge/dw_hdmi: adjust pixel clock values in N calculation
> > drm: bridge/dw_hdmi: avoid being recursive in N calculation
> > drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes
> > drm: bridge/dw_hdmi-ahb-audio: basic support for multi-channel PCM audio
> > drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
> > drm: bridge/dw_hdmi-ahb-audio: add audio driver
> > drm: bridge/dw_hdmi: improve HDMI enable/disable handling
> > drm: bridge/dw_hdmi: add connector mode forcing
> > drm: bridge/dw_hdmi: add support for interlaced video modes
> > gpu: imx: fix support for interlaced modes
> > gpu: imx: simplify sync polarity setting
> > 
> > I haven't yet decided what, if anything, from that stack I'm going to
> > try to get into the next merge window.  Given the lack of interest last
> > time I posted these patches, I'm loosing interest myself in trying to
> > get them merged, especially ones which are getting on for being 2 years
> > old.
> 
> I'm still very interested to see at least the "gpu: imx: fix support for
> interlaced modes" and "gpu: imx: simplify sync polarity setting" merged.
> May I take them into the imx-drm tree separately?

The "gpu: imx:" patches sound like they are standalone, so taking them
through the imx-drm tree would be the easiest.

Thierry
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150929/8b2a31bc/attachment.sig>


WARNING: CPU: 4 PID: 863 at include/drm/drm_crtc.h:1577 drm_helper_choose_encoder_dpms+0x88/0x90() - evildoer found and neutralized

2015-09-29 Thread Borislav Petkov
On Tue, Sep 29, 2015 at 04:50:36PM +0800, Jiang Liu wrote:
> So could you please help to apply the attached debug patch to gather
> more information about the regression?

Sure, just did.

I'm sending you a full s/r cycle attempt caught over serial in a private
message.

Thanks.

-- 
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--


[PATCH 07/12] drm/amdgpu: implement cgs gpu memory callbacks

2015-09-29 Thread Alex Deucher
On Tue, Sep 29, 2015 at 11:20 AM, Daniel Vetter  wrote:
> On Tue, Sep 29, 2015 at 02:39:49PM +0200, Christian König wrote:
>> On 29.09.2015 13:40, Daniel Vetter wrote:
>> >On Thu, Jul 09, 2015 at 12:21:06PM -0400, Alex Deucher wrote:
>> >>From: Chunming Zhou 
>> >>
>> >>This implements the cgs interface for allocating
>> >>GPU memory.
>> >>
>> >>Reviewed-by: Jammy Zhou 
>> >I don't see that review anywhere on a m-l ... where is it?
>>
>> Jammy reviewed the stuff internally before we made it public, that's why you
>> can't find it.
>>
>> >
>> >I stumbled over this patch because it adds a new dev->struct_mutex user
>> >(that should be a big warning sign) and then I somehow unrolled some giant
>> >chain of wtfs. Either I'm completely missing what this is used for or it
>> >probably should get reworked asap.
>>
>> The CGS functions aren't used at the moment because none of the components
>> depending on them made it into the kernel, but we wanted to keep it so that
>> we can get reviews on the general idea and if necessary rework it.
>>
>> In general it's an abstraction layer of device driver dependent functions
>> which enables us to share more code internally.
>>
>> We worked quite hard on trying to avoid the OS abstraction trap with this,
>> but if you think this still won't work feel free to object.
>
> The bit that made me look really is the import_gpu_mem thing, which seems
> to partially reinvent drm_prime.c. Given how tricky importing and
> import-caching is I'd really like to see that gone (and Alex said on irc
> he'd be ok with that).
>

See attached patch.  It was really only added for completeness.  We
don't have any users of it at the moment.  If we end up needing the
functionality in the future we can revisit it.

> The other stuff seems a lot more benign. For the irq abstraction
> specifically it might be worth looking at the irq_chip stuff linux core
> has, which is what's used to virtualize/abstract irq routing and handling.
> But for that stuff it's a balance thing really how much you reinvent
> wheels internally in the driver (e.g. i915 has it's own power_well stuff
> which is pretty much just powerdomains reinvented, with less features).
>

I think that's one of the hardest things in the kernel: finding out if
a solution already exists or not.  We implemented our own version of
mfd for our ACP audio block driver.  Upon upsteaming we were alerted
to mfd's existence and we converted the driver to use mfd.  At the end
of the day it was a lot of work for minimal gain, at least from a
functionality perspective.  I wish we had known about it sooner.  I'll
take a look at the irq_chip stuff.  Thanks for the heads up!

Alex

> But really I can't tell without the users whether I'd expect this to be
> hurt longterm or not for you ;-) But the import stuff is hurt for me since
> you noodle around in drm internals. And specifically I'd like to make
> modern drivers completely struct_mutex free with the goal to untangle the
> last hold-outs of that lock in the drm core.
> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
-- next part --
A non-text attachment was scrubbed...
Name: 0001-drm-amdgpu-cgs-remove-import_gpu_mem.patch
Type: text/x-patch
Size: 3760 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150929/1e0f0d74/attachment-0001.bin>


No more new fbdev drivers, please

2015-09-29 Thread Laurent Pinchart
Hi Gerd,

On Tuesday 29 September 2015 10:23:23 Gerd Hoffmann wrote:
> On Mo, 2015-09-28 at 14:36 +0200, Daniel Vetter wrote:
> > On Mon, Sep 28, 2015 at 09:39:13AM +0200, Gerd Hoffmann wrote:
> > >   Hi,
> > >   
> > > > As Daniel mentioned, the connector+encoder+crtc combination is one of
> > > > those simplifications that would make sense if more such drivers are
> > > > added.
> > > 
> > > Another one is memory management.  It's pretty complex because it can
> > > handle _way_ more than what simple drivers need, and the result is
> > > _alot_ of ttm boilerplate in the drivers.
> > 
> > ttm is pretty impressive overkill for most simplistic drm drivers. If you
> > just need contiguous framebuffers for display then the cma helpers should
> > take care of pretty much all the boilerplate for you. They have ready-made
> > simple gem and dumb framebuffer mmap support, which is all a basic kms
> > driver needs.
> 
> Does that work on !arm meanwhile?  Last time I checked (when writing
> bochsdrm, around v3.14) the cma helpers didn't even build on x86 ...

config DRM_GEM_CMA_HELPER
bool
depends on DRM && HAVE_DMA_ATTRS
help
  Choose this if you need the GEM CMA helper functions

x86 defines HAVE_DMA_ATTRS.

-- 
Regards,

Laurent Pinchart



[Intel-gfx] [PATCH v4 1/2] drm/dp: Store the drm_connector device pointer on the helper.

2015-09-29 Thread kbuild test robot
em.c:3355: warning: No description found for 
parameter 'obj'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for 
parameter 'vm'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for 
parameter 'ggtt_view'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for 
parameter 'alignment'

vim +/connector +703 include/drm/drm_dp_helper.h

1d002fa7 Simon Farnsworth  2015-02-10  687   * received, the adapter will drop 
down to the size given by the partial
1d002fa7 Simon Farnsworth  2015-02-10  688   * response for this transaction 
only.
732d50b4 Alex Deucher  2014-04-07  689   *
732d50b4 Alex Deucher  2014-04-07  690   * Note that the aux helper code 
assumes that the .transfer() function
732d50b4 Alex Deucher  2014-04-07  691   * only modifies the reply field of 
the drm_dp_aux_msg structure.  The
732d50b4 Alex Deucher  2014-04-07  692   * retry logic and i2c helpers 
assume this is the case.
c197db75 Thierry Reding2013-11-28  693   */
c197db75 Thierry Reding2013-11-28  694  struct drm_dp_aux {
9dc40560 Jani Nikula   2014-03-14  695  const char *name;
88759686 Thierry Reding2013-12-12  696  struct i2c_adapter ddc;
c197db75 Thierry Reding2013-11-28  697  struct device *dev;
2bb29be3 Rafael Antognolli 2015-09-28  698  struct device *connector;
4f71d0cb Dave Airlie   2014-06-04  699  struct mutex hw_mutex;
c197db75 Thierry Reding2013-11-28  700  ssize_t (*transfer)(struct 
drm_dp_aux *aux,
c197db75 Thierry Reding2013-11-28  701  struct 
drm_dp_aux_msg *msg);
e9cf6194 Todd Previte  2014-11-04  702  unsigned i2c_nack_count, 
i2c_defer_count;
c197db75 Thierry Reding2013-11-28 @703  };
c197db75 Thierry Reding2013-11-28  704  
c197db75 Thierry Reding2013-11-28  705  ssize_t drm_dp_dpcd_read(struct 
drm_dp_aux *aux, unsigned int offset,
c197db75 Thierry Reding2013-11-28  706   void *buffer, 
size_t size);
c197db75 Thierry Reding2013-11-28  707  ssize_t drm_dp_dpcd_write(struct 
drm_dp_aux *aux, unsigned int offset,
c197db75 Thierry Reding2013-11-28  708void *buffer, 
size_t size);
c197db75 Thierry Reding2013-11-28  709  
c197db75 Thierry Reding2013-11-28  710  /**
c197db75 Thierry Reding2013-11-28  711   * drm_dp_dpcd_readb() - read a 
single byte from the DPCD

:: The code at line 703 was first introduced by commit
:: c197db75ff5c1d4f015c7668a3715e230a5d7e27 drm/dp: Add AUX channel 
infrastructure

:: TO: Thierry Reding 
:: CC: Thierry Reding 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
-- next part --
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 6062 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150929/c948814c/attachment-0001.obj>


[Bug 91731] ATI RV250/M9 : screen needs to be refreshed after suspend/resume

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=91731

--- Comment #4 from José Jorge  ---
(In reply to Michel Dänzer from comment #1)
> Please attach /var/log/Xorg.0.log and the output of dmesg captured after
> suspend/resume.

So did I. I noticed that with Firefox and Konsole opened, the screen is ok
after resmued. Reducing both has triggered the bug on second suspend.

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


[Bug 91731] ATI RV250/M9 : screen needs to be refreshed after suspend/resume

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=91731

--- Comment #3 from José Jorge  ---
Created attachment 118518
  --> https://bugs.freedesktop.org/attachment.cgi?id=118518=edit
dmesg after 2 suspends : first ok, second black screen except mouse cursor

Same comment as for Xorg.log

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


[PATCH] drm/rockchip: vop: Correct enabled clocks during setup

2015-09-29 Thread Sjoerd Simons
When doing the initial setup both the hclk and the aclk need to be
enabled otherwise the board will simply hang. This only occurs when
building the vop driver as a module, when its built-in the initial setup
happens to run before the clock framework shuts of unused clocks
(including the aclk).

While there also switch to doing prepare and enable in one step rather
then separate steps to reduce the amount of code required.

Signed-off-by: Sjoerd Simons 

---

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 +++--
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 5d8ae5e..48719df 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1575,32 +1575,25 @@ static int vop_initial(struct vop *vop)
return PTR_ERR(vop->dclk);
}

-   ret = clk_prepare(vop->hclk);
-   if (ret < 0) {
-   dev_err(vop->dev, "failed to prepare hclk\n");
-   return ret;
-   }
-
ret = clk_prepare(vop->dclk);
if (ret < 0) {
dev_err(vop->dev, "failed to prepare dclk\n");
-   goto err_unprepare_hclk;
+   return ret;
}

-   ret = clk_prepare(vop->aclk);
+   /* Enable both the hclk and aclk to setup the vop */
+   ret = clk_prepare_enable(vop->hclk);
if (ret < 0) {
-   dev_err(vop->dev, "failed to prepare aclk\n");
+   dev_err(vop->dev, "failed to prepare/enable hclk\n");
goto err_unprepare_dclk;
}

-   /*
-* enable hclk, so that we can config vop register.
-*/
-   ret = clk_enable(vop->hclk);
+   ret = clk_prepare_enable(vop->aclk);
if (ret < 0) {
-   dev_err(vop->dev, "failed to prepare aclk\n");
-   goto err_unprepare_aclk;
+   dev_err(vop->dev, "failed to prepare/enable aclk\n");
+   goto err_disable_hclk;
}
+
/*
 * do hclk_reset, reset all vop registers.
 */
@@ -1608,7 +1601,7 @@ static int vop_initial(struct vop *vop)
if (IS_ERR(ahb_rst)) {
dev_err(vop->dev, "failed to get ahb reset\n");
ret = PTR_ERR(ahb_rst);
-   goto err_disable_hclk;
+   goto err_disable_aclk;
}
reset_control_assert(ahb_rst);
usleep_range(10, 20);
@@ -1634,26 +1627,25 @@ static int vop_initial(struct vop *vop)
if (IS_ERR(vop->dclk_rst)) {
dev_err(vop->dev, "failed to get dclk reset\n");
ret = PTR_ERR(vop->dclk_rst);
-   goto err_unprepare_aclk;
+   goto err_disable_aclk;
}
reset_control_assert(vop->dclk_rst);
usleep_range(10, 20);
reset_control_deassert(vop->dclk_rst);

clk_disable(vop->hclk);
+   clk_disable(vop->aclk);

vop->is_enabled = false;

return 0;

+err_disable_aclk:
+   clk_disable_unprepare(vop->aclk);
 err_disable_hclk:
-   clk_disable(vop->hclk);
-err_unprepare_aclk:
-   clk_unprepare(vop->aclk);
+   clk_disable_unprepare(vop->hclk);
 err_unprepare_dclk:
clk_unprepare(vop->dclk);
-err_unprepare_hclk:
-   clk_unprepare(vop->hclk);
return ret;
 }

-- 
2.5.3



[Bug 91731] ATI RV250/M9 : screen needs to be refreshed after suspend/resume

2015-09-29 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=91731

--- Comment #2 from José Jorge  ---
Created attachment 118517
  --> https://bugs.freedesktop.org/attachment.cgi?id=118517=edit
Xorg.log after 2 suspends : first ok, second only mouse cursor is visible

After second suspend, all is ok after Alt-Tab the bring back a reduced window.

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


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

2015-09-29 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the drm-misc tree got a conflict in:

  drivers/gpu/drm/i915/intel_audio.c

between commit:

  b8abe859c9d6 ("drm/i915: Always call the adjusted mode 'adjusted_mode'")

from the drm-intel tree and commit:

  9e5a3b529e84 ("drm: Remove the 'mode' argument from drm_select_eld()")

from the drm-misc tree.

I fixed it up (I used the drm-misc tree version) and can carry the fix
as necessary (no action is required).

-- 
Cheers,
Stephen Rothwellsfr at canb.auug.org.au


  1   2   >