[RFC 0/3] drm: Add DRM text mode

2016-08-03 Thread Noralf Trønnes

Den 02.08.2016 15:05, skrev Daniel Vetter:
> On Sat, Jul 30, 2016 at 5:48 PM, Noralf Trønnes  
> wrote:
>> Den 29.07.2016 10:23, skrev Daniel Vetter:
>>> Actually adding David.
>>> -Daniel
>>>
>>> On Fri, Jul 29, 2016 at 10:20:51AM +0200, Daniel Vetter wrote:
 On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:



 Aside: Where's the pull request for your driver? ;-)
>>
>> I have been working on tinydrm for 6 months straight now and it wasn't fun
>> anymore. So I figured this was a good time to take a break from it and do
>> something else for a while :-)
> :( Still looking forward to it, I think with all the nice prep work
> you've done it would be a shame if the reason for it all wouldn't make
> it in.

I've spent too much time on tinydrm to drop it now, I just need a break.

Noralf.



[Intel-gfx] [PATCH] drm: Avoid printing negative values for unsigned variables.

2016-08-03 Thread Ville Syrjälä
On Wed, Aug 03, 2016 at 09:53:46AM -0700, Rodrigo Vivi wrote:
> It was really strange to see negative vblank seqs on debug
> messages. It is rare to have that big number, but when it
> happens it is confusing and misleading.
> 
> Signed-off-by: Rodrigo Vivi 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_irq.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 77f357b..01a5079 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -1295,7 +1295,7 @@ void drm_vblank_off(struct drm_device *dev, unsigned 
> int pipe)
>   if (e->pipe != pipe)
>   continue;
>   DRM_DEBUG("Sending premature vblank event on disable: "
> -   "wanted %d, current %d\n",
> +   "wanted %u, current %u\n",
> e->event.sequence, seq);
>   list_del(>base.link);
>   drm_vblank_put(dev, pipe);
> @@ -1585,7 +1585,7 @@ static int drm_queue_vblank_event(struct drm_device 
> *dev, unsigned int pipe,
>  
>   seq = drm_vblank_count_and_time(dev, pipe, );
>  
> - DRM_DEBUG("event on vblank count %d, current %d, crtc %u\n",
> + DRM_DEBUG("event on vblank count %u, current %u, crtc %u\n",
> vblwait->request.sequence, seq, pipe);
>  
>   trace_drm_vblank_event_queued(current->pid, pipe,
> @@ -1693,7 +1693,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
>   return drm_queue_vblank_event(dev, pipe, vblwait, file_priv);
>   }
>  
> - DRM_DEBUG("waiting on vblank count %d, crtc %u\n",
> + DRM_DEBUG("waiting on vblank count %u, crtc %u\n",
> vblwait->request.sequence, pipe);
>   DRM_WAIT_ON(ret, vblank->queue, 3 * HZ,
>   (((drm_vblank_count(dev, pipe) -
> @@ -1708,7 +1708,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
>   vblwait->reply.tval_sec = now.tv_sec;
>   vblwait->reply.tval_usec = now.tv_usec;
>  
> - DRM_DEBUG("returning %d to client\n",
> + DRM_DEBUG("returning %u to client\n",
> vblwait->reply.sequence);
>   } else {
>   DRM_DEBUG("vblank wait interrupted by signal\n");
> @@ -1735,7 +1735,7 @@ static void drm_handle_vblank_events(struct drm_device 
> *dev, unsigned int pipe)
>   if ((seq - e->event.sequence) > (1<<23))
>   continue;
>  
> - DRM_DEBUG("vblank event on %d, current %d\n",
> + DRM_DEBUG("vblank event on %u, current %u\n",
> e->event.sequence, seq);
>  
>   list_del(>base.link);
> -- 
> 2.5.5
> 
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC


[PATCH 2/2] drm: Used DRM_LEGACY for all legacy functions

2016-08-03 Thread Daniel Vetter
Except for nouveau, only legacy drivers need this really. And nouveau
is already marked up with DRIVER_KMS_LEGACY_CONTEXT as the special
case.

I've tried to be careful to leave everything related to modeset still
using the DRIVER_MODESET flag. Otherwise it's a direct replacement of
!DRIVER_MODESET with DRIVER_LEGACY checks. Also helps readability
since fewer negative checks overall.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_agpsupport.c |  6 ++
 drivers/gpu/drm/drm_auth.c   |  2 +-
 drivers/gpu/drm/drm_bufs.c   | 22 +++---
 drivers/gpu/drm/drm_context.c| 24 
 drivers/gpu/drm/drm_dma.c|  6 ++
 drivers/gpu/drm/drm_fops.c   |  6 +++---
 drivers/gpu/drm/drm_ioctl.c  |  4 ++--
 drivers/gpu/drm/drm_irq.c| 10 +-
 drivers/gpu/drm/drm_lock.c   |  4 ++--
 drivers/gpu/drm/drm_pci.c|  8 
 drivers/gpu/drm/drm_scatter.c|  6 +++---
 11 files changed, 47 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
index 605bd243fb36..d621c8a4cf00 100644
--- a/drivers/gpu/drm/drm_agpsupport.c
+++ b/drivers/gpu/drm/drm_agpsupport.c
@@ -430,9 +430,7 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev)
  * intact so it can still be used. It is safe to call this if AGP is disabled 
or
  * was already removed.
  *
- * If DRIVER_MODESET is active, nothing is done to protect the modesetting
- * resources from getting destroyed. Drivers are responsible of cleaning them 
up
- * during device shutdown.
+ * Cleanup is only done for drivers who have DRIVER_LEGACY set.
  */
 void drm_legacy_agp_clear(struct drm_device *dev)
 {
@@ -440,7 +438,7 @@ void drm_legacy_agp_clear(struct drm_device *dev)

if (!dev->agp)
return;
-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return;

list_for_each_entry_safe(entry, tempe, >agp->memory, head) {
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 4153e8a193af..6b143514a566 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -251,7 +251,7 @@ void drm_master_release(struct drm_file *file_priv)
if (!drm_is_current_master(file_priv))
goto out;

-   if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
+   if (drm_core_check_feature(dev, DRIVER_LEGACY)) {
/*
 * Since the master is disappearing, so is the
 * possibility to lock.
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index c3a12cd8bd0d..32191513e82d 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -397,7 +397,7 @@ int drm_legacy_addmap_ioctl(struct drm_device *dev, void 
*data,
return -EPERM;

if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

err = drm_addmap_core(dev, map->offset, map->size, map->type,
@@ -443,7 +443,7 @@ int drm_legacy_getmap_ioctl(struct drm_device *dev, void 
*data,
int i;

if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

idx = map->offset;
@@ -545,7 +545,7 @@ EXPORT_SYMBOL(drm_legacy_rmmap_locked);
 void drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map)
 {
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return;

mutex_lock(>struct_mutex);
@@ -558,7 +558,7 @@ void drm_legacy_master_rmmaps(struct drm_device *dev, 
struct drm_master *master)
 {
struct drm_map_list *r_list, *list_temp;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return;

mutex_lock(>struct_mutex);
@@ -595,7 +595,7 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void 
*data,
int ret;

if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

mutex_lock(>struct_mutex);
@@ -1220,7 +1220,7 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data,
struct drm_buf_desc *request = data;
int ret;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
@@ -1266,7 +1266,7 @@ int drm_legacy_infobufs(struct 

[PATCH 1/2] drm: Mark up legacy/dri1 drivers with DRM_LEGACY

2016-08-03 Thread Daniel Vetter
It's super confusing that new drivers need to be marked with
DRIVER_MODESET when really it means DRIVER_MODERN. Much better to
invert the meaning and rename it to something that's suitably
off-putting.

Since there's over 100 places using DRIVER_MODESET we need to roll out
this change without a flag day.

v2: Update docs.

Signed-off-by: Daniel Vetter 
---
 Documentation/gpu/drm-internals.rst | 9 ++---
 drivers/gpu/drm/i810/i810_drv.c | 4 +---
 drivers/gpu/drm/mga/mga_drv.c   | 2 +-
 drivers/gpu/drm/r128/r128_drv.c | 2 +-
 drivers/gpu/drm/savage/savage_drv.c | 2 +-
 drivers/gpu/drm/sis/sis_drv.c   | 2 +-
 drivers/gpu/drm/tdfx/tdfx_drv.c | 1 +
 drivers/gpu/drm/via/via_drv.c   | 2 +-
 include/drm/drmP.h  | 1 +
 9 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/Documentation/gpu/drm-internals.rst 
b/Documentation/gpu/drm-internals.rst
index 3bb26135971f..37284bcc7764 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -53,9 +53,12 @@ u32 driver_features;
 DRIVER_USE_AGP
 Driver uses AGP interface, the DRM core will manage AGP resources.

-DRIVER_REQUIRE_AGP
-Driver needs AGP interface to function. AGP initialization failure
-will become a fatal error.
+DRIVER_LEGACY
+Denote a legacy driver using shadow attach. Don't use.
+
+DRIVER_KMS_LEGACY_CONTEXT
+Used only by nouveau for backwards compatibility with existing userspace.
+Don't use.

 DRIVER_PCI_DMA
 Driver is capable of PCI DMA, mapping of PCI DMA buffers to
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
index 44f4a131c8dd..0be55dc1ef4b 100644
--- a/drivers/gpu/drm/i810/i810_drv.c
+++ b/drivers/gpu/drm/i810/i810_drv.c
@@ -56,9 +56,7 @@ static const struct file_operations i810_driver_fops = {
 };

 static struct drm_driver driver = {
-   .driver_features =
-   DRIVER_USE_AGP |
-   DRIVER_HAVE_DMA,
+   .driver_features = DRIVER_USE_AGP | DRIVER_HAVE_DMA | DRIVER_LEGACY,
.dev_priv_size = sizeof(drm_i810_buf_priv_t),
.load = i810_driver_load,
.lastclose = i810_driver_lastclose,
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index 5e2f131a6a72..25b2a1a424e6 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -58,7 +58,7 @@ static const struct file_operations mga_driver_fops = {

 static struct drm_driver driver = {
.driver_features =
-   DRIVER_USE_AGP | DRIVER_PCI_DMA |
+   DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_LEGACY |
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.dev_priv_size = sizeof(drm_mga_buf_priv_t),
.load = mga_driver_load,
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index c57b4de63caf..a982be57d1ef 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -56,7 +56,7 @@ static const struct file_operations r128_driver_fops = {

 static struct drm_driver driver = {
.driver_features =
-   DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
+   DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_LEGACY |
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
.load = r128_driver_load,
diff --git a/drivers/gpu/drm/savage/savage_drv.c 
b/drivers/gpu/drm/savage/savage_drv.c
index 21aed1febeb4..3b807135a5cd 100644
--- a/drivers/gpu/drm/savage/savage_drv.c
+++ b/drivers/gpu/drm/savage/savage_drv.c
@@ -50,7 +50,7 @@ static const struct file_operations savage_driver_fops = {

 static struct drm_driver driver = {
.driver_features =
-   DRIVER_USE_AGP | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
+   DRIVER_USE_AGP | DRIVER_HAVE_DMA | DRIVER_PCI_DMA | DRIVER_LEGACY,
.dev_priv_size = sizeof(drm_savage_buf_priv_t),
.load = savage_driver_load,
.firstopen = savage_driver_firstopen,
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 79bce76cb8f7..ae9839886c4d 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -102,7 +102,7 @@ static void sis_driver_postclose(struct drm_device *dev, 
struct drm_file *file)
 }

 static struct drm_driver driver = {
-   .driver_features = DRIVER_USE_AGP,
+   .driver_features = DRIVER_USE_AGP | DRIVER_LEGACY,
.load = sis_driver_load,
.unload = sis_driver_unload,
.open = sis_driver_open,
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c
index fab5ebcb0fef..f418892b0c71 100644
--- a/drivers/gpu/drm/tdfx/tdfx_drv.c
+++ b/drivers/gpu/drm/tdfx/tdfx_drv.c
@@ -56,6 +56,7 @@ static const struct file_operations tdfx_driver_fops = {
 };

 static struct drm_driver driver = {
+   .driver_features = DRIVER_LEGACY,
.set_busid = drm_pci_set_busid,
.fops = _driver_fops,
.name = DRIVER_NAME,

simpledrm problem: Kconfig:error: recursive dependency detected!

2016-08-03 Thread Noralf Trønnes
Hi,

I have changed simpledrm to use drm_simple_kms_helper and now I'm
facing this:

drivers/video/fbdev/Kconfig:5:error: recursive dependency detected!
For a resolution refer to Documentation/kbuild/kconfig-language.txt

drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER

drivers/gpu/drm/Kconfig:42: symbol DRM_KMS_FB_HELPER depends on 
DRM_KMS_HELPER

drivers/gpu/drm/Kconfig:36: symbol DRM_KMS_HELPER is selected by 
DRM_SIMPLEDRM

drivers/gpu/drm/simpledrm/Kconfig:1:symbol DRM_SIMPLEDRM depends on 
FB_SIMPLE

drivers/video/fbdev/Kconfig:2428:   symbol FB_SIMPLE depends on FB


Using this Kconfig:

config DRM_SIMPLEDRM
 tristate "Simple firmware framebuffer DRM driver"
 depends on DRM && (FB_SIMPLE = n)
 select DRM_KMS_HELPER


Is there a solution to this apart from depending on DRM_KMS_HELPER or
removing the FB_SIMPLE dependency?

video/ is before gpu/ in drivers/Makefile, so having both simpledrm and
simplefb selected, I guess simplefb will be the one that's used?


Noralf.



[PATCH 1/3] drm/rockchip: inno_hdmi: add audio support

2016-08-03 Thread Heiko Stübner
Am Dienstag, 2. August 2016, 10:16:04 schrieb Yakir Yang:
> Hi Mark & Heiko,
> 
> Ping..

devicetree side looks good, so we're waiting on Mark to pick up patch 1.


Heiko

> On 06/15/2016 09:28 PM, Yakir Yang wrote:
> > Using the common hdmi-codec driver to support hdmi audio function.
> > 
> > Signed-off-by: Yakir Yang 
> > ---
> > 
> >   drivers/gpu/drm/rockchip/inno_hdmi.c | 237
> >   ++-
> >   drivers/gpu/drm/rockchip/inno_hdmi.h |   2 +
> >   2 files changed, 237 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c
> > b/drivers/gpu/drm/rockchip/inno_hdmi.c index f8b4feb..c31dc07 100644
> > --- a/drivers/gpu/drm/rockchip/inno_hdmi.c
> > +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
> > @@ -29,6 +29,8 @@
> > 
> >   #include 
> >   #include 
> > 
> > +#include 
> > +
> > 
> >   #include "rockchip_drm_drv.h"
> >   #include "rockchip_drm_vop.h"
> > 
> > @@ -36,6 +38,12 @@
> > 
> >   #define to_inno_hdmi(x)   container_of(x, struct inno_hdmi, x)
> > 
> > +struct audio_info {
> > +   int sample_rate;
> > +   int channels;
> > +   int sample_width;
> > +};
> > +
> > 
> >   struct hdmi_data_info {
> >   
> > int vic;
> > bool sink_is_hdmi;
> > 
> > @@ -71,6 +79,9 @@ struct inno_hdmi {
> > 
> > unsigned int tmds_rate;
> > 
> > +   struct platform_device *audio_pdev;
> > +   bool audio_enable;
> > +
> > 
> > struct hdmi_data_info   hdmi_data;
> > struct drm_display_mode previous_mode;
> >   
> >   };
> > 
> > @@ -306,6 +317,57 @@ static int inno_hdmi_config_video_avi(struct
> > inno_hdmi *hdmi,> 
> > return inno_hdmi_upload_frame(hdmi, rc, , INFOFRAME_AVI, 0, 0,
> > 0);
> >   
> >   }
> > 
> > +static int inno_hdmi_config_audio_aai(struct inno_hdmi *hdmi,
> > + struct audio_info *audio)
> > +{
> > +   struct hdmi_audio_infoframe *faudio;
> > +   union hdmi_infoframe frame;
> > +   int rc;
> > +
> > +   rc = hdmi_audio_infoframe_init();
> > +   faudio = (struct hdmi_audio_infoframe *)
> > +
> > +   faudio->channels = audio->channels;
> > +
> > +   switch (audio->sample_width) {
> > +   case 16:
> > +   faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> > +   break;
> > +   case 20:
> > +   faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
> > +   break;
> > +   case 24:
> > +   faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
> > +   break;
> > +   }
> > +
> > +   switch (audio->sample_rate) {
> > +   case 32000:
> > +   faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_32000;
> > +   break;
> > +   case 44100:
> > +   faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_44100;
> > +   break;
> > +   case 48000:
> > +   faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
> > +   break;
> > +   case 88200:
> > +   faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_88200;
> > +   break;
> > +   case 96000:
> > +   faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_96000;
> > +   break;
> > +   case 176400:
> > +   faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_176400;
> > +   break;
> > +   case 192000:
> > +   faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_192000;
> > +   break;
> > +   }
> > +
> > +   return inno_hdmi_upload_frame(hdmi, rc, , INFOFRAME_AAI, 0, 0, 
0);
> > +}
> > +
> > 
> >   static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
> >   {
> >   
> > struct hdmi_data_info *data = >hdmi_data;
> > 
> > @@ -478,8 +540,9 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
> > 
> > inno_hdmi_i2c_init(hdmi);
> > 
> > /* Unmute video and audio output */
> > 
> > -   hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
> > - v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
> > +   hdmi_modb(hdmi, HDMI_AV_MUTE, m_VIDEO_BLACK, v_VIDEO_MUTE(0));
> > +   if (hdmi->audio_enable)
> > +   hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE, v_AUDIO_MUTE(0));
> > 
> > return 0;
> >   
> >   }
> > 
> > @@ -616,6 +679,174 @@ static struct drm_connector_helper_funcs
> > inno_hdmi_connector_helper_funcs = {> 
> > .best_encoder = inno_hdmi_connector_best_encoder,
> >   
> >   };
> > 
> > +int inno_hdmi_audio_config_set(struct inno_hdmi *hdmi, struct audio_info
> > *audio) +{
> > +   int rate, N, channel;
> > +
> > +   if (audio->channels < 3)
> > +   channel = I2S_CHANNEL_1_2;
> > +   else if (audio->channels < 5)
> > +   channel = I2S_CHANNEL_3_4;
> > +   else if (audio->channels < 7)
> > +   channel = I2S_CHANNEL_5_6;
> > +   else
> > +   channel = I2S_CHANNEL_7_8;
> > +
> > +   switch (audio->sample_rate) {
> > +   case 32000:
> > +   rate = AUDIO_32K;
> > +   N = N_32K;
> > +   break;
> > +   case 44100:
> > +   rate = AUDIO_441K;
> > +   N = N_441K;
> > +   break;
> > +   

[PATCH 5/8] drm: use drm_file to tag vm-bos

2016-08-03 Thread Chris Wilson
On Wed, Aug 03, 2016 at 08:04:29PM +0200, David Herrmann wrote:
> Rather than using "struct file*", use "struct drm_file*" as tag VM tag for
> BOs. This will pave the way for "struct drm_file*" without any "struct
> file*" back-pointer.
> 
> Signed-off-by: David Herrmann 

Ok, the danger of untyped is having to check each and trying to spot any
missed conversions.

Couldn't find a mistake or omission,
Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 4/4] drm/i915/dp: Dump DP link status when link training stages fails

2016-08-03 Thread Dhinakaran Pandiyan
A full dump of link status can be handy in debugging link training
failures. Let's add that to the debug messages when link training fails.

Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 11 +++
 drivers/gpu/drm/i915/intel_drv.h  |  6 --
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c 
b/drivers/gpu/drm/i915/intel_dp_link_training.c
index c0a858d..ab7d1a6 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -24,6 +24,15 @@
 #include "intel_drv.h"

 static void
+intel_dp_dump_link_status(const uint8_t link_status[DP_LINK_STATUS_SIZE])
+{
+
+   DRM_DEBUG_KMS("ln0_1:0x%x ln2_3:0x%x align:0x%x sink:0x%x 
adj_req0_1:0x%x adj_req2_3:0x%x",
+ link_status[0], link_status[1], link_status[2],
+ link_status[3], link_status[4], link_status[5]);
+}
+
+static void
 intel_get_adjust_train(struct intel_dp *intel_dp,
   const uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
@@ -170,6 +179,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp 
*intel_dp)
++loop_tries;
if (loop_tries == 5) {
DRM_ERROR("too many full retries, give up\n");
+   intel_dp_dump_link_status(link_status);
break;
}
intel_dp_reset_link_train(intel_dp,
@@ -257,6 +267,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp 
*intel_dp)

if (cr_tries > 5) {
DRM_ERROR("failed to train DP, aborting\n");
+   intel_dp_dump_link_status(link_status);
break;
}

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 87069ba..549a8fd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1356,8 +1356,6 @@ bool intel_dp_init_connector(struct intel_digital_port 
*intel_dig_port,
 struct intel_connector *intel_connector);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
  const struct intel_crtc_state *pipe_config);
-void intel_dp_start_link_train(struct intel_dp *intel_dp);
-void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 void intel_dp_encoder_reset(struct drm_encoder *encoder);
 void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
@@ -1409,6 +1407,10 @@ static inline unsigned int intel_dp_unused_lane_mask(int 
lane_count)
return ~((1 << lane_count) - 1) & 0xf;
 }

+/* intel_dp_link_training.c */
+void intel_dp_start_link_train(struct intel_dp *intel_dp);
+void intel_dp_stop_link_train(struct intel_dp *intel_dp);
+
 /* intel_dp_aux_backlight.c */
 int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector);

-- 
2.5.0



[PATCH 3/4] drm/dp: Clarify clock recovery and channel equalization failures

2016-08-03 Thread Dhinakaran Pandiyan
The causes of clock recovery and channel equalization failures are not
explicitly printed in debug messages. Help debugging link training
failures by printing why it failed.

Doing this in the driver would mean re-implementing some of the drm static
functions that decode link status. Let's avoid that with these debug
messages in drm.

Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/drm_dp_helper.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 091053e..d763b57 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -64,12 +64,16 @@ bool drm_dp_channel_eq_ok(const u8 
link_status[DP_LINK_STATUS_SIZE],

lane_align = dp_link_status(link_status,
DP_LANE_ALIGN_STATUS_UPDATED);
-   if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
+   if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) {
+   DRM_DEBUG_KMS("Inter-lane alignment not done\n");
return false;
+   }
for (lane = 0; lane < lane_count; lane++) {
lane_status = dp_get_lane_status(link_status, lane);
-   if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
+   if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS) {
+   DRM_DEBUG_KMS("Channel equalization not done for lane 
%d\n", lane);
return false;
+   }
}
return true;
 }
@@ -83,8 +87,10 @@ bool drm_dp_clock_recovery_ok(const u8 
link_status[DP_LINK_STATUS_SIZE],

for (lane = 0; lane < lane_count; lane++) {
lane_status = dp_get_lane_status(link_status, lane);
-   if ((lane_status & DP_LANE_CR_DONE) == 0)
+   if ((lane_status & DP_LANE_CR_DONE) == 0) {
+   DRM_DEBUG_KMS("Clock recovery not done for lane %d\n", 
lane);
return false;
+   }
}
return true;
 }
-- 
2.5.0



[PATCH 2/4] drm/i915/dp: Switch to using the DRM function for reading DP link status

2016-08-03 Thread Dhinakaran Pandiyan
Since a DRM function that reads link DP link status is available, let's
use that instead of the i915 clone.

Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/i915/intel_dp.c   | 15 +++
 drivers/gpu/drm/i915/intel_dp_link_training.c | 11 ---
 drivers/gpu/drm/i915/intel_drv.h  |  2 --
 3 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3ca33bd..c5c0201 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2863,17 +2863,6 @@ static void chv_dp_post_pll_disable(struct intel_encoder 
*encoder)
chv_phy_post_pll_disable(encoder);
 }

-/*
- * Fetch AUX CH registers 0x202 - 0x207 which contain
- * link status information
- */
-bool
-intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t 
link_status[DP_LINK_STATUS_SIZE])
-{
-   return drm_dp_dpcd_read(_dp->aux, DP_LANE0_1_STATUS, link_status,
-   DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
-}
-
 /* These are source-specific values. */
 uint8_t
 intel_dp_voltage_max(struct intel_dp *intel_dp)
@@ -3869,10 +3858,12 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
struct intel_encoder *intel_encoder = _to_dig_port(intel_dp)->base;
struct drm_device *dev = intel_dp_to_dev(intel_dp);
u8 link_status[DP_LINK_STATUS_SIZE];
+   int len;

WARN_ON(!drm_modeset_is_locked(>mode_config.connection_mutex));

-   if (!intel_dp_get_link_status(intel_dp, link_status)) {
+   len = drm_dp_dpcd_read_link_status(_dp->aux, link_status);
+   if (len != DP_LINK_STATUS_SIZE) {
DRM_ERROR("Failed to get link status\n");
return;
}
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c 
b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 60fb39c..c0a858d 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -107,7 +107,7 @@ intel_dp_update_link_train(struct intel_dp *intel_dp)
 static void
 intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 {
-   int i;
+   int i, len;
uint8_t voltage;
int voltage_tries, loop_tries;
uint8_t link_config[2];
@@ -150,7 +150,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp 
*intel_dp)
uint8_t link_status[DP_LINK_STATUS_SIZE];

drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
-   if (!intel_dp_get_link_status(intel_dp, link_status)) {
+
+   len = drm_dp_dpcd_read_link_status(_dp->aux, link_status);
+   if (len != DP_LINK_STATUS_SIZE) {
DRM_ERROR("failed to get link status\n");
break;
}
@@ -235,6 +237,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp 
*intel_dp)
bool channel_eq = false;
int tries, cr_tries;
u32 training_pattern;
+   int len;

training_pattern = intel_dp_training_pattern(intel_dp);

@@ -258,7 +261,9 @@ intel_dp_link_training_channel_equalization(struct intel_dp 
*intel_dp)
}

drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
-   if (!intel_dp_get_link_status(intel_dp, link_status)) {
+
+   len = drm_dp_dpcd_read_link_status(_dp->aux, link_status);
+   if (len != DP_LINK_STATUS_SIZE) {
DRM_ERROR("failed to get link status\n");
break;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e74d851..87069ba 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1403,8 +1403,6 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, 
uint8_t voltage_swing);
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
   uint8_t *link_bw, uint8_t *rate_select);
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
-bool
-intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t 
link_status[DP_LINK_STATUS_SIZE]);

 static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 {
-- 
2.5.0



[PATCH 1/4] drm/i915/dp: Add debug messages to print DP link training pattern

2016-08-03 Thread Dhinakaran Pandiyan
Currently we do not print the training pattern used in any of the DP link
training stages. Including this piece of information in debug messages will
help debugging.

Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/i915/intel_dp.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 21b04c3..3ca33bd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2547,6 +2547,10 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(dev);
enum port port = intel_dig_port->port;

+   if (dp_train_pat & DP_TRAINING_PATTERN_MASK)
+   DRM_DEBUG_KMS("Using DP training pattern TPS%d\n",
+ dp_train_pat & DP_TRAINING_PATTERN_MASK);
+
if (HAS_DDI(dev)) {
uint32_t temp = I915_READ(DP_TP_CTL(port));

@@ -2588,7 +2592,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
*DP |= DP_LINK_TRAIN_PAT_2_CPT;
break;
case DP_TRAINING_PATTERN_3:
-   DRM_ERROR("DP training pattern 3 not supported\n");
+   DRM_ERROR("TPS3 not supported, using TPS2 instead\n");
*DP |= DP_LINK_TRAIN_PAT_2_CPT;
break;
}
@@ -2613,7 +2617,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
if (IS_CHERRYVIEW(dev)) {
*DP |= DP_LINK_TRAIN_PAT_3_CHV;
} else {
-   DRM_ERROR("DP training pattern 3 not 
supported\n");
+   DRM_ERROR("TPS3 not supported, using TPS2 
instead\n");
*DP |= DP_LINK_TRAIN_PAT_2;
}
break;
@@ -2629,11 +2633,8 @@ static void intel_dp_enable_port(struct intel_dp 
*intel_dp)
to_intel_crtc(dp_to_dig_port(intel_dp)->base.base.crtc);

/* enable with pattern 1 (as per spec) */
-   _intel_dp_set_link_train(intel_dp, _dp->DP,
-DP_TRAINING_PATTERN_1);

-   I915_WRITE(intel_dp->output_reg, intel_dp->DP);
-   POSTING_READ(intel_dp->output_reg);
+   intel_dp_program_link_training_pattern(intel_dp, DP_TRAINING_PATTERN_1);

/*
 * Magic for VLV/CHV. We _must_ first set up the register
-- 
2.5.0



[PATCH 0/4] Improve logging for DP link training

2016-08-03 Thread Dhinakaran Pandiyan
We do not currently output enough information to help debugging DP link
training issues. For e.g., training pattern and link status information.
This series aims to correct that by adding debug messages that can help
developers.

Dhinakaran Pandiyan (4):
  drm/i915/dp: Add debug messages to print DP link training pattern
  drm/i915/dp: Switch to using the DRM function for reading DP link
status
  drm/dp: Clarify clock recovery and channel equalization failures
  drm/i915/dp: Dump DP link status when link training stages fails

 drivers/gpu/drm/drm_dp_helper.c   | 12 +---
 drivers/gpu/drm/i915/intel_dp.c   | 28 ++-
 drivers/gpu/drm/i915/intel_dp_link_training.c | 22 ++---
 drivers/gpu/drm/i915/intel_drv.h  |  8 
 4 files changed, 42 insertions(+), 28 deletions(-)

-- 
2.5.0



[PATCH 8/8] drm: provide management functions for drm_file

2016-08-03 Thread David Herrmann
Rather than doing drm_file allocation/destruction right in the fops, lets
provide separate helpers. This decouples drm_file management from the
still-mandatory drm-fops. It prepares for use of drm_file without the
fops, both by possible separate fops implementations and APIs (not that I
am aware of any such plans), and more importantly from in-kernel use where
no real file is available.

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/drm_drv.c  | 135 +
 drivers/gpu/drm/drm_fops.c | 132 +++-
 drivers/gpu/drm/drm_internal.h |   4 ++
 3 files changed, 147 insertions(+), 124 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 57ce973..9ab0016 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -95,6 +95,141 @@ void drm_ut_debug_printk(const char *function_name, const 
char *format, ...)
 }
 EXPORT_SYMBOL(drm_ut_debug_printk);

+/**
+ * drm_file_alloc - allocate file context
+ * @minor: minor to allocate on
+ *
+ * This allocates a new DRM file context. It is not linked into any context and
+ * can be used by the caller freely. Note that the context keeps a pointer to
+ * @minor, so it must be freed before @minor is.
+ *
+ * The legacy paths might require the drm_global_mutex to be held.
+ *
+ * RETURNS:
+ * Pointer to newly allocated context, ERR_PTR on failure.
+ */
+struct drm_file *drm_file_alloc(struct drm_minor *minor)
+{
+   struct drm_device *dev = minor->dev;
+   struct drm_file *file;
+   int ret;
+
+   file = kzalloc(sizeof(*file), GFP_KERNEL);
+   if (!file)
+   return ERR_PTR(-ENOMEM);
+
+   file->pid = get_pid(task_pid(current));
+   file->minor = minor;
+   file->authenticated = capable(CAP_SYS_ADMIN); /* legacy compat */
+   INIT_LIST_HEAD(>lhead);
+   INIT_LIST_HEAD(>fbs);
+   mutex_init(>fbs_lock);
+   INIT_LIST_HEAD(>blobs);
+   INIT_LIST_HEAD(>pending_event_list);
+   INIT_LIST_HEAD(>event_list);
+   init_waitqueue_head(>event_wait);
+   file->event_space = 4096; /* set aside 4k for event buffer */
+   mutex_init(>event_read_lock);
+
+   if (drm_core_check_feature(dev, DRIVER_GEM))
+   drm_gem_open(dev, file);
+   if (drm_core_check_feature(dev, DRIVER_PRIME))
+   drm_prime_init_file_private(>prime);
+
+   if (dev->driver->open) {
+   ret = dev->driver->open(dev, file);
+   if (ret < 0)
+   goto out_prime_destroy;
+   }
+
+   if (drm_is_primary_client(file)) {
+   ret = drm_master_open(file);
+   if (ret)
+   goto out_close;
+   }
+
+   return file;
+
+out_close:
+   if (dev->driver->postclose)
+   dev->driver->postclose(dev, file);
+out_prime_destroy:
+   if (drm_core_check_feature(dev, DRIVER_PRIME))
+   drm_prime_destroy_file_private(>prime);
+   if (drm_core_check_feature(dev, DRIVER_GEM))
+   drm_gem_release(dev, file);
+   put_pid(file->pid);
+   kfree(file);
+   return ERR_PTR(ret);
+}
+
+/**
+ * drm_file_free - free file context
+ * @file: context to free, or NULL
+ *
+ * This destroys and deallocates a DRM file context previously allocated via
+ * drm_file_alloc(). The caller must make sure to unlink it from any contexts
+ * before calling this.
+ *
+ * The legacy paths might require the drm_global_mutex to be held.
+ *
+ * If NULL is passed, this is a no-op.
+ *
+ * RETURNS:
+ * 0 on success, or error code on failure.
+ */
+void drm_file_free(struct drm_file *file)
+{
+   struct drm_pending_event *e;
+   struct drm_device *dev;
+
+   if (!file)
+   return;
+
+   dev = file->minor->dev;
+
+   if (dev->driver->preclose)
+   dev->driver->preclose(dev, file);
+   if (!drm_core_check_feature(dev, DRIVER_MODESET))
+   drm_legacy_lock_release(dev, file->legacy_filp);
+   if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+   drm_legacy_reclaim_buffers(dev, file);
+
+   spin_lock_irq(>event_lock);
+   while ((e = list_first_entry_or_null(>pending_event_list,
+struct drm_pending_event,
+pending_link))) {
+   list_del(>pending_link);
+   e->file_priv = NULL;
+   }
+   while ((e = list_first_entry_or_null(>event_list,
+struct drm_pending_event, link))) {
+   list_del(>link);
+   kfree(e);
+   }
+   spin_unlock_irq(>event_lock);
+
+   drm_legacy_ctxbitmap_flush(dev, file);
+
+   if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+   drm_fb_release(file);
+   drm_property_destroy_user_blobs(dev, file);
+   }
+
+   if (drm_core_check_feature(dev, DRIVER_GEM))
+

[PATCH 7/8] drm: rename drm_file.filp to drm_file.legacy_filp

2016-08-03 Thread David Herrmann
We don't want anyone but legacy DRM1 code to use drm_file.filp. Especially
for in-kernel contexts, this might be set to NULL, so lets make sure
no-one accesses it, ever.

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/drm_bufs.c | 7 ---
 drivers/gpu/drm/drm_fops.c | 2 +-
 include/drm/drmP.h | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index c3a12cd..d2803de 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -1456,7 +1456,7 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;

-   if (!dma)
+   if (!dma || !file_priv->legacy_filp)
return -EINVAL;

spin_lock(>buf_lock);
@@ -1478,12 +1478,13 @@ int drm_legacy_mapbufs(struct drm_device *dev, void 
*data,
retcode = -EINVAL;
goto done;
}
-   virtual = vm_mmap(file_priv->filp, 0, map->size,
+   virtual = vm_mmap(file_priv->legacy_filp, 0, map->size,
  PROT_READ | PROT_WRITE,
  MAP_SHARED,
  token);
} else {
-   virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,
+   virtual = vm_mmap(file_priv->legacy_filp, 0,
+ dma->byte_count,
  PROT_READ | PROT_WRITE,
  MAP_SHARED, 0);
}
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index e9d66f5..69ef23c 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -198,7 +198,7 @@ static int drm_open_helper(struct file *filp, struct 
drm_minor *minor)
return -ENOMEM;

filp->private_data = priv;
-   priv->filp = filp;
+   priv->legacy_filp = filp;
priv->pid = get_pid(task_pid(current));
priv->minor = minor;

diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 0f69f56..2197ab1 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -330,7 +330,7 @@ struct drm_file {
/** Lock for synchronization of access to object_idr. */
spinlock_t table_lock;

-   struct file *filp;
+   struct file *legacy_filp; /* might be NULL! */
void *driver_priv;

struct drm_master *master; /* master this node is currently associated 
with
-- 
2.9.2



[PATCH 6/8] drm: use priv->pid to deduce task EUID

2016-08-03 Thread David Herrmann
Rather than accessing priv->filp->f_cred, use priv->pid->task->creds. We
want to get rid of "priv->filp", so lets avoid it if possible.

Since we already are in an rcu-read-side, we can use __task_cred() rather
than task_cred_xxx().

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/drm_info.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 247ba2b..1df2d33 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -99,7 +99,7 @@ int drm_clients_info(struct seq_file *m, void *data)

rcu_read_lock(); /* locks pid_task()->comm */
task = pid_task(priv->pid, PIDTYPE_PID);
-   uid = priv->filp ? priv->filp->f_cred->euid : GLOBAL_ROOT_UID;
+   uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID;
seq_printf(m, "%20s %5d %3d   %c%c %5d %10u\n",
   task ? task->comm : "",
   pid_vnr(priv->pid),
-- 
2.9.2



[PATCH 5/8] drm: use drm_file to tag vm-bos

2016-08-03 Thread David Herrmann
Rather than using "struct file*", use "struct drm_file*" as tag VM tag for
BOs. This will pave the way for "struct drm_file*" without any "struct
file*" back-pointer.

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 3 ++-
 drivers/gpu/drm/ast/ast_ttm.c   | 3 ++-
 drivers/gpu/drm/bochs/bochs_mm.c| 3 ++-
 drivers/gpu/drm/cirrus/cirrus_ttm.c | 3 ++-
 drivers/gpu/drm/drm_gem.c   | 8 
 drivers/gpu/drm/mgag200/mgag200_ttm.c   | 3 ++-
 drivers/gpu/drm/nouveau/nouveau_bo.c| 3 ++-
 drivers/gpu/drm/qxl/qxl_ttm.c   | 3 ++-
 drivers/gpu/drm/radeon/radeon_ttm.c | 3 ++-
 9 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index b7742e6..58099c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -225,7 +225,8 @@ static int amdgpu_verify_access(struct ttm_buffer_object 
*bo, struct file *filp)

if (amdgpu_ttm_tt_get_usermm(bo->ttm))
return -EPERM;
-   return drm_vma_node_verify_access(>gem_base.vma_node, filp);
+   return drm_vma_node_verify_access(>gem_base.vma_node,
+ filp->private_data);
 }

 static void amdgpu_move_null(struct ttm_buffer_object *bo,
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index b29a412..608df4c 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -150,7 +150,8 @@ static int ast_bo_verify_access(struct ttm_buffer_object 
*bo, struct file *filp)
 {
struct ast_bo *astbo = ast_bo(bo);

-   return drm_vma_node_verify_access(>gem.vma_node, filp);
+   return drm_vma_node_verify_access(>gem.vma_node,
+ filp->private_data);
 }

 static int ast_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index 5c5638a..269cfca 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -128,7 +128,8 @@ static int bochs_bo_verify_access(struct ttm_buffer_object 
*bo,
 {
struct bochs_bo *bochsbo = bochs_bo(bo);

-   return drm_vma_node_verify_access(>gem.vma_node, filp);
+   return drm_vma_node_verify_access(>gem.vma_node,
+ filp->private_data);
 }

 static int bochs_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c 
b/drivers/gpu/drm/cirrus/cirrus_ttm.c
index 1cc9ee6..bb2438d 100644
--- a/drivers/gpu/drm/cirrus/cirrus_ttm.c
+++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c
@@ -150,7 +150,8 @@ static int cirrus_bo_verify_access(struct ttm_buffer_object 
*bo, struct file *fi
 {
struct cirrus_bo *cirrusbo = cirrus_bo(bo);

-   return drm_vma_node_verify_access(>gem.vma_node, filp);
+   return drm_vma_node_verify_access(>gem.vma_node,
+ filp->private_data);
 }

 static int cirrus_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 9134ae1..465bacd 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -257,7 +257,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)

if (drm_core_check_feature(dev, DRIVER_PRIME))
drm_gem_remove_prime_handles(obj, file_priv);
-   drm_vma_node_revoke(>vma_node, file_priv->filp);
+   drm_vma_node_revoke(>vma_node, file_priv);

if (dev->driver->gem_close_object)
dev->driver->gem_close_object(obj, file_priv);
@@ -372,7 +372,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,

handle = ret;

-   ret = drm_vma_node_allow(>vma_node, file_priv->filp);
+   ret = drm_vma_node_allow(>vma_node, file_priv);
if (ret)
goto err_remove;

@@ -386,7 +386,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
return 0;

 err_revoke:
-   drm_vma_node_revoke(>vma_node, file_priv->filp);
+   drm_vma_node_revoke(>vma_node, file_priv);
 err_remove:
spin_lock(_priv->table_lock);
idr_remove(_priv->object_idr, handle);
@@ -991,7 +991,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct 
*vma)
if (!obj)
return -EINVAL;

-   if (!drm_vma_node_is_allowed(node, filp)) {
+   if (!drm_vma_node_is_allowed(node, priv)) {
drm_gem_object_unreference_unlocked(obj);
return -EACCES;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c 
b/drivers/gpu/drm/mgag200/mgag200_ttm.c
index 68268e5..919b35f 100644
--- a/drivers/gpu/drm/mgag200/mgag200_ttm.c
+++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c
@@ -150,7 +150,8 @@ static int mgag200_bo_verify_access(struct 
ttm_buffer_object *bo, struct file *f
 {
struct mgag200_bo *mgabo = mgag200_bo(bo);

- 

[PATCH 4/8] drm: make vma-manager entries untyped

2016-08-03 Thread David Herrmann
Right now, the vma-manager requires all entries to provide a "struct
file*" as identifier. This is confusing, since there is no inherent
connection to "struct file" in the vma-manager at all, but it is
exclusively used as tag.

Replace its usage with a simple "void *tag" and make sure callers can use
arbitrary tags.

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/drm_vma_manager.c | 40 +++
 include/drm/drm_vma_manager.h | 18 --
 2 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/drm_vma_manager.c 
b/drivers/gpu/drm/drm_vma_manager.c
index f306c88..954248e 100644
--- a/drivers/gpu/drm/drm_vma_manager.c
+++ b/drivers/gpu/drm/drm_vma_manager.c
@@ -25,7 +25,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -277,9 +276,9 @@ EXPORT_SYMBOL(drm_vma_offset_remove);
 /**
  * drm_vma_node_allow - Add open-file to list of allowed users
  * @node: Node to modify
- * @filp: Open file to add
+ * @tag: Tag of file to remove
  *
- * Add @filp to the list of allowed open-files for this node. If @filp is
+ * Add @tag to the list of allowed open-files for this node. If @tag is
  * already on this list, the ref-count is incremented.
  *
  * The list of allowed-users is preserved across drm_vma_offset_add() and
@@ -294,7 +293,7 @@ EXPORT_SYMBOL(drm_vma_offset_remove);
  * RETURNS:
  * 0 on success, negative error code on internal failure (out-of-mem)
  */
-int drm_vma_node_allow(struct drm_vma_offset_node *node, struct file *filp)
+int drm_vma_node_allow(struct drm_vma_offset_node *node, void *tag)
 {
struct rb_node **iter;
struct rb_node *parent = NULL;
@@ -315,10 +314,10 @@ int drm_vma_node_allow(struct drm_vma_offset_node *node, 
struct file *filp)
parent = *iter;
entry = rb_entry(*iter, struct drm_vma_offset_file, vm_rb);

-   if (filp == entry->vm_filp) {
+   if (tag == entry->vm_tag) {
entry->vm_count++;
goto unlock;
-   } else if (filp > entry->vm_filp) {
+   } else if (tag > entry->vm_tag) {
iter = &(*iter)->rb_right;
} else {
iter = &(*iter)->rb_left;
@@ -330,7 +329,7 @@ int drm_vma_node_allow(struct drm_vma_offset_node *node, 
struct file *filp)
goto unlock;
}

-   new->vm_filp = filp;
+   new->vm_tag = tag;
new->vm_count = 1;
rb_link_node(>vm_rb, parent, iter);
rb_insert_color(>vm_rb, >vm_files);
@@ -346,17 +345,17 @@ EXPORT_SYMBOL(drm_vma_node_allow);
 /**
  * drm_vma_node_revoke - Remove open-file from list of allowed users
  * @node: Node to modify
- * @filp: Open file to remove
+ * @tag: Tag of file to remove
  *
- * Decrement the ref-count of @filp in the list of allowed open-files on @node.
- * If the ref-count drops to zero, remove @filp from the list. You must call
- * this once for every drm_vma_node_allow() on @filp.
+ * Decrement the ref-count of @tag in the list of allowed open-files on @node.
+ * If the ref-count drops to zero, remove @tag from the list. You must call
+ * this once for every drm_vma_node_allow() on @tag.
  *
  * This is locked against concurrent access internally.
  *
- * If @filp is not on the list, nothing is done.
+ * If @tag is not on the list, nothing is done.
  */
-void drm_vma_node_revoke(struct drm_vma_offset_node *node, struct file *filp)
+void drm_vma_node_revoke(struct drm_vma_offset_node *node, void *tag)
 {
struct drm_vma_offset_file *entry;
struct rb_node *iter;
@@ -366,13 +365,13 @@ void drm_vma_node_revoke(struct drm_vma_offset_node 
*node, struct file *filp)
iter = node->vm_files.rb_node;
while (likely(iter)) {
entry = rb_entry(iter, struct drm_vma_offset_file, vm_rb);
-   if (filp == entry->vm_filp) {
+   if (tag == entry->vm_tag) {
if (!--entry->vm_count) {
rb_erase(>vm_rb, >vm_files);
kfree(entry);
}
break;
-   } else if (filp > entry->vm_filp) {
+   } else if (tag > entry->vm_tag) {
iter = iter->rb_right;
} else {
iter = iter->rb_left;
@@ -386,9 +385,9 @@ EXPORT_SYMBOL(drm_vma_node_revoke);
 /**
  * drm_vma_node_is_allowed - Check whether an open-file is granted access
  * @node: Node to check
- * @filp: Open-file to check for
+ * @tag: Tag of file to remove
  *
- * Search the list in @node whether @filp is currently on the list of allowed
+ * Search the list in @node whether @tag is currently on the list of allowed
  * open-files (see drm_vma_node_allow()).
  *
  * This is locked against concurrent access internally.
@@ -396,8 +395,7 @@ EXPORT_SYMBOL(drm_vma_node_revoke);
  * RETURNS:
  * 

[PATCH 3/8] drm: reduce GETCLIENT to a minimum

2016-08-03 Thread David Herrmann
The *only* known user of GETCLIENT is libva, which uses it to check
whether its own context is authenticated. It used to iterate all clients,
look for one that matches its own pid and then check its state.

The entire purpose for us to still have a GETCLIENT implementation is to
serve libva. So lets not pretend we do anything else: Make this function
return information on the caller's context only, fake the PID to the
caller's pid so they always match, and just fill in the "authenticated"
bit, nothing else.

This patch reduces the complexity of GETCLIENT to a bare minimum, avoids
any dependency on priv->uid or priv->pid (allows us to get rid of them),
and makes libva happy by always *exactly* returning the information it
wants.

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/drm_ioctl.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 49cd835..bc5c65e 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -189,11 +189,8 @@ static int drm_getclient(struct drm_device *dev, void 
*data,
 */
if (client->idx == 0) {
client->auth = file_priv->authenticated;
-   client->pid = pid_vnr(file_priv->pid);
-   client->uid = from_kuid_munged(current_user_ns(),
-  file_priv->filp ?
-  file_priv->filp->f_cred->euid :
-  GLOBAL_ROOT_UID);
+   client->pid = task_pid_vnr(current);
+   client->uid = overflowuid;
client->magic = 0;
client->iocs = 0;

-- 
2.9.2



[PATCH 2/8] drm: remove redundant drm_file->uid

2016-08-03 Thread David Herrmann
Each DRM file-context caches the EUID of the process that opened the file.
It is used exclusively for debugging purposes in /proc/dri/ and friends.

Note, however, that "struct file" already caches the credentials of a
process at open-time. So lets just use drm_file->filp->f_cred->euid if
available. The pointer-chasing will not hurt us, since it is only about
debugging, anyway.

Check priv->filp for NULL before deref, to prepare for in-kernel contexts
(if they ever appear). We should not rely on "struct file" contexts to be
around at all times, anyway.

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/drm_fops.c  | 1 -
 drivers/gpu/drm/drm_info.c  | 4 +++-
 drivers/gpu/drm/drm_ioctl.c | 4 +++-
 include/drm/drmP.h  | 1 -
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 323c238..e9d66f5 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -199,7 +199,6 @@ static int drm_open_helper(struct file *filp, struct 
drm_minor *minor)

filp->private_data = priv;
priv->filp = filp;
-   priv->uid = current_euid();
priv->pid = get_pid(task_pid(current));
priv->minor = minor;

diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 9ae353f..247ba2b 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -80,6 +80,7 @@ int drm_clients_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_file *priv;
+   kuid_t uid;

seq_printf(m,
   "%20s %5s %3s master a %5s %10s\n",
@@ -98,13 +99,14 @@ int drm_clients_info(struct seq_file *m, void *data)

rcu_read_lock(); /* locks pid_task()->comm */
task = pid_task(priv->pid, PIDTYPE_PID);
+   uid = priv->filp ? priv->filp->f_cred->euid : GLOBAL_ROOT_UID;
seq_printf(m, "%20s %5d %3d   %c%c %5d %10u\n",
   task ? task->comm : "",
   pid_vnr(priv->pid),
   priv->minor->index,
   drm_is_current_master(priv) ? 'y' : 'n',
   priv->authenticated ? 'y' : 'n',
-  from_kuid_munged(seq_user_ns(m), priv->uid),
+  from_kuid_munged(seq_user_ns(m), uid),
   priv->magic);
rcu_read_unlock();
}
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 33af4a5..49cd835 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -191,7 +191,9 @@ static int drm_getclient(struct drm_device *dev, void *data,
client->auth = file_priv->authenticated;
client->pid = pid_vnr(file_priv->pid);
client->uid = from_kuid_munged(current_user_ns(),
-  file_priv->uid);
+  file_priv->filp ?
+  file_priv->filp->f_cred->euid :
+  GLOBAL_ROOT_UID);
client->magic = 0;
client->iocs = 0;

diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index d488a72..0f69f56 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -320,7 +320,6 @@ struct drm_file {
unsigned is_master:1;

struct pid *pid;
-   kuid_t uid;
drm_magic_t magic;
struct list_head lhead;
struct drm_minor *minor;
-- 
2.9.2



[PATCH 1/8] drm: rename DRM_MINOR_LEGACY to DRM_MINOR_PRIMARY

2016-08-03 Thread David Herrmann
The minor referred to by "DRM_MINOR_LEGACY" is called 'dev->primary' and
gets 'cardX' as name assigned. Lets reduce this magnificent number of
names for the same concept by one and rename DRM_MINOR_LEGACY to
DRM_MINOR_PRIMARY (to match the actual struct-member name).

Furthermore, this is in no way a legacy node, so lets not call it that.

Signed-off-by: David Herrmann 
---
 drivers/gpu/drm/drm_drv.c | 14 +++---
 include/drm/drmP.h|  4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index be27ed3..57ce973 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -112,7 +112,7 @@ static struct drm_minor **drm_minor_get_slot(struct 
drm_device *dev,
 unsigned int type)
 {
switch (type) {
-   case DRM_MINOR_LEGACY:
+   case DRM_MINOR_PRIMARY:
return >primary;
case DRM_MINOR_RENDER:
return >render;
@@ -512,7 +512,7 @@ int drm_dev_init(struct drm_device *dev,
goto err_minors;
}

-   ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
+   ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
if (ret)
goto err_minors;

@@ -545,7 +545,7 @@ err_ctxbitmap:
drm_legacy_ctxbitmap_cleanup(dev);
drm_ht_remove(>map_hash);
 err_minors:
-   drm_minor_free(dev, DRM_MINOR_LEGACY);
+   drm_minor_free(dev, DRM_MINOR_PRIMARY);
drm_minor_free(dev, DRM_MINOR_RENDER);
drm_minor_free(dev, DRM_MINOR_CONTROL);
drm_fs_inode_free(dev->anon_inode);
@@ -608,7 +608,7 @@ static void drm_dev_release(struct kref *ref)
drm_ht_remove(>map_hash);
drm_fs_inode_free(dev->anon_inode);

-   drm_minor_free(dev, DRM_MINOR_LEGACY);
+   drm_minor_free(dev, DRM_MINOR_PRIMARY);
drm_minor_free(dev, DRM_MINOR_RENDER);
drm_minor_free(dev, DRM_MINOR_CONTROL);

@@ -684,7 +684,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
if (ret)
goto err_minors;

-   ret = drm_minor_register(dev, DRM_MINOR_LEGACY);
+   ret = drm_minor_register(dev, DRM_MINOR_PRIMARY);
if (ret)
goto err_minors;

@@ -701,7 +701,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
goto out_unlock;

 err_minors:
-   drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+   drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drm_minor_unregister(dev, DRM_MINOR_RENDER);
drm_minor_unregister(dev, DRM_MINOR_CONTROL);
 out_unlock:
@@ -741,7 +741,7 @@ void drm_dev_unregister(struct drm_device *dev)
list_for_each_entry_safe(r_list, list_temp, >maplist, head)
drm_legacy_rmmap(dev, r_list->map);

-   drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+   drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drm_minor_unregister(dev, DRM_MINOR_RENDER);
drm_minor_unregister(dev, DRM_MINOR_CONTROL);
 }
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index d377865..d488a72 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -642,7 +642,7 @@ struct drm_driver {
 };

 enum drm_minor_type {
-   DRM_MINOR_LEGACY,
+   DRM_MINOR_PRIMARY,
DRM_MINOR_CONTROL,
DRM_MINOR_RENDER,
DRM_MINOR_CNT,
@@ -856,7 +856,7 @@ static inline bool drm_is_control_client(const struct 
drm_file *file_priv)

 static inline bool drm_is_primary_client(const struct drm_file *file_priv)
 {
-   return file_priv->minor->type == DRM_MINOR_LEGACY;
+   return file_priv->minor->type == DRM_MINOR_PRIMARY;
 }

 /**/
-- 
2.9.2



[PATCH 0/8] DRM File Context Cleanups

2016-08-03 Thread David Herrmann
Hi

Some rather random cleanups on drm_file and whatever I found on the way. The
idea here really is to get to a point where we can allocate drm_file from a
kernel context to get in-kernel rendering to work. This would allow allocating
dumb-buffers, dma-bufs, etc. from within the kernel and get fbdev generically
working, as well as panic renderers et al.

The only critical thing is drm_file->filp, which points to the underlying
"struct file". We really don't want to fake a "struct file" for in-kernel
renderers (even though it is possible), so this series tries to get rid of all
non-legacy users of it. The only real place left is vm_mmap() in drm_bufs.c.

Tested on i915 only.

Thanks
David

David Herrmann (8):
  drm: rename DRM_MINOR_LEGACY to DRM_MINOR_PRIMARY
  drm: remove redundant drm_file->uid
  drm: reduce GETCLIENT to a minimum
  drm: make vma-manager entries untyped
  drm: use drm_file to tag vm-bos
  drm: use priv->pid to deduce task EUID
  drm: rename drm_file.filp to drm_file.legacy_filp
  drm: provide management functions for drm_file

 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c |   3 +-
 drivers/gpu/drm/ast/ast_ttm.c   |   3 +-
 drivers/gpu/drm/bochs/bochs_mm.c|   3 +-
 drivers/gpu/drm/cirrus/cirrus_ttm.c |   3 +-
 drivers/gpu/drm/drm_bufs.c  |   7 +-
 drivers/gpu/drm/drm_drv.c   | 149 ++--
 drivers/gpu/drm/drm_fops.c  | 133 ++--
 drivers/gpu/drm/drm_gem.c   |   8 +-
 drivers/gpu/drm/drm_info.c  |   4 +-
 drivers/gpu/drm/drm_internal.h  |   4 +
 drivers/gpu/drm/drm_ioctl.c |   5 +-
 drivers/gpu/drm/drm_vma_manager.c   |  40 -
 drivers/gpu/drm/mgag200/mgag200_ttm.c   |   3 +-
 drivers/gpu/drm/nouveau/nouveau_bo.c|   3 +-
 drivers/gpu/drm/qxl/qxl_ttm.c   |   3 +-
 drivers/gpu/drm/radeon/radeon_ttm.c |   3 +-
 include/drm/drmP.h  |   7 +-
 include/drm/drm_vma_manager.h   |  18 ++--
 18 files changed, 213 insertions(+), 186 deletions(-)

-- 
2.9.2



[PATCH 2/8] drm: remove redundant drm_file->uid

2016-08-03 Thread Chris Wilson
On Wed, Aug 03, 2016 at 08:04:26PM +0200, David Herrmann wrote:
> @@ -98,13 +99,14 @@ int drm_clients_info(struct seq_file *m, void *data)
>  
>   rcu_read_lock(); /* locks pid_task()->comm */
>   task = pid_task(priv->pid, PIDTYPE_PID);
> + uid = priv->filp ? priv->filp->f_cred->euid : GLOBAL_ROOT_UID;
>   seq_printf(m, "%20s %5d %3d   %c%c %5d %10u\n",
>  task ? task->comm : "",
>  pid_vnr(priv->pid),
>  priv->minor->index,
>  drm_is_current_master(priv) ? 'y' : 'n',
>  priv->authenticated ? 'y' : 'n',
> -from_kuid_munged(seq_user_ns(m), priv->uid),
> +from_kuid_munged(seq_user_ns(m), uid),
>  priv->magic);
>   rcu_read_unlock();
>   }
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index 33af4a5..49cd835 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -191,7 +191,9 @@ static int drm_getclient(struct drm_device *dev, void 
> *data,
>   client->auth = file_priv->authenticated;
>   client->pid = pid_vnr(file_priv->pid);
>   client->uid = from_kuid_munged(current_user_ns(),
> -file_priv->uid);
> +file_priv->filp ?
> +file_priv->filp->f_cred->euid :
> +GLOBAL_ROOT_UID);

Why can't we use task_euid(pid_task(file_priv->pid)) here as well?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 6/8] drm: use priv->pid to deduce task EUID

2016-08-03 Thread Chris Wilson
On Wed, Aug 03, 2016 at 08:04:30PM +0200, David Herrmann wrote:
> Rather than accessing priv->filp->f_cred, use priv->pid->task->creds. We
> want to get rid of "priv->filp", so lets avoid it if possible.
> 
> Since we already are in an rcu-read-side, we can use __task_cred() rather
> than task_cred_xxx().
> 
> Signed-off-by: David Herrmann 
> ---
>  drivers/gpu/drm/drm_info.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
> index 247ba2b..1df2d33 100644
> --- a/drivers/gpu/drm/drm_info.c
> +++ b/drivers/gpu/drm/drm_info.c
> @@ -99,7 +99,7 @@ int drm_clients_info(struct seq_file *m, void *data)
>  
>   rcu_read_lock(); /* locks pid_task()->comm */
>   task = pid_task(priv->pid, PIDTYPE_PID);
> - uid = priv->filp ? priv->filp->f_cred->euid : GLOBAL_ROOT_UID;
> + uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID;

Squash this into patch 2, so the poor reader doesn't have to learn about
f_cred.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 2/8] drm: remove redundant drm_file->uid

2016-08-03 Thread Chris Wilson
On Wed, Aug 03, 2016 at 08:04:26PM +0200, David Herrmann wrote:
> diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
> index 323c238..e9d66f5 100644
> --- a/drivers/gpu/drm/drm_fops.c
> +++ b/drivers/gpu/drm/drm_fops.c
> @@ -199,7 +199,6 @@ static int drm_open_helper(struct file *filp, struct 
> drm_minor *minor)
>  
>   filp->private_data = priv;
>   priv->filp = filp;
> - priv->uid = current_euid();
>   priv->pid = get_pid(task_pid(current));
>   priv->minor = minor;
>  
> diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
> index 9ae353f..247ba2b 100644
> --- a/drivers/gpu/drm/drm_info.c
> +++ b/drivers/gpu/drm/drm_info.c
> @@ -98,13 +99,14 @@ int drm_clients_info(struct seq_file *m, void *data)
>  
>   rcu_read_lock(); /* locks pid_task()->comm */
>   task = pid_task(priv->pid, PIDTYPE_PID);
> + uid = priv->filp ? priv->filp->f_cred->euid : GLOBAL_ROOT_UID;

uid = task_euid(task);

>   seq_printf(m, "%20s %5d %3d   %c%c %5d %10u\n",
>  task ? task->comm : "",
>  pid_vnr(priv->pid),
>  priv->minor->index,
>  drm_is_current_master(priv) ? 'y' : 'n',
>  priv->authenticated ? 'y' : 'n',
> -from_kuid_munged(seq_user_ns(m), priv->uid),
> +from_kuid_munged(seq_user_ns(m), uid),
   from_kuid_munged(seq_user_ns(m), task_euid(task)),

Just fits.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 1/3] drm: Track drm_mm nodes with an interval tree

2016-08-03 Thread David Herrmann
Hey

On Wed, Aug 3, 2016 at 5:04 PM, Chris Wilson  
wrote:
> In addition to the last-in/first-out stack for accessing drm_mm nodes,
> we occasionally and in the future often want to find a drm_mm_node by an
> address. To do so efficiently we need to track the nodes in an interval
> tree - lookups for a particular address will then be O(lg(N)), where N
> is the number of nodes in the range manager as opposed to O(N).
> Insertion however gains an extra O(lg(N)) step for all nodes
> irrespective of whether the interval tree is in use. For future i915
> patches, eliminating the linear walk is a significant improvement.
>
> v2: Use generic interval-tree template for u64 and faster insertion.
>
> Signed-off-by: Chris Wilson 
> Cc: David Herrmann 
> Cc: dri-devel at lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_mm.c | 133 
> +++
>  include/drm/drm_mm.h |  12 +
>  2 files changed, 122 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
> index cb39f45d6a16..5c188c56894b 100644
> --- a/drivers/gpu/drm/drm_mm.c
> +++ b/drivers/gpu/drm/drm_mm.c
> @@ -46,6 +46,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  /**
>   * DOC: Overview
> @@ -103,6 +104,72 @@ static struct drm_mm_node 
> *drm_mm_search_free_in_range_generic(const struct drm_
> u64 end,
> enum drm_mm_search_flags 
> flags);
>
> +#define START(node) ((node)->start)
> +#define LAST(node)  ((node)->start + (node)->size - 1)

So this goes nuts with "size == 0". We do not explicitly prevent that
from happening, I think, but might be prevented in the upper layers.
Might wanna add WARN_ONs?

Otherwise, looks good to me:

Reviewed-by: David Herrmann 

Thanks
David

> +
> +INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
> +u64, __subtree_last,
> +START, LAST, static inline, drm_mm_interval_tree)
> +
> +struct drm_mm_node *
> +drm_mm_interval_first(struct drm_mm *mm, u64 start, u64 last)
> +{
> +   return drm_mm_interval_tree_iter_first(>interval_tree,
> +  start, last);
> +}
> +EXPORT_SYMBOL(drm_mm_interval_first);
> +
> +struct drm_mm_node *
> +drm_mm_interval_next(struct drm_mm_node *node, u64 start, u64 last)
> +{
> +   return drm_mm_interval_tree_iter_next(node, start, last);
> +}
> +EXPORT_SYMBOL(drm_mm_interval_next);
> +
> +static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
> + struct drm_mm_node *node)
> +{
> +   struct drm_mm *mm = hole_node->mm;
> +   struct rb_node **link, *rb;
> +   struct drm_mm_node *parent;
> +
> +   node->__subtree_last = LAST(node);
> +
> +   if (hole_node->allocated) {
> +   rb = _node->rb;
> +   while (rb) {
> +   parent = rb_entry(rb, struct drm_mm_node, rb);
> +   if (parent->__subtree_last >= node->__subtree_last)
> +   break;
> +
> +   parent->__subtree_last = node->__subtree_last;
> +   rb = rb_parent(rb);
> +   }
> +
> +   rb = _node->rb;
> +   link = _node->rb.rb_right;
> +   } else {
> +   rb = NULL;
> +   link = >interval_tree.rb_node;
> +   }
> +
> +   while (*link) {
> +   rb = *link;
> +   parent = rb_entry(rb, struct drm_mm_node, rb);
> +   if (parent->__subtree_last < node->__subtree_last)
> +   parent->__subtree_last = node->__subtree_last;
> +   if (node->start < parent->start)
> +   link = >rb.rb_left;
> +   else
> +   link = >rb.rb_right;
> +   }
> +
> +   rb_link_node(>rb, rb, link);
> +   rb_insert_augmented(>rb,
> +   >interval_tree,
> +   _mm_interval_tree_augment);
> +}
> +
>  static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
>  struct drm_mm_node *node,
>  u64 size, unsigned alignment,
> @@ -153,6 +220,8 @@ static void drm_mm_insert_helper(struct drm_mm_node 
> *hole_node,
> INIT_LIST_HEAD(>hole_stack);
> list_add(>node_list, _node->node_list);
>
> +   drm_mm_interval_tree_add_node(hole_node, node);
> +
> BUG_ON(node->start + node->size > adj_end);
>
> node->hole_follows = 0;
> @@ -178,41 +247,52 @@ static void drm_mm_insert_helper(struct drm_mm_node 
> *hole_node,
>   */
>  int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
>  {
> +   u64 end = node->start + node->size;
> struct drm_mm_node *hole;
> -   u64 end;
> -   u64 hole_start;
> -   u64 hole_end;
> -
> -   BUG_ON(node == NULL);
> +   

[PATCH 4/8] drm: make vma-manager entries untyped

2016-08-03 Thread Chris Wilson
On Wed, Aug 03, 2016 at 08:04:28PM +0200, David Herrmann wrote:
> Right now, the vma-manager requires all entries to provide a "struct
> file*" as identifier. This is confusing, since there is no inherent
> connection to "struct file" in the vma-manager at all, but it is
> exclusively used as tag.
> 
> Replace its usage with a simple "void *tag" and make sure callers can use
> arbitrary tags.
> 
> Signed-off-by: David Herrmann 
> ---

>  struct drm_vma_offset_file {

Now a misnomer.

Lgtm,
Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 3/3] drm: Skip initialising the drm_mm_node->hole_stack

2016-08-03 Thread David Herrmann
Hi Chris

On Wed, Aug 3, 2016 at 5:04 PM, Chris Wilson  
wrote:
> As we always add this to the drm_mm->hole_stack as our first operation,
> we do not need to initialise the list node.
>
> Signed-off-by: Chris Wilson 
> Cc: David Herrmann 
> Cc: dri-devel at lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_mm.c | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)

"hole_follows" tells whether it is linked or not. So yeah, indeed, redundant.

Reviewed-by: David Herrmann 

Thanks
David

> diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
> index 5c188c56894b..3f56d4b0cdae 100644
> --- a/drivers/gpu/drm/drm_mm.c
> +++ b/drivers/gpu/drm/drm_mm.c
> @@ -217,7 +217,6 @@ static void drm_mm_insert_helper(struct drm_mm_node 
> *hole_node,
> node->color = color;
> node->allocated = 1;
>
> -   INIT_LIST_HEAD(>hole_stack);
> list_add(>node_list, _node->node_list);
>
> drm_mm_interval_tree_add_node(hole_node, node);
> @@ -276,14 +275,13 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
> drm_mm_node *node)
> node->mm = mm;
> node->allocated = 1;
>
> -   INIT_LIST_HEAD(>hole_stack);
> list_add(>node_list, >node_list);
>
> drm_mm_interval_tree_add_node(hole, node);
>
> if (node->start == hole_start) {
> hole->hole_follows = 0;
> -   list_del_init(>hole_stack);
> +   list_del(>hole_stack);
> }
>
> node->hole_follows = 0;
> @@ -379,7 +377,6 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
> *hole_node,
> node->color = color;
> node->allocated = 1;
>
> -   INIT_LIST_HEAD(>hole_stack);
> list_add(>node_list, _node->node_list);
>
> drm_mm_interval_tree_add_node(hole_node, node);
> @@ -833,7 +830,6 @@ void drm_mm_init(struct drm_mm * mm, u64 start, u64 size)
>
> /* Clever trick to avoid a special case in the free hole tracking. */
> INIT_LIST_HEAD(>head_node.node_list);
> -   INIT_LIST_HEAD(>head_node.hole_stack);
> mm->head_node.hole_follows = 1;
> mm->head_node.scanned_block = 0;
> mm->head_node.scanned_prev_free = 0;
> --
> 2.8.1
>


[PATCH 2/3] drm: Convert drm_vma_manager to embedded interval-tree in drm_mm

2016-08-03 Thread David Herrmann
Hi Chris

On Wed, Aug 3, 2016 at 5:04 PM, Chris Wilson  
wrote:
> Having added an interval-tree to struct drm_mm, we can replace the
> auxiliary rb-tree inside the drm_vma_manager with it.
>
> Signed-off-by: Chris Wilson 
> Cc: David Herrmann 
> Cc: dri-devel at lists.freedesktop.org
> ---

Should have done that right from start when writing drm_vma_manager..

Reviewed-by: David Herrmann 

Thanks
David

>  drivers/gpu/drm/drm_vma_manager.c | 43 
> ---
>  include/drm/drm_vma_manager.h |  2 --
>  2 files changed, 9 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vma_manager.c 
> b/drivers/gpu/drm/drm_vma_manager.c
> index f306c8855978..0aef432679f9 100644
> --- a/drivers/gpu/drm/drm_vma_manager.c
> +++ b/drivers/gpu/drm/drm_vma_manager.c
> @@ -86,7 +86,6 @@ void drm_vma_offset_manager_init(struct 
> drm_vma_offset_manager *mgr,
>  unsigned long page_offset, unsigned long 
> size)
>  {
> rwlock_init(>vm_lock);
> -   mgr->vm_addr_space_rb = RB_ROOT;
> drm_mm_init(>vm_addr_space_mm, page_offset, size);
>  }
>  EXPORT_SYMBOL(drm_vma_offset_manager_init);
> @@ -145,16 +144,16 @@ struct drm_vma_offset_node 
> *drm_vma_offset_lookup_locked(struct drm_vma_offset_m
>  unsigned long start,
>  unsigned long pages)
>  {
> -   struct drm_vma_offset_node *node, *best;
> +   struct drm_mm_node *node, *best;
> struct rb_node *iter;
> unsigned long offset;
>
> -   iter = mgr->vm_addr_space_rb.rb_node;
> +   iter = mgr->vm_addr_space_mm.interval_tree.rb_node;
> best = NULL;
>
> while (likely(iter)) {
> -   node = rb_entry(iter, struct drm_vma_offset_node, vm_rb);
> -   offset = node->vm_node.start;
> +   node = rb_entry(iter, struct drm_mm_node, rb);
> +   offset = node->start;
> if (start >= offset) {
> iter = iter->rb_right;
> best = node;
> @@ -167,38 +166,17 @@ struct drm_vma_offset_node 
> *drm_vma_offset_lookup_locked(struct drm_vma_offset_m
>
> /* verify that the node spans the requested area */
> if (best) {
> -   offset = best->vm_node.start + best->vm_node.size;
> +   offset = best->start + best->size;
> if (offset < start + pages)
> best = NULL;
> }
>
> -   return best;
> -}
> -EXPORT_SYMBOL(drm_vma_offset_lookup_locked);
> -
> -/* internal helper to link @node into the rb-tree */
> -static void _drm_vma_offset_add_rb(struct drm_vma_offset_manager *mgr,
> -  struct drm_vma_offset_node *node)
> -{
> -   struct rb_node **iter = >vm_addr_space_rb.rb_node;
> -   struct rb_node *parent = NULL;
> -   struct drm_vma_offset_node *iter_node;
> -
> -   while (likely(*iter)) {
> -   parent = *iter;
> -   iter_node = rb_entry(*iter, struct drm_vma_offset_node, 
> vm_rb);
> +   if (!best)
> +   return NULL;
>
> -   if (node->vm_node.start < iter_node->vm_node.start)
> -   iter = &(*iter)->rb_left;
> -   else if (node->vm_node.start > iter_node->vm_node.start)
> -   iter = &(*iter)->rb_right;
> -   else
> -   BUG();
> -   }
> -
> -   rb_link_node(>vm_rb, parent, iter);
> -   rb_insert_color(>vm_rb, >vm_addr_space_rb);
> +   return container_of(best, struct drm_vma_offset_node, vm_node);
>  }
> +EXPORT_SYMBOL(drm_vma_offset_lookup_locked);
>
>  /**
>   * drm_vma_offset_add() - Add offset node to manager
> @@ -240,8 +218,6 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr,
> if (ret)
> goto out_unlock;
>
> -   _drm_vma_offset_add_rb(mgr, node);
> -
>  out_unlock:
> write_unlock(>vm_lock);
> return ret;
> @@ -265,7 +241,6 @@ void drm_vma_offset_remove(struct drm_vma_offset_manager 
> *mgr,
> write_lock(>vm_lock);
>
> if (drm_mm_node_allocated(>vm_node)) {
> -   rb_erase(>vm_rb, >vm_addr_space_rb);
> drm_mm_remove_node(>vm_node);
> memset(>vm_node, 0, sizeof(node->vm_node));
> }
> diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h
> index 06ea8e077ec2..afba6fcac853 100644
> --- a/include/drm/drm_vma_manager.h
> +++ b/include/drm/drm_vma_manager.h
> @@ -40,13 +40,11 @@ struct drm_vma_offset_file {
>  struct drm_vma_offset_node {
> rwlock_t vm_lock;
> struct drm_mm_node vm_node;
> -   struct rb_node vm_rb;
> struct rb_root vm_files;
>  };
>
>  struct drm_vma_offset_manager {
> rwlock_t vm_lock;
> -   struct rb_root vm_addr_space_rb;
> struct drm_mm vm_addr_space_mm;
>  };
>
> --

[PATCH] drm: Declare that create drm_mm nodes with size 0 is illegal

2016-08-03 Thread Chris Wilson
At a higher level, all objects are created with definite size i.e. 0 is
illegal. In forthcoming patches, this assumption is dependent upon in
the drm_mm range manager, i.e. trying to create a drm_mm node with size
0 will have undefined behaviour. Add a couple of WARNs upon creating the
drm_mm node to prevent later bugs.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index cb39f45d6a16..e8c15795386d 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -185,6 +185,9 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)

BUG_ON(node == NULL);

+   if (WARN_ON(node->size == 0))
+   return -EINVAL;
+
end = node->start + node->size;

/* Find the relevant hole to add our node to */
@@ -239,6 +242,9 @@ int drm_mm_insert_node_generic(struct drm_mm *mm, struct 
drm_mm_node *node,
 {
struct drm_mm_node *hole_node;

+   if (WARN_ON(size == 0))
+   return -EINVAL;
+
hole_node = drm_mm_search_free_generic(mm, size, alignment,
   color, sflags);
if (!hole_node)
@@ -340,6 +346,9 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, 
struct drm_mm_node *n
 {
struct drm_mm_node *hole_node;

+   if (WARN_ON(size == 0))
+   return -EINVAL;
+
hole_node = drm_mm_search_free_in_range_generic(mm,
size, alignment, color,
start, end, sflags);
-- 
2.8.1



[PATCH 0/3] DesignWare HDMI I2S suport

2016-08-03 Thread Mark Brown
On Tue, Aug 02, 2016 at 05:25:38AM +, Kuninori Morimoto wrote:

> I understand that 1) patch will be handled by drm side maintainer.
> And 2) was already accepted by you.
> I believe maintainer of 3) patch is you ??

Yes.
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160803/02e20f22/attachment.sig>


[PATCH v6 6/6] drm/i915/skl: Update DDB values atomically with wms/plane attrs

2016-08-03 Thread Ville Syrjälä
On Tue, Aug 02, 2016 at 06:37:37PM -0400, Lyude wrote:
> Now that we can hook into update_crtcs and control the order in which we
> update CRTCs at each modeset, we can finish the final step of fixing
> Skylake's watermark handling by performing DDB updates at the same time
> as plane updates and watermark updates.
> 
> The first major change in this patch is skl_update_crtcs(), which
> handles ensuring that we order each CRTC update in our atomic commits
> properly so that they honor the DDB flush order.
> 
> The second major change in this patch is the order in which we flush the
> pipes. While the previous order may have worked, it can't be used in
> this approach since it no longer will do the right thing. For example,
> using the old ddb flush order:
> 
> We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
> allocation looks like this:
> 
> |   A   |   B   |xxx|
> 
> Since we're performing the ddb updates after performing any CRTC
> disablements in intel_atomic_commit_tail(), the space to the right of
> pipe B is unallocated.
> 
> 1. Flush pipes with new allocation contained into old space. None
>apply, so we skip this
> 2. Flush pipes having their allocation reduced, but overlapping with a
>previous allocation. None apply, so we also skip this
> 3. Flush pipes that got more space allocated. This applies to A and B,
>giving us the following update order: A, B
> 
> This is wrong, since updating pipe A first will cause it to overlap with
> B and potentially burst into flames. Our new order (see the code
> comments for details) would update the pipes in the proper order: B, A.
> 
> As well, we calculate the order for each DDB update during the check
> phase, and reference it later in the commit phase when we hit
> skl_update_crtcs().
> 
> This long overdue patch fixes the rest of the underruns on Skylake.
> 
> Changes since v1:
>  - Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
> 
> Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
> Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
> Signed-off-by: Lyude 
> [omitting CC for stable, since this patch will need to be changed for
> such backports first]
> Cc: Ville Syrjälä 
> Cc: Daniel Vetter 
> Cc: Radhakrishna Sripada 
> Cc: Hans de Goede 
> Cc: Matt Roper 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 100 ++--
>  drivers/gpu/drm/i915/intel_drv.h |  10 ++
>  drivers/gpu/drm/i915/intel_pm.c  | 288 
> ---
>  3 files changed, 233 insertions(+), 165 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 59cf513..06295f7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12897,16 +12897,23 @@ static void verify_wm_state(struct drm_crtc *crtc,
> hw_entry->start, hw_entry->end);
>   }
>  
> - /* cursor */
> - hw_entry = _ddb.plane[pipe][PLANE_CURSOR];
> - sw_entry = _ddb->plane[pipe][PLANE_CURSOR];
> -
> - if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
> - DRM_ERROR("mismatch in DDB state pipe %c cursor "
> -   "(expected (%u,%u), found (%u,%u))\n",
> -   pipe_name(pipe),
> -   sw_entry->start, sw_entry->end,
> -   hw_entry->start, hw_entry->end);
> + /*
> +  * cursor
> +  * If the cursor plane isn't active, we may not have updated it's ddb
> +  * allocation. In that case since the ddb allocation will be updated
> +  * once the plane becomes visible, we can skip this check
> +  */
> + if (intel_crtc->cursor_addr) {
> + hw_entry = _ddb.plane[pipe][PLANE_CURSOR];
> + sw_entry = _ddb->plane[pipe][PLANE_CURSOR];
> +
> + if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
> + DRM_ERROR("mismatch in DDB state pipe %c cursor "
> +   "(expected (%u,%u), found (%u,%u))\n",
> +   pipe_name(pipe),
> +   sw_entry->start, sw_entry->end,
> +   hw_entry->start, hw_entry->end);
> + }
>   }
>  }
>  
> @@ -13658,6 +13665,72 @@ static void intel_update_crtcs(struct 
> drm_atomic_state *state,
>   }
>  }
>  
> +static inline void
> +skl_do_ddb_step(struct drm_atomic_state *state,
> + enum skl_ddb_step step)
> +{
> + struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *old_crtc_state;
> + unsigned int crtc_vblank_mask; /* unused */
> + int i;
> +
> + for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *cstate =
> + to_intel_crtc_state(crtc->state);
> +  

[PATCH libdrm] Make sure the second argument to container_of() is initialized

2016-08-03 Thread Michel Dänzer
On 03.08.2016 02:49, Nicolai Hähnle wrote:
> On 02.08.2016 12:08, Michel Dänzer wrote:
>> From: Michel Dänzer 
>>
>> Fixes warnings and miscompilation resulting in crashes with clang.
> 
> How annoying. Seems like this would affect most (current and future)
> uses of container_of, and so it would be better to switch to the Linux
> kernel version of container_of, where the second parameter is the type...

Rob proposed http://hastebin.com/vefenavoje.coffee on IRC, using
typeof(). I'm fine with going for that instead of my patch, just FYI: My
patch was based on xserver's list.h, which works with compilers which
don't support typeof(). Not sure that's relevant for libdrm though.


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



[PATCH v6 6/6] drm/i915/skl: Update DDB values atomically with wms/plane attrs

2016-08-03 Thread Lyude Paul
On Wed, 2016-08-03 at 18:00 +0300, Ville Syrjälä wrote:
> On Tue, Aug 02, 2016 at 06:37:37PM -0400, Lyude wrote:
> > 
> > Now that we can hook into update_crtcs and control the order in which we
> > update CRTCs at each modeset, we can finish the final step of fixing
> > Skylake's watermark handling by performing DDB updates at the same time
> > as plane updates and watermark updates.
> > 
> > The first major change in this patch is skl_update_crtcs(), which
> > handles ensuring that we order each CRTC update in our atomic commits
> > properly so that they honor the DDB flush order.
> > 
> > The second major change in this patch is the order in which we flush the
> > pipes. While the previous order may have worked, it can't be used in
> > this approach since it no longer will do the right thing. For example,
> > using the old ddb flush order:
> > 
> > We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
> > allocation looks like this:
> > 
> > > 
> > >   A   |   B   |xxx|
> > 
> > Since we're performing the ddb updates after performing any CRTC
> > disablements in intel_atomic_commit_tail(), the space to the right of
> > pipe B is unallocated.
> > 
> > 1. Flush pipes with new allocation contained into old space. None
> >    apply, so we skip this
> > 2. Flush pipes having their allocation reduced, but overlapping with a
> >    previous allocation. None apply, so we also skip this
> > 3. Flush pipes that got more space allocated. This applies to A and B,
> >    giving us the following update order: A, B
> > 
> > This is wrong, since updating pipe A first will cause it to overlap with
> > B and potentially burst into flames. Our new order (see the code
> > comments for details) would update the pipes in the proper order: B, A.
> > 
> > As well, we calculate the order for each DDB update during the check
> > phase, and reference it later in the commit phase when we hit
> > skl_update_crtcs().
> > 
> > This long overdue patch fixes the rest of the underruns on Skylake.
> > 
> > Changes since v1:
> >  - Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
> > 
> > Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
> > Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
> > Signed-off-by: Lyude 
> > [omitting CC for stable, since this patch will need to be changed for
> > such backports first]
> > Cc: Ville Syrjälä 
> > Cc: Daniel Vetter 
> > Cc: Radhakrishna Sripada 
> > Cc: Hans de Goede 
> > Cc: Matt Roper 
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 100 ++--
> >  drivers/gpu/drm/i915/intel_drv.h     |  10 ++
> >  drivers/gpu/drm/i915/intel_pm.c      | 288 
> > --
> > -
> >  3 files changed, 233 insertions(+), 165 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 59cf513..06295f7 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -12897,16 +12897,23 @@ static void verify_wm_state(struct drm_crtc *crtc,
> >      hw_entry->start, hw_entry->end);
> >    }
> >  
> > -   /* cursor */
> > -   hw_entry = _ddb.plane[pipe][PLANE_CURSOR];
> > -   sw_entry = _ddb->plane[pipe][PLANE_CURSOR];
> > -
> > -   if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
> > -   DRM_ERROR("mismatch in DDB state pipe %c cursor "
> > -     "(expected (%u,%u), found (%u,%u))\n",
> > -     pipe_name(pipe),
> > -     sw_entry->start, sw_entry->end,
> > -     hw_entry->start, hw_entry->end);
> > +   /*
> > +    * cursor
> > +    * If the cursor plane isn't active, we may not have updated it's
> > ddb
> > +    * allocation. In that case since the ddb allocation will be
> > updated
> > +    * once the plane becomes visible, we can skip this check
> > +    */
> > +   if (intel_crtc->cursor_addr) {
> > +   hw_entry = _ddb.plane[pipe][PLANE_CURSOR];
> > +   sw_entry = _ddb->plane[pipe][PLANE_CURSOR];
> > +
> > +   if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
> > +   DRM_ERROR("mismatch in DDB state pipe %c cursor "
> > +     "(expected (%u,%u), found (%u,%u))\n",
> > +     pipe_name(pipe),
> > +     sw_entry->start, sw_entry->end,
> > +     hw_entry->start, hw_entry->end);
> > +   }
> >    }
> >  }
> >  
> > @@ -13658,6 +13665,72 @@ static void intel_update_crtcs(struct
> > drm_atomic_state *state,
> >    }
> >  }
> >  
> > +static inline void
> > +skl_do_ddb_step(struct drm_atomic_state *state,
> > +   enum skl_ddb_step step)
> > +{
> > +   struct intel_atomic_state *intel_state =
> > to_intel_atomic_state(state);
> > +   struct drm_crtc *crtc;
> > +   struct drm_crtc_state *old_crtc_state;
> > +   

[PATCH 0210/1285] Replace numeric parameter like 0444 with macro

2016-08-03 Thread Krzysztof Kozlowski
On Tue, Aug 02, 2016 at 06:50:01PM +0800, Baole Ni wrote:
> I find that the developers often just specified the numeric value
> when calling a macro which is defined with a parameter for access permission.
> As we know, these numeric value for access permission have had the 
> corresponding macro,
> and that using macro can improve the robustness and readability of the code,
> thus, I suggest replacing the numeric parameter with the macro.
> 
> Signed-off-by: Chuansheng Liu 
> Signed-off-by: Baole Ni 
> ---
>  drivers/gpu/drm/qxl/qxl_drv.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

I got almost 1000 patches out of your mail bomb. For all of them: NACK.
Other people pointed actual reasons (title, readability, cc-list). The
commit msg should be also written in a more readable way.

Anyway, in Intel there are a lot of people having kernel contributions
so it is a shame that you didn't ask them for advice how to do it...

BR,
Krzysztof


[PATCH v2 11/13] gpu: ipu-ic: Add complete image conversion support with tiling

2016-08-03 Thread Steve Longerbeam
On 08/01/2016 02:29 AM, Philipp Zabel wrote:
> Am Donnerstag, den 28.07.2016, 16:09 -0700 schrieb Steve Longerbeam:
>>> Now split the frame in half and suddenly pixel x' = 640 is the start of
>>> a new tile, so it is sampled at x = 160, and pixel x' = 1279 will be
>>> sampled at x = 160 + (1279 - 640) * 8192/32846. = 319.37, reading over
>>> the edge of the source image.
>> Here's where we part.
>>
>> The 320x200 --> 1280x800 conversion is split into two 160x200 -->
>> 640x800 conversions. The DMA controller and ipu_ic_task_init() are given
>> those width/height dimensions, not the dimensions of the original images.
>> So this is simply two separate 160x200 --> 640x800 conversions. The only
>> difference from a true 160x200 --> 640x800 image conversion is that the DMA
>> controller must be given the stride lengths of the original 320x200 and 
>> 1280x800
>> images.
>>
>> The rsc for the 160x200 --> 640x800 conversions is
>>
>> x = x' * (160-1)/(640-1) = x' * 8192/rsc, so rsc = 32923
>>
>>
>> So original horizontal position 640 is really x' = 0 of the second 
>> conversion,
>> which is sampled at x = 0 of the second conversion. And the pixel at x' 
>> = 1279
>> is really x' = 639 of the second conversion, which is sampled at x = 639 
>> * 8192/32923
>> = 158.98, which does not read over the edge of the source tile.
> My bad, I somehow thought that the scaling factor is calculated per
> image (as it IMHO should be), not just per tile.
>
> Of course in that case you won't ever read over the edge, but on the
> other hand the visual problems are worse because you underestimate the
> scaling factor and introduce a sharp edge at the center: even if the
> source pixel step per target pixel step is a fraction, between pixels
> width/2-1 and width/2 there's always a whole source pixel step.
>
> Take the extreme example of scaling 32x32 to 1080x1080 pixels. The ideal
> source pixels for x' = 519 and 520 should be x = 14.911 and 14.939,
> respectively. Due to tiling they will be x = 15 and 16, introducing a
> sharp seam in the otherwise blurry mess.

I think you mean at x' = 539 and x' = 540.

But yes I agree. Due to tiling, at x' = 539, the input pixel is sampled at x = 
15.
If the interpolation were to continue (no tiling), at x' = 540, the input pixel
would be sampled at (31/1079)*540 = 15.514. Instead, because of tiling,
there is a discontinuity in the interpolation (it is reset), beginning again at
x' = 0 (540), which is sampled at x = 0 (16).

The only way I can think of to resolve this problem is to add some width
to the output tiles such that the interpolation completes a full span between
input position w - 2 and w - 1. That is, add to w' until floor(F*w') increments
to the next whole integer, where F = (w-1)/(w'-1) is the scaling factor.

But that will likely cause the next tile DMA addrs to fail to fall on the IDMAC
8 byte alignment.


>
>
>> That said, I _have_ noticed seams, but I have always attributed them to the
>> fact that we have a discontinuity in color-space conversion and/or resize
>> interpolation at the boundary between tiles.
>>
>> I've also found that the seams are quite noticeable when rendered to a
>> display overlay, but become significantly less pronounced if the images are
>> converted to a back buffer, and then page-flipped to front buffer when the
>> conversion (all tiles) completes.
> I don't know what to make of this. Maybe it is a timing issue and what
> you are actually seeing is tearing between tiles of different frames?

Yes, that's always been my assumption, a scan-out contains a mix
of tiles from different frames, when page-flip is not used.

Steve



[PATCH] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-03 Thread Mark yao
On 2016年08月03日 16:46, Daniel Vetter wrote:
> On Wed, Aug 03, 2016 at 10:43:21AM +0200, Daniel Vetter wrote:
>> On Wed, Aug 03, 2016 at 04:13:45PM +0800, Mark Yao wrote:
>>> [1.162571] Unable to handle kernel NULL pointer dereference at virtual 
>>> address 0200
>>> [1.165656] Modules linked in:
>>> [1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
>>> [1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 (Android) 
>>> (DT)
>>> [1.167153] Workqueue: events output_poll_execute
>>> [1.168231] PC is at mutex_lock+0x14/0x44
>>> [1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
>>> [1.172192] [] mutex_lock+0x14/0x44
>>> [1.172196] [] drm_fb_helper_hotplug_event+0x28/0xcc
>>> [1.172201] [] 
>>> rockchip_drm_output_poll_changed+0x14/0x1c
>>> [1.172204] [] drm_kms_helper_hotplug_event+0x28/0x34
>>> [1.172207] [] output_poll_execute+0x150/0x198
>>> [1.172212] [] process_one_work+0x218/0x3dc
>>> [1.172215] [] worker_thread+0x24c/0x374
>>> [1.172217] [] kthread+0xdc/0xe4
>>> [1.17] [] ret_from_fork+0x10/0x40
>>>
>>> Signed-off-by: Mark Yao 
>> Erhm, how exactly did you manage to blow up in there? Without fbdev
>> support enable drm_fb_helper_hotplug_event() does nothing at all.
>>
>> The fbdev helper is designed such that you _don't_ have to check for NULL
>> everywhere in the driver, that would be pretty bad code.
> And indeed this issue seems preexisting, and was already attempt to fix in
>
> commit 765c35bbd267e93eabe15a94534688ddaa0b9dc7
> Author: Heiko Stübner 
> Date:   Tue Jun 2 16:41:45 2015 +0200
>
>  drm/rockchip: only call drm_fb_helper_hotplug_event if fb_helper present
>
> except that patch is complete nonsense - the added check is always true.
> Oh and it's missing your s-o-b, which is not good at all.
>
> The proper fix is to make delayed fbdev loading work correctly, Thierry
> has patches for that on the mailing list. Not add even more hacks like the
> above (and then slap a misleading subject onto your patch).
> -Daniel

Hmmm, there is a mistake on Heiko's patch:

 struct drm_fb_helper *fb_helper = >fbdev_helper;

-   drm_fb_helper_hotplug_event(fb_helper);
   +   if (fb_helper)
   +   drm_fb_helper_hotplug_event(fb_helper);

But the fb_helper would never be NULL, because the private->fbdev_helper 
is not a pointer.

So the first step is making private->fbdev_helper to a pointer, that's 
what I do on this patch.


>> -Daniel
>>
>>> ---
>>>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   | 13 ++---
>>>   drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  8 ++--
>>>   drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  6 +++---
>>>   drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 26 
>>> +-
>>>   4 files changed, 36 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
>>> b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> index a822d49..1a4dad6 100644
>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> @@ -261,7 +261,10 @@ static void rockchip_drm_lastclose(struct drm_device 
>>> *dev)
>>>   {
>>> struct rockchip_drm_private *priv = dev->dev_private;
>>>   
>>> -   drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev_helper);
>>> +   if (!priv->fbdev)
>>> +   return;
>>> +
>>> +   drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev->fbdev_helper);
>>>   }
>>>   
>>>   static const struct file_operations rockchip_drm_driver_fops = {
>>> @@ -310,8 +313,10 @@ void rockchip_drm_fb_suspend(struct drm_device *drm)
>>>   {
>>> struct rockchip_drm_private *priv = drm->dev_private;
>>>   
>>> +   if (!priv->fbdev)
>>> +   return;
>>> console_lock();
>>> -   drm_fb_helper_set_suspend(>fbdev_helper, 1);
>>> +   drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 1);
>>> console_unlock();
>>>   }
>>>   
>>> @@ -319,8 +324,10 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
>>>   {
>>> struct rockchip_drm_private *priv = drm->dev_private;
>>>   
>>> +   if (!priv->fbdev)
>>> +   return;
>>> console_lock();
>>> -   drm_fb_helper_set_suspend(>fbdev_helper, 0);
>>> +   drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 0);
>>> console_unlock();
>>>   }
>>>   
>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
>>> b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
>>> index ea39329..c054fc2 100644
>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
>>> @@ -50,6 +50,11 @@ struct rockchip_crtc_state {
>>>   #define to_rockchip_crtc_state(s) \
>>> container_of(s, struct rockchip_crtc_state, base)
>>>   
>>> +struct rockchip_drm_fbdev {
>>> +   struct drm_fb_helper fbdev_helper;
>>> +   struct drm_gem_object *fbdev_bo;
>>> +};
>>> +
>>>   /*
>>>* Rockchip drm private structure.
>>>*
>>> @@ -57,8 +62,7 @@ 

[PATCH 4/4] drm: Add and handle new aspect ratios in DRM layer

2016-08-03 Thread Shashank Sharma
HDMI 2.0/CEA-861-F introduces two new aspect ratios:
- 64:27
- 256:135

This patch:
-  Adds new DRM flags for to represent these new aspect ratios.
-  Adds new cases to handle these aspect ratios while converting
from user->kernel mode or viseversa.

Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/drm_modes.c | 12 
 include/uapi/drm/drm_mode.h |  6 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index e6029e0..bdc353d 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1481,6 +1481,12 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo 
*out,
case HDMI_PICTURE_ASPECT_16_9:
out->flags |= DRM_MODE_FLAG_PAR16_9;
break;
+   case HDMI_PICTURE_ASPECT_64_27:
+   out->flags |= DRM_MODE_FLAG_PAR64_27;
+   break;
+   case DRM_MODE_PICTURE_ASPECT_256_135:
+   out->flags |= DRM_MODE_FLAG_PAR256_135;
+   break;
case HDMI_PICTURE_ASPECT_NONE:
case HDMI_PICTURE_ASPECT_RESERVED:
default:
@@ -1543,6 +1549,12 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
case DRM_MODE_FLAG_PAR16_9:
out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9;
break;
+   case DRM_MODE_FLAG_PAR64_27:
+   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_64_27;
+   break;
+   case DRM_MODE_FLAG_PAR256_135:
+   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_256_135;
+   break;
default:
out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
}
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index cd66a95..6291eae 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -81,6 +81,8 @@ extern "C" {
 #define DRM_MODE_PICTURE_ASPECT_NONE   0
 #define DRM_MODE_PICTURE_ASPECT_4_31
 #define DRM_MODE_PICTURE_ASPECT_16_9   2
+#define DRM_MODE_PICTURE_ASPECT_64_27  3
+#define DRM_MODE_PICTURE_ASPECT_256_1354

 /* Aspect ratio flag bitmask (4 bits 22:19) */
 #define DRM_MODE_FLAG_PARMASK  (0x0F<<19)
@@ -90,6 +92,10 @@ extern "C" {
(DRM_MODE_PICTURE_ASPECT_4_3 << 19)
 #define  DRM_MODE_FLAG_PAR16_9 \
(DRM_MODE_PICTURE_ASPECT_16_9 << 19)
+#define  DRM_MODE_FLAG_PAR64_27 \
+   (DRM_MODE_PICTURE_ASPECT_64_27 << 19)
+#define  DRM_MODE_FLAG_PAR256_135 \
+   (DRM_MODE_PICTURE_ASPECT_256_135 << 19)

 /* DPMS flags */
 /* bit compatible with the xorg definitions. */
-- 
1.9.1



[PATCH 3/4] video: Add new aspect ratios for HDMI 2.0

2016-08-03 Thread Shashank Sharma
HDMI 2.0/CEA-861-F introduces two new aspect ratios:
- 64:27
- 256:135

This patch adds enumeration for the new aspect ratios
in the existing aspect ratio list.

Signed-off-by: Shashank Sharma 
---
 drivers/video/hdmi.c | 4 
 include/linux/hdmi.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 1626892..1cf907e 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -533,6 +533,10 @@ hdmi_picture_aspect_get_name(enum hdmi_picture_aspect 
picture_aspect)
return "4:3";
case HDMI_PICTURE_ASPECT_16_9:
return "16:9";
+   case HDMI_PICTURE_ASPECT_64_27:
+   return "64:27";
+   case HDMI_PICTURE_ASPECT_256_135:
+   return "256:135";
case HDMI_PICTURE_ASPECT_RESERVED:
return "Reserved";
}
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index e974420..edbb4fc 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -78,6 +78,8 @@ enum hdmi_picture_aspect {
HDMI_PICTURE_ASPECT_NONE,
HDMI_PICTURE_ASPECT_4_3,
HDMI_PICTURE_ASPECT_16_9,
+   HDMI_PICTURE_ASPECT_64_27,
+   HDMI_PICTURE_ASPECT_256_135,
HDMI_PICTURE_ASPECT_RESERVED,
 };

-- 
1.9.1



[PATCH 2/4] drm: Add aspect ratio parsing in DRM layer

2016-08-03 Thread Shashank Sharma
Current DRM layer functions dont parse aspect ratio information
while converting a user mode->kernel mode or viceversa. This
causes modeset to pick mode with wrong aspect ratio, eventually
cauing failures in HDMI compliance test cases, due to wrong VIC.

This patch adds aspect ratio information in DRM's mode conversion
and mode comparision functions, to make sure kernel picks mode
with right aspect ratio (as per the VIC).

Signed-off-by: Shashank Sharma 
Signed-off-by: Lin, Jia 
Signed-off-by: Akashdeep Sharma 
---
 drivers/gpu/drm/drm_modes.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index fc5040a..e6029e0 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -969,6 +969,7 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct 
drm_display_mode *mode1,
mode1->vsync_end == mode2->vsync_end &&
mode1->vtotal == mode2->vtotal &&
mode1->vscan == mode2->vscan &&
+   mode1->picture_aspect_ratio == mode2->picture_aspect_ratio &&
(mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
 (mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
return true;
@@ -1471,6 +1472,22 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo 
*out,
out->vrefresh = in->vrefresh;
out->flags = in->flags;
out->type = in->type;
+   out->flags &= ~DRM_MODE_FLAG_PARMASK;
+
+   switch (in->picture_aspect_ratio) {
+   case HDMI_PICTURE_ASPECT_4_3:
+   out->flags |= DRM_MODE_FLAG_PAR4_3;
+   break;
+   case HDMI_PICTURE_ASPECT_16_9:
+   out->flags |= DRM_MODE_FLAG_PAR16_9;
+   break;
+   case HDMI_PICTURE_ASPECT_NONE:
+   case HDMI_PICTURE_ASPECT_RESERVED:
+   default:
+   out->flags |= DRM_MODE_FLAG_PARNONE;
+   break;
+   }
+
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 }
@@ -1516,6 +1533,20 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;

+   /* Clearing picture aspect ratio bits from out flags */
+   out->flags &= ~DRM_MODE_FLAG_PARMASK;
+
+   switch (in->flags & DRM_MODE_FLAG_PARMASK) {
+   case DRM_MODE_FLAG_PAR4_3:
+   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_4_3;
+   break;
+   case DRM_MODE_FLAG_PAR16_9:
+   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9;
+   break;
+   default:
+   out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+   }
+
out->status = drm_mode_validate_basic(out);
if (out->status != MODE_OK)
goto out;
-- 
1.9.1



[PATCH 1/4] drm: add picture aspect ratio flags

2016-08-03 Thread Shashank Sharma
This patch adds drm flag bits for aspect ratio information

Currently drm flag bits don't have field for mode's picture
aspect ratio. This field will help the driver to pick mode with
right aspect ratio, and help in setting right VIC field in avi
infoframes.

Signed-off-by: Shashank Sharma 
---
 include/uapi/drm/drm_mode.h | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 49a7265..cd66a95 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -77,6 +77,19 @@ extern "C" {
 #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM   (7<<14)
 #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF(8<<14)

+/* Picture aspect ratio options */
+#define DRM_MODE_PICTURE_ASPECT_NONE   0
+#define DRM_MODE_PICTURE_ASPECT_4_31
+#define DRM_MODE_PICTURE_ASPECT_16_9   2
+
+/* Aspect ratio flag bitmask (4 bits 22:19) */
+#define DRM_MODE_FLAG_PARMASK  (0x0F<<19)
+#define  DRM_MODE_FLAG_PARNONE \
+   (DRM_MODE_PICTURE_ASPECT_NONE << 19)
+#define  DRM_MODE_FLAG_PAR4_3 \
+   (DRM_MODE_PICTURE_ASPECT_4_3 << 19)
+#define  DRM_MODE_FLAG_PAR16_9 \
+   (DRM_MODE_PICTURE_ASPECT_16_9 << 19)

 /* DPMS flags */
 /* bit compatible with the xorg definitions. */
@@ -92,11 +105,6 @@ extern "C" {
 #define DRM_MODE_SCALE_CENTER  2 /* Centered, no scaling */
 #define DRM_MODE_SCALE_ASPECT  3 /* Full screen, preserve aspect */

-/* Picture aspect ratio options */
-#define DRM_MODE_PICTURE_ASPECT_NONE   0
-#define DRM_MODE_PICTURE_ASPECT_4_31
-#define DRM_MODE_PICTURE_ASPECT_16_9   2
-
 /* Dithering mode options */
 #define DRM_MODE_DITHERING_OFF 0
 #define DRM_MODE_DITHERING_ON  1
-- 
1.9.1



[PATCH 0/4]: Picture aspect ratio support in DRM layer

2016-08-03 Thread Shashank Sharma
This patch series adds 4 patches.
- The first two patches add aspect ratio support in DRM layes
- Next two patches add new aspect ratios defined in CEA-861-F
  supported for HDMI 2.0 4k modes.

Adding aspect ratio support in DRM layer:
- The CEA videmodes contain aspect ratio information, which we
  parse when we read the modes from EDID. But while transforming
  user_mode to kernel_mode or viceversa, DRM layer lose this
  information.
- HDMI compliance testing for CEA modes, expects the AVI info frames
  to contain exact VIC no for the 'video mode under test'. Now CEA
  modes have different VIC for same modes but different aspect ratio
  for example:
VIC 2 = 720x480 at 60 4:3 
VIC 3 = 720x480 at 60 16:9
  In this way, lack of aspect ratio information, can cause wrong VIC
  no in AVI IF, causing HDMI complaince test to fail.
- This patch set adds code, which embeds the aspect ratio information
  also in DRM video mode flags, and uses it while comparing two modes. 

Adding new aspect ratios for HDMI 2.0
- CEA-861-F defines two new aspect ratios, to be used for 4k HDMI 2.0
  modes.
- 64:27
- 256:135
Last two patches in the series, adds code to handle these new
aspect ratios.

Shashank Sharma (4):
  drm: add picture aspect ratio flags
  drm: Add aspect ratio parsing in DRM layer
  video: Add new aspect ratios for HDMI 2.0
  drm: Add and handle new aspect ratios in DRM layer

 drivers/gpu/drm/drm_modes.c | 43 +++
 drivers/video/hdmi.c|  4 
 include/linux/hdmi.h|  2 ++
 include/uapi/drm/drm_mode.h | 24 +++-
 4 files changed, 68 insertions(+), 5 deletions(-)

-- 
1.9.1



[PATCH] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-03 Thread Mark Yao
[1.162571] Unable to handle kernel NULL pointer dereference at virtual 
address 0200
[1.165656] Modules linked in:
[1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
[1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 (Android) (DT)
[1.167153] Workqueue: events output_poll_execute
[1.168231] PC is at mutex_lock+0x14/0x44
[1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
[1.172192] [] mutex_lock+0x14/0x44
[1.172196] [] drm_fb_helper_hotplug_event+0x28/0xcc
[1.172201] [] rockchip_drm_output_poll_changed+0x14/0x1c
[1.172204] [] drm_kms_helper_hotplug_event+0x28/0x34
[1.172207] [] output_poll_execute+0x150/0x198
[1.172212] [] process_one_work+0x218/0x3dc
[1.172215] [] worker_thread+0x24c/0x374
[1.172217] [] kthread+0xdc/0xe4
[1.17] [] ret_from_fork+0x10/0x40

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   | 13 ++---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  8 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  6 +++---
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 26 +-
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index a822d49..1a4dad6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -261,7 +261,10 @@ static void rockchip_drm_lastclose(struct drm_device *dev)
 {
struct rockchip_drm_private *priv = dev->dev_private;

-   drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev_helper);
+   if (!priv->fbdev)
+   return;
+
+   drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev->fbdev_helper);
 }

 static const struct file_operations rockchip_drm_driver_fops = {
@@ -310,8 +313,10 @@ void rockchip_drm_fb_suspend(struct drm_device *drm)
 {
struct rockchip_drm_private *priv = drm->dev_private;

+   if (!priv->fbdev)
+   return;
console_lock();
-   drm_fb_helper_set_suspend(>fbdev_helper, 1);
+   drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 1);
console_unlock();
 }

@@ -319,8 +324,10 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
 {
struct rockchip_drm_private *priv = drm->dev_private;

+   if (!priv->fbdev)
+   return;
console_lock();
-   drm_fb_helper_set_suspend(>fbdev_helper, 0);
+   drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 0);
console_unlock();
 }

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index ea39329..c054fc2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -50,6 +50,11 @@ struct rockchip_crtc_state {
 #define to_rockchip_crtc_state(s) \
container_of(s, struct rockchip_crtc_state, base)

+struct rockchip_drm_fbdev {
+   struct drm_fb_helper fbdev_helper;
+   struct drm_gem_object *fbdev_bo;
+};
+
 /*
  * Rockchip drm private structure.
  *
@@ -57,8 +62,7 @@ struct rockchip_crtc_state {
  * @num_pipe: number of pipes for this device.
  */
 struct rockchip_drm_private {
-   struct drm_fb_helper fbdev_helper;
-   struct drm_gem_object *fbdev_bo;
+   struct rockchip_drm_fbdev *fbdev;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
 };
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 55c5273..fef6f8d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -156,10 +156,10 @@ err_gem_object_unreference:
 static void rockchip_drm_output_poll_changed(struct drm_device *dev)
 {
struct rockchip_drm_private *private = dev->dev_private;
-   struct drm_fb_helper *fb_helper = >fbdev_helper;
+   struct rockchip_drm_fbdev *fbdev = private->fbdev;

-   if (fb_helper)
-   drm_fb_helper_hotplug_event(fb_helper);
+   if (fbdev)
+   drm_fb_helper_hotplug_event(>fbdev_helper);
 }

 static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index 207e01d..cc5781a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -22,16 +22,16 @@
 #include "rockchip_drm_fb.h"

 #define PREFERRED_BPP  32
-#define to_drm_private(x) \
-   container_of(x, struct rockchip_drm_private, fbdev_helper)
+#define to_rockchip_fbdev(x) \
+   container_of(x, struct rockchip_drm_fbdev, fbdev_helper)

 static int rockchip_fbdev_mmap(struct fb_info *info,
   struct vm_area_struct *vma)
 {
struct drm_fb_helper *helper = info->par;
-   struct 

[PATCH 3/3] drm: Skip initialising the drm_mm_node->hole_stack

2016-08-03 Thread Chris Wilson
As we always add this to the drm_mm->hole_stack as our first operation,
we do not need to initialise the list node.

Signed-off-by: Chris Wilson 
Cc: David Herrmann 
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/drm_mm.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 5c188c56894b..3f56d4b0cdae 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -217,7 +217,6 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
node->color = color;
node->allocated = 1;

-   INIT_LIST_HEAD(>hole_stack);
list_add(>node_list, _node->node_list);

drm_mm_interval_tree_add_node(hole_node, node);
@@ -276,14 +275,13 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
node->mm = mm;
node->allocated = 1;

-   INIT_LIST_HEAD(>hole_stack);
list_add(>node_list, >node_list);

drm_mm_interval_tree_add_node(hole, node);

if (node->start == hole_start) {
hole->hole_follows = 0;
-   list_del_init(>hole_stack);
+   list_del(>hole_stack);
}

node->hole_follows = 0;
@@ -379,7 +377,6 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
node->color = color;
node->allocated = 1;

-   INIT_LIST_HEAD(>hole_stack);
list_add(>node_list, _node->node_list);

drm_mm_interval_tree_add_node(hole_node, node);
@@ -833,7 +830,6 @@ void drm_mm_init(struct drm_mm * mm, u64 start, u64 size)

/* Clever trick to avoid a special case in the free hole tracking. */
INIT_LIST_HEAD(>head_node.node_list);
-   INIT_LIST_HEAD(>head_node.hole_stack);
mm->head_node.hole_follows = 1;
mm->head_node.scanned_block = 0;
mm->head_node.scanned_prev_free = 0;
-- 
2.8.1



[PATCH 2/3] drm: Convert drm_vma_manager to embedded interval-tree in drm_mm

2016-08-03 Thread Chris Wilson
Having added an interval-tree to struct drm_mm, we can replace the
auxiliary rb-tree inside the drm_vma_manager with it.

Signed-off-by: Chris Wilson 
Cc: David Herrmann 
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/drm_vma_manager.c | 43 ---
 include/drm/drm_vma_manager.h |  2 --
 2 files changed, 9 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/drm_vma_manager.c 
b/drivers/gpu/drm/drm_vma_manager.c
index f306c8855978..0aef432679f9 100644
--- a/drivers/gpu/drm/drm_vma_manager.c
+++ b/drivers/gpu/drm/drm_vma_manager.c
@@ -86,7 +86,6 @@ void drm_vma_offset_manager_init(struct 
drm_vma_offset_manager *mgr,
 unsigned long page_offset, unsigned long size)
 {
rwlock_init(>vm_lock);
-   mgr->vm_addr_space_rb = RB_ROOT;
drm_mm_init(>vm_addr_space_mm, page_offset, size);
 }
 EXPORT_SYMBOL(drm_vma_offset_manager_init);
@@ -145,16 +144,16 @@ struct drm_vma_offset_node 
*drm_vma_offset_lookup_locked(struct drm_vma_offset_m
 unsigned long start,
 unsigned long pages)
 {
-   struct drm_vma_offset_node *node, *best;
+   struct drm_mm_node *node, *best;
struct rb_node *iter;
unsigned long offset;

-   iter = mgr->vm_addr_space_rb.rb_node;
+   iter = mgr->vm_addr_space_mm.interval_tree.rb_node;
best = NULL;

while (likely(iter)) {
-   node = rb_entry(iter, struct drm_vma_offset_node, vm_rb);
-   offset = node->vm_node.start;
+   node = rb_entry(iter, struct drm_mm_node, rb);
+   offset = node->start;
if (start >= offset) {
iter = iter->rb_right;
best = node;
@@ -167,38 +166,17 @@ struct drm_vma_offset_node 
*drm_vma_offset_lookup_locked(struct drm_vma_offset_m

/* verify that the node spans the requested area */
if (best) {
-   offset = best->vm_node.start + best->vm_node.size;
+   offset = best->start + best->size;
if (offset < start + pages)
best = NULL;
}

-   return best;
-}
-EXPORT_SYMBOL(drm_vma_offset_lookup_locked);
-
-/* internal helper to link @node into the rb-tree */
-static void _drm_vma_offset_add_rb(struct drm_vma_offset_manager *mgr,
-  struct drm_vma_offset_node *node)
-{
-   struct rb_node **iter = >vm_addr_space_rb.rb_node;
-   struct rb_node *parent = NULL;
-   struct drm_vma_offset_node *iter_node;
-
-   while (likely(*iter)) {
-   parent = *iter;
-   iter_node = rb_entry(*iter, struct drm_vma_offset_node, vm_rb);
+   if (!best)
+   return NULL;

-   if (node->vm_node.start < iter_node->vm_node.start)
-   iter = &(*iter)->rb_left;
-   else if (node->vm_node.start > iter_node->vm_node.start)
-   iter = &(*iter)->rb_right;
-   else
-   BUG();
-   }
-
-   rb_link_node(>vm_rb, parent, iter);
-   rb_insert_color(>vm_rb, >vm_addr_space_rb);
+   return container_of(best, struct drm_vma_offset_node, vm_node);
 }
+EXPORT_SYMBOL(drm_vma_offset_lookup_locked);

 /**
  * drm_vma_offset_add() - Add offset node to manager
@@ -240,8 +218,6 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr,
if (ret)
goto out_unlock;

-   _drm_vma_offset_add_rb(mgr, node);
-
 out_unlock:
write_unlock(>vm_lock);
return ret;
@@ -265,7 +241,6 @@ void drm_vma_offset_remove(struct drm_vma_offset_manager 
*mgr,
write_lock(>vm_lock);

if (drm_mm_node_allocated(>vm_node)) {
-   rb_erase(>vm_rb, >vm_addr_space_rb);
drm_mm_remove_node(>vm_node);
memset(>vm_node, 0, sizeof(node->vm_node));
}
diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h
index 06ea8e077ec2..afba6fcac853 100644
--- a/include/drm/drm_vma_manager.h
+++ b/include/drm/drm_vma_manager.h
@@ -40,13 +40,11 @@ struct drm_vma_offset_file {
 struct drm_vma_offset_node {
rwlock_t vm_lock;
struct drm_mm_node vm_node;
-   struct rb_node vm_rb;
struct rb_root vm_files;
 };

 struct drm_vma_offset_manager {
rwlock_t vm_lock;
-   struct rb_root vm_addr_space_rb;
struct drm_mm vm_addr_space_mm;
 };

-- 
2.8.1



[PATCH 1/3] drm: Track drm_mm nodes with an interval tree

2016-08-03 Thread Chris Wilson
In addition to the last-in/first-out stack for accessing drm_mm nodes,
we occasionally and in the future often want to find a drm_mm_node by an
address. To do so efficiently we need to track the nodes in an interval
tree - lookups for a particular address will then be O(lg(N)), where N
is the number of nodes in the range manager as opposed to O(N).
Insertion however gains an extra O(lg(N)) step for all nodes
irrespective of whether the interval tree is in use. For future i915
patches, eliminating the linear walk is a significant improvement.

v2: Use generic interval-tree template for u64 and faster insertion.

Signed-off-by: Chris Wilson 
Cc: David Herrmann 
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/drm_mm.c | 133 +++
 include/drm/drm_mm.h |  12 +
 2 files changed, 122 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index cb39f45d6a16..5c188c56894b 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include 

 /**
  * DOC: Overview
@@ -103,6 +104,72 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
u64 end,
enum drm_mm_search_flags flags);

+#define START(node) ((node)->start)
+#define LAST(node)  ((node)->start + (node)->size - 1)
+
+INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
+u64, __subtree_last,
+START, LAST, static inline, drm_mm_interval_tree)
+
+struct drm_mm_node *
+drm_mm_interval_first(struct drm_mm *mm, u64 start, u64 last)
+{
+   return drm_mm_interval_tree_iter_first(>interval_tree,
+  start, last);
+}
+EXPORT_SYMBOL(drm_mm_interval_first);
+
+struct drm_mm_node *
+drm_mm_interval_next(struct drm_mm_node *node, u64 start, u64 last)
+{
+   return drm_mm_interval_tree_iter_next(node, start, last);
+}
+EXPORT_SYMBOL(drm_mm_interval_next);
+
+static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
+ struct drm_mm_node *node)
+{
+   struct drm_mm *mm = hole_node->mm;
+   struct rb_node **link, *rb;
+   struct drm_mm_node *parent;
+
+   node->__subtree_last = LAST(node);
+
+   if (hole_node->allocated) {
+   rb = _node->rb;
+   while (rb) {
+   parent = rb_entry(rb, struct drm_mm_node, rb);
+   if (parent->__subtree_last >= node->__subtree_last)
+   break;
+
+   parent->__subtree_last = node->__subtree_last;
+   rb = rb_parent(rb);
+   }
+
+   rb = _node->rb;
+   link = _node->rb.rb_right;
+   } else {
+   rb = NULL;
+   link = >interval_tree.rb_node;
+   }
+
+   while (*link) {
+   rb = *link;
+   parent = rb_entry(rb, struct drm_mm_node, rb);
+   if (parent->__subtree_last < node->__subtree_last)
+   parent->__subtree_last = node->__subtree_last;
+   if (node->start < parent->start)
+   link = >rb.rb_left;
+   else
+   link = >rb.rb_right;
+   }
+
+   rb_link_node(>rb, rb, link);
+   rb_insert_augmented(>rb,
+   >interval_tree,
+   _mm_interval_tree_augment);
+}
+
 static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
 struct drm_mm_node *node,
 u64 size, unsigned alignment,
@@ -153,6 +220,8 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
INIT_LIST_HEAD(>hole_stack);
list_add(>node_list, _node->node_list);

+   drm_mm_interval_tree_add_node(hole_node, node);
+
BUG_ON(node->start + node->size > adj_end);

node->hole_follows = 0;
@@ -178,41 +247,52 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
  */
 int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
 {
+   u64 end = node->start + node->size;
struct drm_mm_node *hole;
-   u64 end;
-   u64 hole_start;
-   u64 hole_end;
-
-   BUG_ON(node == NULL);
+   u64 hole_start, hole_end;

end = node->start + node->size;

/* Find the relevant hole to add our node to */
-   drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
-   if (hole_start > node->start || hole_end < end)
-   continue;
+   hole = drm_mm_interval_tree_iter_first(>interval_tree,
+  node->start, ~(u64)0);
+   if (hole) {
+   if (hole->start < end)
+   return -ENOSPC;
+   } else {
+   hole 

[PATCH 0/4]: Picture aspect ratio support in DRM layer

2016-08-03 Thread Sharma, Shashank
Hello Joes,
> I've also seen this before and I am using them in order to pass HDMI 
> compliance. Without
> these patches the compliance fails. Still, I've made some changes which I can 
> submit. I've
> some comments to you (Shashank):
Thanks for addressing these patches. You are welcome to review the series.
Will it be possible for you, to comment in-line with the patch code, it's 
easier that way, and kind of conventional too. 

> Second, you are expecting that the picture aspect field is correctly set in 
> the HDMI parsing but, at least in the test equipment that I am using, this 
> field is not set by the DRM layer because the mode is coming in the detailed 
> timings section which does not
> include a picture aspect field. In my implementation I add a function which 
> given the mode width and height (fields
> ->width_mm and ->height_mm of mode) computes the aspect ratio and populates 
> the field.
Please note that we can run the aspect ratio test cases (7-27 and similar) for 
CEA modes only. For the modes coming from DTDs and VSDBs can be with or without 
aspect ratio.
But the suggestion to initialize all the drm_modes with 
ASPECT_RATIO_NONE/DEFAULT is a good one, and it might help for these modes too. 
I think Daniel also had similar suggestion last time, in a different context.

> Third, I am facing some difficulties when using Xserver and Xrandr. Using 
> libdrm's modetest application everything works ok but with xrandr the aspect 
> ratio gets lost between the link DRM
> -> Xserver -> DRM. I set the aspect ratio in the flags field when
> passing the mode to user level (just like you do in patch 2) but then when 
> the mode is returned and delivered to the DRM driver the picture aspect is 
> not present. I think this is due to how Xserver or xrandr sets the mode but I 
> am not sure.
I think while parsing the aspect ratio from libdrm to userspace (X), it's 
getting lost, and we have to fix your Xserver implementation.
We had added similar support in our HWComposer, and I guess it would be 
required for X and Wayland too, coz finally these guys issue the modeset.
So May be X server is not handling these flags, ignoring these flags, and 
sending the flagless modeset back to libdrm.

Regards
Shashank
-Original Message-
From: Jose Abreu [mailto:jose.ab...@synopsys.com] 
Sent: Wednesday, August 3, 2016 6:38 PM
To: Daniel Vetter ; Sharma, Shashank 
Cc: intel-gfx at lists.freedesktop.org; dri-devel at lists.freedesktop.org; 
Vetter, Daniel ; Carlos Palminha 
Subject: Re: [PATCH 0/4]: Picture aspect ratio support in DRM layer

Hi,


On 03-08-2016 12:48, Daniel Vetter wrote:
> On Wed, Aug 03, 2016 at 04:26:24PM +0530, Shashank Sharma wrote:
>> This patch series adds 4 patches.
>> - The first two patches add aspect ratio support in DRM layes
>> - Next two patches add new aspect ratios defined in CEA-861-F
>>   supported for HDMI 2.0 4k modes.
>>
>> Adding aspect ratio support in DRM layer:
>> - The CEA videmodes contain aspect ratio information, which we
>>   parse when we read the modes from EDID. But while transforming
>>   user_mode to kernel_mode or viceversa, DRM layer lose this
>>   information.
>> - HDMI compliance testing for CEA modes, expects the AVI info frames
>>   to contain exact VIC no for the 'video mode under test'. Now CEA
>>   modes have different VIC for same modes but different aspect ratio
>>   for example:
>>  VIC 2 = 720x480 at 60 4:3 
>>  VIC 3 = 720x480 at 60 16:9
>>   In this way, lack of aspect ratio information, can cause wrong VIC
>>   no in AVI IF, causing HDMI complaince test to fail.
>> - This patch set adds code, which embeds the aspect ratio information
>>   also in DRM video mode flags, and uses it while comparing two modes. 
>>
>> Adding new aspect ratios for HDMI 2.0
>> - CEA-861-F defines two new aspect ratios, to be used for 4k HDMI 2.0
>>   modes.
>>  - 64:27
>>  - 256:135
>> Last two patches in the series, adds code to handle these new aspect 
>> ratios.
>>
>> Shashank Sharma (4):
>>   drm: add picture aspect ratio flags
>>   drm: Add aspect ratio parsing in DRM layer
>>   video: Add new aspect ratios for HDMI 2.0
>>   drm: Add and handle new aspect ratios in DRM layer
> Patch series seems to have 0 changelogs anywhere, but I'm pretty sure 
> I've seen this before. Please try again and state what changed and why 
> you are resubmitting this.
> -Daniel

I've also seen this before and I am using them in order to pass HDMI 
compliance. Without these patches the compliance fails.
Still, I've made some changes which I can submit. I've some comments to you 
(Shashank):

First, you add an if condition in
drm_mode_equal_no_clocks_no_stereo() (patch 2) which unconditionally compares 
the aspect ratio. But I think that you have to take into account that some 
modes handed by the user to the DRM layer do not initialize this field so I 
think the best solution would be to compare the aspect ratios only when the 
field is populated (i.e. 

[PATCH v4 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-08-03 Thread hl

Hi Chanwoo Choi,
On 2016年08月02日 12:21, Chanwoo Choi wrote:
> Hi Lin,
>
> On the next version, I'd like you to add the 'linux-pm at vger.kernel.org'
> because devfreq is a subsystem of power management.
Sure, will do it next version.
> On 2016년 08월 02일 10:03, hl wrote:
>> Hi Chanwoo Choi,
>>
>>  Thanks for reviewing so carefully. And i have some question:
>>
>> On 2016年08月01日 18:28, Chanwoo Choi wrote:
>>> Hi Lin,
>>>
>>> As I mentioned on patch5, you better to make the documentation as following:
>>> - Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
>>> And, I add the comments.
>>>
>>>
>>> On 2016년 07월 29일 16:57, Lin Huang wrote:
 base on dfi result, we do ddr frequency scaling, register
 dmc driver to devfreq framework, and use simple-ondemand
 policy.

 Signed-off-by: Lin Huang 
 ---
 Changes in v4:
 - use arm_smccc_smc() function talk to bl31
 - delete rockchip_dmc.c file and config
 - delete dmc_notify
 - adjust probe order
Changes in v3:
 - operate dram setting through sip call
 - imporve set rate flow

 Changes in v2:
 - None
Changes in v1:
 - move dfi controller to event
 - fix set voltage sequence when set rate fail
 - change Kconfig type from tristate to bool
 - move unuse EXPORT_SYMBOL_GPL()

drivers/devfreq/Kconfig   |   1 +
drivers/devfreq/Makefile  |   1 +
drivers/devfreq/rockchip/Kconfig  |   8 +
drivers/devfreq/rockchip/Makefile |   1 +
drivers/devfreq/rockchip/rk3399_dmc.c | 473 
 ++
5 files changed, 484 insertions(+)
create mode 100644 drivers/devfreq/rockchip/Kconfig
create mode 100644 drivers/devfreq/rockchip/Makefile
create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c

> [snip]
>
 +
 +static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 + u32 flags)
 +{
 +struct platform_device *pdev = container_of(dev, struct 
 platform_device,
 +dev);
 +struct rk3399_dmcfreq *dmcfreq = platform_get_drvdata(pdev);
>>> You can use the 'dev_get_drvdata()' to simplify it instead of 
>>> 'platform_get_drvdata()'.
>>>
>>>  struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);
>>>
 +struct dev_pm_opp *opp;
 +unsigned long old_clk_rate = dmcfreq->rate;
 +unsigned long target_volt, target_rate;
 +int err;
 +
 +rcu_read_lock();
 +opp = devfreq_recommended_opp(dev, freq, flags);
 +if (IS_ERR(opp)) {
 +rcu_read_unlock();
 +return PTR_ERR(opp);
 +}
 +
 +target_rate = dev_pm_opp_get_freq(opp);
 +target_volt = dev_pm_opp_get_voltage(opp);
 +opp = devfreq_recommended_opp(dev, >rate, flags);
 +if (IS_ERR(opp)) {
 +rcu_read_unlock();
 +return PTR_ERR(opp);
 +}
 +dmcfreq->volt = dev_pm_opp_get_voltage(opp);
>>> If you add the 'curr_opp' variable to struct rk3399_dmcfreq,
>>> you can remove the calling of devfreq_recommended_opp().
>>>  dmcfreq->rate = dev_pm_opp_get_freq(dmcfreq->curr_opp);
>>>  dmcfreq->volt = dev_pm_opp_get_freq(dmcfreq->curr_opp);
>>>
>>> Because the current rate and voltage is already decided on previous polling 
>>> cycle,
>>> So we don't need to get the opp with devfreq_recommended_opp().
>> I prefer the way now use, since we get the dmcfreq->rate use clk_get_rate() 
>> after,
>> Base on that,  i do not care the set_rate success or fail. use curr_opp i 
>> need to
>> care about set_rate status, when fail, i must set some rate, when success i 
>> must
>> set other rate.
> I think that it is not good to get the alrady decided opp
> by devfreq_recommended_opp(). Usually, devfreq_recommended_opp() is used
> to get the proper opp which get the close frequency (dmcfreq->rate).
>
> Also, When finishing the rk3399_dmcfreq_target(), the rk3399_dmc.c
> have to know the current opp or rate without any finding sequence.
> The additional finding procedure is un-needed.
>
 +rcu_read_unlock();
 +
 +if (dmcfreq->rate == target_rate)
 +return 0;
 +
 +mutex_lock(>lock);
 +
 +/*
 + * if frequency scaling from low to high, adjust voltage first;
 + * if frequency scaling from high to low, adjuset frequency first;
 + */
>>> s/adjuset/adjust
>>>
>>> I recommend that you use a captital letter for first character and use the 
>>> '.'
>>> instead of ';'.
>>>
 +if (old_clk_rate < target_rate) {
 +err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
 +target_volt);
 +if (err) {
 +dev_err(dev, "Unable to set vol %lu\n", target_volt);
>>> To readability, you better to use the corrent word to pass the 

[PATCH 0/4]: Picture aspect ratio support in DRM layer

2016-08-03 Thread Sharma, Shashank
> Patch series seems to have 0 changelogs anywhere, but I'm pretty sure I've 
> seen this before. > > Please try again and state what changed and why you are 
> resubmitting this.
> -Daniel

Hi Daniel, 
This is a re-spin of the patch series for aspect ratio support. 
The first four patches dint get reviewed for a long time, so I sent it again. 
https://patchwork.freedesktop.org/patch/78308/ 

You gave review comments on the fifth patch, which was In I915, so I kept that 
patch away from this series, and made this as DRM layer only.  So this series 
contains only 4 patches.
https://patchwork.freedesktop.org/patch/78178/ 

We can decide for I915, if we want to keep the aspect ratio property or not, 
internally. 
You are more than welcome to review this series :).

Regards
Shashank
-Original Message-
From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Wednesday, August 3, 2016 5:18 PM
To: Sharma, Shashank 
Cc: dri-devel at lists.freedesktop.org; intel-gfx at lists.freedesktop.org; 
ville.syrjala at linux.intel.com; rodrigo.vivi at gmail.com; Vetter, Daniel 

Subject: Re: [PATCH 0/4]: Picture aspect ratio support in DRM layer

On Wed, Aug 03, 2016 at 04:26:24PM +0530, Shashank Sharma wrote:
> This patch series adds 4 patches.
> - The first two patches add aspect ratio support in DRM layes
> - Next two patches add new aspect ratios defined in CEA-861-F
>   supported for HDMI 2.0 4k modes.
> 
> Adding aspect ratio support in DRM layer:
> - The CEA videmodes contain aspect ratio information, which we
>   parse when we read the modes from EDID. But while transforming
>   user_mode to kernel_mode or viceversa, DRM layer lose this
>   information.
> - HDMI compliance testing for CEA modes, expects the AVI info frames
>   to contain exact VIC no for the 'video mode under test'. Now CEA
>   modes have different VIC for same modes but different aspect ratio
>   for example:
>   VIC 2 = 720x480 at 60 4:3 
>   VIC 3 = 720x480 at 60 16:9
>   In this way, lack of aspect ratio information, can cause wrong VIC
>   no in AVI IF, causing HDMI complaince test to fail.
> - This patch set adds code, which embeds the aspect ratio information
>   also in DRM video mode flags, and uses it while comparing two modes. 
> 
> Adding new aspect ratios for HDMI 2.0
> - CEA-861-F defines two new aspect ratios, to be used for 4k HDMI 2.0
>   modes.
>   - 64:27
>   - 256:135
> Last two patches in the series, adds code to handle these new aspect 
> ratios.
> 
> Shashank Sharma (4):
>   drm: add picture aspect ratio flags
>   drm: Add aspect ratio parsing in DRM layer
>   video: Add new aspect ratios for HDMI 2.0
>   drm: Add and handle new aspect ratios in DRM layer

Patch series seems to have 0 changelogs anywhere, but I'm pretty sure I've seen 
this before. Please try again and state what changed and why you are 
resubmitting this.
-Daniel

> 
>  drivers/gpu/drm/drm_modes.c | 43 +++
>  drivers/video/hdmi.c|  4 
>  include/linux/hdmi.h|  2 ++
>  include/uapi/drm/drm_mode.h | 24 +++-
>  4 files changed, 68 insertions(+), 5 deletions(-)
> 
> --
> 1.9.1
> 
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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


[PATCH v6 6/6] drm/i915/skl: Update DDB values atomically with wms/plane attrs

2016-08-03 Thread Matt Roper
On Wed, Aug 03, 2016 at 06:00:42PM +0300, Ville Syrjälä wrote:
> On Tue, Aug 02, 2016 at 06:37:37PM -0400, Lyude wrote:
> > Now that we can hook into update_crtcs and control the order in which we
> > update CRTCs at each modeset, we can finish the final step of fixing
> > Skylake's watermark handling by performing DDB updates at the same time
> > as plane updates and watermark updates.
> > 
> > The first major change in this patch is skl_update_crtcs(), which
> > handles ensuring that we order each CRTC update in our atomic commits
> > properly so that they honor the DDB flush order.
> > 
> > The second major change in this patch is the order in which we flush the
> > pipes. While the previous order may have worked, it can't be used in
> > this approach since it no longer will do the right thing. For example,
> > using the old ddb flush order:
> > 
> > We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
> > allocation looks like this:
> > 
> > |   A   |   B   |xxx|
> > 
> > Since we're performing the ddb updates after performing any CRTC
> > disablements in intel_atomic_commit_tail(), the space to the right of
> > pipe B is unallocated.
> > 
> > 1. Flush pipes with new allocation contained into old space. None
> >apply, so we skip this
> > 2. Flush pipes having their allocation reduced, but overlapping with a
> >previous allocation. None apply, so we also skip this
> > 3. Flush pipes that got more space allocated. This applies to A and B,
> >giving us the following update order: A, B
> > 
> > This is wrong, since updating pipe A first will cause it to overlap with
> > B and potentially burst into flames. Our new order (see the code
> > comments for details) would update the pipes in the proper order: B, A.
> > 
> > As well, we calculate the order for each DDB update during the check
> > phase, and reference it later in the commit phase when we hit
> > skl_update_crtcs().
> > 
> > This long overdue patch fixes the rest of the underruns on Skylake.
> > 
> > Changes since v1:
> >  - Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
> > 
> > Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
> > Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
> > Signed-off-by: Lyude 
> > [omitting CC for stable, since this patch will need to be changed for
> > such backports first]
> > Cc: Ville Syrjälä 
> > Cc: Daniel Vetter 
> > Cc: Radhakrishna Sripada 
> > Cc: Hans de Goede 
> > Cc: Matt Roper 
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 100 ++--
> >  drivers/gpu/drm/i915/intel_drv.h |  10 ++
> >  drivers/gpu/drm/i915/intel_pm.c  | 288 
> > ---
> >  3 files changed, 233 insertions(+), 165 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 59cf513..06295f7 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -12897,16 +12897,23 @@ static void verify_wm_state(struct drm_crtc *crtc,
> >   hw_entry->start, hw_entry->end);
> > }
> >  
> > -   /* cursor */
> > -   hw_entry = _ddb.plane[pipe][PLANE_CURSOR];
> > -   sw_entry = _ddb->plane[pipe][PLANE_CURSOR];
> > -
> > -   if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
> > -   DRM_ERROR("mismatch in DDB state pipe %c cursor "
> > - "(expected (%u,%u), found (%u,%u))\n",
> > - pipe_name(pipe),
> > - sw_entry->start, sw_entry->end,
> > - hw_entry->start, hw_entry->end);
> > +   /*
> > +* cursor
> > +* If the cursor plane isn't active, we may not have updated it's ddb
> > +* allocation. In that case since the ddb allocation will be updated
> > +* once the plane becomes visible, we can skip this check
> > +*/
> > +   if (intel_crtc->cursor_addr) {
> > +   hw_entry = _ddb.plane[pipe][PLANE_CURSOR];
> > +   sw_entry = _ddb->plane[pipe][PLANE_CURSOR];
> > +
> > +   if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
> > +   DRM_ERROR("mismatch in DDB state pipe %c cursor "
> > + "(expected (%u,%u), found (%u,%u))\n",
> > + pipe_name(pipe),
> > + sw_entry->start, sw_entry->end,
> > + hw_entry->start, hw_entry->end);
> > +   }
> > }
> >  }
> >  
> > @@ -13658,6 +13665,72 @@ static void intel_update_crtcs(struct 
> > drm_atomic_state *state,
> > }
> >  }
> >  
> > +static inline void
> > +skl_do_ddb_step(struct drm_atomic_state *state,
> > +   enum skl_ddb_step step)
> > +{
> > +   struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> > +   struct drm_crtc *crtc;
> > +   struct drm_crtc_state *old_crtc_state;
> > +   unsigned int crtc_vblank_mask; /* unused */
> > +   int i;
> > +
> > +   

[PATCH 6/6] drm/i915: Sanitize drm crtc vblank counter after DC reset frame count.

2016-08-03 Thread Rodrigo Vivi
DC state reset the frame counter that is a read-only register.

So, besides blocking DC state on vblank let's restore the
drm crtc vblank counter to a place we know it is reliable.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/i915_irq.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4efe20c..82d6896 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2759,7 +2759,9 @@ static int gen8_enable_vblank(struct drm_device *dev, 
unsigned int pipe)
 static void gen9_prepare_vblank(struct drm_device *dev, unsigned int pipe)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
+   struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
intel_display_power_get(dev_priv, POWER_DOMAIN_VBLANK);
+   drm_crtc_vblank_sanitize_counter(crtc);
 }

 static void gen9_unprepare_vblank(struct drm_device *dev, unsigned int pipe)
-- 
2.4.3



[PATCH 5/6] drm: Introduce drm_crtc_vblank_sanitize_counter.

2016-08-03 Thread Rodrigo Vivi
In modern systems there are situations that you can let the screen
enabled and sleep or shut off a most of the display controler.

In situations like this the vblank hw counter can be reset.
When this happens everything in the system gets crazy by
the big count.

So, the right approach is to make sure we are avoiding any
runtime suspend when vblank is enabled but also restore
drm crtc vblank counter to a state we can rely.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/drm_irq.c | 46 ++
 include/drm/drm_irq.h |  1 +
 2 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index d0d1dde..7320836 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -265,6 +265,52 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_accurate_vblank_count);

+/**
+ * drm_crtc_vblank_sanitize_counter - Sanitize vblank counter
+ * @crtc: which counter to sanitize
+ *
+ * This function returns drm crtc vblank counter to the latest
+ * known counter.
+ *
+ * This function is useful for runtime suspend where the hw
+ * counter or timer might reset.
+ *
+ * Use this only when there is no risk of the runtime suspend
+ * reseting hardware counter and before enabling vblank irq.
+ */
+void drm_crtc_vblank_sanitize_counter(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   unsigned int pipe = drm_crtc_index(crtc);
+   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   unsigned long irqflags;
+   struct timeval t_vblank;
+   int count = DRM_TIMESTAMP_MAXRETRIES;
+   u32 cur_vblank;
+   bool rc;
+
+   spin_lock_irqsave(>vblank_time_lock, irqflags);
+
+   if (vblank->enabled) {
+   DRM_DEBUG_VBL("Skip sanitize - Vblank is enabled on pipe %d\n",
+ pipe);
+   goto unlock;
+   }
+
+   do {
+   cur_vblank = dev->driver->get_vblank_counter(dev, pipe);
+   rc = drm_get_last_vbltimestamp(dev, pipe, _vblank, 0);
+   } while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe) && 
--count > 0);
+
+   if (!rc)
+   t_vblank = (struct timeval) {0, 0};
+
+   store_vblank(dev, pipe, 0, _vblank, cur_vblank);
+unlock:
+   spin_unlock_irqrestore(>vblank_time_lock, irqflags);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_sanitize_counter);
+
 /*
  * Disable vblank irq's on crtc, make sure that last vblank count
  * of hardware and corresponding consistent software vblank counter
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h
index 93a9e9d..55c419a 100644
--- a/include/drm/drm_irq.h
+++ b/include/drm/drm_irq.h
@@ -160,6 +160,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, 
unsigned int pipe);
 extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc);
 extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
  struct timeval *vblanktime);
+extern void drm_crtc_vblank_sanitize_counter(struct drm_crtc *crtc);
 extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
   struct drm_pending_vblank_event *e);
 extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
-- 
2.4.3



[PATCH 4/6] drm/i915: Introduce vblank power domain to avoid DC entry when waiting for vblank.

2016-08-03 Thread Rodrigo Vivi
Vblank counters are not restored by DMC when exiting deep DC states
because frame counter register is read-only. So it is better to avoid
Deep DC states when waiting for Vblanks. At least we don't mess with
the counters when already waiting for vblank.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/i915_drv.h |  1 +
 drivers/gpu/drm/i915/i915_irq.c | 14 ++
 drivers/gpu/drm/i915/intel_runtime_pm.c |  3 +++
 3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fe152df..7aa87c4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -229,6 +229,7 @@ enum intel_display_power_domain {
POWER_DOMAIN_PORT_OTHER,
POWER_DOMAIN_VGA,
POWER_DOMAIN_AUDIO,
+   POWER_DOMAIN_VBLANK,
POWER_DOMAIN_PLLS,
POWER_DOMAIN_AUX_A,
POWER_DOMAIN_AUX_B,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 76d48da..4efe20c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2756,6 +2756,18 @@ static int gen8_enable_vblank(struct drm_device *dev, 
unsigned int pipe)
return 0;
 }

+static void gen9_prepare_vblank(struct drm_device *dev, unsigned int pipe)
+{
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   intel_display_power_get(dev_priv, POWER_DOMAIN_VBLANK);
+}
+
+static void gen9_unprepare_vblank(struct drm_device *dev, unsigned int pipe)
+{
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   intel_display_power_put(dev_priv, POWER_DOMAIN_VBLANK);
+}
+
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
@@ -4589,6 +4601,8 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev->driver->irq_uninstall = gen8_irq_uninstall;
dev->driver->enable_vblank = gen8_enable_vblank;
dev->driver->disable_vblank = gen8_disable_vblank;
+   dev->driver->prepare_vblank = gen9_prepare_vblank;
+   dev->driver->unprepare_vblank = gen9_unprepare_vblank;
if (IS_BROXTON(dev))
dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
else if (HAS_PCH_SPT(dev) || HAS_PCH_KBP(dev))
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 6e6e079..167fead 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -116,6 +116,8 @@ intel_display_power_domain_str(enum 
intel_display_power_domain domain)
return "VGA";
case POWER_DOMAIN_AUDIO:
return "AUDIO";
+   case POWER_DOMAIN_VBLANK:
+   return "VBLANK";
case POWER_DOMAIN_PLLS:
return "PLLS";
case POWER_DOMAIN_AUX_A:
@@ -419,6 +421,7 @@ static void hsw_set_power_well(struct drm_i915_private 
*dev_priv,
SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
BIT(POWER_DOMAIN_MODESET) | \
BIT(POWER_DOMAIN_AUX_A) |   \
+   BIT(POWER_DOMAIN_VBLANK) |  \
BIT(POWER_DOMAIN_INIT))
 #define SKL_DISPLAY_PSR_BLOCK_POWER_DOMAINS (  \
BIT(POWER_DOMAIN_MODESET) | \
-- 
2.4.3



[PATCH 3/6] drm/i915: Split gen 9 irq hooks definitions.

2016-08-03 Thread Rodrigo Vivi
No functional change. This is just a reorg that aims to allow
a cleaner introduction of new vblank hooks for gen9+.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/i915_irq.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index f5bf4f9..76d48da 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4582,7 +4582,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev->driver->enable_vblank = valleyview_enable_vblank;
dev->driver->disable_vblank = valleyview_disable_vblank;
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
-   } else if (INTEL_INFO(dev_priv)->gen >= 8) {
+   } else if (INTEL_INFO(dev_priv)->gen >= 9) {
dev->driver->irq_handler = gen8_irq_handler;
dev->driver->irq_preinstall = gen8_irq_reset;
dev->driver->irq_postinstall = gen8_irq_postinstall;
@@ -4593,8 +4593,14 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
else if (HAS_PCH_SPT(dev) || HAS_PCH_KBP(dev))
dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup;
-   else
-   dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
+   } else if (INTEL_INFO(dev_priv)->gen >= 8) {
+   dev->driver->irq_handler = gen8_irq_handler;
+   dev->driver->irq_preinstall = gen8_irq_reset;
+   dev->driver->irq_postinstall = gen8_irq_postinstall;
+   dev->driver->irq_uninstall = gen8_irq_uninstall;
+   dev->driver->enable_vblank = gen8_enable_vblank;
+   dev->driver->disable_vblank = gen8_disable_vblank;
+   dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
} else if (HAS_PCH_SPLIT(dev)) {
dev->driver->irq_handler = ironlake_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_reset;
-- 
2.4.3



[PATCH 2/6] drm/i915: Move drm_crtc_vblank_get out of disabled pre-emption area.

2016-08-03 Thread Rodrigo Vivi
drm_crtc_vblank_get call the drm_vblank_prepare that will be used soon
to control power saving states or anything else that needs a mutex
before the vblank happens.

local_irq_disable disables kernel preemption so we won't be able
to use mutex inside drm_crtc_vblank_get. For this reason we need
to move the drm_crtc_vblank_get a little up before disabling the
interruptions.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/intel_sprite.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 0de935a..d8bc27c 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -94,14 +94,14 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
min = vblank_start - usecs_to_scanlines(adjusted_mode, 100);
max = vblank_start - 1;

-   local_irq_disable();
-
if (min <= 0 || max <= 0)
return;

if (WARN_ON(drm_crtc_vblank_get(>base)))
return;

+   local_irq_disable();
+
crtc->debug.min_vbl = min;
crtc->debug.max_vbl = max;
trace_i915_pipe_update_start(crtc);
@@ -166,6 +166,8 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct 
intel_flip_work *work

trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);

+   local_irq_enable();
+
/* We're still in the vblank-evade critical section, this can't race.
 * Would be slightly nice to just grab the vblank count and arm the
 * event outside of the critical section - the spinlock might spin for a
@@ -180,8 +182,6 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct 
intel_flip_work *work
crtc->base.state->event = NULL;
}

-   local_irq_enable();
-
if (crtc->debug.start_vbl_count &&
crtc->debug.start_vbl_count != end_vbl_count) {
DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) 
time %lld us, min %d, max %d, scanline start %d, end %d\n",
-- 
2.4.3



[PATCH 1/6] drm: Add vblank prepare and unprepare hooks.

2016-08-03 Thread Rodrigo Vivi
This will allow drivers to control specific power saving
feature and power domains when dealing with vblanks.

Vblanks code are protected by spin_locks where we can't
have anything that can sleep. While power saving features
and power domain code have mutexes to control the states.

Mutex can sleep so they cannot be used inside spin lock areas.
So the easiest way to deal with them currently is to add these
prepare hook for pre enabling vblanks
and unprepare one for post disabling them.

Let's introduce this optional prepare and unprepare
hooks so drivers can deal with cases like this and any other
case that should require sleeping codes interacting with vblanks.

v2: - Rebase after a split on drm_irq.h.
- Use refcount to minimize the prepare/unprepare calls to
  only when enabling or disabling the vblank irq. (DK's)
- Improved doc.
- Fix the negative unprepare.count case.

Cc: Dhinakaran Pandiyan 
Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/drm_irq.c | 37 -
 include/drm/drmP.h| 43 +++
 include/drm/drm_irq.h | 20 
 3 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 77f357b..d0d1dde 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -339,6 +339,8 @@ void drm_vblank_cleanup(struct drm_device *dev)
drm_core_check_feature(dev, DRIVER_MODESET));

del_timer_sync(>disable_timer);
+
+   flush_work(>unprepare.work);
}

kfree(dev->vblank);
@@ -347,6 +349,24 @@ void drm_vblank_cleanup(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_vblank_cleanup);

+static void drm_vblank_unprepare_work_fn(struct work_struct *work)
+{
+   struct drm_vblank_crtc *vblank;
+   struct drm_device *dev;
+
+   vblank = container_of(work, typeof(*vblank), unprepare.work);
+   dev = vblank->dev;
+
+   if (atomic_read(>unprepare.counter) == 0)
+   return;
+
+   do {
+   if (dev->driver->unprepare_vblank &&
+   atomic_read(>refcount) == 0)
+   dev->driver->unprepare_vblank(dev, vblank->pipe);
+   } while (!atomic_dec_and_test(>unprepare.counter));
+}
+
 /**
  * drm_vblank_init - initialize vblank support
  * @dev: DRM device
@@ -380,6 +400,9 @@ int drm_vblank_init(struct drm_device *dev, unsigned int 
num_crtcs)
setup_timer(>disable_timer, vblank_disable_fn,
(unsigned long)vblank);
seqlock_init(>seqlock);
+
+   INIT_WORK(>unprepare.work,
+ drm_vblank_unprepare_work_fn);
}

DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
@@ -1117,6 +1140,10 @@ static int drm_vblank_get(struct drm_device *dev, 
unsigned int pipe)
if (WARN_ON(pipe >= dev->num_crtcs))
return -EINVAL;

+   if (dev->driver->prepare_vblank &&
+   atomic_read(>refcount) == 0)
+   dev->driver->prepare_vblank(dev, pipe);
+
spin_lock_irqsave(>vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, >refcount) == 1) {
@@ -1129,6 +1156,10 @@ static int drm_vblank_get(struct drm_device *dev, 
unsigned int pipe)
}
spin_unlock_irqrestore(>vbl_lock, irqflags);

+   if (dev->driver->unprepare_vblank &&
+   atomic_read(>refcount) == 0)
+   dev->driver->unprepare_vblank(dev, pipe);
+
return ret;
 }

@@ -1178,6 +1209,11 @@ static void drm_vblank_put(struct drm_device *dev, 
unsigned int pipe)
mod_timer(>disable_timer,
  jiffies + ((drm_vblank_offdelay * HZ)/1000));
}
+
+   if (atomic_read(>refcount) == 0) {
+   atomic_inc(>unprepare.counter);
+   schedule_work(>unprepare.work);
+   }
 }

 /**
@@ -1603,7 +1639,6 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
unsigned int pipe,
}

spin_unlock_irqrestore(>event_lock, flags);
-
return 0;

 err_unlock:
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index d377865..c6ca061 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -422,6 +422,49 @@ struct drm_driver {
u32 (*get_vblank_counter) (struct drm_device *dev, unsigned int pipe);

/**
+* prepare_vblank - Optional prepare vblank hook.
+* @dev: DRM device
+* @pipe: counter to fetch
+*
+* Drivers that need to handle any kind of mutex or any other sleeping
+* code in combination with vblanks need to implement this hook
+* that will be called before drm_vblank_get spin_lock gets.
+*
+* Prepare/Unprepare was designed to be able to sleep so they are not
+* free from concurrence. There might be few 

[PATCH 0/6] Allow DC state to reset the counter on screen enabled.

2016-08-03 Thread Rodrigo Vivi
For now DC is only helping on screen off scenarios since PSR is disabled.

But if we want to enable PSR first we need to make DC reliable with screen on.
Biggest challenge is to deal with vblank counters since frame counter register
is read only and can be reset in DC state.

This series is one of possible approaches, but brings the down side of not
being possible to use runtime pm with vblank enabled. Some test cases needs
to be adapted to represent this new vision.

But also this series is not fully tested. Apparently I have an issue yet
with flip-vs-expired-vblank_* tests and pm_rpm basic tests.

So, while I investigate and finish the test execution I'd like to get some
feedback on this approach. This is why I'm sending this series right now.

Please let me know if this is acceptable or if you have any better aproach
ideas or any idea about the test failures above.

Thanks a lot,
Rodrigo.

Rodrigo Vivi (6):
  drm: Add vblank prepare and unprepare hooks.
  drm/i915: Move drm_crtc_vblank_get out of disabled pre-emption area.
  drm/i915: Split gen 9 irq hooks definitions.
  drm/i915: Introduce vblank power domain to avoid DC entry when waiting
for vblank.
  drm: Introduce drm_crtc_vblank_sanitize_counter.
  drm/i915: Sanitize drm crtc vblank counter after DC reset frame count.

 drivers/gpu/drm/drm_irq.c   | 83 -
 drivers/gpu/drm/i915/i915_drv.h |  1 +
 drivers/gpu/drm/i915/i915_irq.c | 28 +--
 drivers/gpu/drm/i915/intel_runtime_pm.c |  3 ++
 drivers/gpu/drm/i915/intel_sprite.c |  8 ++--
 include/drm/drmP.h  | 43 +
 include/drm/drm_irq.h   | 21 +
 7 files changed, 179 insertions(+), 8 deletions(-)

-- 
2.4.3



[PATCH 2/2] drm: Remove legacy drm_wait_one_vblank(dev, pipe).

2016-08-03 Thread Rodrigo Vivi
Now that this is not used anywhere else anymore we can go ahead
and remove the legacy version.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/drm_irq.c | 35 +++
 include/drm/drm_irq.h |  1 -
 2 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 523419a..6250518 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1194,16 +1194,17 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
 EXPORT_SYMBOL(drm_crtc_vblank_put);

 /**
- * drm_wait_one_vblank - wait for one vblank
- * @dev: DRM device
- * @pipe: CRTC index
+ * drm_crtc_wait_one_vblank - wait for one vblank
+ * @crtc: DRM crtc
  *
- * This waits for one vblank to pass on @pipe, using the irq driver interfaces.
- * It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
+ * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
+ * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
  * due to lack of driver support or because the crtc is off.
  */
-void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
+void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
 {
+   struct drm_device *dev = crtc->dev;
+   unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = >vblank[pipe];
int ret;
u32 last;
@@ -1211,33 +1212,19 @@ void drm_wait_one_vblank(struct drm_device *dev, 
unsigned int pipe)
if (WARN_ON(pipe >= dev->num_crtcs))
return;

-   ret = drm_vblank_get(dev, pipe);
+   ret = drm_crtc_vblank_get(crtc);
if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", pipe, ret))
return;

-   last = drm_vblank_count(dev, pipe);
+   last = drm_crtc_vblank_count(crtc);

ret = wait_event_timeout(vblank->queue,
-last != drm_vblank_count(dev, pipe),
+last != drm_crtc_vblank_count(crtc),
 msecs_to_jiffies(100));

WARN(ret == 0, "vblank wait timed out on crtc %i\n", pipe);

-   drm_vblank_put(dev, pipe);
-}
-EXPORT_SYMBOL(drm_wait_one_vblank);
-
-/**
- * drm_crtc_wait_one_vblank - wait for one vblank
- * @crtc: DRM crtc
- *
- * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
- * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
- * due to lack of driver support or because the crtc is off.
- */
-void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
-{
-   drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
+   drm_crtc_vblank_put(crtc);
 }
 EXPORT_SYMBOL(drm_crtc_wait_one_vblank);

diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h
index 406f954..b90d5ee 100644
--- a/include/drm/drm_irq.h
+++ b/include/drm/drm_irq.h
@@ -148,7 +148,6 @@ extern bool drm_handle_vblank(struct drm_device *dev, 
unsigned int pipe);
 extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
 extern int drm_crtc_vblank_get(struct drm_crtc *crtc);
 extern void drm_crtc_vblank_put(struct drm_crtc *crtc);
-extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
 extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
 extern void drm_crtc_vblank_off(struct drm_crtc *crtc);
 extern void drm_crtc_vblank_reset(struct drm_crtc *crtc);
-- 
2.5.5



[PATCH 1/2] drm/i915: Use drm_crtc_vblank_wait_one_vblank instead the legacy one.

2016-08-03 Thread Rodrigo Vivi
No functional change.

This is the last user of legacy function so we will be able
to clean up drm_irq.c a bit.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/intel_drv.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 50cdc89..37a3ae8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1202,7 +1202,10 @@ intel_crtc_has_dp_encoder(const struct intel_crtc_state 
*crtc_state)
 static inline void
 intel_wait_for_vblank(struct drm_device *dev, int pipe)
 {
-   drm_wait_one_vblank(dev, pipe);
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+
+   drm_crtc_wait_one_vblank(crtc);
 }
 static inline void
 intel_wait_for_vblank_if_active(struct drm_device *dev, int pipe)
-- 
2.5.5



[PATCH 2/2] drm: Remove legacy drm_vblank_{on,off}

2016-08-03 Thread Rodrigo Vivi
No functional change. Only removing unused legacy functions.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/drm_irq.c | 62 +--
 include/drm/drm_irq.h |  2 --
 2 files changed, 12 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 01a5079..523419a 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1242,21 +1242,20 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
 EXPORT_SYMBOL(drm_crtc_wait_one_vblank);

 /**
- * drm_vblank_off - disable vblank events on a CRTC
- * @dev: DRM device
- * @pipe: CRTC index
+ * drm_crtc_vblank_off - disable vblank events on a CRTC
+ * @crtc: CRTC in question
  *
  * Drivers can use this function to shut down the vblank interrupt handling 
when
  * disabling a crtc. This function ensures that the latest vblank frame count 
is
- * stored so that drm_vblank_on() can restore it again.
+ * stored so that drm_vblank_on can restore it again.
  *
  * Drivers must use this function when the hardware vblank counter can get
  * reset, e.g. when suspending.
- *
- * This is the legacy version of drm_crtc_vblank_off().
  */
-void drm_vblank_off(struct drm_device *dev, unsigned int pipe)
+void drm_crtc_vblank_off(struct drm_crtc *crtc)
 {
+   struct drm_device *dev = crtc->dev;
+   unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = >vblank[pipe];
struct drm_pending_vblank_event *e, *t;
struct timeval now;
@@ -1298,30 +1297,11 @@ void drm_vblank_off(struct drm_device *dev, unsigned 
int pipe)
  "wanted %u, current %u\n",
  e->event.sequence, seq);
list_del(>base.link);
-   drm_vblank_put(dev, pipe);
+   drm_crtc_vblank_put(crtc);
send_vblank_event(dev, e, seq, );
}
spin_unlock_irqrestore(>event_lock, irqflags);
 }
-EXPORT_SYMBOL(drm_vblank_off);
-
-/**
- * drm_crtc_vblank_off - disable vblank events on a CRTC
- * @crtc: CRTC in question
- *
- * Drivers can use this function to shut down the vblank interrupt handling 
when
- * disabling a crtc. This function ensures that the latest vblank frame count 
is
- * stored so that drm_vblank_on can restore it again.
- *
- * Drivers must use this function when the hardware vblank counter can get
- * reset, e.g. when suspending.
- *
- * This is the native kms version of drm_vblank_off().
- */
-void drm_crtc_vblank_off(struct drm_crtc *crtc)
-{
-   drm_vblank_off(crtc->dev, drm_crtc_index(crtc));
-}
 EXPORT_SYMBOL(drm_crtc_vblank_off);

 /**
@@ -1357,19 +1337,18 @@ void drm_crtc_vblank_reset(struct drm_crtc *crtc)
 EXPORT_SYMBOL(drm_crtc_vblank_reset);

 /**
- * drm_vblank_on - enable vblank events on a CRTC
- * @dev: DRM device
- * @pipe: CRTC index
+ * drm_crtc_vblank_on - enable vblank events on a CRTC
+ * @crtc: CRTC in question
  *
  * This functions restores the vblank interrupt state captured with
  * drm_vblank_off() again. Note that calls to drm_vblank_on() and
  * drm_vblank_off() can be unbalanced and so can also be unconditionally called
  * in driver load code to reflect the current hardware state of the crtc.
- *
- * This is the legacy version of drm_crtc_vblank_on().
  */
-void drm_vblank_on(struct drm_device *dev, unsigned int pipe)
+void drm_crtc_vblank_on(struct drm_crtc *crtc)
 {
+   struct drm_device *dev = crtc->dev;
+   unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = >vblank[pipe];
unsigned long irqflags;

@@ -1396,23 +1375,6 @@ void drm_vblank_on(struct drm_device *dev, unsigned int 
pipe)
WARN_ON(drm_vblank_enable(dev, pipe));
spin_unlock_irqrestore(>vbl_lock, irqflags);
 }
-EXPORT_SYMBOL(drm_vblank_on);
-
-/**
- * drm_crtc_vblank_on - enable vblank events on a CRTC
- * @crtc: CRTC in question
- *
- * This functions restores the vblank interrupt state captured with
- * drm_vblank_off() again. Note that calls to drm_vblank_on() and
- * drm_vblank_off() can be unbalanced and so can also be unconditionally called
- * in driver load code to reflect the current hardware state of the crtc.
- *
- * This is the native kms version of drm_vblank_on().
- */
-void drm_crtc_vblank_on(struct drm_crtc *crtc)
-{
-   drm_vblank_on(crtc->dev, drm_crtc_index(crtc));
-}
 EXPORT_SYMBOL(drm_crtc_vblank_on);

 /**
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h
index 2401b14..406f954 100644
--- a/include/drm/drm_irq.h
+++ b/include/drm/drm_irq.h
@@ -150,8 +150,6 @@ extern int drm_crtc_vblank_get(struct drm_crtc *crtc);
 extern void drm_crtc_vblank_put(struct drm_crtc *crtc);
 extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
 extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
-extern void drm_vblank_off(struct drm_device *dev, unsigned int pipe);
-extern void drm_vblank_on(struct drm_device *dev, unsigned int pipe);
 

[PATCH 1/2] drm/nouveau: Use drm_crtc_vblank_{on, off} instead of old legacy ones.

2016-08-03 Thread Rodrigo Vivi
No functional change. Justs finish the migration from
drm_vblank_*(dev, pipe) to drm_crtc_vblank_*(crtc)

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/nouveau/nouveau_display.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index afbf557..148bd40 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -390,11 +390,11 @@ nouveau_display_fini(struct drm_device *dev)
struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_connector *connector;
-   int head;
+   struct drm_crtc *crtc;

/* Make sure that drm and hw vblank irqs get properly disabled. */
-   for (head = 0; head < dev->mode_config.num_crtc; head++)
-   drm_vblank_off(dev, head);
+   list_for_each_entry(crtc, >mode_config.crtc_list, head)
+   drm_crtc_vblank_off(crtc);

/* disable flip completion events */
nvif_notify_put(>flip);
@@ -647,13 +647,18 @@ nouveau_display_resume(struct drm_device *dev, bool 
runtime)

drm_helper_resume_force_mode(dev);

-   /* Make sure that drm and hw vblank irqs get resumed if needed. */
+
for (head = 0; head < dev->mode_config.num_crtc; head++)
-   drm_vblank_on(dev, head);
+

list_for_each_entry(crtc, >mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

+   /* Make sure that drm and hw vblank
+* irqs get resumed if needed.
+*/
+   drm_crtc_vblank_on(crtc);
+
if (!nv_crtc->cursor.nvbo)
continue;

-- 
2.5.5



[PATCH v5 3/6] drm/i915/skl: Update plane watermarks atomically during plane updates

2016-08-03 Thread Matt Roper
On Wed, Aug 03, 2016 at 02:14:53PM -0700, Matt Roper wrote:
...
> 
> I imagine we'll eventually probably want to create a new display vfunc
> to handle platform-specific pipe-level stuff that needs to happen under
> vblank evasion (like the scalers and linetime WM we have today) to keep
> the code clean; maybe add a TODO comment to that effect?
> 
> Anyway, this looks good enough for now, so
> 
> Reviewed-by: Matt Roper 

Woops, meant to add this reply to your v6 version of the patch
obviously...


Matt



[PATCH v5 3/6] drm/i915/skl: Update plane watermarks atomically during plane updates

2016-08-03 Thread Matt Roper
On Tue, Aug 02, 2016 at 02:20:33PM -0700, Matt Roper wrote:
> On Tue, Aug 02, 2016 at 02:52:51PM -0400, Lyude wrote:
> > Thanks to Ville for suggesting this as a potential solution to pipe
> > underruns on Skylake.
> > 
> > On Skylake all of the registers for configuring planes, including the
> > registers for configuring their watermarks, are double buffered. New
> > values written to them won't take effect until said registers are
> > "armed", which is done by writing to the PLANE_SURF (or in the case of
> > cursor planes, the CURBASE register) register.
> > 
> > With this in mind, up until now we've been updating watermarks on skl
> > like this:
> > 
> >   non-modeset {
> >- calculate (during atomic check phase)
> >- finish_atomic_commit:
> >  - intel_pre_plane_update:
> > - intel_update_watermarks()
> >  - {vblank happens; new watermarks + old plane values => underrun }
> >  - drm_atomic_helper_commit_planes_on_crtc:
> > - start vblank evasion
> > - write new plane registers
> > - end vblank evasion
> >   }
> > 
> >   or
> > 
> >   modeset {
> >- calculate (during atomic check phase)
> >- finish_atomic_commit:
> >  - crtc_enable:
> > - intel_update_watermarks()
> >  - {vblank happens; new watermarks + old plane values => underrun }
> >  - drm_atomic_helper_commit_planes_on_crtc:
> > - start vblank evasion
> > - write new plane registers
> > - end vblank evasion
> >   }
> > 
> > Now we update watermarks atomically like this:
> > 
> >   non-modeset {
> >- calculate (during atomic check phase)
> >- finish_atomic_commit:
> >  - intel_pre_plane_update:
> > - intel_update_watermarks() (wm values aren't written yet)
> >  - drm_atomic_helper_commit_planes_on_crtc:
> > - start vblank evasion
> > - write new plane registers
> > - write new wm values
> > - end vblank evasion
> >   }
> > 
> >   modeset {
> >- calculate (during atomic check phase)
> >- finish_atomic_commit:
> >  - crtc_enable:
> > - intel_update_watermarks() (actual wm values aren't written
> >   yet)
> >  - drm_atomic_helper_commit_planes_on_crtc:
> > - start vblank evasion
> > - write new plane registers
> > - write new wm values
> > - end vblank evasion
> >   }
> > 
> > So this patch moves all of the watermark writes into the right place;
> > inside of the vblank evasion where we update all of the registers for
> > each plane. While this patch doesn't fix everything, it does allow us to
> > update the watermark values in the way the hardware expects us to.
> > 
> > Changes since original patch series:
> >  - Remove mutex_lock/mutex_unlock since they don't do anything and we're
> >not touching global state
> >  - Move skl_write_cursor_wm/skl_write_plane_wm functions into
> >intel_pm.c, make externally visible
> >  - Add skl_write_plane_wm calls to skl_update_plane
> >  - Fix conditional for for loop in skl_write_plane_wm (level < max_level
> >should be level <= max_level)
> >  - Make diagram in commit more accurate to what's actually happening
> >  - Add Fixes:
> > 
> > Changes since v1:
> >  - Use IS_GEN9() instead of IS_SKYLAKE() since these fixes apply to more
> >then just Skylake
> >  - Update description to make it clear this patch doesn't fix everything
> >  - Check if pipes were actually changed before writing watermarks
> > 
> > Changes since v2:
> >  - Write PIPE_WM_LINETIME during vblank evasion
> > 
> > Changes since v3:
> >  - Rebase against new SAGV patch changes
> > 
> > Changes since v4:
> >  - Add a parameter to choose what skl_wm_values struct to use when
> >writing new plane watermarks
> > 
> > Fixes: 2d41c0b59afc ("drm/i915/skl: SKL Watermark Computation")
> > Signed-off-by: Lyude 
> > Cc: stable at vger.kernel.org
> > Cc: Ville Syrjälä 
> > Cc: Daniel Vetter 
> > Cc: Radhakrishna Sripada 
> > Cc: Hans de Goede 
> > Cc: Matt Roper 

I imagine we'll eventually probably want to create a new display vfunc
to handle platform-specific pipe-level stuff that needs to happen under
vblank evasion (like the scalers and linetime WM we have today) to keep
the code clean; maybe add a TODO comment to that effect?

Anyway, this looks good enough for now, so

Reviewed-by: Matt Roper 

> > ---
> >  drivers/gpu/drm/i915/intel_display.c |  8 +
> >  drivers/gpu/drm/i915/intel_drv.h |  5 
> >  drivers/gpu/drm/i915/intel_pm.c  | 58 
> > ++--
> >  drivers/gpu/drm/i915/intel_sprite.c  |  6 
> >  4 files changed, 61 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 76ba79f..79d146c 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2980,6 +2980,7 @@ static void skylake_update_primary_plane(struct 
> > drm_plane 

[PATCH 0/4]: Picture aspect ratio support in DRM layer

2016-08-03 Thread Jose Abreu
Hi,


On 03-08-2016 12:48, Daniel Vetter wrote:
> On Wed, Aug 03, 2016 at 04:26:24PM +0530, Shashank Sharma wrote:
>> This patch series adds 4 patches.
>> - The first two patches add aspect ratio support in DRM layes
>> - Next two patches add new aspect ratios defined in CEA-861-F
>>   supported for HDMI 2.0 4k modes.
>>
>> Adding aspect ratio support in DRM layer:
>> - The CEA videmodes contain aspect ratio information, which we
>>   parse when we read the modes from EDID. But while transforming
>>   user_mode to kernel_mode or viceversa, DRM layer lose this
>>   information.
>> - HDMI compliance testing for CEA modes, expects the AVI info frames
>>   to contain exact VIC no for the 'video mode under test'. Now CEA
>>   modes have different VIC for same modes but different aspect ratio
>>   for example:
>>  VIC 2 = 720x480 at 60 4:3 
>>  VIC 3 = 720x480 at 60 16:9
>>   In this way, lack of aspect ratio information, can cause wrong VIC
>>   no in AVI IF, causing HDMI complaince test to fail.
>> - This patch set adds code, which embeds the aspect ratio information
>>   also in DRM video mode flags, and uses it while comparing two modes. 
>>
>> Adding new aspect ratios for HDMI 2.0
>> - CEA-861-F defines two new aspect ratios, to be used for 4k HDMI 2.0
>>   modes.
>>  - 64:27
>>  - 256:135
>> Last two patches in the series, adds code to handle these new
>> aspect ratios.
>>
>> Shashank Sharma (4):
>>   drm: add picture aspect ratio flags
>>   drm: Add aspect ratio parsing in DRM layer
>>   video: Add new aspect ratios for HDMI 2.0
>>   drm: Add and handle new aspect ratios in DRM layer
> Patch series seems to have 0 changelogs anywhere, but I'm pretty sure I've
> seen this before. Please try again and state what changed and why you are
> resubmitting this.
> -Daniel

I've also seen this before and I am using them in order to pass
HDMI compliance. Without these patches the compliance fails.
Still, I've made some changes which I can submit. I've some
comments to you (Shashank):

First, you add an if condition in
drm_mode_equal_no_clocks_no_stereo() (patch 2) which
unconditionally compares the aspect ratio. But I think that you
have to take into account that some modes handed by the user to
the DRM layer do not initialize this field so I think the best
solution would be to compare the aspect ratios only when the
field is populated (i.e. picture_aspect_ratio !=
HDMI_PICTURE_ASPECT_NONE).

Second, you are expecting that the picture aspect field is
correctly set in the HDMI parsing but, at least in the test
equipment that I am using, this field is not set by the DRM layer
because the mode is coming in the detailed timings section which
does not include a picture aspect field. In my implementation I
add a function which given the mode width and height (fields
->width_mm and ->height_mm of mode) computes the aspect ratio and
populates the field.

Third, I am facing some difficulties when using Xserver and
Xrandr. Using libdrm's modetest application everything works ok
but with xrandr the aspect ratio gets lost between the link DRM
-> Xserver -> DRM. I set the aspect ratio in the flags field when
passing the mode to user level (just like you do in patch 2) but
then when the mode is returned and delivered to the DRM driver
the picture aspect is not present. I think this is due to how
Xserver or xrandr sets the mode but I am not sure.

@Daniel, can you give some comments regarding this?

>>  drivers/gpu/drm/drm_modes.c | 43 +++
>>  drivers/video/hdmi.c|  4 
>>  include/linux/hdmi.h|  2 ++
>>  include/uapi/drm/drm_mode.h | 24 +++-
>>  4 files changed, 68 insertions(+), 5 deletions(-)
>>
>> -- 
>> 1.9.1
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel

Best regards,
Jose Miguel Abreu


[PATCH 4/5] drm/intel/dp: Try harder to get bpc of a DP sink if EDID doesn't tell.

2016-08-03 Thread Mario Kleiner
On 08/03/2016 08:09 AM, Daniel Vetter wrote:
> On Wed, Aug 03, 2016 at 01:07:12PM +1000, Dave Airlie wrote:
>> On 6 July 2016 at 20:05, Mario Kleiner  wrote:
>>> For DP sinks which don't expose color depth via EDID, use
>>> the drm_dp_sink_bpc() helper to derive the bpc of the sink.
>>>
>>> This should handle DP native sinks with the "Assume 6 bpc if EDID
>>> doesn't tell us" as mandated by DP spec. It gives more accurate
>>> values for DP->legacy converters for HDMI, DVI and VGA.
>>
>> Haswell says no.
>
> Yup indeed, sorry for missing that. Tomeu and Mika Kahola are working on
> some fancy new dp helper to probe all that, and as part of that suitably
> fill out connector->display_info, too. That would allow both the
> inversion, and the dpcd transaction from within atomic_check (which is
> kinda not that cool either).
> -Daniel
>

Ups, sorry. They were only successfully tested with Ironlake and 
Ivybridge, non-MST, all the Intel hw i have here.

Anyway, patches 1+2 and 5 are independent of those and will fix existing 
bugs and regressions in stable kernels. Patch 1 fixes what the commit 
reverted in patch 2 was fixing. Patch 2 fixes the DP->legacy regressions 
which affect my users, patch 5 adds robustness for DVI sinks in general, 
making full use of EDID 1.3 info.

Maybe the logic in patch 3 can be somehow useful for Tomeu and Mika, as 
it was tested with different dp -> xx adapters. Happy to review or test 
once they have stuff ready.

thanks,
-mario

>>
>> ug 03 12:58:46 tyrion-bne-redhat-com kernel: fbcon: inteldrmfb (fb0)
>> is primary device
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: BUG: unable to handle
>> kernel NULL pointer dereference at 011b
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: IP: []
>> drm_dp_sink_bpc+0x5/0xb0 [drm_kms_helper]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: PGD 0
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Oops:  [#1] SMP
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Modules linked in: i915
>> ccm xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 tun
>> ip6t_rpfilter ip6t_
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  videobuf2_core
>> snd_hda_codec videodev mei_me mei snd_hwdep snd_seq snd_hda_core
>> rtsx_pci media i2c_i
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: CPU: 1 PID: 752 Comm:
>> kworker/1:3 Not tainted 4.7.0+ #12
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Hardware name: LENOVO
>> 20ARS25701/20ARS25701, BIOS GJET72WW (2.22 ) 02/21/2014
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Workqueue: events_long
>> drm_dp_mst_link_probe_work [drm_kms_helper]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: task: 880308583a80
>> task.stack: 880309f2
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RIP:
>> 0010:[]  []
>> drm_dp_sink_bpc+0x5/0xb0 [drm_kms_helper]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RSP:
>> 0018:880309f23b48  EFLAGS: 00010202
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RAX: 000a
>> RBX: 0006 RCX: 
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RDX: 
>> RSI: 0127 RDI: 0116
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RBP: 880309f23b50
>> R08: 880309734800 R09: 0024
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: R10: 
>> R11:  R12: 880309737800
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: R13: 88030a334000
>> R14: 880309737000 R15: 880309737800
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: FS:
>> () GS:88031e24()
>> knlGS:
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: CS:  0010 DS:  ES:
>>  CR0: 80050033
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: CR2: 011b
>> CR3: 01c06000 CR4: 001406e0
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Stack:
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  a09d4295
>> 880309f23bd8 a09a7c1f 8122544d
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  880306660258
>> 88030666 09737800 88030a331000
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  010088030024
>> 880309f23bb8 0024 880309737800
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Call Trace:
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
>> intel_dp_sink_bpc+0x25/0x30 [i915]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
>> intel_atomic_check+0xacf/0x1250 [i915]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
>> __kmalloc_track_caller+0x12d/0x210
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
>> drm_atomic_check_only+0x187/0x610 [drm]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
>> drm_atomic_add_affected_connectors+0x27/0xf0 [drm]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
>> drm_atomic_commit+0x17/0x60 [drm]
>> Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
>> restore_fbdev_mode+0x14c/0x260 

[PATCH 00/10] drm/edid: Clean up display_info stuff

2016-08-03 Thread Christian König
Looks reasonable to me, adding a few more AMD people which probably want 
to take a look as well.

Patch #3 and #4 are Reviewed-by: Christian König 
 since they touch the radeon/amdgpu driver.

Patch #1, #2 and #5 - #8 are Acked-by: Christian König 
.

Regards,
Christian.

Am 03.08.2016 um 08:33 schrieb ville.syrjala at linux.intel.com:
> From: Ville Syrjälä 
>
> This series aims to clean up the way we fill out the display_info
> structure a bit. Mainly doing a clean separation of the audio and
> video related bits.
>
> My aim is getting i915 to respect the HDMI sink TMDS clock limit
> (currently we respect only the DP++ dongle limit, and the source
> limit). But while doing that, I noticed that the display_info stuff
> was a bit of mess, hence it resulted in this bigger series.
>
> Entire series available here:
> git://github.com/vsyrjala/linux.git hdmi_sink_tmds_limit_3
>
> Ville Syrjälä (10):
>drm/edid: Clear old audio latency values before parsing the new EDID
>drm/edid: Clear old dvi_dual/max_tmds_clock before parsing the new
>  EDID
>drm/edid: Make max_tmds_clock kHz instead of MHz
>drm/edid: Move dvi_dual/max_tmds_clock to drm_display_info
>drm/edid: Don't pass around drm_display_info needlessly
>drm/edid: Reduce the number of times we parse the CEA extension block
>drm/edid: Clear the old cea_rev when there's no CEA extension in the
>  new EDID
>drm/edid: Move dvi_dual/max_tmds_clock parsing out from
>  drm_edid_to_eld()
>drm/i915: Replace a bunch of connector->base.display_info with a local
>  variable
>drm/i915: Account for sink max TMDS clock when checking the port clock
>
>   drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |   4 +-
>   drivers/gpu/drm/drm_edid.c | 258 
> +
>   drivers/gpu/drm/i915/intel_display.c   |  14 +-
>   drivers/gpu/drm/i915/intel_hdmi.c  |   9 +-
>   drivers/gpu/drm/radeon/radeon_connectors.c |   4 +-
>   include/drm/drm_crtc.h |   7 +-
>   6 files changed, 152 insertions(+), 144 deletions(-)
>



[PATCH] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-03 Thread Daniel Vetter
On Wed, Aug 03, 2016 at 04:56:20PM +0800, Mark yao wrote:
> On 2016年08月03日 16:46, Daniel Vetter wrote:
> > On Wed, Aug 03, 2016 at 10:43:21AM +0200, Daniel Vetter wrote:
> > > On Wed, Aug 03, 2016 at 04:13:45PM +0800, Mark Yao wrote:
> > > > [1.162571] Unable to handle kernel NULL pointer dereference at 
> > > > virtual address 0200
> > > > [1.165656] Modules linked in:
> > > > [1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
> > > > [1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 
> > > > (Android) (DT)
> > > > [1.167153] Workqueue: events output_poll_execute
> > > > [1.168231] PC is at mutex_lock+0x14/0x44
> > > > [1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
> > > > [1.172192] [] mutex_lock+0x14/0x44
> > > > [1.172196] [] 
> > > > drm_fb_helper_hotplug_event+0x28/0xcc
> > > > [1.172201] [] 
> > > > rockchip_drm_output_poll_changed+0x14/0x1c
> > > > [1.172204] [] 
> > > > drm_kms_helper_hotplug_event+0x28/0x34
> > > > [1.172207] [] output_poll_execute+0x150/0x198
> > > > [1.172212] [] process_one_work+0x218/0x3dc
> > > > [1.172215] [] worker_thread+0x24c/0x374
> > > > [1.172217] [] kthread+0xdc/0xe4
> > > > [1.17] [] ret_from_fork+0x10/0x40
> > > > 
> > > > Signed-off-by: Mark Yao 
> > > Erhm, how exactly did you manage to blow up in there? Without fbdev
> > > support enable drm_fb_helper_hotplug_event() does nothing at all.
> > > 
> > > The fbdev helper is designed such that you _don't_ have to check for NULL
> > > everywhere in the driver, that would be pretty bad code.
> > And indeed this issue seems preexisting, and was already attempt to fix in
> > 
> > commit 765c35bbd267e93eabe15a94534688ddaa0b9dc7
> > Author: Heiko Stübner 
> > Date:   Tue Jun 2 16:41:45 2015 +0200
> > 
> >  drm/rockchip: only call drm_fb_helper_hotplug_event if fb_helper 
> > present
> > 
> > except that patch is complete nonsense - the added check is always true.
> > Oh and it's missing your s-o-b, which is not good at all.
> > 
> > The proper fix is to make delayed fbdev loading work correctly, Thierry
> > has patches for that on the mailing list. Not add even more hacks like the
> > above (and then slap a misleading subject onto your patch).
> > -Daniel
> 
> Hmmm, there is a mistake on Heiko's patch:
> 
> struct drm_fb_helper *fb_helper = >fbdev_helper;
> 
>-   drm_fb_helper_hotplug_event(fb_helper);
>   +   if (fb_helper)
>   +   drm_fb_helper_hotplug_event(fb_helper);
> 
> But the fb_helper would never be NULL, because the private->fbdev_helper is
> not a pointer.
> 
> So the first step is making private->fbdev_helper to a pointer, that's what
> I do on this patch.

You've done more, you also wrapped that pointer into another structure,
which means you have to splatter NULL checks all over the place. If you
really only do the struct->pointer conversion alone the patch would be a
lot cleaner.
-Daniel

> 
> 
> > > -Daniel
> > > 
> > > > ---
> > > >   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   | 13 ++---
> > > >   drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  8 ++--
> > > >   drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  6 +++---
> > > >   drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 26 
> > > > +-
> > > >   4 files changed, 36 insertions(+), 17 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
> > > > b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > > > index a822d49..1a4dad6 100644
> > > > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > > > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > > > @@ -261,7 +261,10 @@ static void rockchip_drm_lastclose(struct 
> > > > drm_device *dev)
> > > >   {
> > > > struct rockchip_drm_private *priv = dev->dev_private;
> > > > -   drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev_helper);
> > > > +   if (!priv->fbdev)
> > > > +   return;
> > > > +
> > > > +   
> > > > drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev->fbdev_helper);
> > > >   }
> > > >   static const struct file_operations rockchip_drm_driver_fops = {
> > > > @@ -310,8 +313,10 @@ void rockchip_drm_fb_suspend(struct drm_device 
> > > > *drm)
> > > >   {
> > > > struct rockchip_drm_private *priv = drm->dev_private;
> > > > +   if (!priv->fbdev)
> > > > +   return;
> > > > console_lock();
> > > > -   drm_fb_helper_set_suspend(>fbdev_helper, 1);
> > > > +   drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 1);
> > > > console_unlock();
> > > >   }
> > > > @@ -319,8 +324,10 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
> > > >   {
> > > > struct rockchip_drm_private *priv = drm->dev_private;
> > > > +   if (!priv->fbdev)
> > > > +   return;
> > > > console_lock();
> > > > -   drm_fb_helper_set_suspend(>fbdev_helper, 0);
> > > > +   

[PATCH 0/4]: Picture aspect ratio support in DRM layer

2016-08-03 Thread Daniel Vetter
On Wed, Aug 03, 2016 at 04:26:24PM +0530, Shashank Sharma wrote:
> This patch series adds 4 patches.
> - The first two patches add aspect ratio support in DRM layes
> - Next two patches add new aspect ratios defined in CEA-861-F
>   supported for HDMI 2.0 4k modes.
> 
> Adding aspect ratio support in DRM layer:
> - The CEA videmodes contain aspect ratio information, which we
>   parse when we read the modes from EDID. But while transforming
>   user_mode to kernel_mode or viceversa, DRM layer lose this
>   information.
> - HDMI compliance testing for CEA modes, expects the AVI info frames
>   to contain exact VIC no for the 'video mode under test'. Now CEA
>   modes have different VIC for same modes but different aspect ratio
>   for example:
>   VIC 2 = 720x480 at 60 4:3 
>   VIC 3 = 720x480 at 60 16:9
>   In this way, lack of aspect ratio information, can cause wrong VIC
>   no in AVI IF, causing HDMI complaince test to fail.
> - This patch set adds code, which embeds the aspect ratio information
>   also in DRM video mode flags, and uses it while comparing two modes. 
> 
> Adding new aspect ratios for HDMI 2.0
> - CEA-861-F defines two new aspect ratios, to be used for 4k HDMI 2.0
>   modes.
>   - 64:27
>   - 256:135
> Last two patches in the series, adds code to handle these new
> aspect ratios.
> 
> Shashank Sharma (4):
>   drm: add picture aspect ratio flags
>   drm: Add aspect ratio parsing in DRM layer
>   video: Add new aspect ratios for HDMI 2.0
>   drm: Add and handle new aspect ratios in DRM layer

Patch series seems to have 0 changelogs anywhere, but I'm pretty sure I've
seen this before. Please try again and state what changed and why you are
resubmitting this.
-Daniel

> 
>  drivers/gpu/drm/drm_modes.c | 43 +++
>  drivers/video/hdmi.c|  4 
>  include/linux/hdmi.h|  2 ++
>  include/uapi/drm/drm_mode.h | 24 +++-
>  4 files changed, 68 insertions(+), 5 deletions(-)
> 
> -- 
> 1.9.1
> 
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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


RFC: hardware accelerated bitblt using dma engine

2016-08-03 Thread Dave Airlie
On 3 August 2016 at 13:33, Enrico Weigelt, metux IT consult
 wrote:
> On 03.08.2016 01:12, Rob Clark wrote:
>
> Hi,
>
>>> Well, if it already does buffer allocation and mapping (which might
>>> also involve copying around phyisical buffers), why not also add
>>> copy-between-buffers ?
>>
>> except "dumb" buffers exist *only* for CPU rendered content, you
>> cannot assume that a gpu can accelerate anything with them.
>
> Exactly my usecase: having no (usable) GPU at all, but a an sdma
> controller - or even better: an IPU - which can do the bitblt.
> (maybe even w/ colorspace conversion, rotation, etc)
>
> There might be GPUs which can also do that - and in that case it
> should be done by the GPU.
>
>> They basically exist just for simple splash screens and fbcon
>
> Or when you dont have an (usable) GPU at all ?
>
>> there is a reason that there is no generic gpu cmd submission ioctl.
>> It is too much hw specific,
>
> Sure, but I'm not going to use an GPU at all, but different hw.
>
>> and anyway it is only used by device
>> specific userspace (ie. gl driver and/or xorg ddx)
>
> Actually, on my targets I neither have gl nor xorg, and I'd like to
> keep userland generic. I'd hate to hate to have lots of hw-specific
> cairo-backends when I'll have to touch the kernel anyways, in order
> to use smda or ipu.
>
>
> By the way: while hacking a bit on mesa (backporting to Trusty),
> I came around separate hw-specific calls for retrieving the video
> memory size. Seems to be a really common thing ... is there any
> hw that does not have such thing ? Couldn't that be an generic
> ioctl() ?
>
> I somewhat got the strange feeling that anything that goes beyond
> very trivial dumb framebuffer has hw-specific ioctl's ;-o

The thing isstuff looks generic until you go to use it, just abstract
it in userspace.

Because no hw is the same once you go beyond that.

Video memory size means what? VRAM, GPU accessible system RAM,
amount of CPU visible VRAM?

Dave.


[Intel-gfx] [PATCH 4/4] drm: Add and handle new aspect ratios in DRM layer

2016-08-03 Thread Sean Paul
On Wed, Aug 3, 2016 at 6:56 AM, Shashank Sharma
 wrote:
> HDMI 2.0/CEA-861-F introduces two new aspect ratios:
> - 64:27
> - 256:135
>
> This patch:
> -  Adds new DRM flags for to represent these new aspect ratios.
> -  Adds new cases to handle these aspect ratios while converting
> from user->kernel mode or viseversa.
>
> Signed-off-by: Shashank Sharma 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/drm_modes.c | 12 
>  include/uapi/drm/drm_mode.h |  6 ++
>  2 files changed, 18 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index e6029e0..bdc353d 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1481,6 +1481,12 @@ void drm_mode_convert_to_umode(struct 
> drm_mode_modeinfo *out,
> case HDMI_PICTURE_ASPECT_16_9:
> out->flags |= DRM_MODE_FLAG_PAR16_9;
> break;
> +   case HDMI_PICTURE_ASPECT_64_27:
> +   out->flags |= DRM_MODE_FLAG_PAR64_27;
> +   break;
> +   case DRM_MODE_PICTURE_ASPECT_256_135:
> +   out->flags |= DRM_MODE_FLAG_PAR256_135;
> +   break;
> case HDMI_PICTURE_ASPECT_NONE:
> case HDMI_PICTURE_ASPECT_RESERVED:
> default:
> @@ -1543,6 +1549,12 @@ int drm_mode_convert_umode(struct drm_display_mode 
> *out,
> case DRM_MODE_FLAG_PAR16_9:
> out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9;
> break;
> +   case DRM_MODE_FLAG_PAR64_27:
> +   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_64_27;
> +   break;
> +   case DRM_MODE_FLAG_PAR256_135:
> +   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_256_135;
> +   break;
> default:
> out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
> }
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index cd66a95..6291eae 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -81,6 +81,8 @@ extern "C" {
>  #define DRM_MODE_PICTURE_ASPECT_NONE   0
>  #define DRM_MODE_PICTURE_ASPECT_4_31
>  #define DRM_MODE_PICTURE_ASPECT_16_9   2
> +#define DRM_MODE_PICTURE_ASPECT_64_27  3
> +#define DRM_MODE_PICTURE_ASPECT_256_1354
>
>  /* Aspect ratio flag bitmask (4 bits 22:19) */
>  #define DRM_MODE_FLAG_PARMASK  (0x0F<<19)
> @@ -90,6 +92,10 @@ extern "C" {
> (DRM_MODE_PICTURE_ASPECT_4_3 << 19)
>  #define  DRM_MODE_FLAG_PAR16_9 \
> (DRM_MODE_PICTURE_ASPECT_16_9 << 19)
> +#define  DRM_MODE_FLAG_PAR64_27 \
> +   (DRM_MODE_PICTURE_ASPECT_64_27 << 19)
> +#define  DRM_MODE_FLAG_PAR256_135 \
> +   (DRM_MODE_PICTURE_ASPECT_256_135 << 19)
>
>  /* DPMS flags */
>  /* bit compatible with the xorg definitions. */
> --
> 1.9.1
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[PATCH 3/4] video: Add new aspect ratios for HDMI 2.0

2016-08-03 Thread Sean Paul
On Wed, Aug 3, 2016 at 6:56 AM, Shashank Sharma
 wrote:
> HDMI 2.0/CEA-861-F introduces two new aspect ratios:
> - 64:27
> - 256:135
>
> This patch adds enumeration for the new aspect ratios
> in the existing aspect ratio list.
>
> Signed-off-by: Shashank Sharma 

Reviewed-by: Sean Paul 

> ---
>  drivers/video/hdmi.c | 4 
>  include/linux/hdmi.h | 2 ++
>  2 files changed, 6 insertions(+)
>
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> index 1626892..1cf907e 100644
> --- a/drivers/video/hdmi.c
> +++ b/drivers/video/hdmi.c
> @@ -533,6 +533,10 @@ hdmi_picture_aspect_get_name(enum hdmi_picture_aspect 
> picture_aspect)
> return "4:3";
> case HDMI_PICTURE_ASPECT_16_9:
> return "16:9";
> +   case HDMI_PICTURE_ASPECT_64_27:
> +   return "64:27";
> +   case HDMI_PICTURE_ASPECT_256_135:
> +   return "256:135";
> case HDMI_PICTURE_ASPECT_RESERVED:
> return "Reserved";
> }
> diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> index e974420..edbb4fc 100644
> --- a/include/linux/hdmi.h
> +++ b/include/linux/hdmi.h
> @@ -78,6 +78,8 @@ enum hdmi_picture_aspect {
> HDMI_PICTURE_ASPECT_NONE,
> HDMI_PICTURE_ASPECT_4_3,
> HDMI_PICTURE_ASPECT_16_9,
> +   HDMI_PICTURE_ASPECT_64_27,
> +   HDMI_PICTURE_ASPECT_256_135,
> HDMI_PICTURE_ASPECT_RESERVED,
>  };
>
> --
> 1.9.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


RFC: hardware accelerated bitblt using dma engine

2016-08-03 Thread Daniel Vetter
On Wed, Aug 03, 2016 at 11:24:37AM +0200, Marek Szyprowski wrote:
> Hi Enrico,
> 
> 
> On 2016-08-02 15:21, Enrico Weigelt, metux IT consult wrote:
> > I'm currently thinking about adding an hw-accelerated bitblt operation.
> > The idea goes like this:
> > 
> > * we add some bitblt ioctl which copies rects between bo's.
> >(it also handles memory layouts, pixfmt conversion, etc)
> > * the driver can decide to let the GPU or IPU do that, if available
> > * if we have an suitable DMA engine (maybe only the more complex ones
> >which can handle lines on their own ...) we'll use that
> > * as fallback, resort to memcpy().
> > 
> > 
> > Whether an dma engine can/should be used might be highly hw specific,
> > so that probably would be configured in DT.
> > 
> > To use that feature, userland could actually allocate two BO's,
> > one that's mapped as a framebuffer to some crtc, another one just
> > a memory buffer. It could then render to the fast memory buffer and
> > tell the DRM to only copy over the changed regions to the graphics
> > memory via DMA (or whatever is best on that particular hw platform).
> > 
> > 
> > What do you think about that idea ?
> 
> I'm working now on something similar, but more generic. There is already
> a framework for picture processing (converting, scaling, blitting, rotating)
> in Exynos DRM. It is called IPP (Image Post Processing), but its user
> interface is really ugly and limited, so I plan to rewrite it and make
> it really generic. Some discussion on it were already in the following
> thread:
> http://thread.gmane.org/gmane.linux.kernel.samsung-soc/49743
> 
> I plan to propose an API based on DRM object/properties, which will be
> similar to KMS atomic API. I will let you know when I have it ready for
> presenting in public.

In case it's not clear from Dave's, Rob's and my reply: Generic rendering
of any kind is _very_ unpopular in the drm subsystem. We've tried
semi-generic 15 years ago (with some of the shared drm core stuff between
linux and bsd) and it's a disaster of fake generic, single-use code.

The reason for that is that hw accel is actually not simple. You
essentially need to have as little additional abstraction between what's
your real client api (hw composer, Xrender or whatever it is) and the hw.
Because for optimal performance you _must_ supply the commands to the
kernel in an as close to the format/layout used by the hardware as
possible. That means no shared command submission of any kind. And the
other reason is that cache transfers and memory transfers are highly
hardware specific, too. Which means no shared buffer management and
mapping interfaces either.

In short, if you want to get this in you need to disprove the last 15-20
years of linux gfx driver developement and show that we've been wrong on
these. Expect _very_ high resistence to anything remotely looking like a
shared/common blitter uapi. Of course having some common helper code to
make drivers easier to type (like cma helpers, or ttm, or similar) is
something entirely different, this is about the uapi.

And please don't be discourage here, I just want to set clear expectations
to avoid disappointment. Supporting blitter hardware is obviously a good
idea, and I think the drm subsystem is the right place for that
(especially if you have a display block or sometimes a real gpu connected
to that blitter).

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


[PATCH 2/4] drm: Add aspect ratio parsing in DRM layer

2016-08-03 Thread Sean Paul
On Wed, Aug 3, 2016 at 6:56 AM, Shashank Sharma
 wrote:
> Current DRM layer functions dont parse aspect ratio information

s/dont/don't/

> while converting a user mode->kernel mode or viceversa. This

s/viceversa/vice versa/

> causes modeset to pick mode with wrong aspect ratio, eventually
> cauing failures in HDMI compliance test cases, due to wrong VIC.

s/cauing/causing/

Sorry for the spelling nits. I originally just found this one, but
since I was nitpicking one, I figured I should pick at them all.

>
> This patch adds aspect ratio information in DRM's mode conversion
> and mode comparision functions, to make sure kernel picks mode
> with right aspect ratio (as per the VIC).
>
> Signed-off-by: Shashank Sharma 
> Signed-off-by: Lin, Jia 
> Signed-off-by: Akashdeep Sharma 
> ---
>  drivers/gpu/drm/drm_modes.c | 31 +++
>  1 file changed, 31 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index fc5040a..e6029e0 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -969,6 +969,7 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct 
> drm_display_mode *mode1,
> mode1->vsync_end == mode2->vsync_end &&
> mode1->vtotal == mode2->vtotal &&
> mode1->vscan == mode2->vscan &&
> +   mode1->picture_aspect_ratio == mode2->picture_aspect_ratio &&
> (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
>  (mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
> return true;
> @@ -1471,6 +1472,22 @@ void drm_mode_convert_to_umode(struct 
> drm_mode_modeinfo *out,
> out->vrefresh = in->vrefresh;
> out->flags = in->flags;
> out->type = in->type;
> +   out->flags &= ~DRM_MODE_FLAG_PARMASK;
> +
> +   switch (in->picture_aspect_ratio) {
> +   case HDMI_PICTURE_ASPECT_4_3:
> +   out->flags |= DRM_MODE_FLAG_PAR4_3;
> +   break;
> +   case HDMI_PICTURE_ASPECT_16_9:
> +   out->flags |= DRM_MODE_FLAG_PAR16_9;
> +   break;
> +   case HDMI_PICTURE_ASPECT_NONE:
> +   case HDMI_PICTURE_ASPECT_RESERVED:
> +   default:

No need to specify HDMI_PICTURE_ASPECT_NONE &
HDMI_PICTURE_ASPECT_RESERVED if you use default.

> +   out->flags |= DRM_MODE_FLAG_PARNONE;
> +   break;
> +   }
> +
> strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
> out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
>  }
> @@ -1516,6 +1533,20 @@ int drm_mode_convert_umode(struct drm_display_mode 
> *out,
> strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
> out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
>
> +   /* Clearing picture aspect ratio bits from out flags */
> +   out->flags &= ~DRM_MODE_FLAG_PARMASK;
> +
> +   switch (in->flags & DRM_MODE_FLAG_PARMASK) {
> +   case DRM_MODE_FLAG_PAR4_3:
> +   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_4_3;
> +   break;
> +   case DRM_MODE_FLAG_PAR16_9:
> +   out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9;
> +   break;
> +   default:
> +   out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;

For safety,

break;

> +   }
> +
> out->status = drm_mode_validate_basic(out);
> if (out->status != MODE_OK)
> goto out;
> --
> 1.9.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/4] drm: add picture aspect ratio flags

2016-08-03 Thread Sean Paul
On Wed, Aug 3, 2016 at 6:56 AM, Shashank Sharma
 wrote:
> This patch adds drm flag bits for aspect ratio information
>
> Currently drm flag bits don't have field for mode's picture
> aspect ratio. This field will help the driver to pick mode with
> right aspect ratio, and help in setting right VIC field in avi
> infoframes.
>
> Signed-off-by: Shashank Sharma 
> ---
>  include/uapi/drm/drm_mode.h | 18 +-
>  1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 49a7265..cd66a95 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -77,6 +77,19 @@ extern "C" {
>  #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM   (7<<14)
>  #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF(8<<14)
>
> +/* Picture aspect ratio options */
> +#define DRM_MODE_PICTURE_ASPECT_NONE   0
> +#define DRM_MODE_PICTURE_ASPECT_4_31
> +#define DRM_MODE_PICTURE_ASPECT_16_9   2
> +
> +/* Aspect ratio flag bitmask (4 bits 22:19) */
> +#define DRM_MODE_FLAG_PARMASK  (0x0F<<19)
> +#define  DRM_MODE_FLAG_PARNONE \
> +   (DRM_MODE_PICTURE_ASPECT_NONE << 19)

While I prefer the spaces in between the << operator, it seems like
convention in this file is to not have them.

> +#define  DRM_MODE_FLAG_PAR4_3 \
> +   (DRM_MODE_PICTURE_ASPECT_4_3 << 19)
> +#define  DRM_MODE_FLAG_PAR16_9 \
> +   (DRM_MODE_PICTURE_ASPECT_16_9 << 19)

Not crazy about "PAR". Perhaps DRM_MODE_FLAG_ASPECT_BLAH would be more
descriptive?

>
>  /* DPMS flags */
>  /* bit compatible with the xorg definitions. */
> @@ -92,11 +105,6 @@ extern "C" {
>  #define DRM_MODE_SCALE_CENTER  2 /* Centered, no scaling */
>  #define DRM_MODE_SCALE_ASPECT  3 /* Full screen, preserve aspect */
>
> -/* Picture aspect ratio options */
> -#define DRM_MODE_PICTURE_ASPECT_NONE   0
> -#define DRM_MODE_PICTURE_ASPECT_4_31
> -#define DRM_MODE_PICTURE_ASPECT_16_9   2
> -
>  /* Dithering mode options */
>  #define DRM_MODE_DITHERING_OFF 0
>  #define DRM_MODE_DITHERING_ON  1
> --
> 1.9.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 151341] AMDGPU Hawaii: screen freeze, Xorg blocked in fence_default_wait

2016-08-03 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=151341

Alex Deucher  changed:

   What|Removed |Added

 CC||alexdeucher at gmail.com

--- Comment #1 from Alex Deucher  ---
Please attach your xorg log and dmesg output.

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


[PATCH 4/5] drm/intel/dp: Try harder to get bpc of a DP sink if EDID doesn't tell.

2016-08-03 Thread Dave Airlie
On 6 July 2016 at 20:05, Mario Kleiner  wrote:
> For DP sinks which don't expose color depth via EDID, use
> the drm_dp_sink_bpc() helper to derive the bpc of the sink.
>
> This should handle DP native sinks with the "Assume 6 bpc if EDID
> doesn't tell us" as mandated by DP spec. It gives more accurate
> values for DP->legacy converters for HDMI, DVI and VGA.

Haswell says no.

ug 03 12:58:46 tyrion-bne-redhat-com kernel: fbcon: inteldrmfb (fb0)
is primary device
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: BUG: unable to handle
kernel NULL pointer dereference at 011b
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: IP: []
drm_dp_sink_bpc+0x5/0xb0 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: PGD 0
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Oops:  [#1] SMP
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Modules linked in: i915
ccm xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 tun
ip6t_rpfilter ip6t_
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  videobuf2_core
snd_hda_codec videodev mei_me mei snd_hwdep snd_seq snd_hda_core
rtsx_pci media i2c_i
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: CPU: 1 PID: 752 Comm:
kworker/1:3 Not tainted 4.7.0+ #12
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Hardware name: LENOVO
20ARS25701/20ARS25701, BIOS GJET72WW (2.22 ) 02/21/2014
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Workqueue: events_long
drm_dp_mst_link_probe_work [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: task: 880308583a80
task.stack: 880309f2
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RIP:
0010:[]  []
drm_dp_sink_bpc+0x5/0xb0 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RSP:
0018:880309f23b48  EFLAGS: 00010202
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RAX: 000a
RBX: 0006 RCX: 
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RDX: 
RSI: 0127 RDI: 0116
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: RBP: 880309f23b50
R08: 880309734800 R09: 0024
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: R10: 
R11:  R12: 880309737800
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: R13: 88030a334000
R14: 880309737000 R15: 880309737800
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: FS:
() GS:88031e24()
knlGS:
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: CS:  0010 DS:  ES:
 CR0: 80050033
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: CR2: 011b
CR3: 01c06000 CR4: 001406e0
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Stack:
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  a09d4295
880309f23bd8 a09a7c1f 8122544d
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  880306660258
88030666 09737800 88030a331000
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  010088030024
880309f23bb8 0024 880309737800
Aug 03 12:58:46 tyrion-bne-redhat-com kernel: Call Trace:
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
intel_dp_sink_bpc+0x25/0x30 [i915]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
intel_atomic_check+0xacf/0x1250 [i915]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
__kmalloc_track_caller+0x12d/0x210
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_atomic_check_only+0x187/0x610 [drm]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
drm_atomic_add_affected_connectors+0x27/0xf0 [drm]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_atomic_commit+0x17/0x60 [drm]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
restore_fbdev_mode+0x14c/0x260 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_fb_helper_restore_fbdev_mode_unlocked+0x33/0x80 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_fb_helper_set_par+0x2d/0x50 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_fb_helper_hotplug_event+0x148/0x180 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
intel_fbdev_output_poll_changed+0x1a/0x20 [i915]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_kms_helper_hotplug_event+0x27/0x30 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
intel_dp_mst_hotplug+0x15/0x20 [i915]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_dp_send_link_address+0x19a/0x220 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
put_prev_entity+0x33/0x410
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
add_timer_on+0xdb/0x1b0
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
__switch_to+0x2b6/0x600
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  [] ?
pick_next_task_fair+0x10e/0x4d0
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_dp_check_and_send_link_address+0xad/0xc0 [drm_kms_helper]
Aug 03 12:58:46 tyrion-bne-redhat-com kernel:  []
drm_dp_mst_link_probe_work+0x57/0xb0 [drm_kms_helper]
Aug 03 12:58:46 

[PATCH v4 5/5] dma-buf/sync_file: only enable fence signalling on poll()

2016-08-03 Thread Chris Wilson
On Tue, Jul 12, 2016 at 03:08:45PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> Signalling doesn't need to be enabled at sync_file creation, it is only
> required if userspace waiting the fence to signal through poll().
> 
> Thus we delay fence_add_callback() until poll is called. It only adds the
> callback the first time poll() is called. This avoid re-adding the same
> callback multiple times.
> 
> v2: rebase and update to work with new fence support for sync_file
> 
> v3: use atomic operation to set enabled and protect fence_add_callback()

There's actually a spare bit in fence->flags you can use for this.

#define POLL_ENABLED FENCE_FLAG_USER_BITS

if (test_bit(POLL_ENABLED, _file->fence->flags))
fence_remove_callback(sync_file->fence, _file->cb);

...

if (!test_and_set_bit(POLL_ENABLED, _file->fence->flags)) {
if (fence_add_callback(sync_file->fence, _file->cb,
   fence_check_cb_func) < 0)
wake_up_all(_file->wq);
}

Saves adding a raw atomic.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[Bug 91281] Tonga VCE 2160p encode fails with BO to small for addr

2016-08-03 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=91281

--- Comment #4 from Christian König  ---
Nice catch. Brave enough to provide a patch or should Leo and I take a look?

I'm just back from vacation and so busy that I probably won't come to it before
the end of the month.

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


[Bug 97166] lockup during gameplay of Batman series of games

2016-08-03 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=97166

--- Comment #8 from farmboy0+freedesktop at googlemail.com ---
I *think* you need DotNet installed in your prefix.
My Steam install resides there at least.
Otherwise yeah Install and play should suffice.
You might want to remove the intro movies they are annyoing.
Instructions can be found in the PC Gaming Wiki.

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


[bug report] drm/amdgpu/gfx7: set USER_SHADER_ARRAY_CONFIG based on disable_cu parameter

2016-08-03 Thread Dan Carpenter
Hello Nicolai Hähnle,

The patch 324c614a819a: "drm/amdgpu/gfx7: set
USER_SHADER_ARRAY_CONFIG based on disable_cu parameter" from Jun 17,
2016, leads to the following static checker warning:

drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c:5057 gfx_v7_0_get_cu_info()
error: buffer overflow 'cu_info->bitmap' 4 <= 4

drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
  5035  static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev)
  5036  {
  5037  int i, j, k, counter, active_cu_number = 0;
  5038  u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0;
  5039  struct amdgpu_cu_info *cu_info = >gfx.cu_info;
  5040  unsigned disable_masks[4 * 2];
  5041  
  5042  memset(cu_info, 0, sizeof(*cu_info));
  5043  
  5044  amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2);
  5045  
  5046  mutex_lock(>grbm_idx_mutex);
  5047  for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
  5048  for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
  5049  mask = 1;
  5050  ao_bitmap = 0;
  5051  counter = 0;
  5052  gfx_v7_0_select_se_sh(adev, i, j, 0x);
  5053  if (i < 4 && j < 2)
^
Is it really possible for i to be >= 4?

  5054  gfx_v7_0_set_user_cu_inactive_bitmap(
  5055  adev, disable_masks[i * 2 + j]);
  5056  bitmap = gfx_v7_0_get_cu_active_bitmap(adev);
  5057  cu_info->bitmap[i][j] = bitmap;
^
Because if so, then we are screwed here.

  5058  
  5059  for (k = 0; k < 16; k ++) {
  5060  if (bitmap & mask) {
  5061  if (counter < 2)
  5062  ao_bitmap |= mask;
  5063  counter ++;
  5064  }
  5065  mask <<= 1;
  5066  }
  5067  active_cu_number += counter;
  5068  ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
  5069  }
  5070  }
  5071  gfx_v7_0_select_se_sh(adev, 0x, 0x, 0x);
  5072  mutex_unlock(>grbm_idx_mutex);
  5073  
  5074  cu_info->number = active_cu_number;
  5075  cu_info->ao_cu_mask = ao_cu_mask;
  5076  }

regards,
dan carpenter


RFC: hardware accelerated bitblt using dma engine

2016-08-03 Thread Marek Szyprowski
Hi Enrico,


On 2016-08-02 15:21, Enrico Weigelt, metux IT consult wrote:
> I'm currently thinking about adding an hw-accelerated bitblt operation.
> The idea goes like this:
>
> * we add some bitblt ioctl which copies rects between bo's.
>(it also handles memory layouts, pixfmt conversion, etc)
> * the driver can decide to let the GPU or IPU do that, if available
> * if we have an suitable DMA engine (maybe only the more complex ones
>which can handle lines on their own ...) we'll use that
> * as fallback, resort to memcpy().
>
>
> Whether an dma engine can/should be used might be highly hw specific,
> so that probably would be configured in DT.
>
> To use that feature, userland could actually allocate two BO's,
> one that's mapped as a framebuffer to some crtc, another one just
> a memory buffer. It could then render to the fast memory buffer and
> tell the DRM to only copy over the changed regions to the graphics
> memory via DMA (or whatever is best on that particular hw platform).
>
>
> What do you think about that idea ?

I'm working now on something similar, but more generic. There is already
a framework for picture processing (converting, scaling, blitting, rotating)
in Exynos DRM. It is called IPP (Image Post Processing), but its user
interface is really ugly and limited, so I plan to rewrite it and make
it really generic. Some discussion on it were already in the following
thread:
http://thread.gmane.org/gmane.linux.kernel.samsung-soc/49743

I plan to propose an API based on DRM object/properties, which will be
similar to KMS atomic API. I will let you know when I have it ready for
presenting in public.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[bug report] drm/amdgpu/gfx7: set USER_SHADER_ARRAY_CONFIG based on disable_cu parameter

2016-08-03 Thread Nicolai Hähnle
On 03.08.2016 11:09, Dan Carpenter wrote:
> Hello Nicolai Hähnle,
>
> The patch 324c614a819a: "drm/amdgpu/gfx7: set
> USER_SHADER_ARRAY_CONFIG based on disable_cu parameter" from Jun 17,
> 2016, leads to the following static checker warning:
>
>   drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c:5057 gfx_v7_0_get_cu_info()
>   error: buffer overflow 'cu_info->bitmap' 4 <= 4
>
> drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
>   5035  static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev)
>   5036  {
>   5037  int i, j, k, counter, active_cu_number = 0;
>   5038  u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0;
>   5039  struct amdgpu_cu_info *cu_info = >gfx.cu_info;
>   5040  unsigned disable_masks[4 * 2];
>   5041
>   5042  memset(cu_info, 0, sizeof(*cu_info));
>   5043
>   5044  amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2);
>   5045
>   5046  mutex_lock(>grbm_idx_mutex);
>   5047  for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
>   5048  for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
>   5049  mask = 1;
>   5050  ao_bitmap = 0;
>   5051  counter = 0;
>   5052  gfx_v7_0_select_se_sh(adev, i, j, 0x);
>   5053  if (i < 4 && j < 2)
> ^
> Is it really possible for i to be >= 4?

No, because for that to happen we would have to add support for hardware 
with > 4 shader engines. What's the idiomatic way to express this kind 
of assumption in the kernel? BUG_ON(adev->gfx.config.max_shader_engines 
 > 4)? Some other form of assert?

Nicolai

>
>   5054  gfx_v7_0_set_user_cu_inactive_bitmap(
>   5055  adev, disable_masks[i * 2 + 
> j]);
>   5056  bitmap = gfx_v7_0_get_cu_active_bitmap(adev);
>   5057  cu_info->bitmap[i][j] = bitmap;
> ^
> Because if so, then we are screwed here.
>
>   5058
>   5059  for (k = 0; k < 16; k ++) {
>   5060  if (bitmap & mask) {
>   5061  if (counter < 2)
>   5062  ao_bitmap |= mask;
>   5063  counter ++;
>   5064  }
>   5065  mask <<= 1;
>   5066  }
>   5067  active_cu_number += counter;
>   5068  ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
>   5069  }
>   5070  }
>   5071  gfx_v7_0_select_se_sh(adev, 0x, 0x, 
> 0x);
>   5072  mutex_unlock(>grbm_idx_mutex);
>   5073
>   5074  cu_info->number = active_cu_number;
>   5075  cu_info->ao_cu_mask = ao_cu_mask;
>   5076  }
>
> regards,
> dan carpenter
>


[PATCH 04/10] drm: make drm_vblank_{get,put}() static

2016-08-03 Thread Rodrigo Vivi
Oh, nevermind... I saw the places that depends on changes on other
legacy usage like drm_wait_on_vblank...  (not trivial on intel_crt)
and other cases...

So better to just go with the static for now.

Feel free to use:
Reviewed-by: Rodrigo Vivi 


On Wed, Aug 3, 2016 at 12:22 AM, Daniel Vetter  wrote:
> On Tue, Aug 02, 2016 at 11:30:21PM -0700, Rodrigo Vivi wrote:
>> I was going to remove the legacy get/put versions right now, but
>> decided to check if there were any pending patch in mailing lists and
>> found this.
>>
>> What about deleting the functions at all instead of having it internally?
>
> There's (very few) users left, but if you can convert them over to
> drm_crtc_ versions then sure, go ahead, it'd be great!
> -Daniel
>
>>
>>
>> On Tue, Jun 7, 2016 at 7:07 AM, Gustavo Padovan  
>> wrote:
>> > From: Gustavo Padovan 
>> >
>> > As they are not used anywhere outside drm_irq.c make them static.
>> >
>> > Signed-off-by: Gustavo Padovan 
>> > ---
>> >  drivers/gpu/drm/drm_irq.c | 10 ++
>> >  include/drm/drmP.h|  2 --
>> >  2 files changed, 2 insertions(+), 10 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
>> > index 38cc782..76e39c5 100644
>> > --- a/drivers/gpu/drm/drm_irq.c
>> > +++ b/drivers/gpu/drm/drm_irq.c
>> > @@ -1108,7 +1108,7 @@ static int drm_vblank_enable(struct drm_device *dev, 
>> > unsigned int pipe)
>> >   * Returns:
>> >   * Zero on success or a negative error code on failure.
>> >   */
>> > -int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>> > +static int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>> >  {
>> > struct drm_vblank_crtc *vblank = >vblank[pipe];
>> > unsigned long irqflags;
>> > @@ -1134,7 +1134,6 @@ int drm_vblank_get(struct drm_device *dev, unsigned 
>> > int pipe)
>> >
>> > return ret;
>> >  }
>> > -EXPORT_SYMBOL(drm_vblank_get);
>> >
>> >  /**
>> >   * drm_crtc_vblank_get - get a reference count on vblank events
>> > @@ -1143,8 +1142,6 @@ EXPORT_SYMBOL(drm_vblank_get);
>> >   * Acquire a reference count on vblank events to avoid having them 
>> > disabled
>> >   * while in use.
>> >   *
>> > - * This is the native kms version of drm_vblank_get().
>> > - *
>> >   * Returns:
>> >   * Zero on success or a negative error code on failure.
>> >   */
>> > @@ -1164,7 +1161,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_get);
>> >   *
>> >   * This is the legacy version of drm_crtc_vblank_put().
>> >   */
>> > -void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>> > +static void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>> >  {
>> > struct drm_vblank_crtc *vblank = >vblank[pipe];
>> >
>> > @@ -1185,7 +1182,6 @@ void drm_vblank_put(struct drm_device *dev, unsigned 
>> > int pipe)
>> >   jiffies + ((drm_vblank_offdelay * 
>> > HZ)/1000));
>> > }
>> >  }
>> > -EXPORT_SYMBOL(drm_vblank_put);
>> >
>> >  /**
>> >   * drm_crtc_vblank_put - give up ownership of vblank events
>> > @@ -1193,8 +1189,6 @@ EXPORT_SYMBOL(drm_vblank_put);
>> >   *
>> >   * Release ownership of a given vblank counter, turning off interrupts
>> >   * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
>> > - *
>> > - * This is the native kms version of drm_vblank_put().
>> >   */
>> >  void drm_crtc_vblank_put(struct drm_crtc *crtc)
>> >  {
>> > diff --git a/include/drm/drmP.h b/include/drm/drmP.h
>> > index 924b4fd..23f79a5 100644
>> > --- a/include/drm/drmP.h
>> > +++ b/include/drm/drmP.h
>> > @@ -975,8 +975,6 @@ extern void drm_crtc_arm_vblank_event(struct drm_crtc 
>> > *crtc,
>> >   struct drm_pending_vblank_event *e);
>> >  extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
>> >  extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
>> > -extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
>> > -extern void drm_vblank_put(struct drm_device *dev, unsigned int pipe);
>> >  extern int drm_crtc_vblank_get(struct drm_crtc *crtc);
>> >  extern void drm_crtc_vblank_put(struct drm_crtc *crtc);
>> >  extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int 
>> > pipe);
>> > --
>> > 2.5.5
>> >
>> > ___
>> > dri-devel mailing list
>> > dri-devel at lists.freedesktop.org
>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>>
>>
>> --
>> Rodrigo Vivi
>> Blog: http://blog.vivi.eng.br
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br


libdrm-armada repository

2016-08-03 Thread Joshua Clayton


On 08/02/2016 06:38 PM, Fabio Estevam wrote:
> Hi Joshua,
>
> On Tue, Aug 2, 2016 at 8:09 PM, Joshua Clayton  
> wrote:
>> Greetings Russell,
>> I'm publishing an etnaviv yocto layer on github.
> Cool! Could you please let us know when this layer becomes available?
>
> Thanks
Sure, Fabio.
It is available now.

https://github.com/d4ddi0/meta-etnaviv

Thus far tested only on imx6q-evi


[Bug 97166] lockup during gameplay of Batman series of games

2016-08-03 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=97166

--- Comment #7 from Vedran Miletić  ---
(In reply to farmboy0+freedesktop from comment #6)
> Yep , also locking up with normal wine.
> 
> To test just run the benchmark. It will lock up there and in the normal game.

How much hassle is to get Batman working? Is it more than wine Steam.exe,
Install Batman, Play? If not, I could try it tomorrow.

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


libdrm-armada repository

2016-08-03 Thread Joshua Clayton


On 08/02/2016 04:28 PM, Russell King wrote:
> On Tue, Aug 02, 2016 at 04:09:58PM -0700, Joshua Clayton wrote:
>> Greetings Russell,
>> I'm publishing an etnaviv yocto layer on github.
>> One of the components is libdrm-armada, which we get from
>> git://ftp.arm.linux.org.uk/~rmk/libdrm-armada.git
>>
>> I don't want to put an unwanted extra burden on your server.
>>
>> I notice there is also
>> http://git.arm.linux.org.uk/cgit/libdrm-armada.git
> git.arm and ftp.arm are both the same machine, which has recently been
> upgraded to something a tad more modern than the previous 13+ year old
> machine, so it should now be super-fast.  In addition, I've changed
> the DNS slightly.
>
> The preferred URLs are now:
>
>  git://git.armlinux.org.uk/~rmk/libdrm-armada.git
>
> for pulling and cloning from, and the cgit interface
>
>  http://git.armlinux.org.uk/cgit/libdrm-armada.git
>
> Thanks.
>
Thanks for the info.

I've update the url to  git://git.armlinux.org.uk/~rmk/libdrm-armada.git

as it is a download, rather than browser interface.



[PATCH] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-03 Thread Daniel Vetter
On Wed, Aug 03, 2016 at 10:43:21AM +0200, Daniel Vetter wrote:
> On Wed, Aug 03, 2016 at 04:13:45PM +0800, Mark Yao wrote:
> > [1.162571] Unable to handle kernel NULL pointer dereference at virtual 
> > address 0200
> > [1.165656] Modules linked in:
> > [1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
> > [1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 (Android) 
> > (DT)
> > [1.167153] Workqueue: events output_poll_execute
> > [1.168231] PC is at mutex_lock+0x14/0x44
> > [1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
> > [1.172192] [] mutex_lock+0x14/0x44
> > [1.172196] [] drm_fb_helper_hotplug_event+0x28/0xcc
> > [1.172201] [] 
> > rockchip_drm_output_poll_changed+0x14/0x1c
> > [1.172204] [] drm_kms_helper_hotplug_event+0x28/0x34
> > [1.172207] [] output_poll_execute+0x150/0x198
> > [1.172212] [] process_one_work+0x218/0x3dc
> > [1.172215] [] worker_thread+0x24c/0x374
> > [1.172217] [] kthread+0xdc/0xe4
> > [1.17] [] ret_from_fork+0x10/0x40
> > 
> > Signed-off-by: Mark Yao 
> 
> Erhm, how exactly did you manage to blow up in there? Without fbdev
> support enable drm_fb_helper_hotplug_event() does nothing at all.
> 
> The fbdev helper is designed such that you _don't_ have to check for NULL
> everywhere in the driver, that would be pretty bad code.

And indeed this issue seems preexisting, and was already attempt to fix in

commit 765c35bbd267e93eabe15a94534688ddaa0b9dc7
Author: Heiko Stübner 
Date:   Tue Jun 2 16:41:45 2015 +0200

drm/rockchip: only call drm_fb_helper_hotplug_event if fb_helper present

except that patch is complete nonsense - the added check is always true.
Oh and it's missing your s-o-b, which is not good at all.

The proper fix is to make delayed fbdev loading work correctly, Thierry
has patches for that on the mailing list. Not add even more hacks like the
above (and then slap a misleading subject onto your patch).
-Daniel

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/rockchip/rockchip_drm_drv.c   | 13 ++---
> >  drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  8 ++--
> >  drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  6 +++---
> >  drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 26 
> > +-
> >  4 files changed, 36 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
> > b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > index a822d49..1a4dad6 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > @@ -261,7 +261,10 @@ static void rockchip_drm_lastclose(struct drm_device 
> > *dev)
> >  {
> > struct rockchip_drm_private *priv = dev->dev_private;
> >  
> > -   drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev_helper);
> > +   if (!priv->fbdev)
> > +   return;
> > +
> > +   drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev->fbdev_helper);
> >  }
> >  
> >  static const struct file_operations rockchip_drm_driver_fops = {
> > @@ -310,8 +313,10 @@ void rockchip_drm_fb_suspend(struct drm_device *drm)
> >  {
> > struct rockchip_drm_private *priv = drm->dev_private;
> >  
> > +   if (!priv->fbdev)
> > +   return;
> > console_lock();
> > -   drm_fb_helper_set_suspend(>fbdev_helper, 1);
> > +   drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 1);
> > console_unlock();
> >  }
> >  
> > @@ -319,8 +324,10 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
> >  {
> > struct rockchip_drm_private *priv = drm->dev_private;
> >  
> > +   if (!priv->fbdev)
> > +   return;
> > console_lock();
> > -   drm_fb_helper_set_suspend(>fbdev_helper, 0);
> > +   drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 0);
> > console_unlock();
> >  }
> >  
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
> > b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> > index ea39329..c054fc2 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> > @@ -50,6 +50,11 @@ struct rockchip_crtc_state {
> >  #define to_rockchip_crtc_state(s) \
> > container_of(s, struct rockchip_crtc_state, base)
> >  
> > +struct rockchip_drm_fbdev {
> > +   struct drm_fb_helper fbdev_helper;
> > +   struct drm_gem_object *fbdev_bo;
> > +};
> > +
> >  /*
> >   * Rockchip drm private structure.
> >   *
> > @@ -57,8 +62,7 @@ struct rockchip_crtc_state {
> >   * @num_pipe: number of pipes for this device.
> >   */
> >  struct rockchip_drm_private {
> > -   struct drm_fb_helper fbdev_helper;
> > -   struct drm_gem_object *fbdev_bo;
> > +   struct rockchip_drm_fbdev *fbdev;
> > const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
> > struct drm_atomic_state *state;
> >  };
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
> > b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> > index 55c5273..fef6f8d 100644
> > --- 

[PATCH] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-03 Thread Daniel Vetter
On Wed, Aug 03, 2016 at 04:13:45PM +0800, Mark Yao wrote:
> [1.162571] Unable to handle kernel NULL pointer dereference at virtual 
> address 0200
> [1.165656] Modules linked in:
> [1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
> [1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 (Android) 
> (DT)
> [1.167153] Workqueue: events output_poll_execute
> [1.168231] PC is at mutex_lock+0x14/0x44
> [1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
> [1.172192] [] mutex_lock+0x14/0x44
> [1.172196] [] drm_fb_helper_hotplug_event+0x28/0xcc
> [1.172201] [] rockchip_drm_output_poll_changed+0x14/0x1c
> [1.172204] [] drm_kms_helper_hotplug_event+0x28/0x34
> [1.172207] [] output_poll_execute+0x150/0x198
> [1.172212] [] process_one_work+0x218/0x3dc
> [1.172215] [] worker_thread+0x24c/0x374
> [1.172217] [] kthread+0xdc/0xe4
> [1.17] [] ret_from_fork+0x10/0x40
> 
> Signed-off-by: Mark Yao 

Erhm, how exactly did you manage to blow up in there? Without fbdev
support enable drm_fb_helper_hotplug_event() does nothing at all.

The fbdev helper is designed such that you _don't_ have to check for NULL
everywhere in the driver, that would be pretty bad code.
-Daniel

> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.c   | 13 ++---
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  8 ++--
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  6 +++---
>  drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 26 +-
>  4 files changed, 36 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index a822d49..1a4dad6 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -261,7 +261,10 @@ static void rockchip_drm_lastclose(struct drm_device 
> *dev)
>  {
>   struct rockchip_drm_private *priv = dev->dev_private;
>  
> - drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev_helper);
> + if (!priv->fbdev)
> + return;
> +
> + drm_fb_helper_restore_fbdev_mode_unlocked(>fbdev->fbdev_helper);
>  }
>  
>  static const struct file_operations rockchip_drm_driver_fops = {
> @@ -310,8 +313,10 @@ void rockchip_drm_fb_suspend(struct drm_device *drm)
>  {
>   struct rockchip_drm_private *priv = drm->dev_private;
>  
> + if (!priv->fbdev)
> + return;
>   console_lock();
> - drm_fb_helper_set_suspend(>fbdev_helper, 1);
> + drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 1);
>   console_unlock();
>  }
>  
> @@ -319,8 +324,10 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
>  {
>   struct rockchip_drm_private *priv = drm->dev_private;
>  
> + if (!priv->fbdev)
> + return;
>   console_lock();
> - drm_fb_helper_set_suspend(>fbdev_helper, 0);
> + drm_fb_helper_set_suspend(>fbdev->fbdev_helper, 0);
>   console_unlock();
>  }
>  
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
> b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> index ea39329..c054fc2 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> @@ -50,6 +50,11 @@ struct rockchip_crtc_state {
>  #define to_rockchip_crtc_state(s) \
>   container_of(s, struct rockchip_crtc_state, base)
>  
> +struct rockchip_drm_fbdev {
> + struct drm_fb_helper fbdev_helper;
> + struct drm_gem_object *fbdev_bo;
> +};
> +
>  /*
>   * Rockchip drm private structure.
>   *
> @@ -57,8 +62,7 @@ struct rockchip_crtc_state {
>   * @num_pipe: number of pipes for this device.
>   */
>  struct rockchip_drm_private {
> - struct drm_fb_helper fbdev_helper;
> - struct drm_gem_object *fbdev_bo;
> + struct rockchip_drm_fbdev *fbdev;
>   const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
>   struct drm_atomic_state *state;
>  };
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 55c5273..fef6f8d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -156,10 +156,10 @@ err_gem_object_unreference:
>  static void rockchip_drm_output_poll_changed(struct drm_device *dev)
>  {
>   struct rockchip_drm_private *private = dev->dev_private;
> - struct drm_fb_helper *fb_helper = >fbdev_helper;
> + struct rockchip_drm_fbdev *fbdev = private->fbdev;
>  
> - if (fb_helper)
> - drm_fb_helper_hotplug_event(fb_helper);
> + if (fbdev)
> + drm_fb_helper_hotplug_event(>fbdev_helper);
>  }
>  
>  static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc)
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
> index 207e01d..cc5781a 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
> +++ 

[PATCH v3 2/3] drm: Add API for capturing frame CRCs

2016-08-03 Thread Ville Syrjälä
On Fri, Jul 22, 2016 at 04:10:44PM +0200, Tomeu Vizoso wrote:
> Adds files and directories to debugfs for controlling and reading frame
> CRCs, per CRTC:
> 
> dri/0/crtc-0/crc
> dri/0/crtc-0/crc/control
> dri/0/crtc-0/crc/data
> 
> Drivers can implement the set_crc_source callback() in drm_crtc_funcs to
> start and stop generating frame CRCs and can add entries to the output
> by calling drm_crtc_add_crc_entry.
> 
> v2:
> - Lots of good fixes suggested by Thierry.
> - Added documentation.
> - Changed the debugfs layout.
> - Moved to allocate the entries circular queue once when frame
>   generation gets enabled for the first time.
> v3:
> - Use the control file just to select the source, and start and stop
>   capture when the data file is opened and closed, respectively.
> - Make variable the number of CRC values per entry, per source.
> - Allocate entries queue each time we start capturing as now there
>   isn't a fixed number of CRC values per entry.
> - Store the frame counter in the data file as a 8-digit hex number.
> - For sources that cannot provide useful frame numbers, place
>    in the frame field.
> 
> Signed-off-by: Tomeu Vizoso 
> ---
> 
>  Documentation/gpu/drm-uapi.rst|   6 +
>  drivers/gpu/drm/Makefile  |   3 +-
>  drivers/gpu/drm/drm_crtc.c|  12 ++
>  drivers/gpu/drm/drm_debugfs.c |  36 +++-
>  drivers/gpu/drm/drm_debugfs_crc.c | 370 
> ++
>  drivers/gpu/drm/drm_drv.c |   9 +
>  drivers/gpu/drm/drm_internal.h|  10 ++
>  include/drm/drmP.h|   5 +
>  include/drm/drm_crtc.h|  41 +
>  include/drm/drm_debugfs_crc.h |  74 
>  10 files changed, 564 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_debugfs_crc.c
>  create mode 100644 include/drm/drm_debugfs_crc.h
> 
> diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
> index 536bf3eaadd4..33f778696ccd 100644
> --- a/Documentation/gpu/drm-uapi.rst
> +++ b/Documentation/gpu/drm-uapi.rst
> @@ -109,3 +109,9 @@ interfaces. Especially since all hardware-acceleration 
> interfaces to
>  userspace are driver specific for efficiency and other reasons these
>  interfaces can be rather substantial. Hence every driver has its own
>  chapter.
> +
> +Testing and validation
> +==
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
> +   :doc: CRC ABI
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index e3dba6f44a79..b53b5aaaeb4d 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -12,7 +12,8 @@ drm-y   :=  drm_auth.o drm_bufs.o drm_cache.o \
>   drm_info.o drm_debugfs.o drm_encoder_slave.o \
>   drm_trace_points.o drm_global.o drm_prime.o \
>   drm_rect.o drm_vma_manager.o drm_flip_work.o \
> - drm_modeset_lock.o drm_atomic.o drm_bridge.o
> + drm_modeset_lock.o drm_atomic.o drm_bridge.o \
> + drm_debugfs_crc.o
>  
>  drm-$(CONFIG_COMPAT) += drm_ioc32.o
>  drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 10b73f68c023..087345af96e7 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -40,6 +40,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "drm_crtc_internal.h"
>  #include "drm_internal.h"
> @@ -738,6 +739,12 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
> struct drm_crtc *crtc,
>   if (cursor)
>   cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
>  
> +#ifdef CONFIG_DEBUG_FS
> + spin_lock_init(>crc.lock);
> + init_waitqueue_head(>crc.wq);
> + crtc->crc.source = kstrdup("auto", GFP_KERNEL);
> +#endif
> +
>   if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>   drm_object_attach_property(>base, config->prop_active, 0);
>   drm_object_attach_property(>base, config->prop_mode_id, 
> 0);
> @@ -764,6 +771,11 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
>* the indices on the drm_crtc after us in the crtc_list.
>*/
>  
> +#ifdef CONFIG_DEBUG_FS
> + drm_debugfs_crtc_remove(crtc);
> + kfree(crtc->crc.source);
> +#endif
> +
>   kfree(crtc->gamma_store);
>   crtc->gamma_store = NULL;
>  
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index fa10cef2ba37..73530cbf1316 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -415,5 +415,39 @@ void drm_debugfs_connector_remove(struct drm_connector 
> *connector)
>   connector->debugfs_entry = NULL;
>  }
>  
> -#endif /* CONFIG_DEBUG_FS */
> +int drm_debugfs_crtc_add(struct drm_crtc *crtc)
> +{
> + struct drm_minor *minor = crtc->dev->primary;
> + struct dentry *root;
> + char *name;
> +
> + name = kasprintf(GFP_KERNEL, "crtc-%d", 

[PATCH v3 3/3] drm/i915: Use new CRC debugfs API

2016-08-03 Thread Daniel Vetter
On Fri, Jul 22, 2016 at 04:10:45PM +0200, Tomeu Vizoso wrote:
> The core provides now an ABI to userspace for generation of frame CRCs,
> so implement the ->set_crc_source() callback and reuse as much code as
> possible with the previous ABI implementation.
> 
> v2:
> - Leave the legacy implementation in place as the ABI implementation
>   in the core is incompatible with it.
> v3:
> - Use the "cooked" vblank counter so we have a whole 32 bits.

This should be a separate patch.

> - Make sure we don't mess with the state of the legacy CRC capture
>   ABI implementation.

Hm, as for keeping the legacy debugfs interface alive I think it'd be nice
if we can implement the old one internal with the new one. I.e. call the
set_crc_sourc function (after minimal parsing), use the same ringbuffer
and rework the read function to use the same ringbuffer. Or maybe that's
not worth it since the plan is to nuke all that code anyway after a few
months?
-Daniel

> 
> Signed-off-by: Tomeu Vizoso 

> ---
> 
>  drivers/gpu/drm/i915/i915_irq.c   |  69 ---
>  drivers/gpu/drm/i915/intel_display.c  |   1 +
>  drivers/gpu/drm/i915/intel_drv.h  |   2 +
>  drivers/gpu/drm/i915/intel_pipe_crc.c | 124 
> --
>  4 files changed, 133 insertions(+), 63 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index b77d808b71cd..f2726171f7c8 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1492,41 +1492,58 @@ static void display_pipe_crc_irq_handler(struct 
> drm_i915_private *dev_priv,
>  {
>   struct intel_pipe_crc *pipe_crc = _priv->pipe_crc[pipe];
>   struct intel_pipe_crc_entry *entry;
> - int head, tail;
> + struct drm_crtc *crtc = intel_get_crtc_for_pipe(_priv->drm, pipe);
> + struct drm_driver *driver = dev_priv->drm.driver;
> + uint32_t crcs[5];
> + int head, tail, ret;
>  
>   spin_lock(_crc->lock);
> + if (pipe_crc->source) {
> + if (!pipe_crc->entries) {
> + spin_unlock(_crc->lock);
> + DRM_DEBUG_KMS("spurious interrupt\n");
> + return;
> + }
>  
> - if (!pipe_crc->entries) {
> - spin_unlock(_crc->lock);
> - DRM_DEBUG_KMS("spurious interrupt\n");
> - return;
> - }
> -
> - head = pipe_crc->head;
> - tail = pipe_crc->tail;
> + head = pipe_crc->head;
> + tail = pipe_crc->tail;
>  
> - if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) {
> - spin_unlock(_crc->lock);
> - DRM_ERROR("CRC buffer overflowing\n");
> - return;
> - }
> + if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) {
> + spin_unlock(_crc->lock);
> + DRM_ERROR("CRC buffer overflowing\n");
> + return;
> + }
>  
> - entry = _crc->entries[head];
> + entry = _crc->entries[head];
>  
> - entry->frame = dev_priv->drm.driver->get_vblank_counter(_priv->drm,
> -  pipe);
> - entry->crc[0] = crc0;
> - entry->crc[1] = crc1;
> - entry->crc[2] = crc2;
> - entry->crc[3] = crc3;
> - entry->crc[4] = crc4;
> + entry->frame = driver->get_vblank_counter(_priv->drm, pipe);
> + entry->crc[0] = crc0;
> + entry->crc[1] = crc1;
> + entry->crc[2] = crc2;
> + entry->crc[3] = crc3;
> + entry->crc[4] = crc4;
>  
> - head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
> - pipe_crc->head = head;
> + head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
> + pipe_crc->head = head;
>  
> - spin_unlock(_crc->lock);
> + spin_unlock(_crc->lock);
>  
> - wake_up_interruptible(_crc->wq);
> + wake_up_interruptible(_crc->wq);
> + } else {
> + spin_unlock(_crc->lock);
> + spin_lock(>crc.lock);
> + crcs[0] = crc0;
> + crcs[1] = crc1;
> + crcs[2] = crc2;
> + crcs[3] = crc3;
> + crcs[4] = crc4;
> + ret = drm_crtc_add_crc_entry(crtc, true,
> +  drm_accurate_vblank_count(crtc),
> +  crcs);
> + spin_unlock(>crc.lock);
> + if (!ret)
> + wake_up_interruptible(>crc.wq);
> + }
>  }
>  #else
>  static inline void
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 111b350d1d7e..d91a2f779fb1 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14019,6 +14019,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = 
> {
>   .page_flip = intel_crtc_page_flip,
>   

[PATCH v3 2/3] drm: Add API for capturing frame CRCs

2016-08-03 Thread Daniel Vetter
On Wed, Aug 03, 2016 at 10:06:38AM +0300, Ville Syrjälä wrote:
> On Fri, Jul 22, 2016 at 04:10:44PM +0200, Tomeu Vizoso wrote:
> > Adds files and directories to debugfs for controlling and reading frame
> > CRCs, per CRTC:
> > 
> > dri/0/crtc-0/crc
> > dri/0/crtc-0/crc/control
> > dri/0/crtc-0/crc/data
> > 
> > Drivers can implement the set_crc_source callback() in drm_crtc_funcs to
> > start and stop generating frame CRCs and can add entries to the output
> > by calling drm_crtc_add_crc_entry.
> > 
> > v2:
> > - Lots of good fixes suggested by Thierry.
> > - Added documentation.
> > - Changed the debugfs layout.
> > - Moved to allocate the entries circular queue once when frame
> >   generation gets enabled for the first time.
> > v3:
> > - Use the control file just to select the source, and start and stop
> >   capture when the data file is opened and closed, respectively.
> > - Make variable the number of CRC values per entry, per source.
> > - Allocate entries queue each time we start capturing as now there
> >   isn't a fixed number of CRC values per entry.
> > - Store the frame counter in the data file as a 8-digit hex number.
> > - For sources that cannot provide useful frame numbers, place
> >    in the frame field.
> > 
> > Signed-off-by: Tomeu Vizoso 
> > ---
> > 
> >  Documentation/gpu/drm-uapi.rst|   6 +
> >  drivers/gpu/drm/Makefile  |   3 +-
> >  drivers/gpu/drm/drm_crtc.c|  12 ++
> >  drivers/gpu/drm/drm_debugfs.c |  36 +++-
> >  drivers/gpu/drm/drm_debugfs_crc.c | 370 
> > ++
> >  drivers/gpu/drm/drm_drv.c |   9 +
> >  drivers/gpu/drm/drm_internal.h|  10 ++
> >  include/drm/drmP.h|   5 +
> >  include/drm/drm_crtc.h|  41 +
> >  include/drm/drm_debugfs_crc.h |  74 
> >  10 files changed, 564 insertions(+), 2 deletions(-)
> >  create mode 100644 drivers/gpu/drm/drm_debugfs_crc.c
> >  create mode 100644 include/drm/drm_debugfs_crc.h
> > 
> > diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
> > index 536bf3eaadd4..33f778696ccd 100644
> > --- a/Documentation/gpu/drm-uapi.rst
> > +++ b/Documentation/gpu/drm-uapi.rst
> > @@ -109,3 +109,9 @@ interfaces. Especially since all hardware-acceleration 
> > interfaces to
> >  userspace are driver specific for efficiency and other reasons these
> >  interfaces can be rather substantial. Hence every driver has its own
> >  chapter.
> > +
> > +Testing and validation
> > +==
> > +
> > +.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
> > +   :doc: CRC ABI
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index e3dba6f44a79..b53b5aaaeb4d 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -12,7 +12,8 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
> > drm_info.o drm_debugfs.o drm_encoder_slave.o \
> > drm_trace_points.o drm_global.o drm_prime.o \
> > drm_rect.o drm_vma_manager.o drm_flip_work.o \
> > -   drm_modeset_lock.o drm_atomic.o drm_bridge.o
> > +   drm_modeset_lock.o drm_atomic.o drm_bridge.o \
> > +   drm_debugfs_crc.o
> >  
> >  drm-$(CONFIG_COMPAT) += drm_ioc32.o
> >  drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
> > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> > index 10b73f68c023..087345af96e7 100644
> > --- a/drivers/gpu/drm/drm_crtc.c
> > +++ b/drivers/gpu/drm/drm_crtc.c
> > @@ -40,6 +40,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #include "drm_crtc_internal.h"
> >  #include "drm_internal.h"
> > @@ -738,6 +739,12 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
> > struct drm_crtc *crtc,
> > if (cursor)
> > cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
> >  
> > +#ifdef CONFIG_DEBUG_FS
> > +   spin_lock_init(>crc.lock);
> > +   init_waitqueue_head(>crc.wq);
> > +   crtc->crc.source = kstrdup("auto", GFP_KERNEL);
> > +#endif
> > +
> > if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> > drm_object_attach_property(>base, config->prop_active, 0);
> > drm_object_attach_property(>base, config->prop_mode_id, 
> > 0);
> > @@ -764,6 +771,11 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
> >  * the indices on the drm_crtc after us in the crtc_list.
> >  */
> >  
> > +#ifdef CONFIG_DEBUG_FS
> > +   drm_debugfs_crtc_remove(crtc);
> > +   kfree(crtc->crc.source);
> > +#endif
> > +
> > kfree(crtc->gamma_store);
> > crtc->gamma_store = NULL;
> >  
> > diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> > index fa10cef2ba37..73530cbf1316 100644
> > --- a/drivers/gpu/drm/drm_debugfs.c
> > +++ b/drivers/gpu/drm/drm_debugfs.c
> > @@ -415,5 +415,39 @@ void drm_debugfs_connector_remove(struct drm_connector 
> > *connector)
> > 

[PATCH] drm: Avoid printing negative values for unsigned variables.

2016-08-03 Thread Rodrigo Vivi
It was really strange to see negative vblank seqs on debug
messages. It is rare to have that big number, but when it
happens it is confusing and misleading.

Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/drm_irq.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 77f357b..01a5079 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1295,7 +1295,7 @@ void drm_vblank_off(struct drm_device *dev, unsigned int 
pipe)
if (e->pipe != pipe)
continue;
DRM_DEBUG("Sending premature vblank event on disable: "
- "wanted %d, current %d\n",
+ "wanted %u, current %u\n",
  e->event.sequence, seq);
list_del(>base.link);
drm_vblank_put(dev, pipe);
@@ -1585,7 +1585,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
unsigned int pipe,

seq = drm_vblank_count_and_time(dev, pipe, );

-   DRM_DEBUG("event on vblank count %d, current %d, crtc %u\n",
+   DRM_DEBUG("event on vblank count %u, current %u, crtc %u\n",
  vblwait->request.sequence, seq, pipe);

trace_drm_vblank_event_queued(current->pid, pipe,
@@ -1693,7 +1693,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
return drm_queue_vblank_event(dev, pipe, vblwait, file_priv);
}

-   DRM_DEBUG("waiting on vblank count %d, crtc %u\n",
+   DRM_DEBUG("waiting on vblank count %u, crtc %u\n",
  vblwait->request.sequence, pipe);
DRM_WAIT_ON(ret, vblank->queue, 3 * HZ,
(((drm_vblank_count(dev, pipe) -
@@ -1708,7 +1708,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
vblwait->reply.tval_sec = now.tv_sec;
vblwait->reply.tval_usec = now.tv_usec;

-   DRM_DEBUG("returning %d to client\n",
+   DRM_DEBUG("returning %u to client\n",
  vblwait->reply.sequence);
} else {
DRM_DEBUG("vblank wait interrupted by signal\n");
@@ -1735,7 +1735,7 @@ static void drm_handle_vblank_events(struct drm_device 
*dev, unsigned int pipe)
if ((seq - e->event.sequence) > (1<<23))
continue;

-   DRM_DEBUG("vblank event on %d, current %d\n",
+   DRM_DEBUG("vblank event on %u, current %u\n",
  e->event.sequence, seq);

list_del(>base.link);
-- 
2.5.5



[PATCH v6 1/6] drm/i915/skl: Add support for the SAGV, fix underrun hangs

2016-08-03 Thread Maarten Lankhorst
Op 03-08-16 om 00:37 schreef Lyude:
> Since the watermark calculations for Skylake are still broken, we're apt
> to hitting underruns very easily under multi-monitor configurations.
> While it would be lovely if this was fixed, it's not. Another problem
> that's been coming from this however, is the mysterious issue of
> underruns causing full system hangs. An easy way to reproduce this with
> a skylake system:
>
> - Get a laptop with a skylake GPU, and hook up two external monitors to
>   it
> - Move the cursor from the built-in LCD to one of the external displays
>   as quickly as you can
> - You'll get a few pipe underruns, and eventually the entire system will
>   just freeze.
>
> After doing a lot of investigation and reading through the bspec, I
> found the existence of the SAGV, which is responsible for adjusting the
> system agent voltage and clock frequencies depending on how much power
> we need. According to the bspec:
>
> "The display engine access to system memory is blocked during the
>  adjustment time. SAGV defaults to enabled. Software must use the
>  GT-driver pcode mailbox to disable SAGV when the display engine is not
>  able to tolerate the blocking time."
>
> The rest of the bspec goes on to explain that software can simply leave
> the SAGV enabled, and disable it when we use interlaced pipes/have more
> then one pipe active.
>
> Sure enough, with this patchset the system hangs resulting from pipe
> underruns on Skylake have completely vanished on my T460s. Additionally,
> the bspec mentions turning off the SAGV   with more then one pipe enabled
> as a workaround for display underruns. While this patch doesn't entirely
> fix that, it looks like it does improve the situation a little bit so
> it's likely this is going to be required to make watermarks on Skylake
> fully functional.
>
> Changes since v5:
>  - Don't use is_power_of_2. Makes things confusing
>  - Don't use the old state to figure out whether or not to
>enable/disable the sagv, use the new one
>  - Split the loop in skl_disable_sagv into it's own function
>  - Move skl_sagv_enable/disable() calls into intel_atomic_commit_tail()
> Changes since v4:
>  - Use is_power_of_2 against active_crtcs to check whether we have > 1
>pipe enabled
>  - Fix skl_sagv_get_hw_state(): (temp & 0x1) indicates disabled, 0x0
>enabled
>  - Call skl_sagv_enable/disable() from pre/post-plane updates
> Changes since v3:
>  - Use time_before() to compare timeout to jiffies
> Changes since v2:
>  - Really apply minor style nitpicks to patch this time
> Changes since v1:
>  - Added comments about this probably being one of the requirements to
>fixing Skylake's watermark issues
>  - Minor style nitpicks from Matt Roper
>  - Disable these functions on Broxton, since it doesn't have an SAGV
>
> Reviewed-by: Matt Roper 
> Signed-off-by: Lyude 
> Cc: Daniel Vetter 
> Cc: Ville Syrjälä 
> Cc: stable at vger.kernel.org
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |   2 +
>  drivers/gpu/drm/i915/i915_reg.h  |   5 ++
>  drivers/gpu/drm/i915/intel_display.c |  11 
>  drivers/gpu/drm/i915/intel_drv.h |   2 +
>  drivers/gpu/drm/i915/intel_pm.c  | 112 
> +++
>  5 files changed, 132 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 65ada5d..87018d3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1962,6 +1962,8 @@ struct drm_i915_private {
>   struct i915_suspend_saved_registers regfile;
>   struct vlv_s0ix_state vlv_s0ix_state;
>  
> + bool skl_sagv_enabled;
> +
>   struct {
>   /*
>* Raw watermark latency values:
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 2f93d4a..5fb1c63 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7170,6 +7170,11 @@ enum {
>  #define   HSW_PCODE_DE_WRITE_FREQ_REQ0x17
>  #define   DISPLAY_IPS_CONTROL0x19
>  #defineHSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL  0x1A
> +#define   GEN9_PCODE_SAGV_CONTROL0x21
> +#define GEN9_SAGV_DISABLE0x0
> +#define GEN9_SAGV_LOW_FREQ   0x1
> +#define GEN9_SAGV_HIGH_FREQ  0x2
> +#define GEN9_SAGV_DYNAMIC_FREQ  0x3
>  #define GEN6_PCODE_DATA  _MMIO(0x138128)
>  #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
>  #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT   16
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index a8e8cc8..001c885 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13692,6 +13692,14 @@ static void intel_atomic_commit_tail(struct 
> drm_atomic_state *state)
>intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco))
>   

[PATCH v7] drm/i915/skl: Add support for the SAGV, fix underrun hangs

2016-08-03 Thread Lyude
Since the watermark calculations for Skylake are still broken, we're apt
to hitting underruns very easily under multi-monitor configurations.
While it would be lovely if this was fixed, it's not. Another problem
that's been coming from this however, is the mysterious issue of
underruns causing full system hangs. An easy way to reproduce this with
a skylake system:

- Get a laptop with a skylake GPU, and hook up two external monitors to
  it
- Move the cursor from the built-in LCD to one of the external displays
  as quickly as you can
- You'll get a few pipe underruns, and eventually the entire system will
  just freeze.

After doing a lot of investigation and reading through the bspec, I
found the existence of the SAGV, which is responsible for adjusting the
system agent voltage and clock frequencies depending on how much power
we need. According to the bspec:

"The display engine access to system memory is blocked during the
 adjustment time. SAGV defaults to enabled. Software must use the
 GT-driver pcode mailbox to disable SAGV when the display engine is not
 able to tolerate the blocking time."

The rest of the bspec goes on to explain that software can simply leave
the SAGV enabled, and disable it when we use interlaced pipes/have more
then one pipe active.

Sure enough, with this patchset the system hangs resulting from pipe
underruns on Skylake have completely vanished on my T460s. Additionally,
the bspec mentions turning off the SAGV with more then one pipe enabled
as a workaround for display underruns. While this patch doesn't entirely
fix that, it looks like it does improve the situation a little bit so
it's likely this is going to be required to make watermarks on Skylake
fully functional.

Changes since v6:
 - Protect skl_enable_sagv() with intel_state->modeset conditional in
   intel_atomic_commit_tail()
Changes since v5:
 - Don't use is_power_of_2. Makes things confusing
 - Don't use the old state to figure out whether or not to
   enable/disable the sagv, use the new one
 - Split the loop in skl_disable_sagv into it's own function
 - Move skl_sagv_enable/disable() calls into intel_atomic_commit_tail()
Changes since v4:
 - Use is_power_of_2 against active_crtcs to check whether we have > 1
   pipe enabled
 - Fix skl_sagv_get_hw_state(): (temp & 0x1) indicates disabled, 0x0
   enabled
 - Call skl_sagv_enable/disable() from pre/post-plane updates
Changes since v3:
 - Use time_before() to compare timeout to jiffies
Changes since v2:
 - Really apply minor style nitpicks to patch this time
Changes since v1:
 - Added comments about this probably being one of the requirements to
   fixing Skylake's watermark issues
 - Minor style nitpicks from Matt Roper
 - Disable these functions on Broxton, since it doesn't have an SAGV

Reviewed-by: Matt Roper 
Signed-off-by: Lyude 
Cc: Daniel Vetter 
Cc: Ville Syrjälä 
Cc: stable at vger.kernel.org

fixup! drm/i915/skl: Add support for the SAGV, fix underrun hangs
---
 drivers/gpu/drm/i915/i915_drv.h  |   2 +
 drivers/gpu/drm/i915/i915_reg.h  |   5 ++
 drivers/gpu/drm/i915/intel_display.c |  11 
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_pm.c  | 112 +++
 5 files changed, 132 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 65ada5d..87018d3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1962,6 +1962,8 @@ struct drm_i915_private {
struct i915_suspend_saved_registers regfile;
struct vlv_s0ix_state vlv_s0ix_state;

+   bool skl_sagv_enabled;
+
struct {
/*
 * Raw watermark latency values:
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f93d4a..5fb1c63 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7170,6 +7170,11 @@ enum {
 #define   HSW_PCODE_DE_WRITE_FREQ_REQ  0x17
 #define   DISPLAY_IPS_CONTROL  0x19
 #define  HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL  0x1A
+#define   GEN9_PCODE_SAGV_CONTROL  0x21
+#define GEN9_SAGV_DISABLE  0x0
+#define GEN9_SAGV_LOW_FREQ 0x1
+#define GEN9_SAGV_HIGH_FREQ0x2
+#define GEN9_SAGV_DYNAMIC_FREQ  0x3
 #define GEN6_PCODE_DATA_MMIO(0x138128)
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT   8
 #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index a8e8cc8..f4caf4c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13692,6 +13692,14 @@ static void intel_atomic_commit_tail(struct 
drm_atomic_state *state)
 intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco))
dev_priv->display.modeset_commit_cdclk(state);

[Bug 94249] libdrm_amdgpu: Crash when built with clang

2016-08-03 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=94249

Michel Dänzer  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|NEW |RESOLVED

--- Comment #16 from Michel Dänzer  ---
Should be fixed with

commit b214b05ccd433c484a6a65e491a1a51b19e4811d
Author: Rob Clark 
Date:   Tue Aug 2 16:16:02 2016 -0400

list: fix an issue with android build using clang

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


[PATCH 10/10] drm/i915: Account for sink max TMDS clock when checking the port clock

2016-08-03 Thread ville.syrj...@linux.intel.com
From: Ville Syrjälä 

It's perfectly legal for the sink to support 12bpc only for
some lower resolution modes, while the higher resolution modes
can only be used with 8bpc. So let's take the sink's max TMDS clock
into account before we go and decide that a particular mode can
be used with 12bpc.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_hdmi.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 4df9f384910c..8b013301cf11 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1204,10 +1204,17 @@ static int hdmi_port_clock_limit(struct intel_hdmi 
*hdmi,
int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev));

if (respect_downstream_limits) {
+   struct intel_connector *connector = hdmi->attached_connector;
+   const struct drm_display_info *info = 
>base.display_info;
+
if (hdmi->dp_dual_mode.max_tmds_clock)
max_tmds_clock = min(max_tmds_clock,
 hdmi->dp_dual_mode.max_tmds_clock);
-   if (!hdmi->has_hdmi_sink)
+
+   if (info->max_tmds_clock)
+   max_tmds_clock = min(max_tmds_clock,
+info->max_tmds_clock);
+   else if (!hdmi->has_hdmi_sink)
max_tmds_clock = min(max_tmds_clock, 165000);
}

-- 
2.7.4



[PATCH 09/10] drm/i915: Replace a bunch of connector->base.display_info with a local variable

2016-08-03 Thread ville.syrj...@linux.intel.com
From: Ville Syrjälä 

Reduce the eyesore with a local variable.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_display.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index a8e8cc8dfae9..b9cdf9060da6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12090,22 +12090,22 @@ static void
 connected_sink_compute_bpp(struct intel_connector *connector,
   struct intel_crtc_state *pipe_config)
 {
+   const struct drm_display_info *info = >base.display_info;
int bpp = pipe_config->pipe_bpp;

DRM_DEBUG_KMS("[CONNECTOR:%d:%s] checking for sink bpp constrains\n",
-   connector->base.base.id,
-   connector->base.name);
+ connector->base.base.id,
+ connector->base.name);

/* Don't use an invalid EDID bpc value */
-   if (connector->base.display_info.bpc &&
-   connector->base.display_info.bpc * 3 < bpp) {
+   if (info->bpc != 0 && info->bpc * 3 < bpp) {
DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported 
max of %d\n",
- bpp, connector->base.display_info.bpc*3);
-   pipe_config->pipe_bpp = connector->base.display_info.bpc*3;
+ bpp, info->bpc * 3);
+   pipe_config->pipe_bpp = info->bpc * 3;
}

/* Clamp bpp to default limit on screens without EDID 1.4 */
-   if (connector->base.display_info.bpc == 0) {
+   if (info->bpc == 0) {
int type = connector->base.connector_type;
int clamp_bpp = 24;

-- 
2.7.4



[PATCH 08/10] drm/edid: Move dvi_dual/max_tmds_clock parsing out from drm_edid_to_eld()

2016-08-03 Thread ville.syrj...@linux.intel.com
From: Ville Syrjälä 

drm_edid_to_eld() is just mean to cook up the ELD for the audio driver,
so having it parse non-audio related stuff seems just wrong, and
potentially could lead to that information not being even filled out
if the function doesn't even get called. Let's move that stuff to the
place where we parse the color formats and whatnot from the CEA ext
block.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_edid.c | 64 +-
 1 file changed, 35 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 452e8c51a729..3cf8e44e040d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3248,17 +3248,12 @@ static void fixup_detailed_cea_mode_clock(struct 
drm_display_mode *mode)
 }

 static void
-parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db)
+drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db)
 {
-   struct drm_display_info *info = >display_info;
u8 len = cea_db_payload_len(db);

-   if (len >= 6) {
+   if (len >= 6)
connector->eld[5] |= (db[6] >> 7) << 1;  /* Supports_AI */
-   info->dvi_dual = db[6] & 1;
-   }
-   if (len >= 7)
-   info->max_tmds_clock = db[7] * 5000;
if (len >= 8) {
connector->latency_present[0] = db[8] >> 7;
connector->latency_present[1] = (db[8] >> 6) & 1;
@@ -3272,19 +3267,15 @@ parse_hdmi_vsdb(struct drm_connector *connector, const 
u8 *db)
if (len >= 12)
connector->audio_latency[1] = db[12];

-   DRM_DEBUG_KMS("HDMI: DVI dual %d, "
-   "max TMDS clock %d, "
-   "latency present %d %d, "
-   "video latency %d %d, "
-   "audio latency %d %d\n",
-   info->dvi_dual,
-   info->max_tmds_clock,
- (int) connector->latency_present[0],
- (int) connector->latency_present[1],
-   connector->video_latency[0],
-   connector->video_latency[1],
-   connector->audio_latency[0],
-   connector->audio_latency[1]);
+   DRM_DEBUG_KMS("HDMI: latency present %d %d, "
+ "video latency %d %d, "
+ "audio latency %d %d\n",
+ connector->latency_present[0],
+ connector->latency_present[1],
+ connector->video_latency[0],
+ connector->video_latency[1],
+ connector->audio_latency[0],
+ connector->audio_latency[1]);
 }

 static void
@@ -3345,7 +3336,6 @@ EXPORT_SYMBOL(drm_edid_get_monitor_name);
  */
 void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 {
-   struct drm_display_info *info = >display_info;
uint8_t *eld = connector->eld;
u8 *cea;
u8 *db;
@@ -3362,9 +3352,6 @@ void drm_edid_to_eld(struct drm_connector *connector, 
struct edid *edid)
connector->video_latency[1] = 0;
connector->audio_latency[1] = 0;

-   info->max_tmds_clock = 0;
-   info->dvi_dual = false;
-
cea = drm_find_cea_extension(edid);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
@@ -3414,7 +3401,7 @@ void drm_edid_to_eld(struct drm_connector *connector, 
struct edid *edid)
case VENDOR_BLOCK:
/* HDMI Vendor-Specific Data Block */
if (cea_db_is_hdmi_vsdb(db))
-   parse_hdmi_vsdb(connector, db);
+   drm_parse_hdmi_vsdb_audio(connector, 
db);
break;
default:
break;
@@ -3795,6 +3782,25 @@ static void drm_parse_hdmi_deep_color_info(struct 
drm_connector *connector,
}
 }

+static void
+drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
+{
+   struct drm_display_info *info = >display_info;
+   u8 len = cea_db_payload_len(db);
+
+   if (len >= 6)
+   info->dvi_dual = db[6] & 1;
+   if (len >= 7)
+   info->max_tmds_clock = db[7] * 5000;
+
+   DRM_DEBUG_KMS("HDMI: DVI dual %d, "
+ "max TMDS clock %d kHz\n",
+ info->dvi_dual,
+ info->max_tmds_clock);
+
+   drm_parse_hdmi_deep_color_info(connector, db);
+}
+
 static void drm_parse_cea_ext(struct drm_connector *connector,
  struct edid *edid)
 {
@@ -3821,10 +3827,8 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
for_each_cea_db(edid_ext, i, start, end) {
const u8 *db = _ext[i];

-   if (!cea_db_is_hdmi_vsdb(db))
-   continue;
-
-

[PATCH 07/10] drm/edid: Clear the old cea_rev when there's no CEA extension in the new EDID

2016-08-03 Thread ville.syrj...@linux.intel.com
From: Ville Syrjälä 

It's not a good idea to leave stale cea_rev in the drm_display_info. The
current EDID might not even have a CEA ext block in which case we'd end
up leaving the stale value in place.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_edid.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 82ab57c4d6c9..452e8c51a729 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3848,6 +3848,7 @@ static void drm_add_display_info(struct drm_connector 
*connector,
/* driver figures it out in this case */
info->bpc = 0;
info->color_formats = 0;
+   info->cea_rev = 0;

if (edid->revision < 3)
return;
-- 
2.7.4



[PATCH 06/10] drm/edid: Reduce the number of times we parse the CEA extension block

2016-08-03 Thread ville.syrj...@linux.intel.com
From: Ville Syrjälä 

Instead of parsing parts of the CEA extension block in two places
to determine supported color formats and whatnot, let's just
consolidate it to one function. This also makes it possible to neatly
flatten drm_assign_hdmi_deep_color_info().

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_edid.c | 192 +
 1 file changed, 89 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d8c7da56ab75..82ab57c4d6c9 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3728,119 +3728,119 @@ bool drm_rgb_quant_range_selectable(struct edid *edid)
 }
 EXPORT_SYMBOL(drm_rgb_quant_range_selectable);

-/**
- * drm_assign_hdmi_deep_color_info - detect whether monitor supports
- * hdmi deep color modes and update drm_display_info if so.
- * @edid: monitor EDID information
- * @connector: DRM connector, used only for debug output
- *
- * Parse the CEA extension according to CEA-861-B.
- * Return true if HDMI deep color supported, false if not or unknown.
- */
-static bool drm_assign_hdmi_deep_color_info(struct edid *edid,
-struct drm_connector *connector)
+static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
+  const u8 *hdmi)
 {
struct drm_display_info *info = >display_info;
-   u8 *edid_ext, *hdmi;
-   int i;
-   int start_offset, end_offset;
unsigned int dc_bpc = 0;

-   edid_ext = drm_find_cea_extension(edid);
-   if (!edid_ext)
-   return false;
+   /* HDMI supports at least 8 bpc */
+   info->bpc = 8;

-   if (cea_db_offsets(edid_ext, _offset, _offset))
-   return false;
+   if (cea_db_payload_len(hdmi) < 6)
+   return;
+
+   if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
+   dc_bpc = 10;
+   info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30;
+   DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
+ connector->name);
+   }
+
+   if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
+   dc_bpc = 12;
+   info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36;
+   DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
+ connector->name);
+   }
+
+   if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
+   dc_bpc = 16;
+   info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48;
+   DRM_DEBUG("%s: HDMI sink does deep color 48.\n",
+ connector->name);
+   }
+
+   if (dc_bpc == 0) {
+   DRM_DEBUG("%s: No deep color support on this HDMI sink.\n",
+ connector->name);
+   return;
+   }
+
+   DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n",
+ connector->name, dc_bpc);
+   info->bpc = dc_bpc;

/*
-* Because HDMI identifier is in Vendor Specific Block,
-* search it from all data blocks of CEA extension.
+* Deep color support mandates RGB444 support for all video
+* modes and forbids YCRCB422 support for all video modes per
+* HDMI 1.3 spec.
 */
-   for_each_cea_db(edid_ext, i, start_offset, end_offset) {
-   if (cea_db_is_hdmi_vsdb(_ext[i])) {
-   /* HDMI supports at least 8 bpc */
-   info->bpc = 8;
-
-   hdmi = _ext[i];
-   if (cea_db_payload_len(hdmi) < 6)
-   return false;
-
-   if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
-   dc_bpc = 10;
-   info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30;
-   DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
- connector->name);
-   }
+   info->color_formats = DRM_COLOR_FORMAT_RGB444;

-   if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
-   dc_bpc = 12;
-   info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36;
-   DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
- connector->name);
-   }
+   /* YCRCB444 is optional according to spec. */
+   if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) {
+   info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
+   DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n",
+ connector->name);
+   }

-   if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
-   dc_bpc = 16;
-   info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48;
-   

[PATCH 05/10] drm/edid: Don't pass around drm_display_info needlessly

2016-08-03 Thread ville.syrj...@linux.intel.com
From: Ville Syrjälä 

We already pass the connector to drm_add_display_info() and
drm_assign_hdmi_deep_color_info(), so passing the
connector->display_info also is pointless.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_edid.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index abd6d3c77ef2..d8c7da56ab75 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3732,17 +3732,15 @@ EXPORT_SYMBOL(drm_rgb_quant_range_selectable);
  * drm_assign_hdmi_deep_color_info - detect whether monitor supports
  * hdmi deep color modes and update drm_display_info if so.
  * @edid: monitor EDID information
- * @info: Updated with maximum supported deep color bpc and color format
- *if deep color supported.
  * @connector: DRM connector, used only for debug output
  *
  * Parse the CEA extension according to CEA-861-B.
  * Return true if HDMI deep color supported, false if not or unknown.
  */
 static bool drm_assign_hdmi_deep_color_info(struct edid *edid,
-struct drm_display_info *info,
 struct drm_connector *connector)
 {
+   struct drm_display_info *info = >display_info;
u8 *edid_ext, *hdmi;
int i;
int start_offset, end_offset;
@@ -3832,7 +3830,6 @@ static bool drm_assign_hdmi_deep_color_info(struct edid 
*edid,
 /**
  * drm_add_display_info - pull display info out if present
  * @edid: EDID data
- * @info: display info (attached to connector)
  * @connector: connector whose edid is used to build display info
  *
  * Grab any available display info and stuff it into the drm_display_info
@@ -3840,9 +3837,9 @@ static bool drm_assign_hdmi_deep_color_info(struct edid 
*edid,
  * color spaces.
  */
 static void drm_add_display_info(struct edid *edid,
- struct drm_display_info *info,
  struct drm_connector *connector)
 {
+   struct drm_display_info *info = >display_info;
u8 *edid_ext;

info->width_mm = edid->width_cm * 10;
@@ -3872,7 +3869,7 @@ static void drm_add_display_info(struct edid *edid,
}

/* HDMI deep color modes supported? Assign to info, if so */
-   drm_assign_hdmi_deep_color_info(edid, info, connector);
+   drm_assign_hdmi_deep_color_info(edid, connector);

/* Only defined for 1.4 with digital displays */
if (edid->revision < 4)
@@ -4092,7 +4089,7 @@ int drm_add_edid_modes(struct drm_connector *connector, 
struct edid *edid)
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
edid_fixup_preferred(connector, quirks);

-   drm_add_display_info(edid, >display_info, connector);
+   drm_add_display_info(edid, connector);

if (quirks & EDID_QUIRK_FORCE_8BPC)
connector->display_info.bpc = 8;
-- 
2.7.4



  1   2   >