[PATCH v6v3 02/12] mm: migrate: support non-lru movable page migration

2016-06-01 Thread Minchan Kim
On Tue, May 31, 2016 at 09:52:48AM +0200, Vlastimil Babka wrote:
> On 05/31/2016 02:01 AM, Minchan Kim wrote:
> >Per Vlastimi's review comment.
> >
> >Thanks for the detail review, Vlastimi!
> >If you have another concern, feel free to say.
> 
> I don't for now :)
> 
> [...]
> 
> >Cc: Rik van Riel 
> >Cc: Vlastimil Babka 
> >Cc: Joonsoo Kim 
> >Cc: Mel Gorman 
> >Cc: Hugh Dickins 
> >Cc: Rafael Aquini 
> >Cc: virtualization at lists.linux-foundation.org
> >Cc: Jonathan Corbet 
> >Cc: John Einar Reitan 
> >Cc: dri-devel at lists.freedesktop.org
> >Cc: Sergey Senozhatsky 
> >Signed-off-by: Gioh Kim 
> >Signed-off-by: Minchan Kim 
> 
> Acked-by: Vlastimil Babka 

Thanks for the review, Vlastimil!


[PATCH v7 00/12] Support non-lru page migration

2016-06-01 Thread Minchan Kim
Recently, I got many reports about perfermance degradation in embedded
system(Android mobile phone, webOS TV and so on) and easy fork fail.

The problem was fragmentation caused by zram and GPU driver mainly.
With memory pressure, their pages were spread out all of pageblock and
it cannot be migrated with current compaction algorithm which supports
only LRU pages. In the end, compaction cannot work well so reclaimer
shrinks all of working set pages. It made system very slow and even to
fail to fork easily which requires order-[2 or 3] allocations.

Other pain point is that they cannot use CMA memory space so when OOM
kill happens, I can see many free pages in CMA area, which is not
memory efficient. In our product which has big CMA memory, it reclaims
zones too exccessively to allocate GPU and zram page although there are
lots of free space in CMA so system becomes very slow easily.

To solve these problem, this patch tries to add facility to migrate
non-lru pages via introducing new functions and page flags to help
migration.

struct address_space_operations {
..
..
bool (*isolate_page)(struct page *, isolate_mode_t);
void (*putback_page)(struct page *);
..
}

new page flags

PG_movable
PG_isolated

For details, please read description in "mm: migrate: support non-lru
movable page migration".

Originally, Gioh Kim had tried to support this feature but he moved so
I took over the work. I took many code from his work and changed a little
bit and Konstantin Khlebnikov helped Gioh a lot so he should deserve to have
many credit, too.

And I should mention Chulmin who have tested this patchset heavily
so I can find many bugs from him. :)

Thanks, Gioh, Konstantin and Chulmin!

This patchset consists of five parts.

1. clean up migration
  mm: use put_page to free page instead of putback_lru_page

2. add non-lru page migration feature
  mm: migrate: support non-lru movable page migration

3. rework KVM memory-ballooning
  mm: balloon: use general non-lru movable page feature

4. zsmalloc refactoring for preparing page migration
  zsmalloc: keep max_object in size_class
  zsmalloc: use bit_spin_lock
  zsmalloc: use accessor
  zsmalloc: factor page chain functionality out
  zsmalloc: introduce zspage structure
  zsmalloc: separate free_zspage from putback_zspage
  zsmalloc: use freeobj for index

5. zsmalloc page migration
  zsmalloc: page migration support
  zram: use __GFP_MOVABLE for memory allocation

* From v6
  * rebase on mmotm-2016-05-27-15-19
  * clean up zsmalloc - Sergey
  * clean up non-lru page migration - Vlastimil

* From v5
  * rebase on next-20160520
  * move utility functions to compaction.c and export - Sergey
  * zsmalloc dobule free fix - Sergey
  * add additional Reviewed-by for zsmalloc - Sergey

* From v4
  * rebase on mmotm-2016-05-05-17-19
  * fix huge object migration - Chulmin
  * !CONFIG_COMPACTION support for zsmalloc

* From v3
  * rebase on mmotm-2016-04-06-20-40
  * fix swap_info deadlock - Chulmin
  * race without page_lock - Vlastimil
  * no use page._mapcount for potential user-mapped page driver - Vlastimil
  * fix and enhance doc/description - Vlastimil
  * use page->mapping lower bits to represent PG_movable
  * make driver side's rule simple.

* From v2
  * rebase on mmotm-2016-03-29-15-54-16
  * check PageMovable before lock_page - Joonsoo
  * check PageMovable before PageIsolated checking - Joonsoo
  * add more description about rule

* From v1
  * rebase on v4.5-mmotm-2016-03-17-15-04
  * reordering patches to merge clean-up patches first
  * add Acked-by/Reviewed-by from Vlastimil and Sergey
  * use each own mount model instead of reusing anon_inode_fs - Al Viro
  * small changes - YiPing, Gioh

Cc: Vlastimil Babka 
Cc: dri-devel at lists.freedesktop.org
Cc: Hugh Dickins 
Cc: John Einar Reitan 
Cc: Jonathan Corbet 
Cc: Joonsoo Kim 
Cc: Konstantin Khlebnikov 
Cc: Mel Gorman 
Cc: Naoya Horiguchi 
Cc: Rafael Aquini 
Cc: Rik van Riel 
Cc: Sergey Senozhatsky 
Cc: virtualization at lists.linux-foundation.org
Cc: Gioh Kim 
Cc: Chan Gyun Jeong 
Cc: Sangseok Lee 
Cc: Kyeongdon Kim 
Cc: Chulmin Kim 

Minchan Kim (12):
  mm: use put_page to free page instead of putback_lru_page
  mm: migrate: support non-lru movable page migration
  mm: balloon: use general non-lru movable page feature
  zsmalloc: keep max_object in size_class
  zsmalloc: use bit_spin_lock
  zsmalloc: use accessor
  zsmalloc: factor page chain functionality out
  zsmalloc: introduce zspage structure
  zsmalloc: separate free_zspage from putback_zspage
  zsmalloc: use freeobj for index
  zsmalloc: page migration support
  zram: use __GFP_MOVABLE for memory allocation

 Documentation/filesystems/Locking  |4 +
 Documentation/filesystems/vfs.txt  |   11 +
 Documentation/vm/page_migration|  107 ++-
 drivers/block/zram/zram_drv.c  |6 +-
 drivers/virtio/virtio_balloon.c|   54 +-
 include/linux/balloon_compaction.h |   53 +-
 include/linux/compacti

[PATCH v7 02/12] mm: migrate: support non-lru movable page migration

2016-06-01 Thread Minchan Kim
We have allowed migration for only LRU pages until now and it was
enough to make high-order pages. But recently, embedded system(e.g.,
webOS, android) uses lots of non-movable pages(e.g., zram, GPU memory)
so we have seen several reports about troubles of small high-order
allocation. For fixing the problem, there were several efforts
(e,g,. enhance compaction algorithm, SLUB fallback to 0-order page,
reserved memory, vmalloc and so on) but if there are lots of
non-movable pages in system, their solutions are void in the long run.

So, this patch is to support facility to change non-movable pages
with movable. For the feature, this patch introduces functions related
to migration to address_space_operations as well as some page flags.

If a driver want to make own pages movable, it should define three functions
which are function pointers of struct address_space_operations.

1. bool (*isolate_page) (struct page *page, isolate_mode_t mode);

What VM expects on isolate_page function of driver is to return *true*
if driver isolates page successfully. On returing true, VM marks the page
as PG_isolated so concurrent isolation in several CPUs skip the page
for isolation. If a driver cannot isolate the page, it should return *false*.

Once page is successfully isolated, VM uses page.lru fields so driver
shouldn't expect to preserve values in that fields.

2. int (*migratepage) (struct address_space *mapping,
struct page *newpage, struct page *oldpage, enum migrate_mode);

After isolation, VM calls migratepage of driver with isolated page.
The function of migratepage is to move content of the old page to new page
and set up fields of struct page newpage. Keep in mind that you should
indicate to the VM the oldpage is no longer movable via __ClearPageMovable()
under page_lock if you migrated the oldpage successfully and returns 0.
If driver cannot migrate the page at the moment, driver can return -EAGAIN.
On -EAGAIN, VM will retry page migration in a short time because VM interprets
-EAGAIN as "temporal migration failure". On returning any error except -EAGAIN,
VM will give up the page migration without retrying in this time.

Driver shouldn't touch page.lru field VM using in the functions.

3. void (*putback_page)(struct page *);

If migration fails on isolated page, VM should return the isolated page
to the driver so VM calls driver's putback_page with migration failed page.
In this function, driver should put the isolated page back to the own data
structure.

4. non-lru movable page flags

There are two page flags for supporting non-lru movable page.

* PG_movable

Driver should use the below function to make page movable under page_lock.

void __SetPageMovable(struct page *page, struct address_space *mapping)

It needs argument of address_space for registering migration family functions
which will be called by VM. Exactly speaking, PG_movable is not a real flag of
struct page. Rather than, VM reuses page->mapping's lower bits to represent it.

#define PAGE_MAPPING_MOVABLE 0x2
page->mapping = page->mapping | PAGE_MAPPING_MOVABLE;

so driver shouldn't access page->mapping directly. Instead, driver should
use page_mapping which mask off the low two bits of page->mapping so it can get
right struct address_space.

For testing of non-lru movable page, VM supports __PageMovable function.
However, it doesn't guarantee to identify non-lru movable page because
page->mapping field is unified with other variables in struct page.
As well, if driver releases the page after isolation by VM, page->mapping
doesn't have stable value although it has PAGE_MAPPING_MOVABLE
(Look at __ClearPageMovable). But __PageMovable is cheap to catch whether
page is LRU or non-lru movable once the page has been isolated. Because
LRU pages never can have PAGE_MAPPING_MOVABLE in page->mapping. It is also
good for just peeking to test non-lru movable pages before more expensive
checking with lock_page in pfn scanning to select victim.

For guaranteeing non-lru movable page, VM provides PageMovable function.
Unlike __PageMovable, PageMovable functions validates page->mapping and
mapping->a_ops->isolate_page under lock_page. The lock_page prevents sudden
destroying of page->mapping.

Driver using __SetPageMovable should clear the flag via __ClearMovablePage
under page_lock before the releasing the page.

* PG_isolated

To prevent concurrent isolation among several CPUs, VM marks isolated page
as PG_isolated under lock_page. So if a CPU encounters PG_isolated non-lru
movable page, it can skip it. Driver doesn't need to manipulate the flag
because VM will set/clear it automatically. Keep in mind that if driver
sees PG_isolated page, it means the page have been isolated by VM so it
shouldn't touch page.lru field.
PG_isolated is alias with PG_reclaim flag so driver shouldn't use the flag
for own purpose.

Cc: Rik van Riel 
Cc: Joonsoo Kim 
Cc: Mel Gorman 
Cc: Hugh Dickins 
Cc: Rafael Aquini 
Cc: virtualization at list

[PATCH 2/3] drm/exynos: fimd: add HW trigger support

2016-06-01 Thread Inki Dae
Hi Javier,

2016년 05월 31일 07:58에 Javier Martinez Canillas 이(가) 쓴 글:
> Hello Inki,
> 
> On 04/05/2016 04:27 AM, Inki Dae wrote:
>> This patch adds HW trigger support on i80 mode.
>>
>> Until now, Exynos DRM only supported SW trigger which was set
>> SWTRGCMD bit of TRIGCON register by CPU to transfer scanout
>> buffer to Display bus device or panel.
>>
>> With this patch, the transmission to Display bus device or
>> panel will be initiated by FIMD controller.
>>
>> Signed-off-by: Inki Dae 
>> ---
> 
> There is a regression for the Exynos5800 Peach Pi Chromebook display due
> this patch. The display is blank and I noticed that it only happens when
> HW start trigger is enabled, but works with SW trigger (as it was before).
> 
> So for example with the following diff on top of v4.7-rc1, display works
> again. Do you have any hints about what could be the issue?

Right, there is a regression on boards with i80 Panel and in case that 
bootloader set trigger mode to SW trigger. The current trigger mode should be 
changed to other one after entering into PSR mode of Panel device according to 
HW guy's saying. If the panel doesn't support the PSR mode, then the mode 
should be changed after Panel power off and on again. I don't understand 
exactly what is the PSR mode so I need more details about PSR mode.

I will fix it soon.

Thanks,
Inki Dae  


> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
> b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 0444d7fc400d..8c62830e9514 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -171,7 +171,7 @@ static struct fimd_driver_data 
> exynos5420_fimd_driver_data = {
>   .lcdblk_vt_shift = 24,
>   .lcdblk_bypass_shift = 15,
>   .lcdblk_mic_bypass_shift = 11,
> - .trg_type = I80_HW_TRG,
>   .has_shadowcon = 1,
>   .has_vidoutcon = 1,
>   .has_vtsel = 1,
> 
> Best regards,
> 


[PATCH v2 26/27] [media] omap_vout: Switch to use the video/omapfb_dss.h header file

2016-06-01 Thread Peter Ujfalusi
The omap_vout is only supported with omapfb. Switch the driver to use the
correct header file.

Signed-off-by: Peter Ujfalusi 
---
 drivers/media/platform/omap/omap_vout.c| 2 +-
 drivers/media/platform/omap/omap_voutdef.h | 2 +-
 drivers/media/platform/omap/omap_voutlib.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/omap/omap_vout.c 
b/drivers/media/platform/omap/omap_vout.c
index 70c28d19ea04..22cf60991df6 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -45,7 +45,7 @@
 #include 

 #include 
-#include 
+#include 

 #include "omap_voutlib.h"
 #include "omap_voutdef.h"
diff --git a/drivers/media/platform/omap/omap_voutdef.h 
b/drivers/media/platform/omap/omap_voutdef.h
index 9ccfe1f475a4..94b5d65afb19 100644
--- a/drivers/media/platform/omap/omap_voutdef.h
+++ b/drivers/media/platform/omap/omap_voutdef.h
@@ -11,7 +11,7 @@
 #ifndef OMAP_VOUTDEF_H
 #define OMAP_VOUTDEF_H

-#include 
+#include 
 #include 

 #define YUYV_BPP2
diff --git a/drivers/media/platform/omap/omap_voutlib.c 
b/drivers/media/platform/omap/omap_voutlib.c
index 80b0d88f125c..58a25fdf0cce 100644
--- a/drivers/media/platform/omap/omap_voutlib.c
+++ b/drivers/media/platform/omap/omap_voutlib.c
@@ -26,7 +26,7 @@

 #include 

-#include 
+#include 

 #include "omap_voutlib.h"

-- 
2.8.3



[PATCH v2 27/27] drm/omap: Remove the video/omapdss.h and move it's content to local header file

2016-06-01 Thread Peter Ujfalusi
Move the contents of the video/omapdss.h header file to omapdrm/dss local
header file and remove the original global header. The omapfb stach is
using video/omapfb_dss.h so this change will complete the separation of the
two driver implementation.

Signed-off-by: Peter Ujfalusi 
---
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 866 -
 include/video/omapdss.h   | 888 --
 2 files changed, 865 insertions(+), 889 deletions(-)
 delete mode 100644 include/video/omapdss.h

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index d7e7c909bbc2..9263283952b9 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -18,7 +18,871 @@
 #ifndef __OMAP_DRM_DSS_H
 #define __OMAP_DRM_DSS_H

-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DISPC_IRQ_FRAMEDONE(1 << 0)
+#define DISPC_IRQ_VSYNC(1 << 1)
+#define DISPC_IRQ_EVSYNC_EVEN  (1 << 2)
+#define DISPC_IRQ_EVSYNC_ODD   (1 << 3)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT(1 << 4)
+#define DISPC_IRQ_PROG_LINE_NUM(1 << 5)
+#define DISPC_IRQ_GFX_FIFO_UNDERFLOW   (1 << 6)
+#define DISPC_IRQ_GFX_END_WIN  (1 << 7)
+#define DISPC_IRQ_PAL_GAMMA_MASK   (1 << 8)
+#define DISPC_IRQ_OCP_ERR  (1 << 9)
+#define DISPC_IRQ_VID1_FIFO_UNDERFLOW  (1 << 10)
+#define DISPC_IRQ_VID1_END_WIN (1 << 11)
+#define DISPC_IRQ_VID2_FIFO_UNDERFLOW  (1 << 12)
+#define DISPC_IRQ_VID2_END_WIN (1 << 13)
+#define DISPC_IRQ_SYNC_LOST(1 << 14)
+#define DISPC_IRQ_SYNC_LOST_DIGIT  (1 << 15)
+#define DISPC_IRQ_WAKEUP   (1 << 16)
+#define DISPC_IRQ_SYNC_LOST2   (1 << 17)
+#define DISPC_IRQ_VSYNC2   (1 << 18)
+#define DISPC_IRQ_VID3_END_WIN (1 << 19)
+#define DISPC_IRQ_VID3_FIFO_UNDERFLOW  (1 << 20)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT2   (1 << 21)
+#define DISPC_IRQ_FRAMEDONE2   (1 << 22)
+#define DISPC_IRQ_FRAMEDONEWB  (1 << 23)
+#define DISPC_IRQ_FRAMEDONETV  (1 << 24)
+#define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25)
+#define DISPC_IRQ_WBUNCOMPLETEERROR(1 << 26)
+#define DISPC_IRQ_SYNC_LOST3   (1 << 27)
+#define DISPC_IRQ_VSYNC3   (1 << 28)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT3   (1 << 29)
+#define DISPC_IRQ_FRAMEDONE3   (1 << 30)
+
+struct omap_dss_device;
+struct omap_overlay_manager;
+struct dss_lcd_mgr_config;
+struct snd_aes_iec958;
+struct snd_cea_861_aud_if;
+struct hdmi_avi_infoframe;
+
+enum omap_display_type {
+   OMAP_DISPLAY_TYPE_NONE  = 0,
+   OMAP_DISPLAY_TYPE_DPI   = 1 << 0,
+   OMAP_DISPLAY_TYPE_DBI   = 1 << 1,
+   OMAP_DISPLAY_TYPE_SDI   = 1 << 2,
+   OMAP_DISPLAY_TYPE_DSI   = 1 << 3,
+   OMAP_DISPLAY_TYPE_VENC  = 1 << 4,
+   OMAP_DISPLAY_TYPE_HDMI  = 1 << 5,
+   OMAP_DISPLAY_TYPE_DVI   = 1 << 6,
+};
+
+enum omap_plane {
+   OMAP_DSS_GFX= 0,
+   OMAP_DSS_VIDEO1 = 1,
+   OMAP_DSS_VIDEO2 = 2,
+   OMAP_DSS_VIDEO3 = 3,
+   OMAP_DSS_WB = 4,
+};
+
+enum omap_channel {
+   OMAP_DSS_CHANNEL_LCD= 0,
+   OMAP_DSS_CHANNEL_DIGIT  = 1,
+   OMAP_DSS_CHANNEL_LCD2   = 2,
+   OMAP_DSS_CHANNEL_LCD3   = 3,
+   OMAP_DSS_CHANNEL_WB = 4,
+};
+
+enum omap_color_mode {
+   OMAP_DSS_COLOR_CLUT1= 1 << 0,  /* BITMAP 1 */
+   OMAP_DSS_COLOR_CLUT2= 1 << 1,  /* BITMAP 2 */
+   OMAP_DSS_COLOR_CLUT4= 1 << 2,  /* BITMAP 4 */
+   OMAP_DSS_COLOR_CLUT8= 1 << 3,  /* BITMAP 8 */
+   OMAP_DSS_COLOR_RGB12U   = 1 << 4,  /* RGB12, 16-bit container */
+   OMAP_DSS_COLOR_ARGB16   = 1 << 5,  /* ARGB16 */
+   OMAP_DSS_COLOR_RGB16= 1 << 6,  /* RGB16 */
+   OMAP_DSS_COLOR_RGB24U   = 1 << 7,  /* RGB24, 32-bit container */
+   OMAP_DSS_COLOR_RGB24P   = 1 << 8,  /* RGB24, 24-bit container */
+   OMAP_DSS_COLOR_YUV2 = 1 << 9,  /* YUV2 4:2:2 co-sited */
+   OMAP_DSS_COLOR_UYVY = 1 << 10, /* UYVY 4:2:2 co-sited */
+   OMAP_DSS_COLOR_ARGB32   = 1 << 11, /* ARGB32 */
+   OMAP_DSS_COLOR_RGBA32   = 1 << 12, /* RGBA32 */
+   OMAP_DSS_COLOR_RGBX32   = 1 << 13, /* RGBx32 */
+   OMAP_DSS_COLOR_NV12 = 1 << 14, /* NV12 format: YUV 4:2:0 */
+   OMAP_DSS_COLOR_RGBA16   = 1 << 15, /* RGBA16 -  */
+   OMAP_DSS_COLOR_RGBX16   = 1 << 16, /* RGBx16 -  */
+   OMAP_DSS_COLOR_ARGB16_1555  = 1 << 17, /* ARGB16 - 1555 */
+   OMAP_DSS_COLOR_XRGB16_1555  = 1 << 18, /* xRGB16 - 1555 */
+};
+
+enum omap_dss_load_mode {
+   OMAP_DSS_LOAD_CLUT_AND_FRAME= 0,
+   OMAP_DSS_LOAD_CLUT_ONLY = 1,
+   OMAP_DSS_LOAD_FRAME_ONLY= 2,
+   OMAP_DSS_LOAD_CLUT_ONCE_FRAME   = 3,
+};
+
+enum omap_dss_trans_key_type {
+   OMAP_DSS_COLOR_KEY_GFX_DST = 0,
+ 

[PATCH v2 00/27] fb/drm: omapdss: Clean up the headers and separate the two stack

2016-06-01 Thread Peter Ujfalusi
Hi,

Changes since v1:
- patches (2) added to remove the inclusion of video/omap-panel-data.h when it
  is not needed
- Transitional patch to create the video/omapfb_dss.h has been changed to copy
  the content of the omapdss.h in one step.

omapfb is deprecated. It will not receive new features, only bug fixes. On the.
other hand omapdrm is in active development and the fact that both
implementation (omapfb and omapdrm) is using the same header file
(video/omapdss.h) makes implementing new features or doing bigger clean ups in
omapdrm harder and hared as the change should not break omapfb.

To overcome this issue we need to separate the two implementation. This is the
aim of this series:
Create platform_data header for omapdss,
clean up the header usage and dependencies,
new header file for omapfb stack (video/omapfb_dss.h)
local omapdss.h header file for omapdrm.

Regards,
Peter
---
Peter Ujfalusi (27):
  omapfb: panel-tpo-td028ttec1: Remove legacy boot support
  omapfb: panel-nec-nl8048hl11: Remove legacy boot support
  omapfb: panel-tpo-td043mtea1: Remove legacy boot support
  omapfb: panel-sharp-ls037v7dw01: Remove legacy boot support
  omapfb: panel-lgphilips-lb035q02: Remove legacy boot support
  omapfb: panel-dsi-cm: Remove legacy boot support
  omapfb: connector-hdmi: Remove legacy boot support
  omapfb: connector-dvi: Remove legacy boot support
  omapfb: encoder-tfp410: Remove legacy boot support
  omapfb: encoder-tpd12s015: No need to include video/omap-panle-data.h
  drm/omap: displays: Do not include video/omap-panel-data.h if not
needed
  omapdss: omap-panel-data.h: Remove struct omap_dss_device declaration
  drm/omap: connector-analog-tv: Support only Composite type in legacy
boot
  omapfb: connector-analog-tv: Support only Composite type in legacy
boot
  ARM: OMAP: rx51-video: Do not set TV connector_type
  omapdss: omap-panel-data.h: Remove connector_type from atv pdata
  ARM/video: omap2: Move omap_display_init declaration to
mach-omap2/display.h
  drm/omap: Remove reference to pdata->default_device
  omapfb: Remove reference to pdata->default_device
  video: omapdss: Remove unused members from struct omap_dss_board_info
  video/platform_data: omapdss: Create new header file for platform data
  ARM: OMAP2: Use the platform_data header for omapdss
  omapdss: hdmi audio: Make header file independent of video/omapdss.h
  drm/omap: Do not include video/omapdss.h directly in drivers
  omapfb: Create new header file for omapfb DSS implementation
  [media] omap_vout: Switch to use the video/omapfb_dss.h header file
  drm/omap: Remove the video/omapdss.h and move it's content to local
header file

 arch/arm/mach-omap2/board-ldp.c|   3 +-
 arch/arm/mach-omap2/board-rx51-video.c |   4 +-
 arch/arm/mach-omap2/display.c  |   2 +-
 arch/arm/mach-omap2/display.h  |   5 +
 arch/arm/mach-omap2/dss-common.c   |   2 +-
 .../gpu/drm/omapdrm/displays/connector-analog-tv.c |  11 +-
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |   4 +-
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |   4 +-
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c  |   2 +-
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c  |   3 +-
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |   3 +-
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c   |   3 +-
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c|   4 +-
 .../omapdrm/displays/panel-lgphilips-lb035q02.c|   3 +-
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c|   2 +-
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c |   3 +-
 .../drm/omapdrm/displays/panel-sony-acx565akm.c|   3 +-
 .../drm/omapdrm/displays/panel-tpo-td028ttec1.c|   3 +-
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c|   2 +-
 drivers/gpu/drm/omapdrm/dss/core.c |   5 +-
 drivers/gpu/drm/omapdrm/dss/dispc.c|   3 +-
 drivers/gpu/drm/omapdrm/dss/dispc_coefs.c  |   2 +-
 drivers/gpu/drm/omapdrm/dss/display.c  |   2 +-
 drivers/gpu/drm/omapdrm/dss/dpi.c  |   3 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c  |   2 +-
 drivers/gpu/drm/omapdrm/dss/dss-of.c   |   3 +-
 drivers/gpu/drm/omapdrm/dss/dss.c  |   3 +-
 drivers/gpu/drm/omapdrm/dss/dss_features.c |   3 +-
 drivers/gpu/drm/omapdrm/dss/hdmi.h |   3 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c|   2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c|   2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi_common.c  |   2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi_phy.c |   2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi_pll.c |   3 +-
 drivers/gpu/drm/omapdrm/dss/hdmi_wp.c  |   2 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h  | 866 -
 drivers/gpu/drm/omapdrm/dss/output.c   |   3 +-
 drivers/gpu/drm/omapdrm/dss/pll.c   

[PATCH v2 03/27] omapfb: panel-tpo-td043mtea1: Remove legacy boot support

2016-06-01 Thread Peter Ujfalusi
The panel is not used by any legacy board files so the legacy (pdata) boot
support can be dropped.

Signed-off-by: Peter Ujfalusi 
---
 .../omap2/omapfb/displays/panel-tpo-td043mtea1.c   | 44 +++---
 include/video/omap-panel-data.h| 16 
 2 files changed, 6 insertions(+), 54 deletions(-)

diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td043mtea1.c 
b/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td043mtea1.c
index 68e3b68a2920..f49e60da5bd3 100644
--- a/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td043mtea1.c
@@ -20,7 +20,6 @@
 #include 

 #include 
-#include 

 #define TPO_R02_MODE(x)((x) & 7)
 #define TPO_R02_MODE_800x480   7
@@ -465,32 +464,6 @@ static struct omap_dss_driver tpo_td043_ops = {
 };


-static int tpo_td043_probe_pdata(struct spi_device *spi)
-{
-   const struct panel_tpo_td043mtea1_platform_data *pdata;
-   struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-   struct omap_dss_device *dssdev, *in;
-
-   pdata = dev_get_platdata(&spi->dev);
-
-   ddata->nreset_gpio = pdata->nreset_gpio;
-
-   in = omap_dss_find_output(pdata->source);
-   if (in == NULL) {
-   dev_err(&spi->dev, "failed to find video source '%s'\n",
-   pdata->source);
-   return -EPROBE_DEFER;
-   }
-   ddata->in = in;
-
-   ddata->data_lines = pdata->data_lines;
-
-   dssdev = &ddata->dssdev;
-   dssdev->name = pdata->name;
-
-   return 0;
-}
-
 static int tpo_td043_probe_of(struct spi_device *spi)
 {
struct device_node *node = spi->dev.of_node;
@@ -524,6 +497,9 @@ static int tpo_td043_probe(struct spi_device *spi)

dev_dbg(&spi->dev, "%s\n", __func__);

+   if (!spi->dev.of_node)
+   return -ENODEV;
+
spi->bits_per_word = 16;
spi->mode = SPI_MODE_0;

@@ -541,17 +517,9 @@ static int tpo_td043_probe(struct spi_device *spi)

ddata->spi = spi;

-   if (dev_get_platdata(&spi->dev)) {
-   r = tpo_td043_probe_pdata(spi);
-   if (r)
-   return r;
-   } else if (spi->dev.of_node) {
-   r = tpo_td043_probe_of(spi);
-   if (r)
-   return r;
-   } else {
-   return -ENODEV;
-   }
+   r = tpo_td043_probe_of(spi);
+   if (r)
+   return r;

ddata->mode = TPO_R02_MODE_800x480;
memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));
diff --git a/include/video/omap-panel-data.h b/include/video/omap-panel-data.h
index a0c95cd1ed11..34ee7509752f 100644
--- a/include/video/omap-panel-data.h
+++ b/include/video/omap-panel-data.h
@@ -189,20 +189,4 @@ struct panel_sharp_ls037v7dw01_platform_data {
int ud_gpio;
 };

-/**
- * panel-tpo-td043mtea1 platform data
- * @name: name for this display entity
- * @source: name of the display entity used as a video source
- * @data_lines: number of DPI datalines
- * @nreset_gpio: reset signal
- */
-struct panel_tpo_td043mtea1_platform_data {
-   const char *name;
-   const char *source;
-
-   int data_lines;
-
-   int nreset_gpio;
-};
-
 #endif /* __OMAP_PANEL_DATA_H */
-- 
2.8.3



[PATCH v2 09/27] omapfb: encoder-tfp410: Remove legacy boot support

2016-06-01 Thread Peter Ujfalusi
The panel is not used by any legacy board files so the legacy (pdata) boot
support can be dropped.

Signed-off-by: Peter Ujfalusi 
---
 .../fbdev/omap2/omapfb/displays/encoder-tfp410.c   | 44 +++---
 include/video/omap-panel-data.h| 14 ---
 2 files changed, 6 insertions(+), 52 deletions(-)

diff --git a/drivers/video/fbdev/omap2/omapfb/displays/encoder-tfp410.c 
b/drivers/video/fbdev/omap2/omapfb/displays/encoder-tfp410.c
index d9048b3df495..778e3b384c2f 100644
--- a/drivers/video/fbdev/omap2/omapfb/displays/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/omapfb/displays/encoder-tfp410.c
@@ -16,7 +16,6 @@
 #include 

 #include 
-#include 

 struct panel_drv_data {
struct omap_dss_device dssdev;
@@ -166,32 +165,6 @@ static const struct omapdss_dvi_ops tfp410_dvi_ops = {
.get_timings= tfp410_get_timings,
 };

-static int tfp410_probe_pdata(struct platform_device *pdev)
-{
-   struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct encoder_tfp410_platform_data *pdata;
-   struct omap_dss_device *dssdev, *in;
-
-   pdata = dev_get_platdata(&pdev->dev);
-
-   ddata->pd_gpio = pdata->power_down_gpio;
-
-   ddata->data_lines = pdata->data_lines;
-
-   in = omap_dss_find_output(pdata->source);
-   if (in == NULL) {
-   dev_err(&pdev->dev, "Failed to find video source\n");
-   return -ENODEV;
-   }
-
-   ddata->in = in;
-
-   dssdev = &ddata->dssdev;
-   dssdev->name = pdata->name;
-
-   return 0;
-}
-
 static int tfp410_probe_of(struct platform_device *pdev)
 {
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
@@ -225,23 +198,18 @@ static int tfp410_probe(struct platform_device *pdev)
struct omap_dss_device *dssdev;
int r;

+   if (!pdev->dev.of_node)
+   return -ENODEV;
+
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;

platform_set_drvdata(pdev, ddata);

-   if (dev_get_platdata(&pdev->dev)) {
-   r = tfp410_probe_pdata(pdev);
-   if (r)
-   return r;
-   } else if (pdev->dev.of_node) {
-   r = tfp410_probe_of(pdev);
-   if (r)
-   return r;
-   } else {
-   return -ENODEV;
-   }
+   r = tfp410_probe_of(pdev);
+   if (r)
+   return r;

if (gpio_is_valid(ddata->pd_gpio)) {
r = devm_gpio_request_one(&pdev->dev, ddata->pd_gpio,
diff --git a/include/video/omap-panel-data.h b/include/video/omap-panel-data.h
index 4d0b8832ae11..a64e9ba12b0d 100644
--- a/include/video/omap-panel-data.h
+++ b/include/video/omap-panel-data.h
@@ -33,20 +33,6 @@
 struct omap_dss_device;

 /**
- * encoder_tfp410 platform data
- * @name: name for this display entity
- * @power_down_gpio: gpio number for PD pin (or -1 if not available)
- * @data_lines: number of DPI datalines
- */
-struct encoder_tfp410_platform_data {
-   const char *name;
-   const char *source;
-   int power_down_gpio;
-   int data_lines;
-};
-
-
-/**
  * connector_atv platform data
  * @name: name for this display entity
  * @source: name of the display entity used as a video source
-- 
2.8.3



[PATCH v2 10/27] omapfb: encoder-tpd12s015: No need to include video/omap-panle-data.h

2016-06-01 Thread Peter Ujfalusi
The driver does not support legacy (pdata) based probing.

Signed-off-by: Peter Ujfalusi 
---
 drivers/video/fbdev/omap2/omapfb/displays/encoder-tpd12s015.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/omapfb/displays/encoder-tpd12s015.c 
b/drivers/video/fbdev/omap2/omapfb/displays/encoder-tpd12s015.c
index 677e2545fcbe..7939157af957 100644
--- a/drivers/video/fbdev/omap2/omapfb/displays/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/omapfb/displays/encoder-tpd12s015.c
@@ -17,7 +17,6 @@
 #include 

 #include 
-#include 

 struct panel_drv_data {
struct omap_dss_device dssdev;
-- 
2.8.3



[PATCH v2 13/27] drm/omap: connector-analog-tv: Support only Composite type in legacy boot

2016-06-01 Thread Peter Ujfalusi
In legacy mode (non DT mode) support only composite connector type. The
only user for this is rx51, using composite type.
Dropping the connector_type selection via pdata will allow cleanups in
omapdss (drm vs fbdev).

Signed-off-by: Peter Ujfalusi 
---
 drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 8511c648a15c..d963b4a9cfc0 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -25,7 +25,6 @@ struct panel_drv_data {

struct omap_video_timings timings;

-   enum omap_dss_venc_type connector_type;
bool invert_polarity;
 };

@@ -45,10 +44,6 @@ static const struct omap_video_timings tvc_pal_timings = {

 static const struct of_device_id tvc_of_match[];

-struct tvc_of_data {
-   enum omap_dss_venc_type connector_type;
-};
-
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)

 static int tvc_connect(struct omap_dss_device *dssdev)
@@ -99,7 +94,7 @@ static int tvc_enable(struct omap_dss_device *dssdev)
in->ops.atv->set_timings(in, &ddata->timings);

if (!ddata->dev->of_node) {
-   in->ops.atv->set_type(in, ddata->connector_type);
+   in->ops.atv->set_type(in, OMAP_DSS_VENC_TYPE_COMPOSITE);

in->ops.atv->invert_vid_out_polarity(in,
ddata->invert_polarity);
@@ -207,7 +202,6 @@ static int tvc_probe_pdata(struct platform_device *pdev)

ddata->in = in;

-   ddata->connector_type = pdata->connector_type;
ddata->invert_polarity = pdata->invert_polarity;

dssdev = &ddata->dssdev;
-- 
2.8.3



[PATCH v2 16/27] omapdss: omap-panel-data.h: Remove connector_type from atv pdata

2016-06-01 Thread Peter Ujfalusi
The driver only supports composite connection when booted in legacy mode
so the omap_dss_venc_type can be dropped from the pdata.
At the same time the video/omapdss.h include can be removed as it is no
longer needed.

Signed-off-by: Peter Ujfalusi 
---
 include/video/omap-panel-data.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/include/video/omap-panel-data.h b/include/video/omap-panel-data.h
index 7b4fadf82cd5..e7003ee6e063 100644
--- a/include/video/omap-panel-data.h
+++ b/include/video/omap-panel-data.h
@@ -27,21 +27,18 @@
 #ifndef __OMAP_PANEL_DATA_H
 #define __OMAP_PANEL_DATA_H

-#include 
 #include 

 /**
  * connector_atv platform data
  * @name: name for this display entity
  * @source: name of the display entity used as a video source
- * @connector_type: composite/svideo
  * @invert_polarity: invert signal polarity
  */
 struct connector_atv_platform_data {
const char *name;
const char *source;

-   enum omap_dss_venc_type connector_type;
bool invert_polarity;
 };

-- 
2.8.3



[PATCH v2 17/27] ARM/video: omap2: Move omap_display_init declaration to mach-omap2/display.h

2016-06-01 Thread Peter Ujfalusi
The omap_display_init() is implemented in the mach-omap2/display.c so the
declaration should have been there as well.
Change the board files to include display.h to avoid build breakage at the
same time.

Signed-off-by: Peter Ujfalusi 
---
 arch/arm/mach-omap2/board-ldp.c| 1 +
 arch/arm/mach-omap2/board-rx51-video.c | 1 +
 arch/arm/mach-omap2/display.h  | 5 +
 include/video/omapdss.h| 3 ---
 4 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index d9c3ffc39329..f364a1b779f0 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -47,6 +47,7 @@
 #include "hsmmc.h"
 #include "control.h"
 #include "common-board-devices.h"
+#include "display.h"

 #define LDP_SMSC911X_CS1
 #define LDP_SMSC911X_GPIO  152
diff --git a/arch/arm/mach-omap2/board-rx51-video.c 
b/arch/arm/mach-omap2/board-rx51-video.c
index b76f84245ad9..9866ec06a395 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -22,6 +22,7 @@

 #include "soc.h"
 #include "board-rx51.h"
+#include "display.h"

 #include "mux.h"

diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h
index 7375854b16c7..78f253005279 100644
--- a/arch/arm/mach-omap2/display.h
+++ b/arch/arm/mach-omap2/display.h
@@ -33,4 +33,9 @@ int omap_init_vout(void);

 struct device_node * __init omapdss_find_dss_of_node(void);

+struct omap_dss_board_info;
+
+/* Init with the board info */
+int omap_display_init(struct omap_dss_board_info *board_data);
+
 #endif
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 8e14ad7327c9..0c7ae93ebd76 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -330,9 +330,6 @@ struct omap_dss_board_info {
enum omapdss_version version;
 };

-/* Init with the board info */
-extern int omap_display_init(struct omap_dss_board_info *board_data);
-
 struct omap_video_timings {
/* Unit: pixels */
u16 x_res;
-- 
2.8.3



[PATCH v2 23/27] omapdss: hdmi audio: Make header file independent of video/omapdss.h

2016-06-01 Thread Peter Ujfalusi
Clean up the header files regarding to hdmi audio so the omap-hdmi-audio.h
file will only need to include the platform_data/omapdss.h file.

Signed-off-by: Peter Ujfalusi 
CC: Mark Brown 
CC: Jyri Sarha 
CC: Liam Girdwood 
---
 drivers/gpu/drm/omapdrm/dss/hdmi.h  | 1 +
 drivers/video/fbdev/omap2/omapfb/dss/hdmi.h | 1 +
 include/sound/omap-hdmi-audio.h | 9 +++--
 include/video/omapdss.h | 5 -
 sound/soc/omap/omap-hdmi-audio.c| 1 -
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h 
b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index 53616b02b613..c32a21a26054 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "dss.h"

diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi.h 
b/drivers/video/fbdev/omap2/omapfb/dss/hdmi.h
index 53616b02b613..c32a21a26054 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "dss.h"

diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h
index afdb416898e0..1df2ff61a4dd 100644
--- a/include/sound/omap-hdmi-audio.h
+++ b/include/sound/omap-hdmi-audio.h
@@ -16,11 +16,16 @@
  *
  */

-#include 
-
 #ifndef __OMAP_HDMI_AUDIO_H__
 #define __OMAP_HDMI_AUDIO_H__

+#include 
+
+struct omap_dss_audio {
+   struct snd_aes_iec958 *iec;
+   struct snd_cea_861_aud_if *cea;
+};
+
 struct omap_hdmi_audio_ops {
int (*audio_startup)(struct device *dev,
 void (*abort_cb)(struct device *dev));
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 53ada70cf23c..b25e2eab4b48 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -168,11 +168,6 @@ enum omap_dss_display_state {
OMAP_DSS_DISPLAY_ACTIVE,
 };

-struct omap_dss_audio {
-   struct snd_aes_iec958 *iec;
-   struct snd_cea_861_aud_if *cea;
-};
-
 enum omap_dss_rotation_type {
OMAP_DSS_ROT_DMA= 1 << 0,
OMAP_DSS_ROT_VRFB   = 1 << 1,
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index 64425d352962..888133f9e65d 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -28,7 +28,6 @@
 #include 
 #include 
 #include 
-#include 

 #define DRV_NAME "omap-hdmi-audio"

-- 
2.8.3



[PATCH] drm/doc: Switch to sphinx/rst fixed-width quoting

2016-06-01 Thread Daniel Vetter
There's still something very fishy going on with some of these, e.g.
the drm_modeset_lock Example: and the "Standard GTF Parameters:" Line
somehow get treated as heading when just appending a :: at the end of
those lines. But it seems to work everywhere else. Maybe the
kernel-doc heading generation logic is still a bit wonky?

v2: Found more. Also s/\//#/ in the vgpu ascii-art - sphinx treats
those as comments and switch to variable-width, which wreaks the
layout.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_bridge.c|  2 +-
 drivers/gpu/drm/drm_fb_cma_helper.c |  2 +-
 drivers/gpu/drm/drm_fops.c  |  2 +-
 drivers/gpu/drm/drm_modes.c |  5 -
 drivers/gpu/drm/drm_modeset_lock.c  |  2 +-
 drivers/gpu/drm/drm_vma_manager.c   |  3 +++
 drivers/gpu/drm/i915/i915_reg.h |  2 +-
 drivers/gpu/drm/i915/i915_vgpu.c| 24 
 include/drm/drm_modes.h |  2 ++
 9 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index b3654404abd0..255543086590 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -36,7 +36,7 @@
  * encoder chain.
  *
  * A bridge is always attached to a single &drm_encoder at a time, but can be
- * either connected to it directly, or through an intermediate bridge:
+ * either connected to it directly, or through an intermediate bridge::
  *
  * encoder ---> bridge B ---> bridge A
  *
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c 
b/drivers/gpu/drm/drm_fb_cma_helper.c
index 2b33b191a172..c50a0ba6fdba 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -52,7 +52,7 @@ struct drm_fbdev_cma {
  * will be set up automatically. dirty() is called by
  * drm_fb_helper_deferred_io() in process context (struct delayed_work).
  *
- * Example fbdev deferred io code:
+ * Example fbdev deferred io code::
  *
  * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb,
  *  struct drm_file *file_priv,
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 5921b203503a..323c238fcac7 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -68,7 +68,7 @@ DEFINE_MUTEX(drm_global_mutex);
  * specific implementations. For GEM-based drivers this is drm_gem_mmap().
  *
  * No other file operations are supported by the DRM userspace API. Overall the
- * following is an example #file_operations structure:
+ * following is an example #file_operations structure::
  *
  * static const example_drm_fops = {
  * .owner = THIS_MODULE,
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index e5e6f504d8cc..aae86c1857ec 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -552,7 +552,10 @@ EXPORT_SYMBOL(drm_gtf_mode_complex);
  * I also refer to the function of fb_get_mode in the file of
  * drivers/video/fbmon.c
  *
- * Standard GTF parameters:
+ * Standard GTF parameters
+ *
+ * ::
+ *
  * M = 600
  * C = 40
  * K = 128
diff --git a/drivers/gpu/drm/drm_modeset_lock.c 
b/drivers/gpu/drm/drm_modeset_lock.c
index f33ebe638a28..61146f5b4f56 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -37,7 +37,7 @@
  *
  * For basic principles of &ww_mutex, see: 
Documentation/locking/ww-mutex-design.txt
  *
- * The basic usage pattern is to:
+ * The basic usage pattern is to::
  *
  * drm_modeset_acquire_init(&ctx)
  * retry:
diff --git a/drivers/gpu/drm/drm_vma_manager.c 
b/drivers/gpu/drm/drm_vma_manager.c
index 2f2ecde8285b..f306c8855978 100644
--- a/drivers/gpu/drm/drm_vma_manager.c
+++ b/drivers/gpu/drm/drm_vma_manager.c
@@ -127,6 +127,9 @@ EXPORT_SYMBOL(drm_vma_offset_manager_destroy);
  * used to implement weakly referenced lookups using kref_get_unless_zero().
  *
  * Example:
+ *
+ * ::
+ *
  * drm_vma_offset_lock_lookup(mgr);
  * node = drm_vma_offset_lookup_locked(mgr);
  * if (node)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 216cc4ba74ee..d25dd1d694bc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -886,7 +886,7 @@ enum skl_disp_power_wells {
  * PLLs can be routed to any transcoder A/B/C.
  *
  * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is
- * digital port D (CHV) or port A (BXT).
+ * digital port D (CHV) or port A (BXT). ::
  *
  *
  * Dual channel PHY (VLV/CHV/BXT)
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index d5a7a5e7ee7e..004326291854 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -150,28 +150,28 @@ static int vgt_balloon_space(struct drm_mm *mm,
  * of its graphic space being zero. Yet there are some portions ballooned out(
  * the shadow part, which are marked as reserved by drm allocator). From the
  * host poin

[RFC v2 1/5] drm/mediatek: rename macros, add chip suffix

2016-06-01 Thread YT Shen
Hi Thierry,

On Mon, 2016-05-30 at 12:41 +0200, Thierry Reding wrote:
> On Fri, May 20, 2016 at 11:05:32PM +0800, yt.shen at mediatek.com wrote:
> > From: YT Shen 
> > 
> > Add MT8173 suffix for hardware related macros.
> > 
> > Signed-off-by: YT Shen 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp.c |   62 
> > 
> >  1 file changed, 31 insertions(+), 31 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> > index 17ba935..d6aafd4 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> > @@ -36,21 +36,21 @@
> >  #define DISP_REG_MUTEX_MOD(n)  (0x2c + 0x20 * (n))
> >  #define DISP_REG_MUTEX_SOF(n)  (0x30 + 0x20 * (n))
> >  
> > -#define MUTEX_MOD_DISP_OVL0BIT(11)
> > -#define MUTEX_MOD_DISP_OVL1BIT(12)
> > -#define MUTEX_MOD_DISP_RDMA0   BIT(13)
> > -#define MUTEX_MOD_DISP_RDMA1   BIT(14)
> > -#define MUTEX_MOD_DISP_RDMA2   BIT(15)
> > -#define MUTEX_MOD_DISP_WDMA0   BIT(16)
> > -#define MUTEX_MOD_DISP_WDMA1   BIT(17)
> > -#define MUTEX_MOD_DISP_COLOR0  BIT(18)
> > -#define MUTEX_MOD_DISP_COLOR1  BIT(19)
> > -#define MUTEX_MOD_DISP_AAL BIT(20)
> > -#define MUTEX_MOD_DISP_GAMMA   BIT(21)
> > -#define MUTEX_MOD_DISP_UFOEBIT(22)
> > -#define MUTEX_MOD_DISP_PWM0BIT(23)
> > -#define MUTEX_MOD_DISP_PWM1BIT(24)
> > -#define MUTEX_MOD_DISP_OD  BIT(25)
> > +#define MUTEX_MOD_DISP_OVL0_MT8173 BIT(11)
> > +#define MUTEX_MOD_DISP_OVL1_MT8173 BIT(12)
> > +#define MUTEX_MOD_DISP_RDMA0_MT8173BIT(13)
> > +#define MUTEX_MOD_DISP_RDMA1_MT8173BIT(14)
> > +#define MUTEX_MOD_DISP_RDMA2_MT8173BIT(15)
> > +#define MUTEX_MOD_DISP_WDMA0_MT8173BIT(16)
> > +#define MUTEX_MOD_DISP_WDMA1_MT8173BIT(17)
> > +#define MUTEX_MOD_DISP_COLOR0_MT8173   BIT(18)
> > +#define MUTEX_MOD_DISP_COLOR1_MT8173   BIT(19)
> > +#define MUTEX_MOD_DISP_AAL_MT8173  BIT(20)
> > +#define MUTEX_MOD_DISP_GAMMA_MT8173BIT(21)
> > +#define MUTEX_MOD_DISP_UFOE_MT8173 BIT(22)
> > +#define MUTEX_MOD_DISP_PWM0_MT8173 BIT(23)
> > +#define MUTEX_MOD_DISP_PWM1_MT8173 BIT(24)
> > +#define MUTEX_MOD_DISP_OD_MT8173   BIT(25)
> 
> Just a random fly-by comment: this looks like a hardware spinlock, have
> you ever considered implementing this as a hwspinlock driver? See the
> drivers/hwspinlock subdirectory for existing examples.
> 
> Thierry

I see the drivers/hwspinlock and Documentation/hwspinlock.txt
Yes, we can implement this like a hardware spinlock.  But I have some
questions, the document says:

"Hardware spinlock modules provide hardware assistance for
synchronization and mutual exclusion between heterogeneous processors
and those not operating under a single, shared operating system"

The mutex here is a handshake interface between software and hardware.
The hardware is the display controller, the software is the drm display
driver, and no other consumers need to access this mutex.  So I think
that using hwspinlock to implement a bit too complicated, am I right?

I will use iopoll macros to implement this part in the next version.
Thanks.

yt.shen





[RFC v2 3/5] drm/mediatek: add *driver_data for different hardware settings

2016-06-01 Thread YT Shen
Hi Thierry,

On Mon, 2016-05-30 at 12:45 +0200, Thierry Reding wrote:
> On Mon, May 23, 2016 at 05:43:02PM +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > One comment below.
> > 
> > On Fri, 2016-05-20 at 23:05 +0800, yt.shen at mediatek.com wrote:
> > > From: YT Shen 
> > > 
> > > There are some hardware settings changed, between MT8173 & MT2701:
> > > DISP_OVL address offset changed, color format definition changed.
> > > DISP_RDMA fifo size changed.
> > > DISP_COLOR offset changed.
> > > 
> > > Signed-off-by: YT Shen 
> > > ---
> > > +
> > > +static inline struct mtk_ddp_comp_driver_data *mtk_ovl_get_driver_data(
> > > + struct platform_device *pdev)
> > > +{
> > > + const struct of_device_id *of_id =
> > > + of_match_device(mtk_disp_ovl_driver_dt_match, &pdev->dev);
> > > +
> > > + return (struct mtk_ddp_comp_driver_data *)of_id->data;
> > > +}
> > > +
> > > +static inline struct mtk_ddp_comp_driver_data *mtk_rdma_get_driver_data(
> > > + struct platform_device *pdev)
> > > +{
> > > + const struct of_device_id *of_id =
> > > + of_match_device(mtk_disp_rdma_driver_dt_match, &pdev->dev);
> > > +
> > > + return (struct mtk_ddp_comp_driver_data *)of_id->data;
> > > +}
> > > +
> > > +static inline struct mtk_ddp_comp_driver_data *mtk_color_get_driver_data(
> > > + struct device_node *node)
> > > +{
> > > + const struct of_device_id *of_id =
> > > + of_match_node(mtk_disp_color_driver_dt_match, node);
> > > +
> > > + return (struct mtk_ddp_comp_driver_data *)of_id->data;
> > > +}
> > > + 
> > 
> > These three functions looks the same with different parameter:
> > mtk_disp_ovl_driver_dt_match, mtk_disp_rdma_driver_dt_match, and
> > mtk_disp_color_driver_dt_match. So merge them to prevent duplicated
> > code.
> 
> I think what you really want is of_device_get_match_data().
> 
> Thierry

Great, that function is really what we need, thanks.

yt.shen




[PATCH] drm/rockchip: vop: do axi reset in vop initial time

2016-06-01 Thread Yakir Yang
There is a bug in RK3399 VOP, when bootloader/kernel only enable
VOP Big or VOP Little to display, then VOP IOMMU would failed to
reset at the initial time and VOP register couldn't write rightly.

After do the pure reset of VOP module, then things back to right.

Signed-off-by: Yakir Yang 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1c4d5b5..4150323 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1292,7 +1292,7 @@ static int vop_initial(struct vop *vop)
 {
const struct vop_data *vop_data = vop->data;
const struct vop_reg_data *init_table = vop_data->init_table;
-   struct reset_control *ahb_rst;
+   struct reset_control *ahb_rst, *axi_rst;
int i, ret;

vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
@@ -1331,6 +1331,19 @@ static int vop_initial(struct vop *vop)
}

/*
+* do aclk_reset, reset all vop registers.
+*/
+   axi_rst = devm_reset_control_get(vop->dev, "axi");
+   if (IS_ERR(axi_rst)) {
+   dev_err(vop->dev, "failed to get axi reset\n");
+   ret = PTR_ERR(axi_rst);
+   goto err_disable_aclk;
+   }
+   reset_control_assert(axi_rst);
+   usleep_range(10, 20);
+   reset_control_deassert(axi_rst);
+
+   /*
 * do hclk_reset, reset all vop registers.
 */
ahb_rst = devm_reset_control_get(vop->dev, "ahb");
-- 
1.9.1




[PATCH v3] drm: Only create a cmdline mode if no probed modes match

2016-06-01 Thread Chris Wilson
The intention of using video=: is primarily to select
the user's preferred resolution at startup. Currently we always create a
new mode irrespective of whether the monitor has a native mode at the
desired resolution. This has the issue that we may then select the fake
mode rather the native mode during fb_helper->inital_config() and so
if the fake mode is invalid we then end up with a loss of signal. Oops.
This invalid fake mode would also be exported to userspace, who
potentially may make the same mistake.

To avoid this issue, we filter out the added command line mode if we
detect the desired resolution (and clock if specified) amongst the
probed modes. This fixes the immediate problem of adding a duplicate
mode, but perhaps more generically we should avoid adding a GTF mode if
the monitor has an EDID that is not GTF-compatible, or similarly for
CVT.

Fixes regression from

commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
Author: Chris Wilson 
Date:   Wed Aug 6 10:08:32 2014 +0200

drm: Perform cmdline mode parsing during connector initialisation

that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).

v2: Explicitly delete our earlier cmdline mode
v3: Mode pruning should now be sufficient to delete stale cmdline modes

Reported-by: Radek Dostál 
Signed-off-by: Chris Wilson 
Cc: Radek Dostál 
Cc: Jesse Barnes 
Cc: Ville Syrjälä 
Cc: Daniel Vetter 
Cc: dri-devel at lists.freedesktop.org
Cc: Julia Lemire 
Cc: Dave Airlie 
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/drm_probe_helper.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 0329080d7f7c..a705ed12c062 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -82,13 +82,28 @@ drm_mode_validate_flag(const struct drm_display_mode *mode,

 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
 {
+   struct drm_cmdline_mode *cmdline_mode;
struct drm_display_mode *mode;

-   if (!connector->cmdline_mode.specified)
+   cmdline_mode = &connector->cmdline_mode;
+   if (!cmdline_mode->specified)
return 0;

+   /* Only add a GTF mode if we find no matching probed modes */
+   list_for_each_entry(mode, &connector->probed_modes, head) {
+   if (mode->hdisplay != cmdline_mode->xres ||
+   mode->vdisplay != cmdline_mode->yres)
+   continue;
+
+   if (cmdline_mode->refresh_specified &&
+   mode->vrefresh != cmdline_mode->refresh)
+   continue;
+
+   return 0;
+   }
+
mode = drm_mode_create_from_cmdline_mode(connector->dev,
-&connector->cmdline_mode);
+cmdline_mode);
if (mode == NULL)
return 0;

-- 
2.8.1



[PATCH v3] drm: Only create a cmdline mode if no probed modes match

2016-06-01 Thread Ville Syrjälä
On Wed, Jun 01, 2016 at 10:34:36AM +0100, Chris Wilson wrote:
> The intention of using video=: is primarily to select
> the user's preferred resolution at startup. Currently we always create a
> new mode irrespective of whether the monitor has a native mode at the
> desired resolution. This has the issue that we may then select the fake
> mode rather the native mode during fb_helper->inital_config() and so
> if the fake mode is invalid we then end up with a loss of signal. Oops.
> This invalid fake mode would also be exported to userspace, who
> potentially may make the same mistake.
> 
> To avoid this issue, we filter out the added command line mode if we
> detect the desired resolution (and clock if specified) amongst the
> probed modes. This fixes the immediate problem of adding a duplicate
> mode, but perhaps more generically we should avoid adding a GTF mode if
> the monitor has an EDID that is not GTF-compatible, or similarly for
> CVT.
> 
> Fixes regression from
> 
> commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> Author: Chris Wilson 
> Date:   Wed Aug 6 10:08:32 2014 +0200
> 
> drm: Perform cmdline mode parsing during connector initialisation
> 
> that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
> 
> v2: Explicitly delete our earlier cmdline mode
> v3: Mode pruning should now be sufficient to delete stale cmdline modes
> 
> Reported-by: Radek Dostál 
> Signed-off-by: Chris Wilson 
> Cc: Radek Dostál 
> Cc: Jesse Barnes 
> Cc: Ville Syrjälä 
> Cc: Daniel Vetter 
> Cc: dri-devel at lists.freedesktop.org
> Cc: Julia Lemire 
> Cc: Dave Airlie 
> Cc: stable at vger.kernel.org
> ---
>  drivers/gpu/drm/drm_probe_helper.c | 19 +--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index 0329080d7f7c..a705ed12c062 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -82,13 +82,28 @@ drm_mode_validate_flag(const struct drm_display_mode 
> *mode,
>  
>  static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
>  {
> + struct drm_cmdline_mode *cmdline_mode;
>   struct drm_display_mode *mode;
>  
> - if (!connector->cmdline_mode.specified)
> + cmdline_mode = &connector->cmdline_mode;
> + if (!cmdline_mode->specified)
>   return 0;
>  
> + /* Only add a GTF mode if we find no matching probed modes */
> + list_for_each_entry(mode, &connector->probed_modes, head) {
> + if (mode->hdisplay != cmdline_mode->xres ||
> + mode->vdisplay != cmdline_mode->yres)
> + continue;
> +
> + if (cmdline_mode->refresh_specified &&
> + mode->vrefresh != cmdline_mode->refresh)

I think we might not have .vrefresh populated for the probed modes.
We update .vrefresh only for the modes left on the real mode list in the
end.

> + continue;
> +
> + return 0;
> + }
> +
>   mode = drm_mode_create_from_cmdline_mode(connector->dev,
> -  &connector->cmdline_mode);
> +  cmdline_mode);
>   if (mode == NULL)
>   return 0;
>  
> -- 
> 2.8.1

-- 
Ville Syrjälä
Intel OTC


[Intel-gfx] [PATCH v2 03/21] drm: Make drm_connector_register() safe against multiple calls

2016-06-01 Thread Daniel Vetter
On Mon, May 30, 2016 at 09:38:21AM +0100, Chris Wilson wrote:
> Protect against drivers that may try to register the connector more
> than once, or who try to unregister it multiple times.
> 
> Signed-off-by: Chris Wilson 
> Cc: dri-devel at lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_crtc.c | 9 +
>  include/drm/drm_crtc.h | 1 +
>  2 files changed, 10 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 81641544ac3e..8b9ee921a9e1 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1030,6 +1030,9 @@ int drm_connector_register(struct drm_connector 
> *connector)
>  {
>   int ret;
>  
> + if (connector->registered)
> + return 0;
> +
>   ret = drm_sysfs_connector_add(connector);
>   if (ret)
>   return ret;
> @@ -1047,6 +1050,7 @@ int drm_connector_register(struct drm_connector 
> *connector)
>  
>   drm_mode_object_register(connector->dev, &connector->base);
>  
> + connector->registered = true;
>   return 0;
>  
>  err_debugfs:
> @@ -1065,11 +1069,16 @@ EXPORT_SYMBOL(drm_connector_register);
>   */
>  void drm_connector_unregister(struct drm_connector *connector)
>  {
> + if (!connector->registered)
> + return;
> +
>   if (connector->funcs->early_unregister)
>   connector->funcs->early_unregister(connector);
>  
>   drm_sysfs_connector_remove(connector);
>   drm_debugfs_connector_remove(connector);
> +
> + connector->registered = false;
>  }
>  EXPORT_SYMBOL(drm_connector_unregister);
>  
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 77b775cff4e7..35e47eea5ee1 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -1212,6 +1212,7 @@ struct drm_connector {
>   bool interlace_allowed;
>   bool doublescan_allowed;
>   bool stereo_allowed;
> + bool registered;

Needs kerneldoc for this on, with that fixed

Reviewed-by: Daniel Vetter 

>   struct list_head modes; /* list of modes on this connector */
>  
>   enum drm_connector_status status;
> -- 
> 2.8.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


[Intel-gfx] [PATCH v2 04/21] drm: Automatically unregister the connector during cleanup

2016-06-01 Thread Daniel Vetter
On Mon, May 30, 2016 at 09:38:22AM +0100, Chris Wilson wrote:
> As we now can call drm_connector_unregister() multiple times, provide a
> failsafe unregister for a connector when cleaning it up.
> 
> Signed-off-by: Chris Wilson 
> Cc: dri-devel at lists.freedesktop.org

Reviewed-by: Daniel Vetter 

Maybe WARN_ON(connector->registered); or is that way too noisy?
-Daniel

> ---
>  drivers/gpu/drm/drm_crtc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 8b9ee921a9e1..ba6689ba0ad9 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -984,6 +984,8 @@ void drm_connector_cleanup(struct drm_connector 
> *connector)
>   struct drm_device *dev = connector->dev;
>   struct drm_display_mode *mode, *t;
>  
> + drm_connector_unregister(connector);
> +
>   if (connector->tile_group) {
>   drm_mode_put_tile_group(dev, connector->tile_group);
>   connector->tile_group = NULL;
> -- 
> 2.8.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


[PATCH] drm/doc: Switch to sphinx/rst fixed-width quoting

2016-06-01 Thread Jani Nikula
On Wed, 01 Jun 2016, Daniel Vetter  wrote:
> There's still something very fishy going on with some of these, e.g.
> the drm_modeset_lock Example: and the "Standard GTF Parameters:" Line
> somehow get treated as heading when just appending a :: at the end of
> those lines. But it seems to work everywhere else. Maybe the
> kernel-doc heading generation logic is still a bit wonky?

Try adding a blank line between the line with trailing :: and the actual
preformatted text. Seems to do the right thing for me.

http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#literal-blocks

"Blank lines are required before and after a literal block, but these
blank lines are not included as part of the literal block."


BR,
Jani.

> v2: Found more. Also s/\//#/ in the vgpu ascii-art - sphinx treats
> those as comments and switch to variable-width, which wreaks the
> layout.
>
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_bridge.c|  2 +-
>  drivers/gpu/drm/drm_fb_cma_helper.c |  2 +-
>  drivers/gpu/drm/drm_fops.c  |  2 +-
>  drivers/gpu/drm/drm_modes.c |  5 -
>  drivers/gpu/drm/drm_modeset_lock.c  |  2 +-
>  drivers/gpu/drm/drm_vma_manager.c   |  3 +++
>  drivers/gpu/drm/i915/i915_reg.h |  2 +-
>  drivers/gpu/drm/i915/i915_vgpu.c| 24 
>  include/drm/drm_modes.h |  2 ++
>  9 files changed, 26 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index b3654404abd0..255543086590 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -36,7 +36,7 @@
>   * encoder chain.
>   *
>   * A bridge is always attached to a single &drm_encoder at a time, but can be
> - * either connected to it directly, or through an intermediate bridge:
> + * either connected to it directly, or through an intermediate bridge::
>   *
>   * encoder ---> bridge B ---> bridge A
>   *
> diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c 
> b/drivers/gpu/drm/drm_fb_cma_helper.c
> index 2b33b191a172..c50a0ba6fdba 100644
> --- a/drivers/gpu/drm/drm_fb_cma_helper.c
> +++ b/drivers/gpu/drm/drm_fb_cma_helper.c
> @@ -52,7 +52,7 @@ struct drm_fbdev_cma {
>   * will be set up automatically. dirty() is called by
>   * drm_fb_helper_deferred_io() in process context (struct delayed_work).
>   *
> - * Example fbdev deferred io code:
> + * Example fbdev deferred io code::
>   *
>   * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb,
>   *  struct drm_file *file_priv,
> diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
> index 5921b203503a..323c238fcac7 100644
> --- a/drivers/gpu/drm/drm_fops.c
> +++ b/drivers/gpu/drm/drm_fops.c
> @@ -68,7 +68,7 @@ DEFINE_MUTEX(drm_global_mutex);
>   * specific implementations. For GEM-based drivers this is drm_gem_mmap().
>   *
>   * No other file operations are supported by the DRM userspace API. Overall 
> the
> - * following is an example #file_operations structure:
> + * following is an example #file_operations structure::
>   *
>   * static const example_drm_fops = {
>   * .owner = THIS_MODULE,
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index e5e6f504d8cc..aae86c1857ec 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -552,7 +552,10 @@ EXPORT_SYMBOL(drm_gtf_mode_complex);
>   * I also refer to the function of fb_get_mode in the file of
>   * drivers/video/fbmon.c
>   *
> - * Standard GTF parameters:
> + * Standard GTF parameters
> + *
> + * ::
> + *
>   * M = 600
>   * C = 40
>   * K = 128
> diff --git a/drivers/gpu/drm/drm_modeset_lock.c 
> b/drivers/gpu/drm/drm_modeset_lock.c
> index f33ebe638a28..61146f5b4f56 100644
> --- a/drivers/gpu/drm/drm_modeset_lock.c
> +++ b/drivers/gpu/drm/drm_modeset_lock.c
> @@ -37,7 +37,7 @@
>   *
>   * For basic principles of &ww_mutex, see: 
> Documentation/locking/ww-mutex-design.txt
>   *
> - * The basic usage pattern is to:
> + * The basic usage pattern is to::
>   *
>   * drm_modeset_acquire_init(&ctx)
>   * retry:
> diff --git a/drivers/gpu/drm/drm_vma_manager.c 
> b/drivers/gpu/drm/drm_vma_manager.c
> index 2f2ecde8285b..f306c8855978 100644
> --- a/drivers/gpu/drm/drm_vma_manager.c
> +++ b/drivers/gpu/drm/drm_vma_manager.c
> @@ -127,6 +127,9 @@ EXPORT_SYMBOL(drm_vma_offset_manager_destroy);
>   * used to implement weakly referenced lookups using kref_get_unless_zero().
>   *
>   * Example:
> + *
> + * ::
> + *
>   * drm_vma_offset_lock_lookup(mgr);
>   * node = drm_vma_offset_lookup_locked(mgr);
>   * if (node)
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 216cc4ba74ee..d25dd1d694bc 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -886,7 +886,7 @@ enum skl_disp_power_wells {
>   * PLLs can be routed to any transcoder A/B/C.
>   *
>   * Note: DD

[PATCH v3] drm: Only create a cmdline mode if no probed modes match

2016-06-01 Thread Chris Wilson
On Wed, Jun 01, 2016 at 12:43:53PM +0300, Ville Syrjälä wrote:
> On Wed, Jun 01, 2016 at 10:34:36AM +0100, Chris Wilson wrote:
> > The intention of using video=: is primarily to select
> > the user's preferred resolution at startup. Currently we always create a
> > new mode irrespective of whether the monitor has a native mode at the
> > desired resolution. This has the issue that we may then select the fake
> > mode rather the native mode during fb_helper->inital_config() and so
> > if the fake mode is invalid we then end up with a loss of signal. Oops.
> > This invalid fake mode would also be exported to userspace, who
> > potentially may make the same mistake.
> > 
> > To avoid this issue, we filter out the added command line mode if we
> > detect the desired resolution (and clock if specified) amongst the
> > probed modes. This fixes the immediate problem of adding a duplicate
> > mode, but perhaps more generically we should avoid adding a GTF mode if
> > the monitor has an EDID that is not GTF-compatible, or similarly for
> > CVT.
> > 
> > Fixes regression from
> > 
> > commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> > Author: Chris Wilson 
> > Date:   Wed Aug 6 10:08:32 2014 +0200
> > 
> > drm: Perform cmdline mode parsing during connector initialisation
> > 
> > that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
> > 
> > v2: Explicitly delete our earlier cmdline mode
> > v3: Mode pruning should now be sufficient to delete stale cmdline modes
> > 
> > Reported-by: Radek Dostál 
> > Signed-off-by: Chris Wilson 
> > Cc: Radek Dostál 
> > Cc: Jesse Barnes 
> > Cc: Ville Syrjälä 
> > Cc: Daniel Vetter 
> > Cc: dri-devel at lists.freedesktop.org
> > Cc: Julia Lemire 
> > Cc: Dave Airlie 
> > Cc: stable at vger.kernel.org
> > ---
> >  drivers/gpu/drm/drm_probe_helper.c | 19 +--
> >  1 file changed, 17 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> > b/drivers/gpu/drm/drm_probe_helper.c
> > index 0329080d7f7c..a705ed12c062 100644
> > --- a/drivers/gpu/drm/drm_probe_helper.c
> > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > @@ -82,13 +82,28 @@ drm_mode_validate_flag(const struct drm_display_mode 
> > *mode,
> >  
> >  static int drm_helper_probe_add_cmdline_mode(struct drm_connector 
> > *connector)
> >  {
> > +   struct drm_cmdline_mode *cmdline_mode;
> > struct drm_display_mode *mode;
> >  
> > -   if (!connector->cmdline_mode.specified)
> > +   cmdline_mode = &connector->cmdline_mode;
> > +   if (!cmdline_mode->specified)
> > return 0;
> >  
> > +   /* Only add a GTF mode if we find no matching probed modes */
> > +   list_for_each_entry(mode, &connector->probed_modes, head) {
> > +   if (mode->hdisplay != cmdline_mode->xres ||
> > +   mode->vdisplay != cmdline_mode->yres)
> > +   continue;
> > +
> > +   if (cmdline_mode->refresh_specified &&
> > +   mode->vrefresh != cmdline_mode->refresh)
> 
> I think we might not have .vrefresh populated for the probed modes.
> We update .vrefresh only for the modes left on the real mode list in the
> end.

In that case, if cmdline_mode->refresh_specified keep and leave a
comment suggesting we might be able to do better :)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH v3] drm: Only create a cmdline mode if no probed modes match

2016-06-01 Thread Chris Wilson
On Wed, Jun 01, 2016 at 12:43:53PM +0300, Ville Syrjälä wrote:
> On Wed, Jun 01, 2016 at 10:34:36AM +0100, Chris Wilson wrote:
> > The intention of using video=: is primarily to select
> > the user's preferred resolution at startup. Currently we always create a
> > new mode irrespective of whether the monitor has a native mode at the
> > desired resolution. This has the issue that we may then select the fake
> > mode rather the native mode during fb_helper->inital_config() and so
> > if the fake mode is invalid we then end up with a loss of signal. Oops.
> > This invalid fake mode would also be exported to userspace, who
> > potentially may make the same mistake.
> > 
> > To avoid this issue, we filter out the added command line mode if we
> > detect the desired resolution (and clock if specified) amongst the
> > probed modes. This fixes the immediate problem of adding a duplicate
> > mode, but perhaps more generically we should avoid adding a GTF mode if
> > the monitor has an EDID that is not GTF-compatible, or similarly for
> > CVT.
> > 
> > Fixes regression from
> > 
> > commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> > Author: Chris Wilson 
> > Date:   Wed Aug 6 10:08:32 2014 +0200
> > 
> > drm: Perform cmdline mode parsing during connector initialisation
> > 
> > that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
> > 
> > v2: Explicitly delete our earlier cmdline mode
> > v3: Mode pruning should now be sufficient to delete stale cmdline modes
> > 
> > Reported-by: Radek Dostál 
> > Signed-off-by: Chris Wilson 
> > Cc: Radek Dostál 
> > Cc: Jesse Barnes 
> > Cc: Ville Syrjälä 
> > Cc: Daniel Vetter 
> > Cc: dri-devel at lists.freedesktop.org
> > Cc: Julia Lemire 
> > Cc: Dave Airlie 
> > Cc: stable at vger.kernel.org
> > ---
> >  drivers/gpu/drm/drm_probe_helper.c | 19 +--
> >  1 file changed, 17 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> > b/drivers/gpu/drm/drm_probe_helper.c
> > index 0329080d7f7c..a705ed12c062 100644
> > --- a/drivers/gpu/drm/drm_probe_helper.c
> > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > @@ -82,13 +82,28 @@ drm_mode_validate_flag(const struct drm_display_mode 
> > *mode,
> >  
> >  static int drm_helper_probe_add_cmdline_mode(struct drm_connector 
> > *connector)
> >  {
> > +   struct drm_cmdline_mode *cmdline_mode;
> > struct drm_display_mode *mode;
> >  
> > -   if (!connector->cmdline_mode.specified)
> > +   cmdline_mode = &connector->cmdline_mode;
> > +   if (!cmdline_mode->specified)
> > return 0;
> >  
> > +   /* Only add a GTF mode if we find no matching probed modes */
> > +   list_for_each_entry(mode, &connector->probed_modes, head) {
> > +   if (mode->hdisplay != cmdline_mode->xres ||
> > +   mode->vdisplay != cmdline_mode->yres)
> > +   continue;
> > +
> > +   if (cmdline_mode->refresh_specified &&
> > +   mode->vrefresh != cmdline_mode->refresh)
> 
> I think we might not have .vrefresh populated for the probed modes.
> We update .vrefresh only for the modes left on the real mode list in the
> end.

Or drm_mode_vrefresh() ?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[Intel-gfx] [PATCH v2 05/21] drm: Minimally initialise drm_dp_aux

2016-06-01 Thread Daniel Vetter
On Mon, May 30, 2016 at 09:38:23AM +0100, Chris Wilson wrote:
> When trying to split up the initialisation phase and the registration
> phase, one immediate problem encountered is trying to use our own i2c
> devices before registration with userspace. drm_dp_aux in particular
> only offers an interface for setting up the device after we have exposed
> the connector via sysfs. In order to break the chicken-and-egg problem,
> export drm_dp_aux_init() to minimally prepare the i2c device for
> internal use before drm_connector_register().
> 
> Signed-off-by: Chris Wilson 
> Cc: Rafael Antognolli 
> Cc: dri-devel at lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 18 +-
>  include/drm/drm_dp_helper.h |  1 +
>  2 files changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index eeaf5a7c3aa7..e1900d386685 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -774,6 +774,17 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
>   .master_xfer = drm_dp_i2c_xfer,
>  };
>  
> +void drm_dp_aux_init(struct drm_dp_aux *aux)

Needs kerneldoc. Pleas also cross-reference to drm_dp_aux_register. Didn't
read all the i2c code to make sure stuff really works with just that, but
makes sense.

All three core patches also need an ack from Dave.
-Daniel

> +{
> + mutex_init(&aux->hw_mutex);
> + rt_mutex_init(&aux->ddc.bus_lock);
> +
> + aux->ddc.algo = &drm_dp_i2c_algo;
> + aux->ddc.algo_data = aux;
> + aux->ddc.retries = 3;
> +}
> +EXPORT_SYMBOL(drm_dp_aux_init);
> +
>  /**
>   * drm_dp_aux_register() - initialise and register aux channel
>   * @aux: DisplayPort AUX channel
> @@ -784,11 +795,8 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
>  {
>   int ret;
>  
> - mutex_init(&aux->hw_mutex);
> -
> - aux->ddc.algo = &drm_dp_i2c_algo;
> - aux->ddc.algo_data = aux;
> - aux->ddc.retries = 3;
> + if (!aux->ddc.algo)
> + drm_dp_aux_init(aux);
>  
>   aux->ddc.class = I2C_CLASS_DDC;
>   aux->ddc.owner = THIS_MODULE;
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 5a848e734422..4d85cf2874af 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -805,6 +805,7 @@ int drm_dp_link_power_up(struct drm_dp_aux *aux, struct 
> drm_dp_link *link);
>  int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link);
>  int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
>  
> +void drm_dp_aux_init(struct drm_dp_aux *aux);
>  int drm_dp_aux_register(struct drm_dp_aux *aux);
>  void drm_dp_aux_unregister(struct drm_dp_aux *aux);
>  
> -- 
> 2.8.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


[PATCH] drm/rockchip: vop: do axi reset in vop initial time

2016-06-01 Thread Mark yao
On 2016年06月01日 17:19, Yakir Yang wrote:
> There is a bug in RK3399 VOP, when bootloader/kernel only enable
> VOP Big or VOP Little to display, then VOP IOMMU would failed to
> reset at the initial time and VOP register couldn't write rightly.
>
> After do the pure reset of VOP module, then things back to right.
>
> Signed-off-by: Yakir Yang 
Hi Yakir

I think you get vop iommu reset failed should be IOMMU Page fault, the 
vop iommu access a ummap address.

You should ensure all vop windows access right iommu mapping address 
before attach iommu.

Actually, I'm working no flash display from bootloader to kernel, and 
prepare remove all the reset on vop initial, because it would flash the 
display.

Thanks.

> ---
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 ++-
>   1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 1c4d5b5..4150323 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -1292,7 +1292,7 @@ static int vop_initial(struct vop *vop)
>   {
>   const struct vop_data *vop_data = vop->data;
>   const struct vop_reg_data *init_table = vop_data->init_table;
> - struct reset_control *ahb_rst;
> + struct reset_control *ahb_rst, *axi_rst;
>   int i, ret;
>   
>   vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
> @@ -1331,6 +1331,19 @@ static int vop_initial(struct vop *vop)
>   }
>   
>   /*
> +  * do aclk_reset, reset all vop registers.
> +  */
> + axi_rst = devm_reset_control_get(vop->dev, "axi");
> + if (IS_ERR(axi_rst)) {
> + dev_err(vop->dev, "failed to get axi reset\n");
> + ret = PTR_ERR(axi_rst);
> + goto err_disable_aclk;
> + }
> + reset_control_assert(axi_rst);
> + usleep_range(10, 20);
> + reset_control_deassert(axi_rst);
> +
> + /*
>* do hclk_reset, reset all vop registers.
>*/
>   ahb_rst = devm_reset_control_get(vop->dev, "ahb");


-- 
ï¼­ark Yao




[PATCH v4] drm: Only create a cmdline mode if no probed modes match

2016-06-01 Thread Chris Wilson
The intention of using video=: is primarily to select
the user's preferred resolution at startup. Currently we always create a
new mode irrespective of whether the monitor has a native mode at the
desired resolution. This has the issue that we may then select the fake
mode rather the native mode during fb_helper->inital_config() and so
if the fake mode is invalid we then end up with a loss of signal. Oops.
This invalid fake mode would also be exported to userspace, who
potentially may make the same mistake.

To avoid this issue, we filter out the added command line mode if we
detect the desired resolution (and clock if specified) amongst the
probed modes. This fixes the immediate problem of adding a duplicate
mode, but perhaps more generically we should avoid adding a GTF mode if
the monitor has an EDID that is not GTF-compatible, or similarly for
CVT.

Fixes regression from

commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
Author: Chris Wilson 
Date:   Wed Aug 6 10:08:32 2014 +0200

drm: Perform cmdline mode parsing during connector initialisation

that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).

v2: Explicitly delete our earlier cmdline mode
v3: Mode pruning should now be sufficient to delete stale cmdline modes
v4: Compute the vrefresh for the probed mode

Reported-by: Radek Dostál 
Signed-off-by: Chris Wilson 
Cc: Radek Dostál 
Cc: Jesse Barnes 
Cc: Ville Syrjälä 
Cc: Daniel Vetter 
Cc: dri-devel at lists.freedesktop.org
Cc: Julia Lemire 
Cc: Dave Airlie 
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/drm_probe_helper.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 0329080d7f7c..a0df377d7d1c 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -82,13 +82,30 @@ drm_mode_validate_flag(const struct drm_display_mode *mode,

 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
 {
+   struct drm_cmdline_mode *cmdline_mode;
struct drm_display_mode *mode;

-   if (!connector->cmdline_mode.specified)
+   cmdline_mode = &connector->cmdline_mode;
+   if (!cmdline_mode->specified)
return 0;

+   /* Only add a GTF mode if we find no matching probed modes */
+   list_for_each_entry(mode, &connector->probed_modes, head) {
+   if (mode->hdisplay != cmdline_mode->xres ||
+   mode->vdisplay != cmdline_mode->yres)
+   continue;
+
+   if (cmdline_mode->refresh_specified) {
+   /* The probed mode's vrefresh is set until later */
+   if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
+   continue;
+   }
+
+   return 0;
+   }
+
mode = drm_mode_create_from_cmdline_mode(connector->dev,
-&connector->cmdline_mode);
+cmdline_mode);
if (mode == NULL)
return 0;

-- 
2.8.1



[Intel-gfx] [PATCH v2 05/21] drm: Minimally initialise drm_dp_aux

2016-06-01 Thread Chris Wilson
On Wed, Jun 01, 2016 at 11:49:03AM +0200, Daniel Vetter wrote:
> On Mon, May 30, 2016 at 09:38:23AM +0100, Chris Wilson wrote:
> > When trying to split up the initialisation phase and the registration
> > phase, one immediate problem encountered is trying to use our own i2c
> > devices before registration with userspace. drm_dp_aux in particular
> > only offers an interface for setting up the device after we have exposed
> > the connector via sysfs. In order to break the chicken-and-egg problem,
> > export drm_dp_aux_init() to minimally prepare the i2c device for
> > internal use before drm_connector_register().
> > 
> > Signed-off-by: Chris Wilson 
> > Cc: Rafael Antognolli 
> > Cc: dri-devel at lists.freedesktop.org
> > ---
> >  drivers/gpu/drm/drm_dp_helper.c | 18 +-
> >  include/drm/drm_dp_helper.h |  1 +
> >  2 files changed, 14 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_dp_helper.c 
> > b/drivers/gpu/drm/drm_dp_helper.c
> > index eeaf5a7c3aa7..e1900d386685 100644
> > --- a/drivers/gpu/drm/drm_dp_helper.c
> > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > @@ -774,6 +774,17 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
> > .master_xfer = drm_dp_i2c_xfer,
> >  };
> >  
> > +void drm_dp_aux_init(struct drm_dp_aux *aux)
> 
> Needs kerneldoc. Pleas also cross-reference to drm_dp_aux_register. Didn't
> read all the i2c code to make sure stuff really works with just that, but
> makes sense.

Already added the kerneldoc (mostly copy'pasted from
drm_dp_aux_register), but good job you didn't check the i2c code as it
changed in v4.7. However, it motivated a better patch as i2c now allows
for us to control the locking and so we can make the interaction between
i2c and the drm_dp_aux->hw_mutex (used for the DPCD bypass) much
clearer.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH v3] drm: Only create a cmdline mode if no probed modes match

2016-06-01 Thread Ville Syrjälä
On Wed, Jun 01, 2016 at 10:47:51AM +0100, Chris Wilson wrote:
> On Wed, Jun 01, 2016 at 12:43:53PM +0300, Ville Syrjälä wrote:
> > On Wed, Jun 01, 2016 at 10:34:36AM +0100, Chris Wilson wrote:
> > > The intention of using video=: is primarily to select
> > > the user's preferred resolution at startup. Currently we always create a
> > > new mode irrespective of whether the monitor has a native mode at the
> > > desired resolution. This has the issue that we may then select the fake
> > > mode rather the native mode during fb_helper->inital_config() and so
> > > if the fake mode is invalid we then end up with a loss of signal. Oops.
> > > This invalid fake mode would also be exported to userspace, who
> > > potentially may make the same mistake.
> > > 
> > > To avoid this issue, we filter out the added command line mode if we
> > > detect the desired resolution (and clock if specified) amongst the
> > > probed modes. This fixes the immediate problem of adding a duplicate
> > > mode, but perhaps more generically we should avoid adding a GTF mode if
> > > the monitor has an EDID that is not GTF-compatible, or similarly for
> > > CVT.
> > > 
> > > Fixes regression from
> > > 
> > > commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> > > Author: Chris Wilson 
> > > Date:   Wed Aug 6 10:08:32 2014 +0200
> > > 
> > > drm: Perform cmdline mode parsing during connector initialisation
> > > 
> > > that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
> > > 
> > > v2: Explicitly delete our earlier cmdline mode
> > > v3: Mode pruning should now be sufficient to delete stale cmdline modes
> > > 
> > > Reported-by: Radek Dostál 
> > > Signed-off-by: Chris Wilson 
> > > Cc: Radek Dostál 
> > > Cc: Jesse Barnes 
> > > Cc: Ville Syrjälä 
> > > Cc: Daniel Vetter 
> > > Cc: dri-devel at lists.freedesktop.org
> > > Cc: Julia Lemire 
> > > Cc: Dave Airlie 
> > > Cc: stable at vger.kernel.org
> > > ---
> > >  drivers/gpu/drm/drm_probe_helper.c | 19 +--
> > >  1 file changed, 17 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> > > b/drivers/gpu/drm/drm_probe_helper.c
> > > index 0329080d7f7c..a705ed12c062 100644
> > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > @@ -82,13 +82,28 @@ drm_mode_validate_flag(const struct drm_display_mode 
> > > *mode,
> > >  
> > >  static int drm_helper_probe_add_cmdline_mode(struct drm_connector 
> > > *connector)
> > >  {
> > > + struct drm_cmdline_mode *cmdline_mode;
> > >   struct drm_display_mode *mode;
> > >  
> > > - if (!connector->cmdline_mode.specified)
> > > + cmdline_mode = &connector->cmdline_mode;
> > > + if (!cmdline_mode->specified)
> > >   return 0;
> > >  
> > > + /* Only add a GTF mode if we find no matching probed modes */
> > > + list_for_each_entry(mode, &connector->probed_modes, head) {
> > > + if (mode->hdisplay != cmdline_mode->xres ||
> > > + mode->vdisplay != cmdline_mode->yres)
> > > + continue;
> > > +
> > > + if (cmdline_mode->refresh_specified &&
> > > + mode->vrefresh != cmdline_mode->refresh)
> > 
> > I think we might not have .vrefresh populated for the probed modes.
> > We update .vrefresh only for the modes left on the real mode list in the
> > end.
> 
> Or drm_mode_vrefresh() ?

That should work.

-- 
Ville Syrjälä
Intel OTC


[PATCH v2 02/21] drm: Add a callback from connector registering

2016-06-01 Thread Daniel Vetter
On Mon, May 30, 2016 at 09:38:20AM +0100, Chris Wilson wrote:
> If a driver wants to more precisely control its initialisation and in
> particular, defer registering its interfaces with userspace until after
> everything is setup, it also needs to defer registering the connectors.
> As some devices need more work during registration, add a callback so
> that drivers can do additional work if required for a connector.
> 
> Correspondingly, we also require an unregister callback.
> 
> Signed-off-by: Chris Wilson 
> Cc: Daniel Vetter 
> Cc: dri-devel at lists.freedesktop.org

tbh I'd call these hooks simply register/unregister. There shouldn't be
any need for ordering every with interface registration/unregistartion,
assuming drivers don't fumble things.

Besides naming&kerneldoc (see below) lgtm as an idea.
-Daniel

> ---
>  drivers/gpu/drm/drm_crtc.c | 18 --
>  include/drm/drm_crtc.h | 25 +
>  2 files changed, 41 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index d2a6d958ca76..81641544ac3e 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1036,13 +1036,24 @@ int drm_connector_register(struct drm_connector 
> *connector)
>  
>   ret = drm_debugfs_connector_add(connector);
>   if (ret) {
> - drm_sysfs_connector_remove(connector);
> - return ret;
> + goto err_sysfs;
> + }
> +
> + if (connector->funcs->late_register) {
> + ret = connector->funcs->late_register(connector);
> + if (ret)
> + goto err_debugfs;
>   }
>  
>   drm_mode_object_register(connector->dev, &connector->base);
>  
>   return 0;
> +
> +err_debugfs:
> + drm_debugfs_connector_remove(connector);
> +err_sysfs:
> + drm_sysfs_connector_remove(connector);
> + return ret;
>  }
>  EXPORT_SYMBOL(drm_connector_register);
>  
> @@ -1054,6 +1065,9 @@ EXPORT_SYMBOL(drm_connector_register);
>   */
>  void drm_connector_unregister(struct drm_connector *connector)
>  {
> + if (connector->funcs->early_unregister)
> + connector->funcs->early_unregister(connector);
> +
>   drm_sysfs_connector_remove(connector);
>   drm_debugfs_connector_remove(connector);
>  }
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index d1559cd04e3d..77b775cff4e7 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -926,6 +926,31 @@ struct drm_connector_funcs {
>uint64_t val);
>  
>   /**
> +  * @late_register:
> +  *
> +  * Register the connector with userspace, called from
> +  * drm_connector_register. This should be called after driver
> +  * load during its registration phase. All actions such as registering
> +  * with auxiliary devices (such as drm_dp_aux_register) should be done
> +  * during this callback. A simple guideline is that everything added
> +  * from this callback should be removed during early_unregister (and
> +  * vice versa).

Slight bikeshedding of the kerneldoc:

"This optional hook can be used to register additional userspace
interfaces attached to the connector, like backlight control, i2c, dp aux
or similar interfaces. It is called from drm_connector_register() when
registering all the core drm connector interfaces. Everything added from
this callback should be unregistered in the unregister() callback.

"Returns:

"0 on success or a negative failure code on error."

Similar bikeshed with unregister, i.e. state that it is optional, and that
is just to unregister additional interfaces.
> +  *
> +  */
> + int (*late_register)(struct drm_connector *connector);
> +
> + /**
> +  * @early_unregister:
> +  *
> +  * Unregister the connector with userspace, called from
> +  * drm_connector_unregister. This is called early in the driver

Please add () to drm_connector_unregister() so you end up with a hyperlink.

> +  * unload sequence to disable userspace access before data
> +  * structures are torndown.  A simple guideline is that this callback
> +  * should remove everything added during late_register (and vice versa).
> +  */
> + void (*early_unregister)(struct drm_connector *connector);
> +
> + /**
>* @destroy:
>*
>* Clean up connector resources. This is called at driver unload time
> -- 
> 2.8.1
> 

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


[PATCH v2 01/21] drm: Export drm_dev_init() for subclassing

2016-06-01 Thread Daniel Vetter
On Mon, May 30, 2016 at 09:38:19AM +0100, Chris Wilson wrote:
> In order to allow drivers to pack their privates and drm_device into one
> struct (e.g. for subclassing), export the initialisation routines for
> struct drm_device.
> 
> v2: Missed return ret. That error path had only one job to do!
> 
> Signed-off-by: Chris Wilson 
> Cc: Daniel Vetter 
> Cc: dri-devel at lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_drv.c | 63 
> ---
>  include/drm/drmP.h|  3 +++
>  2 files changed, 52 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index bff89226a344..f0553ccd4f71 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -549,11 +549,12 @@ static void drm_fs_inode_free(struct inode *inode)
>  }
>  
>  /**
> - * drm_dev_alloc - Allocate new DRM device
> - * @driver: DRM driver to allocate device for
> + * drm_dev_init - Initialise new DRM device
> + * @dev: DRM device
> + * @driver: DRM driver
>   * @parent: Parent device object
>   *
> - * Allocate and initialize a new DRM device. No device registration is done.
> + * Initialize a new DRM device. No device registration is done.
>   * Call drm_dev_register() to advertice the device to user space and 
> register it
>   * with other core subsystems. This should be done last in the device
>   * initialization sequence to make sure userspace can't access an 
> inconsistent
> @@ -565,18 +566,14 @@ static void drm_fs_inode_free(struct inode *inode)
>   * Note that for purely virtual devices @parent can be NULL.

Maybe add "Drivers which don't want to allocate their own device structure
embedding &drm_device can instead just call drm_dev_alloc()."
>   *
>   * RETURNS:
> - * Pointer to new DRM device, or NULL if out of memory.
> + * 0 on success, or error code on failure.
>   */
> -struct drm_device *drm_dev_alloc(struct drm_driver *driver,
> -  struct device *parent)
> +int drm_dev_init(struct drm_device *dev,
> +  struct drm_driver *driver,
> +  struct device *parent)
>  {
> - struct drm_device *dev;
>   int ret;
>  
> - dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> - if (!dev)
> - return NULL;
> -
>   kref_init(&dev->ref);
>   dev->dev = parent;
>   dev->driver = driver;
> @@ -638,7 +635,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver 
> *driver,
>   goto err_setunique;
>   }
>  
> - return dev;
> + return 0;
>  
>  err_setunique:
>   if (drm_core_check_feature(dev, DRIVER_GEM))
> @@ -653,8 +650,46 @@ err_minors:
>   drm_fs_inode_free(dev->anon_inode);
>  err_free:
>   mutex_destroy(&dev->master_mutex);
> - kfree(dev);
> - return NULL;
> + return ret;

for "goto err_minors" you need to set ret first, otherwise we'll fail and
return 0. Wasn't a problem because of the unconditional return NULL here.

> +}
> +EXPORT_SYMBOL(drm_dev_init);
> +
> +/**
> + * drm_dev_alloc - Allocate new DRM device
> + * @driver: DRM driver to allocate device for
> + * @parent: Parent device object
> + *
> + * Allocate and initialize a new DRM device. No device registration is done.
> + * Call drm_dev_register() to advertice the device to user space and 
> register it
> + * with other core subsystems. This should be done last in the device
> + * initialization sequence to make sure userspace can't access an 
> inconsistent
> + * state.
> + *
> + * The initial ref-count of the object is 1. Use drm_dev_ref() and
> + * drm_dev_unref() to take and drop further ref-counts.
> + *
> + * Note that for purely virtual devices @parent can be NULL.

Maybe we can also add "Drivers which want to subclass/embed struct
&drm_device should instead look at drm_dev_init()."

> + *
> + * RETURNS:
> + * Pointer to new DRM device, or NULL if out of memory.
> + */
> +struct drm_device *drm_dev_alloc(struct drm_driver *driver,
> +  struct device *parent)
> +{
> + struct drm_device *dev;
> + int ret;
> +
> + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> + if (!dev)
> + return NULL;
> +
> + ret = drm_dev_init(dev, driver, parent);
> + if (ret) {
> + kfree(dev);
> + return NULL;
> + }
> +
> + return dev;
>  }
>  EXPORT_SYMBOL(drm_dev_alloc);
>  
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index c5d29505f937..12dc5f9cad89 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -1075,6 +1075,9 @@ extern void drm_sysfs_hotplug_event(struct drm_device 
> *dev);
>  
>  struct drm_device *drm_dev_alloc(struct drm_driver *driver,
>struct device *parent);
> +int drm_dev_init(struct drm_device *dev,
> +  struct drm_driver *driver,
> +  struct device *parent);
>  void drm_dev_ref(struct drm_device *dev);
>  void drm_dev_unref(struct drm_device *dev);
>  int drm_dev_registe

[PATCH v2 01/21] drm: Export drm_dev_init() for subclassing

2016-06-01 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 12:01:44PM +0200, Daniel Vetter wrote:
> On Mon, May 30, 2016 at 09:38:19AM +0100, Chris Wilson wrote:
> > In order to allow drivers to pack their privates and drm_device into one
> > struct (e.g. for subclassing), export the initialisation routines for
> > struct drm_device.
> > 
> > v2: Missed return ret. That error path had only one job to do!
> > 
> > Signed-off-by: Chris Wilson 
> > Cc: Daniel Vetter 
> > Cc: dri-devel at lists.freedesktop.org
> > ---
> >  drivers/gpu/drm/drm_drv.c | 63 
> > ---
> >  include/drm/drmP.h|  3 +++
> >  2 files changed, 52 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index bff89226a344..f0553ccd4f71 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -549,11 +549,12 @@ static void drm_fs_inode_free(struct inode *inode)
> >  }
> >  
> >  /**
> > - * drm_dev_alloc - Allocate new DRM device
> > - * @driver: DRM driver to allocate device for
> > + * drm_dev_init - Initialise new DRM device
> > + * @dev: DRM device
> > + * @driver: DRM driver
> >   * @parent: Parent device object
> >   *
> > - * Allocate and initialize a new DRM device. No device registration is 
> > done.
> > + * Initialize a new DRM device. No device registration is done.
> >   * Call drm_dev_register() to advertice the device to user space and 
> > register it
> >   * with other core subsystems. This should be done last in the device
> >   * initialization sequence to make sure userspace can't access an 
> > inconsistent
> > @@ -565,18 +566,14 @@ static void drm_fs_inode_free(struct inode *inode)
> >   * Note that for purely virtual devices @parent can be NULL.
> 
> Maybe add "Drivers which don't want to allocate their own device structure
> embedding &drm_device can instead just call drm_dev_alloc()."
> >   *
> >   * RETURNS:
> > - * Pointer to new DRM device, or NULL if out of memory.
> > + * 0 on success, or error code on failure.
> >   */
> > -struct drm_device *drm_dev_alloc(struct drm_driver *driver,
> > -struct device *parent)
> > +int drm_dev_init(struct drm_device *dev,
> > +struct drm_driver *driver,
> > +struct device *parent)
> >  {
> > -   struct drm_device *dev;
> > int ret;
> >  
> > -   dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> > -   if (!dev)
> > -   return NULL;
> > -
> > kref_init(&dev->ref);
> > dev->dev = parent;
> > dev->driver = driver;
> > @@ -638,7 +635,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver 
> > *driver,
> > goto err_setunique;
> > }
> >  
> > -   return dev;
> > +   return 0;
> >  
> >  err_setunique:
> > if (drm_core_check_feature(dev, DRIVER_GEM))
> > @@ -653,8 +650,46 @@ err_minors:
> > drm_fs_inode_free(dev->anon_inode);
> >  err_free:
> > mutex_destroy(&dev->master_mutex);
> > -   kfree(dev);
> > -   return NULL;
> > +   return ret;
> 
> for "goto err_minors" you need to set ret first, otherwise we'll fail and
> return 0. Wasn't a problem because of the unconditional return NULL here.
> 
> > +}
> > +EXPORT_SYMBOL(drm_dev_init);
> > +
> > +/**
> > + * drm_dev_alloc - Allocate new DRM device
> > + * @driver: DRM driver to allocate device for
> > + * @parent: Parent device object
> > + *
> > + * Allocate and initialize a new DRM device. No device registration is 
> > done.
> > + * Call drm_dev_register() to advertice the device to user space and 
> > register it
> > + * with other core subsystems. This should be done last in the device
> > + * initialization sequence to make sure userspace can't access an 
> > inconsistent
> > + * state.
> > + *
> > + * The initial ref-count of the object is 1. Use drm_dev_ref() and
> > + * drm_dev_unref() to take and drop further ref-counts.
> > + *
> > + * Note that for purely virtual devices @parent can be NULL.
> 
> Maybe we can also add "Drivers which want to subclass/embed struct
> &drm_device should instead look at drm_dev_init()."
> 
> > + *
> > + * RETURNS:
> > + * Pointer to new DRM device, or NULL if out of memory.
> > + */
> > +struct drm_device *drm_dev_alloc(struct drm_driver *driver,
> > +struct device *parent)
> > +{
> > +   struct drm_device *dev;
> > +   int ret;
> > +
> > +   dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> > +   if (!dev)
> > +   return NULL;
> > +
> > +   ret = drm_dev_init(dev, driver, parent);
> > +   if (ret) {
> > +   kfree(dev);
> > +   return NULL;
> > +   }
> > +
> > +   return dev;
> >  }
> >  EXPORT_SYMBOL(drm_dev_alloc);
> >  
> > diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> > index c5d29505f937..12dc5f9cad89 100644
> > --- a/include/drm/drmP.h
> > +++ b/include/drm/drmP.h
> > @@ -1075,6 +1075,9 @@ extern void drm_sysfs_hotplug_event(struct drm_device 
> > *dev);
> >  
> >  struct drm_device *drm_dev_alloc(struct drm_driver *driver,
> >

[PATCH v2 01/21] drm: Export drm_dev_init() for subclassing

2016-06-01 Thread Chris Wilson
On Wed, Jun 01, 2016 at 12:01:44PM +0200, Daniel Vetter wrote:
> With the one bug in the error handling fixed, and the kerneldoc augmented:

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index f0553ccd4f71..4f3d3bba08f7 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -565,6 +565,9 @@ static void drm_fs_inode_free(struct inode *inode)
  *
  * Note that for purely virtual devices @parent can be NULL.
  *
+ * Drivers that do not want to allocate their own device struct
+ * embedding struct &drm_device can call drm_dev_alloc() instead.
+ *
  * RETURNS:
  * 0 on success, or error code on failure.
  */
@@ -616,7 +619,8 @@ int drm_dev_init(struct drm_device *dev,
if (ret)
goto err_minors;

-   if (drm_ht_create(&dev->map_hash, 12))
+   ret = drm_ht_create(&dev->map_hash, 12);
+   if (ret)
goto err_minors;

drm_legacy_ctxbitmap_init(dev);
@@ -670,6 +674,9 @@ EXPORT_SYMBOL(drm_dev_init);
  *
  * Note that for purely virtual devices @parent can be NULL.
  *
+ * Drivers that wish to subclass or embed struct &drm_device into their
+ * own struct should look at using drm_dev_init() instead.
+ *
  * RETURNS:
  * Pointer to new DRM device, or NULL if out of memory.
  */

> Reviewed-by: Daniel Vetter 

Thanks, nice catch for err_minors.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH v2 02/21] drm: Add a callback from connector registering

2016-06-01 Thread Chris Wilson
On Wed, Jun 01, 2016 at 11:57:09AM +0200, Daniel Vetter wrote:
> On Mon, May 30, 2016 at 09:38:20AM +0100, Chris Wilson wrote:
> > If a driver wants to more precisely control its initialisation and in
> > particular, defer registering its interfaces with userspace until after
> > everything is setup, it also needs to defer registering the connectors.
> > As some devices need more work during registration, add a callback so
> > that drivers can do additional work if required for a connector.
> > 
> > Correspondingly, we also require an unregister callback.
> > 
> > Signed-off-by: Chris Wilson 
> > Cc: Daniel Vetter 
> > Cc: dri-devel at lists.freedesktop.org
> 
> tbh I'd call these hooks simply register/unregister. There shouldn't be
> any need for ordering every with interface registration/unregistartion,
> assuming drivers don't fumble things.

Ah, calling it late_register had the dual purpose of avoiding the
'register' keyword. :|

For consistency with resume's naming scheme, it should be register_late.
Maybe register_userspace for greater verbage? Though I like the
shorthand that we have register as meaning expose the internal object to
third parties, including userspace.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH] drm: atmel-hlcdc: actually disable scaling when no scaling is required

2016-06-01 Thread Boris Brezillon
The driver is only enabling scaling, but never disabling it, thus, if you
enable the scaling feature once it stays enabled forever.

Signed-off-by: Boris Brezillon 
Reported-by: Alex Vazquez 
Fixes: 1a396789f65a ("drm: add Atmel HLCDC Display Controller support")
Cc: 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index aef3ca8..016c191 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -339,6 +339,8 @@ atmel_hlcdc_plane_update_pos_and_size(struct 
atmel_hlcdc_plane *plane,

atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0x,
 factor_reg);
+   } else {
+   atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0x, 0);
}
 }

-- 
2.7.4



[PATCH v5 1/1] drm: sti: Add ASoC generic hdmi codec support.

2016-06-01 Thread Benjamin Gaignard
Ack-by: Benjamin Gaignard 

2016-05-30 15:31 GMT+02:00 Arnaud Pouliquen :
> Add the interface needed by audio hdmi-codec driver.
>
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/gpu/drm/sti/Kconfig|   1 +
>  drivers/gpu/drm/sti/sti_hdmi.c | 294 
> ++---
>  drivers/gpu/drm/sti/sti_hdmi.h |  13 ++
>  3 files changed, 291 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
> index 5ad43a1..494ab25 100644
> --- a/drivers/gpu/drm/sti/Kconfig
> +++ b/drivers/gpu/drm/sti/Kconfig
> @@ -7,5 +7,6 @@ config DRM_STI
> select DRM_KMS_CMA_HELPER
> select DRM_PANEL
> select FW_LOADER
> +   select SND_SOC_HDMI_CODEC if SND_SOC
> help
>   Choose this option to enable DRM on STM stiH41x chipset
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 6ef0715..f345c2d 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -18,6 +18,8 @@
>  #include 
>  #include 
>
> +#include 
> +
>  #include "sti_hdmi.h"
>  #include "sti_hdmi_tx3g4c28phy.h"
>  #include "sti_hdmi_tx3g0c55phy.h"
> @@ -35,6 +37,8 @@
>  #define HDMI_DFLT_CHL0_DAT  0x0110
>  #define HDMI_DFLT_CHL1_DAT  0x0114
>  #define HDMI_DFLT_CHL2_DAT  0x0118
> +#define HDMI_AUDIO_CFG  0x0200
> +#define HDMI_SPDIF_FIFO_STATUS  0x0204
>  #define HDMI_SW_DI_1_HEAD_WORD  0x0210
>  #define HDMI_SW_DI_1_PKT_WORD0  0x0214
>  #define HDMI_SW_DI_1_PKT_WORD1  0x0218
> @@ -44,6 +48,9 @@
>  #define HDMI_SW_DI_1_PKT_WORD5  0x0228
>  #define HDMI_SW_DI_1_PKT_WORD6  0x022C
>  #define HDMI_SW_DI_CFG  0x0230
> +#define HDMI_SAMPLE_FLAT_MASK   0x0244
> +#define HDMI_AUDN   0x0400
> +#define HDMI_AUD_CTS0x0404
>  #define HDMI_SW_DI_2_HEAD_WORD  0x0600
>  #define HDMI_SW_DI_2_PKT_WORD0  0x0604
>  #define HDMI_SW_DI_2_PKT_WORD1  0x0608
> @@ -103,6 +110,7 @@
>  #define HDMI_INT_DLL_LCKBIT(5)
>  #define HDMI_INT_NEW_FRAME  BIT(6)
>  #define HDMI_INT_GENCTRL_PKTBIT(7)
> +#define HDMI_INT_AUDIO_FIFO_XRUNBIT(8)
>  #define HDMI_INT_SINK_TERM_PRESENT  BIT(11)
>
>  #define HDMI_DEFAULT_INT (HDMI_INT_SINK_TERM_PRESENT \
> @@ -111,6 +119,7 @@
> | HDMI_INT_GLOBAL)
>
>  #define HDMI_WORKING_INT (HDMI_INT_SINK_TERM_PRESENT \
> +   | HDMI_INT_AUDIO_FIFO_XRUN \
> | HDMI_INT_GENCTRL_PKT \
> | HDMI_INT_NEW_FRAME \
> | HDMI_INT_DLL_LCK \
> @@ -121,6 +130,27 @@
>
>  #define HDMI_STA_SW_RST BIT(1)
>
> +#define HDMI_AUD_CFG_8CH   BIT(0)
> +#define HDMI_AUD_CFG_SPDIF_DIV_2   BIT(1)
> +#define HDMI_AUD_CFG_SPDIF_DIV_3   BIT(2)
> +#define HDMI_AUD_CFG_SPDIF_CLK_DIV_4   (BIT(1) | BIT(2))
> +#define HDMI_AUD_CFG_CTS_CLK_256FS BIT(12)
> +#define HDMI_AUD_CFG_DTS_INVALID   BIT(16)
> +#define HDMI_AUD_CFG_ONE_BIT_INVALID   (BIT(18) | BIT(19) | BIT(20) |  
> BIT(21))
> +#define HDMI_AUD_CFG_CH12_VALIDBIT(28)
> +#define HDMI_AUD_CFG_CH34_VALIDBIT(29)
> +#define HDMI_AUD_CFG_CH56_VALIDBIT(30)
> +#define HDMI_AUD_CFG_CH78_VALIDBIT(31)
> +
> +/* sample flat mask */
> +#define HDMI_SAMPLE_FLAT_NO 0
> +#define HDMI_SAMPLE_FLAT_SP0 BIT(0)
> +#define HDMI_SAMPLE_FLAT_SP1 BIT(1)
> +#define HDMI_SAMPLE_FLAT_SP2 BIT(2)
> +#define HDMI_SAMPLE_FLAT_SP3 BIT(3)
> +#define HDMI_SAMPLE_FLAT_ALL (HDMI_SAMPLE_FLAT_SP0 | HDMI_SAMPLE_FLAT_SP1 |\
> + HDMI_SAMPLE_FLAT_SP2 | HDMI_SAMPLE_FLAT_SP3)
> +
>  #define HDMI_INFOFRAME_HEADER_TYPE(x)(((x) & 0xff) <<  0)
>  #define HDMI_INFOFRAME_HEADER_VERSION(x) (((x) & 0xff) <<  8)
>  #define HDMI_INFOFRAME_HEADER_LEN(x) (((x) & 0x0f) << 16)
> @@ -171,6 +201,10 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg)
> wake_up_interruptible(&hdmi->wait_event);
> }
>
> +   /* Audio FIFO underrun IRQ */
> +   if (hdmi->irq_status & HDMI_INT_AUDIO_FIFO_XRUN)
> +   DRM_INFO("Warning: audio FIFO underrun occurs!");
> +
> return IRQ_HANDLED;
>  }
>
> @@ -441,26 +475,29 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi 
> *hdmi)
>   */
>  static int hdmi_audio_infoframe_config(struct sti_hdmi *hdmi)
>  {
> -   struct hdmi_audio_infoframe infofame;
> +   struct hdmi_audio_params *audio = &hdmi->audio;
> u8 buffer[HDMI_INFOFRAME_SIZE(AUDIO)];
> -   int ret;
> -
> -   ret = hdmi_audio_infoframe_init(&infofame);
> -   if (ret < 0) {
> -   DRM_ERROR("failed to setup audio infoframe: %d\n", ret);
> -   return ret;
> -   }
> -
> -   infofame.channels = 2;
> -
> -   ret = hdmi_audio_infoframe_pack(&infofame, buffer, sizeof(buffer));

[PULL] drm: atmel-hlcdc: fixes for 4.7-rc2

2016-06-01 Thread Boris Brezillon
Hi Dave,

This pull request contains 2 trivial fixes for the atmel-hlcdc driver.

The first one is making use of __drm_atomic_helper_crtc_destroy_state()
instead of duplicating its logic in atmel_hlcdc_crtc_reset() and
risking memory leaks if other objects are added to the common CRTC
state.

The second one is fixing a possible NULL pointer dereference.

Regards,

Boris

The following changes since commit 1a695a905c18548062509178b98bc91e67510864:

  Linux 4.7-rc1 (2016-05-29 09:29:24 -0700)

are available in the git repository at:

  git at github.com:bbrezillon/linux-at91.git 
tags/drm-atmel-hlcdc-fixes/for-4.7-rc2

for you to fetch changes up to dcd64e313ff2d2a15574cd92ec27e73194ba7537:

  drm: atmel-hlcdc: fix a NULL check (2016-06-01 13:36:26 +0200)


Two trivial bugfixes on the atmel-hlcdc driver for 4.7-rc2.

The first one is making use of __drm_atomic_helper_crtc_destroy_state()
instead of duplicating its logic in atmel_hlcdc_crtc_reset() and
risking memory leaks if other objects are added to the common CRTC
state.

The second one is fixing a possible NULL pointer dereference.


Boris Brezillon (1):
  drm: atmel-hlcdc: fix atmel_hlcdc_crtc_reset() implementation

Dan Carpenter (1):
  drm: atmel-hlcdc: fix a NULL check

 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


[Nouveau] [PATCH 9/9] drm: Turn off crtc before tearing down its data structure

2016-06-01 Thread Lukas Wunner
On Wed, May 25, 2016 at 03:43:42PM +0200, Daniel Vetter wrote:
> On Wed, May 25, 2016 at 12:51 PM, Lukas Wunner  wrote:
> > On Tue, May 24, 2016 at 11:30:42PM +0200, Daniel Vetter wrote:
> >> On Tue, May 24, 2016 at 06:03:27PM +0200, Lukas Wunner wrote:
> >> > When a drm_crtc structure is destroyed with drm_crtc_cleanup(), the DRM
> >> > core does not turn off the crtc first and neither do the drivers. With
> >> > nouveau, radeon and amdgpu, this causes a runtime pm ref to be leaked on
> >> > driver unload if at least one crtc was enabled.
> >> >
> >> > (See usage of have_disp_power_ref in nouveau_crtc_set_config(),
> >> > radeon_crtc_set_config() and amdgpu_crtc_set_config()).
> >> >
> >> > Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)")
> >> > Cc: Dave Airlie 
> >> > Tested-by: Karol Herbst 
> >> > Signed-off-by: Lukas Wunner 
> >>
> >> This is a core regression, we fixed it again. Previously when unreference
> >> drm_planes the core made sure that it's not longer in use, which had the
> >> side effect of shutting everything off in module unload.
> >>
> >> For a bunch of reasons we've stopped doing that, but that turned out to be
> >> a mistake. It's fixed since
> >>
> >> commit f2d580b9a8149735cbc4b59c4a8df60173658140
> >> Author: Maarten Lankhorst 
> >> Date:   Wed May 4 14:38:26 2016 +0200
> >>
> >> drm/core: Do not preserve framebuffer on rmfb, v4.
> >>
> >> Your patch shouldn't be needed with that any more. If it still is it's
> >> most likely the fbdev cleanup done too late, but you /should/ get a big
> >> WARNING splat in that case from drm_mode_config_cleanup().
> >
> > I tested it and at least with nouveau, the above-mentioned commit does
> > *not* solve the issue, so patch [9/9] of this series is still needed.
> > I do not get a WARN splat when unloading nouveau.
> 
> With legacy kms the only way to keep a crtc enabled is to display a
> drm_framebuffer on it. And drm_mode_config_cleanup has a WARN_ON if
> framebuffers are left behind. There's a bunch of options:
> - nouveau somehow manages to keep the crtc on without a framebuffer
> - nouveau somehow leaks a drm_framebuffer, but removes it from the fb_list
> - something else

Found it. nouveau_fbcon_destroy() doesn't call drm_framebuffer_remove().
If I add that, the crtc gets properly disabled on unload.

It does call drm_framebuffer_cleanup(). That's why there was no WARN,
drm_mode_config_cleanup() only WARNs if a framebuffer was left on the
mode_config.fb_list.

radeon and amdgpu have the same problem. In fact there are very few
drivers that call drm_framebuffer_remove(): tegra, msm, exynos, omapdrm
and i915 (since Imre Deak's 9d6612516da0).

Should we add a WARN to prevent this? How about WARN_ON(crtc->enabled)
in drm_crtc_cleanup()?

Also, i915 calls drm_framebuffer_unregister_private() before it calls
drm_framebuffer_remove(). This ordering has the unfortunate side effect
that the drm_framebuffer has ID 0 in log messages emitted by
drm_framebuffer_remove():

[   39.680874] [drm:drm_mode_object_unreference] OBJ ID: 0 (3)
[   39.680878] [drm:drm_mode_object_unreference] OBJ ID: 0 (2)
[   39.680884] [drm:drm_mode_object_unreference] OBJ ID: 0 (1)

Best regards,

Lukas

> 
> There's still no need to forcefully shut down crtc at cleanup time in
> the core, this is still a driver bug. So yes your patch might be
> needed, but it's not the right fix.
> -Daniel
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch


Fence array patchset

2016-06-01 Thread Christian König
Hi guys,

this is the next iteration of the fence array patch set.

Daniel suggested that I provide an example on how this functionality might be
used by a driver. So I added a few additional patches in this series to show
what I want to do with this in the amdgpu driver.

The main idea is that for each VMID we have a set of hardware fences which are
currently using this VMID. Now when a new command submission needs a VMID we
construct a fence array which should signal when any of the VMIDs becomes
available and gives that back to our the scheduler.

This effort and my testing also found a rather stupid typo in the code and I
also tried to incorporate the comments from Chris and Daniel as well.

I think it's ready to land now, but as usual feel free to take it apart.

Cheers,
Christian.



[PATCH 01/11] dma-buf/fence: make fence context 64 bit v2

2016-06-01 Thread Christian König
From: Christian König 

Fence contexts are created on the fly (for example) by the GPU scheduler used
in the amdgpu driver as a result of an userspace request. Because of this
userspace could in theory force a wrap around of the 32bit context number
if it doesn't behave well.

Avoid this by increasing the context number to 64bits. This way even when
userspace manages to allocate a billion contexts per second it takes more
than 500 years for the context number to wrap around.

v2: fix printf formats as well.

Signed-off-by: Christian König 
---
 drivers/dma-buf/fence.c |  8 
 drivers/gpu/drm/amd/amdgpu/amdgpu.h |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c  |  2 +-
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h   |  2 +-
 drivers/gpu/drm/nouveau/nouveau_fence.h |  3 ++-
 drivers/gpu/drm/qxl/qxl_release.c   |  2 +-
 drivers/gpu/drm/radeon/radeon.h |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c   |  2 +-
 drivers/staging/android/sync.h  |  3 ++-
 include/linux/fence.h   | 13 +++--
 10 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 7b05dbe..4d51f9e 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -35,7 +35,7 @@ EXPORT_TRACEPOINT_SYMBOL(fence_emit);
  * context or not. One device can have multiple separate contexts,
  * and they're used if some engine can run independently of another.
  */
-static atomic_t fence_context_counter = ATOMIC_INIT(0);
+static atomic64_t fence_context_counter = ATOMIC64_INIT(0);

 /**
  * fence_context_alloc - allocate an array of fence contexts
@@ -44,10 +44,10 @@ static atomic_t fence_context_counter = ATOMIC_INIT(0);
  * This function will return the first index of the number of fences allocated.
  * The fence context is used for setting fence->context to a unique number.
  */
-unsigned fence_context_alloc(unsigned num)
+u64 fence_context_alloc(unsigned num)
 {
BUG_ON(!num);
-   return atomic_add_return(num, &fence_context_counter) - num;
+   return atomic64_add_return(num, &fence_context_counter) - num;
 }
 EXPORT_SYMBOL(fence_context_alloc);

@@ -513,7 +513,7 @@ EXPORT_SYMBOL(fence_wait_any_timeout);
  */
 void
 fence_init(struct fence *fence, const struct fence_ops *ops,
-spinlock_t *lock, unsigned context, unsigned seqno)
+spinlock_t *lock, u64 context, unsigned seqno)
 {
BUG_ON(!lock);
BUG_ON(!ops || !ops->wait || !ops->enable_signaling ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 3d0cec2..7d25977 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2045,7 +2045,7 @@ struct amdgpu_device {
struct amdgpu_irq_src   hpd_irq;

/* rings */
-   unsignedfence_context;
+   u64 fence_context;
unsignednum_rings;
struct amdgpu_ring  *rings[AMDGPU_MAX_RINGS];
boolib_pool_ready;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
index 48618ee..d8af37a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -428,7 +428,7 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager 
*sa_manager,
   soffset, eoffset, eoffset - soffset);

if (i->fence)
-   seq_printf(m, " protected by 0x%08x on context %d",
+   seq_printf(m, " protected by 0x%08x on context %llu",
   i->fence->seqno, i->fence->context);

seq_printf(m, "\n");
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h 
b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index f233ac4..6a69214 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -123,7 +123,7 @@ struct etnaviv_gpu {
u32 completed_fence;
u32 retired_fence;
wait_queue_head_t fence_event;
-   unsigned int fence_context;
+   u64 fence_context;
spinlock_t fence_spinlock;

/* worker for handling active-list retiring: */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h 
b/drivers/gpu/drm/nouveau/nouveau_fence.h
index 2e3a62d..64c4ce7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -57,7 +57,8 @@ struct nouveau_fence_priv {
int  (*context_new)(struct nouveau_channel *);
void (*context_del)(struct nouveau_channel *);

-   u32 contexts, context_base;
+   u32 contexts;
+   u64 context_base;
bool uevent;
 };

diff --git a/drivers/gpu/drm/qxl/qxl_release.c 
b/drivers/gpu/drm/qxl/qxl_release.c
index 4efa8e2..f599cd0 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -96,7 +96,7 @@ retry:
 

[PATCH 03/11] dma-buf/fence: add signal_on_any to the fence array v2

2016-06-01 Thread Christian König
From: Christian König 

If @signal_on_any is true the fence array signals if any fence in the array
signals, otherwise it signals when all fences in the array signal.

v2: fix signaled test and add comment suggested by Chris Wilson.

Signed-off-by: Christian König 
---
 drivers/dma-buf/fence-array.c | 33 +
 include/linux/fence-array.h   |  3 ++-
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
index 8141217..a8731c8 100644
--- a/drivers/dma-buf/fence-array.c
+++ b/drivers/dma-buf/fence-array.c
@@ -41,6 +41,7 @@ static void fence_array_cb_func(struct fence *f, struct 
fence_cb *cb)

if (atomic_dec_and_test(&array->num_pending))
fence_signal(&array->base);
+   fence_put(&array->base);
 }

 static bool fence_array_enable_signaling(struct fence *fence)
@@ -51,10 +52,21 @@ static bool fence_array_enable_signaling(struct fence 
*fence)

for (i = 0; i < array->num_fences; ++i) {
cb[i].array = array;
+   /*
+* As we may report that the fence is signaled before all
+* callbacks are complete, we need to take an additional
+* reference count on the array so that we do not free it too
+* early. The core fence handling will only hold the reference
+* until we signal the array as complete (but that is now
+* insufficient).
+*/
+   fence_get(&array->base);
if (fence_add_callback(array->fences[i], &cb[i].cb,
-  fence_array_cb_func))
+  fence_array_cb_func)) {
+   fence_put(&array->base);
if (atomic_dec_and_test(&array->num_pending))
return false;
+   }
}

return true;
@@ -64,7 +76,7 @@ static bool fence_array_signaled(struct fence *fence)
 {
struct fence_array *array = to_fence_array(fence);

-   return atomic_read(&array->num_pending) == 0;
+   return atomic_read(&array->num_pending) <= 0;
 }

 static void fence_array_release(struct fence *fence)
@@ -90,10 +102,11 @@ const struct fence_ops fence_array_ops = {

 /**
  * fence_array_create - Create a custom fence array
- * @num_fences:[in]number of fences to add in the array
- * @fences:[in]array containing the fences
- * @context:   [in]fence context to use
- * @seqno: [in]sequence number to use
+ * @num_fences:[in]number of fences to add in the array
+ * @fences:[in]array containing the fences
+ * @context:   [in]fence context to use
+ * @seqno: [in]sequence number to use
+ * @signal_on_any  [in]signal on any fence in the array
  *
  * Allocate a fence_array object and initialize the base fence with 
fence_init().
  * In case of error it returns NULL.
@@ -101,9 +114,13 @@ const struct fence_ops fence_array_ops = {
  * The caller should allocte the fences array with num_fences size
  * and fill it with the fences it wants to add to the object. Ownership of this
  * array is take and fence_put() is used on each fence on release.
+ *
+ * If @signal_on_any is true the fence array signals if any fence in the array
+ * signals, otherwise it signals when all fences in the array signal.
  */
 struct fence_array *fence_array_create(int num_fences, struct fence **fences,
-  u64 context, unsigned seqno)
+  u64 context, unsigned seqno,
+  bool signal_on_any)
 {
struct fence_array *array;
size_t size = sizeof(*array);
@@ -119,7 +136,7 @@ struct fence_array *fence_array_create(int num_fences, 
struct fence **fences,
   context, seqno);

array->num_fences = num_fences;
-   atomic_set(&array->num_pending, num_fences);
+   atomic_set(&array->num_pending, signal_on_any ? 1 : num_fences);
array->fences = fences;

return array;
diff --git a/include/linux/fence-array.h b/include/linux/fence-array.h
index 593ab98..86baaa4 100644
--- a/include/linux/fence-array.h
+++ b/include/linux/fence-array.h
@@ -67,6 +67,7 @@ static inline struct fence_array *to_fence_array(struct fence 
*fence)
 }

 struct fence_array *fence_array_create(int num_fences, struct fence **fences,
-  u64 context, unsigned seqno);
+  u64 context, unsigned seqno,
+  bool signal_on_any);

 #endif /* __LINUX_FENCE_ARRAY_H */
-- 
2.5.0



[PATCH 02/11] dma-buf/fence: add fence_array fences v6

2016-06-01 Thread Christian König
From: Gustavo Padovan 

struct fence_collection inherits from struct fence and carries a
collection of fences that needs to be waited together.

It is useful to translate a sync_file to a fence to remove the complexity
of dealing with sync_files on DRM drivers. So even if there are many
fences in the sync_file that needs to waited for a commit to happen,
they all get added to the fence_collection and passed for DRM use as
a standard struct fence.

That means that no changes needed to any driver besides supporting fences.

fence_collection's fence doesn't belong to any timeline context, so
fence_is_later() and fence_later() are not meant to be called with
fence_collections fences.

v2: Comments by Daniel Vetter:
- merge fence_collection_init() and fence_collection_add()
- only add callbacks at ->enable_signalling()
- remove fence_collection_put()
- check for type on to_fence_collection()
- adjust fence_is_later() and fence_later() to WARN_ON() if they
are used with collection fences.

v3: - Initialize fence_cb.node at fence init.

Comments by Chris Wilson:
- return "unbound" on fence_collection_get_timeline_name()
- don't stop adding callbacks if one fails
- remove redundant !! on fence_collection_enable_signaling()
- remove redundant () on fence_collection_signaled
- use fence_default_wait() instead

v4 (chk): Rework, simplification and cleanup:
- Drop FENCE_NO_CONTEXT handling, always allocate a context.
- Rename to fence_array.
- Return fixed driver name.
- Register only one callback at a time.
- Document that create function takes ownership of array.

v5 (chk): More work and fixes:
- Avoid deadlocks by adding all callbacks at once again.
- Stop trying to remove the callbacks.
- Provide context and sequence number for the array fence.

v6 (chk): Fixes found during testing
- Fix stupid typo in _enable_signaling().

Signed-off-by: Gustavo Padovan 
Signed-off-by: Christian König 
---
 drivers/dma-buf/Makefile  |   2 +-
 drivers/dma-buf/fence-array.c | 127 ++
 include/linux/fence-array.h   |  72 
 3 files changed, 200 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dma-buf/fence-array.c
 create mode 100644 include/linux/fence-array.h

diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 57a675f..85f6928 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1 +1 @@
-obj-y := dma-buf.o fence.o reservation.o seqno-fence.o
+obj-y := dma-buf.o fence.o reservation.o seqno-fence.o fence-array.o
diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
new file mode 100644
index 000..8141217
--- /dev/null
+++ b/drivers/dma-buf/fence-array.c
@@ -0,0 +1,127 @@
+/*
+ * fence-array: aggregate fences to be waited together
+ *
+ * Copyright (C) 2016 Collabora Ltd
+ * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ * Authors:
+ * Gustavo Padovan 
+ * Christian König 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+
+static void fence_array_cb_func(struct fence *f, struct fence_cb *cb);
+
+static const char *fence_array_get_driver_name(struct fence *fence)
+{
+   return "fence_array";
+}
+
+static const char *fence_array_get_timeline_name(struct fence *fence)
+{
+   return "unbound";
+}
+
+static void fence_array_cb_func(struct fence *f, struct fence_cb *cb)
+{
+   struct fence_array_cb *array_cb =
+   container_of(cb, struct fence_array_cb, cb);
+   struct fence_array *array = array_cb->array;
+
+   if (atomic_dec_and_test(&array->num_pending))
+   fence_signal(&array->base);
+}
+
+static bool fence_array_enable_signaling(struct fence *fence)
+{
+   struct fence_array *array = to_fence_array(fence);
+   struct fence_array_cb *cb = (void *)(&array[1]);
+   unsigned i;
+
+   for (i = 0; i < array->num_fences; ++i) {
+   cb[i].array = array;
+   if (fence_add_callback(array->fences[i], &cb[i].cb,
+  fence_array_cb_func))
+   if (atomic_dec_and_test(&array->num_pending))
+   return false;
+   }
+
+   return true;
+}
+
+static bool fence_array_signaled(struct fence *fence)
+{
+   struct fence_array *array = to_fence_array(fence);
+
+   return atomic_read(&array->num_pending) == 0;
+}
+
+static void fence_array

[PATCH 04/11] drm/amdgpu: document amdgpu_sync_get_fence

2016-06-01 Thread Christian König
From: Christian König 

It's not obvious what it should do.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index 34a9280..e0ff1a1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -297,6 +297,13 @@ int amdgpu_sync_cycle_fences(struct amdgpu_sync *dst, 
struct amdgpu_sync *src,
return 0;
 }

+/**
+ * amdgpu_sync_get_fence - get the next fence from the sync object
+ *
+ * @sync: sync object to use
+ *
+ * Get and removes the next fence from the sync object not signaled yet.
+ */
 struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync)
 {
struct amdgpu_sync_entry *e;
-- 
2.5.0



[PATCH 06/11] drm/amdgpu: remove amdgpu_sync_wait

2016-06-01 Thread Christian König
From: Christian König 

Stop hiding bugs, instead print a proper error when the scheduler
doesn't handle all dependencies.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 19 ---
 3 files changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 7d25977..2f4ab1b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -601,7 +601,6 @@ bool amdgpu_sync_is_idle(struct amdgpu_sync *sync);
 int amdgpu_sync_cycle_fences(struct amdgpu_sync *dst, struct amdgpu_sync *src,
 struct fence *fence);
 struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
-int amdgpu_sync_wait(struct amdgpu_sync *sync);
 void amdgpu_sync_free(struct amdgpu_sync *sync);
 int amdgpu_sync_init(void);
 void amdgpu_sync_fini(void);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index ddfed93..009e905 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -166,11 +166,7 @@ static struct fence *amdgpu_job_run(struct amd_sched_job 
*sched_job)
}
job = to_amdgpu_job(sched_job);

-   r = amdgpu_sync_wait(&job->sync);
-   if (r) {
-   DRM_ERROR("failed to sync wait (%d)\n", r);
-   return NULL;
-   }
+   BUG_ON(!amdgpu_sync_is_idle(&job->sync));

trace_amdgpu_sched_run_job(job);
r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index e0ff1a1..c0ed5b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -326,25 +326,6 @@ struct fence *amdgpu_sync_get_fence(struct amdgpu_sync 
*sync)
return NULL;
 }

-int amdgpu_sync_wait(struct amdgpu_sync *sync)
-{
-   struct amdgpu_sync_entry *e;
-   struct hlist_node *tmp;
-   int i, r;
-
-   hash_for_each_safe(sync->fences, i, tmp, e, node) {
-   r = fence_wait(e->fence, false);
-   if (r)
-   return r;
-
-   hash_del(&e->node);
-   fence_put(e->fence);
-   kmem_cache_free(amdgpu_sync_slab, e);
-   }
-
-   return 0;
-}
-
 /**
  * amdgpu_sync_free - free the sync object
  *
-- 
2.5.0



[PATCH 05/11] drm/amdgpu: generalize the scheduler fence

2016-06-01 Thread Christian König
From: Christian König 

Make it two events, one for the job being scheduled and one when it is finished.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c |  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h   |  4 +-
 drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h |  4 +-
 drivers/gpu/drm/amd/scheduler/gpu_scheduler.c   | 34 +++--
 drivers/gpu/drm/amd/scheduler/gpu_scheduler.h   | 19 
 drivers/gpu/drm/amd/scheduler/sched_fence.c | 63 ++---
 6 files changed, 79 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index d4791a7..ddfed93 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -85,7 +85,7 @@ static void amdgpu_job_free_resources(struct amdgpu_job *job)
unsigned i;

/* use sched fence if available */
-   f = job->base.s_fence ? &job->base.s_fence->base : job->fence;
+   f = job->base.s_fence ? &job->base.s_fence->finished : job->fence;

for (i = 0; i < job->num_ibs; ++i)
amdgpu_ib_free(job->adev, &job->ibs[i], f);
@@ -143,7 +143,7 @@ static struct fence *amdgpu_job_dependency(struct 
amd_sched_job *sched_job)
int r;

r = amdgpu_vm_grab_id(vm, ring, &job->sync,
- &job->base.s_fence->base,
+ &job->base.s_fence->finished,
  &job->vm_id, &job->vm_pd_addr);
if (r)
DRM_ERROR("Error getting VM ID (%d)\n", r);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 38e5689..ecd08f8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -102,7 +102,7 @@ TRACE_EVENT(amdgpu_cs_ioctl,
   __entry->adev = job->adev;
   __entry->sched_job = &job->base;
   __entry->ib = job->ibs;
-  __entry->fence = &job->base.s_fence->base;
+  __entry->fence = &job->base.s_fence->finished;
   __entry->ring_name = job->ring->name;
   __entry->num_ibs = job->num_ibs;
   ),
@@ -127,7 +127,7 @@ TRACE_EVENT(amdgpu_sched_run_job,
   __entry->adev = job->adev;
   __entry->sched_job = &job->base;
   __entry->ib = job->ibs;
-  __entry->fence = &job->base.s_fence->base;
+  __entry->fence = &job->base.s_fence->finished;
   __entry->ring_name = job->ring->name;
   __entry->num_ibs = job->num_ibs;
   ),
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h 
b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
index c89dc77..b961a1c 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
@@ -26,7 +26,7 @@ TRACE_EVENT(amd_sched_job,
TP_fast_assign(
   __entry->entity = sched_job->s_entity;
   __entry->sched_job = sched_job;
-  __entry->fence = &sched_job->s_fence->base;
+  __entry->fence = &sched_job->s_fence->finished;
   __entry->name = sched_job->sched->name;
   __entry->job_count = kfifo_len(
   &sched_job->s_entity->job_queue) / 
sizeof(sched_job);
@@ -46,7 +46,7 @@ TRACE_EVENT(amd_sched_process_job,
),

TP_fast_assign(
-   __entry->fence = &fence->base;
+   __entry->fence = &fence->finished;
),
TP_printk("fence=%p signaled", __entry->fence)
 );
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c 
b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
index 2425172..74aa0b3 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
@@ -140,7 +140,7 @@ int amd_sched_entity_init(struct amd_gpu_scheduler *sched,
return r;

atomic_set(&entity->fence_seq, 0);
-   entity->fence_context = fence_context_alloc(1);
+   entity->fence_context = fence_context_alloc(2);

return 0;
 }
@@ -251,17 +251,21 @@ static bool amd_sched_entity_add_dependency_cb(struct 
amd_sched_entity *entity)

s_fence = to_amd_sched_fence(fence);
if (s_fence && s_fence->sched == sched) {
-   /* Fence is from the same scheduler */
-   if (test_bit(AMD_SCHED_FENCE_SCHEDULED_BIT, &fence->flags)) {
-   /* Ignore it when it is already scheduled */
-   fence_put(entity->de

[PATCH 07/11] drm/amdgpu: add optional ring to amdgpu_sync_is_idle

2016-06-01 Thread Christian König
From: Christian König 

Check if the sync object is idle depending on the ring a submission works with.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 17 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c   |  4 ++--
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 2f4ab1b..f154d9f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -597,7 +597,8 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 struct amdgpu_sync *sync,
 struct reservation_object *resv,
 void *owner);
-bool amdgpu_sync_is_idle(struct amdgpu_sync *sync);
+bool amdgpu_sync_is_idle(struct amdgpu_sync *sync,
+struct amdgpu_ring *ring);
 int amdgpu_sync_cycle_fences(struct amdgpu_sync *dst, struct amdgpu_sync *src,
 struct fence *fence);
 struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 009e905..e395bbe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -166,7 +166,7 @@ static struct fence *amdgpu_job_run(struct amd_sched_job 
*sched_job)
}
job = to_amdgpu_job(sched_job);

-   BUG_ON(!amdgpu_sync_is_idle(&job->sync));
+   BUG_ON(!amdgpu_sync_is_idle(&job->sync, NULL));

trace_amdgpu_sched_run_job(job);
r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index c0ed5b9..a2766d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -226,10 +226,13 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
  * amdgpu_sync_is_idle - test if all fences are signaled
  *
  * @sync: the sync object
+ * @ring: optional ring to use for test
  *
- * Returns true if all fences in the sync object are signaled.
+ * Returns true if all fences in the sync object are signaled or scheduled to
+ * the ring (if provided).
  */
-bool amdgpu_sync_is_idle(struct amdgpu_sync *sync)
+bool amdgpu_sync_is_idle(struct amdgpu_sync *sync,
+struct amdgpu_ring *ring)
 {
struct amdgpu_sync_entry *e;
struct hlist_node *tmp;
@@ -237,6 +240,16 @@ bool amdgpu_sync_is_idle(struct amdgpu_sync *sync)

hash_for_each_safe(sync->fences, i, tmp, e, node) {
struct fence *f = e->fence;
+   struct amd_sched_fence *s_fence = to_amd_sched_fence(f);
+
+   if (ring && s_fence) {
+   /* For fences from the same ring it is sufficient
+* when they are scheduled.
+*/
+   if (s_fence->sched == &ring->sched &&
+   fence_is_signaled(&s_fence->scheduled))
+   continue;
+   }

if (fence_is_signaled(f)) {
hash_del(&e->node);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 62a4c12..2bcb623 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -240,13 +240,13 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,
  struct amdgpu_vm_id,
  list);

-   if (!amdgpu_sync_is_idle(&id->active)) {
+   if (!amdgpu_sync_is_idle(&id->active, NULL)) {
struct list_head *head = &adev->vm_manager.ids_lru;
struct amdgpu_vm_id *tmp;

list_for_each_entry_safe(id, tmp, &adev->vm_manager.ids_lru,
 list) {
-   if (amdgpu_sync_is_idle(&id->active)) {
+   if (amdgpu_sync_is_idle(&id->active, NULL)) {
list_move(&id->list, head);
head = &id->list;
}
-- 
2.5.0



[PATCH 11/11] drm/amdgpu: remove now unnecessary checks

2016-06-01 Thread Christian König
From: Christian König 

vm_flush() now comes directly after vm_grab_id().

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 31 +++
 2 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 52326d3..e054542 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -886,7 +886,6 @@ struct amdgpu_vm_id {
struct fence*first;
struct amdgpu_sync  active;
struct fence*last_flush;
-   struct amdgpu_ring  *last_user;
atomic64_t  owner;

uint64_tpd_gpu_addr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 8ea1c73..48d5ad18 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -237,6 +237,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,
i = ring->idx;
do {
struct fence *flushed;
+   bool same_ring = ring->idx == i;

id = vm->ids[i++];
if (i == AMDGPU_MAX_RINGS)
@@ -252,7 +253,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,
if (pd_addr != id->pd_gpu_addr)
continue;

-   if (id->last_user != ring &&
+   if (!same_ring &&
(!id->last_flush || !fence_is_signaled(id->last_flush)))
continue;

@@ -261,15 +262,9 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,
(!flushed || fence_is_later(updates, flushed)))
continue;

-   /* Good we can use this VMID */
-   if (id->last_user == ring) {
-   r = amdgpu_sync_fence(ring->adev, sync,
- id->first);
-   if (r)
-   goto error;
-   }
-
-   /* And remember this submission as user of the VMID */
+   /* Good we can use this VMID. Remember this submission as
+* user of the VMID.
+*/
r = amdgpu_sync_fence(ring->adev, &id->active, fence);
if (r)
goto error;
@@ -306,7 +301,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,
id->pd_gpu_addr = pd_addr;

list_move_tail(&id->list, &adev->vm_manager.ids_lru);
-   id->last_user = ring;
atomic64_set(&id->owner, vm->client_id);
vm->ids[ring->idx] = id;

@@ -357,16 +351,13 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id);
amdgpu_ring_emit_vm_flush(ring, vm_id, pd_addr);

+   r = amdgpu_fence_emit(ring, &fence);
+   if (r)
+   return r;
+
mutex_lock(&adev->vm_manager.lock);
-   if ((id->pd_gpu_addr == pd_addr) && (id->last_user == ring)) {
-   r = amdgpu_fence_emit(ring, &fence);
-   if (r) {
-   mutex_unlock(&adev->vm_manager.lock);
-   return r;
-   }
-   fence_put(id->last_flush);
-   id->last_flush = fence;
-   }
+   fence_put(id->last_flush);
+   id->last_flush = fence;
mutex_unlock(&adev->vm_manager.lock);
}

-- 
2.5.0



[PATCH 10/11] drm/amdgpu: use a fence array for VMID management

2016-06-01 Thread Christian König
From: Christian König 

Just wait for any fence to become available, instead
of waiting for the last entry of the LRU.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c |  69 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c   | 155 +++
 4 files changed, 117 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index f154d9f..52326d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -597,10 +597,8 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 struct amdgpu_sync *sync,
 struct reservation_object *resv,
 void *owner);
-bool amdgpu_sync_is_idle(struct amdgpu_sync *sync,
-struct amdgpu_ring *ring);
-int amdgpu_sync_cycle_fences(struct amdgpu_sync *dst, struct amdgpu_sync *src,
-struct fence *fence);
+struct fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
+struct amdgpu_ring *ring);
 struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
 void amdgpu_sync_free(struct amdgpu_sync *sync);
 int amdgpu_sync_init(void);
@@ -910,6 +908,10 @@ struct amdgpu_vm_manager {
struct list_headids_lru;
struct amdgpu_vm_id ids[AMDGPU_NUM_VM];

+   /* Handling of VM fences */
+   u64 fence_context;
+   unsignedseqno[AMDGPU_MAX_RINGS];
+
uint32_tmax_pfn;
/* vram base address for page table entry  */
u64 vram_base_offset;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index e395bbe..b50a845 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -166,7 +166,7 @@ static struct fence *amdgpu_job_run(struct amd_sched_job 
*sched_job)
}
job = to_amdgpu_job(sched_job);

-   BUG_ON(!amdgpu_sync_is_idle(&job->sync, NULL));
+   BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL));

trace_amdgpu_sched_run_job(job);
r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index a2766d7..5c8d302 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -223,16 +223,16 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 }

 /**
- * amdgpu_sync_is_idle - test if all fences are signaled
+ * amdgpu_sync_peek_fence - get the next fence not signaled yet
  *
  * @sync: the sync object
  * @ring: optional ring to use for test
  *
- * Returns true if all fences in the sync object are signaled or scheduled to
- * the ring (if provided).
+ * Returns the next fence not signaled yet without removing it from the sync
+ * object.
  */
-bool amdgpu_sync_is_idle(struct amdgpu_sync *sync,
-struct amdgpu_ring *ring)
+struct fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
+struct amdgpu_ring *ring)
 {
struct amdgpu_sync_entry *e;
struct hlist_node *tmp;
@@ -246,68 +246,25 @@ bool amdgpu_sync_is_idle(struct amdgpu_sync *sync,
/* For fences from the same ring it is sufficient
 * when they are scheduled.
 */
-   if (s_fence->sched == &ring->sched &&
-   fence_is_signaled(&s_fence->scheduled))
-   continue;
-   }
+   if (s_fence->sched == &ring->sched) {
+   if (fence_is_signaled(&s_fence->scheduled))
+   continue;

-   if (fence_is_signaled(f)) {
-   hash_del(&e->node);
-   fence_put(f);
-   kmem_cache_free(amdgpu_sync_slab, e);
-   continue;
+   return &s_fence->scheduled;
+   }
}

-   return false;
-   }
-
-   return true;
-}
-
-/**
- * amdgpu_sync_cycle_fences - move fences from one sync object into another
- *
- * @dst: the destination sync object
- * @src: the source sync object
- * @fence: fence to add to source
- *
- * Remove all fences from source and put them into destination and add
- * fence as new one into source.
- */
-int amdgpu_sync_cycle_fences(struct amdgpu_sync *dst, struct amdgpu_sync *src,
-struct fence *fence)
-{
-   struct amdgpu_sync_entry *e, *newone;
-   struct hlist_node *tm

[PATCH 09/11] drm/amdgpu: reuse VMIDs assigned to a VM only if there is also a free one

2016-06-01 Thread Christian König
From: Christian König 

This fixes a fairness problem with the GPU scheduler. VM having lot of
jobs could previously starve VM with less jobs.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 113 +
 1 file changed, 59 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index b6484a2..f206820 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -179,75 +179,80 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,
uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory);
struct amdgpu_device *adev = ring->adev;
struct fence *updates = sync->last_vm_update;
-   struct amdgpu_vm_id *id;
+   struct amdgpu_vm_id *id, *idle;
unsigned i = ring->idx;
int r;

mutex_lock(&adev->vm_manager.lock);

-   /* Check if we can use a VMID already assigned to this VM */
-   do {
-   struct fence *flushed;
-
-   id = vm->ids[i++];
-   if (i == AMDGPU_MAX_RINGS)
-   i = 0;
-
-   /* Check all the prerequisites to using this VMID */
-   if (!id)
-   continue;
-
-   if (atomic64_read(&id->owner) != vm->client_id)
-   continue;
-
-   if (pd_addr != id->pd_gpu_addr)
-   continue;
+   /* Check if we have an idle VMID */
+   list_for_each_entry(idle, &adev->vm_manager.ids_lru, list) {
+   if (amdgpu_sync_is_idle(&idle->active, ring))
+   break;

-   if (id->last_user != ring &&
-   (!id->last_flush || !fence_is_signaled(id->last_flush)))
-   continue;
+   }

-   flushed  = id->flushed_updates;
-   if (updates && (!flushed || fence_is_later(updates, flushed)))
-   continue;
+   /* If we can't find a idle VMID to use, just wait for the oldest */
+   if (&idle->list == &adev->vm_manager.ids_lru) {
+   id = list_first_entry(&adev->vm_manager.ids_lru,
+ struct amdgpu_vm_id,
+ list);
+   } else {
+   /* Check if we can use a VMID already assigned to this VM */
+   do {
+   struct fence *flushed;
+
+   id = vm->ids[i++];
+   if (i == AMDGPU_MAX_RINGS)
+   i = 0;
+
+   /* Check all the prerequisites to using this VMID */
+   if (!id)
+   continue;
+
+   if (atomic64_read(&id->owner) != vm->client_id)
+   continue;
+
+   if (pd_addr != id->pd_gpu_addr)
+   continue;
+
+   if (id->last_user != ring && (!id->last_flush ||
+   !fence_is_signaled(id->last_flush)))
+   continue;
+
+   flushed  = id->flushed_updates;
+   if (updates && (!flushed ||
+   fence_is_later(updates, flushed)))
+   continue;
+
+   /* Good we can use this VMID */
+   if (id->last_user == ring) {
+   r = amdgpu_sync_fence(ring->adev, sync,
+ id->first);
+   if (r)
+   goto error;
+   }

-   /* Good we can use this VMID */
-   if (id->last_user == ring) {
-   r = amdgpu_sync_fence(ring->adev, sync,
- id->first);
+   /* And remember this submission as user of the VMID */
+   r = amdgpu_sync_fence(ring->adev, &id->active, fence);
if (r)
goto error;
-   }
-
-   /* And remember this submission as user of the VMID */
-   r = amdgpu_sync_fence(ring->adev, &id->active, fence);
-   if (r)
-   goto error;

-   list_move_tail(&id->list, &adev->vm_manager.ids_lru);
-   vm->ids[ring->idx] = id;
+   list_move_tail(&id->list, &adev->vm_manager.ids_lru);
+   vm->ids[ring->idx] = id;

-   *vm_id = id - adev->vm_manager.ids;
-   *vm_pd_addr = AMDGPU_VM_NO_FLUSH;
-   trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, *vm_pd_addr);
+   *vm_id = id - adev->vm_manager.ids;
+   *vm_pd_addr = AMDGPU_VM_NO_FLUSH;
+

[PATCH 08/11] drm/amdgpu: prefer VMIDs idle on the current ring

2016-06-01 Thread Christian König
From: Christian König 

Prefer to use a VMIDs which are idle on the ring we want to submit to. This
also removes bubbling idle VMIDs up on the LRU, which is actually not
beneficial.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 24 +---
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 2bcb623..b6484a2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -236,21 +236,15 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,

} while (i != ring->idx);

-   id = list_first_entry(&adev->vm_manager.ids_lru,
- struct amdgpu_vm_id,
- list);
-
-   if (!amdgpu_sync_is_idle(&id->active, NULL)) {
-   struct list_head *head = &adev->vm_manager.ids_lru;
-   struct amdgpu_vm_id *tmp;
-
-   list_for_each_entry_safe(id, tmp, &adev->vm_manager.ids_lru,
-list) {
-   if (amdgpu_sync_is_idle(&id->active, NULL)) {
-   list_move(&id->list, head);
-   head = &id->list;
-   }
-   }
+   /* Check if we have an idle VMID */
+   list_for_each_entry(id, &adev->vm_manager.ids_lru, list) {
+   if (amdgpu_sync_is_idle(&id->active, ring))
+   break;
+
+   }
+
+   /* If we can't find a idle VMID to use, just wait for the oldest */
+   if (&id->list == &adev->vm_manager.ids_lru) {
id = list_first_entry(&adev->vm_manager.ids_lru,
  struct amdgpu_vm_id,
  list);
-- 
2.5.0



[PATCH 2/3] drm/exynos: fimd: add HW trigger support

2016-06-01 Thread Javier Martinez Canillas
Hello Inki,

On 06/01/2016 01:56 AM, Inki Dae wrote:
> Hi Javier,
> 
> 2016년 05월 31일 07:58에 Javier Martinez Canillas 이(가) 쓴 글:
>> Hello Inki,
>>
>> On 04/05/2016 04:27 AM, Inki Dae wrote:
>>> This patch adds HW trigger support on i80 mode.
>>>
>>> Until now, Exynos DRM only supported SW trigger which was set
>>> SWTRGCMD bit of TRIGCON register by CPU to transfer scanout
>>> buffer to Display bus device or panel.
>>>
>>> With this patch, the transmission to Display bus device or
>>> panel will be initiated by FIMD controller.
>>>
>>> Signed-off-by: Inki Dae 
>>> ---
>>
>> There is a regression for the Exynos5800 Peach Pi Chromebook display due
>> this patch. The display is blank and I noticed that it only happens when
>> HW start trigger is enabled, but works with SW trigger (as it was before).
> 
> Posted below pathch,
> [PATCH] drm/exynos: fimd: fix trigger mode change regression
>

Thanks, I noticed you forgot to cc me on that one though.

> Can you test it again with the patch? I have no HW to test it. :(
>

I gave a try to your patch but unfortunately it doesn't solve the issue
on the Peach Pi. I'll try to dig further on this.

> Thanks,
> Inki Dae
> 

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


[PATCH v4] drm: Only create a cmdline mode if no probed modes match

2016-06-01 Thread Alex Deucher
On Wed, Jun 1, 2016 at 5:50 AM, Chris Wilson  
wrote:
> The intention of using video=: is primarily to select
> the user's preferred resolution at startup. Currently we always create a
> new mode irrespective of whether the monitor has a native mode at the
> desired resolution. This has the issue that we may then select the fake
> mode rather the native mode during fb_helper->inital_config() and so
> if the fake mode is invalid we then end up with a loss of signal. Oops.
> This invalid fake mode would also be exported to userspace, who
> potentially may make the same mistake.
>
> To avoid this issue, we filter out the added command line mode if we
> detect the desired resolution (and clock if specified) amongst the
> probed modes. This fixes the immediate problem of adding a duplicate
> mode, but perhaps more generically we should avoid adding a GTF mode if
> the monitor has an EDID that is not GTF-compatible, or similarly for
> CVT.
>
> Fixes regression from
>
> commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> Author: Chris Wilson 
> Date:   Wed Aug 6 10:08:32 2014 +0200
>
> drm: Perform cmdline mode parsing during connector initialisation
>
> that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
>
> v2: Explicitly delete our earlier cmdline mode
> v3: Mode pruning should now be sufficient to delete stale cmdline modes
> v4: Compute the vrefresh for the probed mode

Reviewed-by: Alex Deucher 

>
> Reported-by: Radek Dostál 
> Signed-off-by: Chris Wilson 
> Cc: Radek Dostál 
> Cc: Jesse Barnes 
> Cc: Ville Syrjälä 
> Cc: Daniel Vetter 
> Cc: dri-devel at lists.freedesktop.org
> Cc: Julia Lemire 
> Cc: Dave Airlie 
> Cc: stable at vger.kernel.org
> ---
>  drivers/gpu/drm/drm_probe_helper.c | 21 +++--
>  1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index 0329080d7f7c..a0df377d7d1c 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -82,13 +82,30 @@ drm_mode_validate_flag(const struct drm_display_mode 
> *mode,
>
>  static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
>  {
> +   struct drm_cmdline_mode *cmdline_mode;
> struct drm_display_mode *mode;
>
> -   if (!connector->cmdline_mode.specified)
> +   cmdline_mode = &connector->cmdline_mode;
> +   if (!cmdline_mode->specified)
> return 0;
>
> +   /* Only add a GTF mode if we find no matching probed modes */
> +   list_for_each_entry(mode, &connector->probed_modes, head) {
> +   if (mode->hdisplay != cmdline_mode->xres ||
> +   mode->vdisplay != cmdline_mode->yres)
> +   continue;
> +
> +   if (cmdline_mode->refresh_specified) {
> +   /* The probed mode's vrefresh is set until later */
> +   if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
> +   continue;
> +   }
> +
> +   return 0;
> +   }
> +
> mode = drm_mode_create_from_cmdline_mode(connector->dev,
> -&connector->cmdline_mode);
> +cmdline_mode);
> if (mode == NULL)
> return 0;
>
> --
> 2.8.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: hdlcd: Cleanup the atomic plane operations and vsync handling

2016-06-01 Thread Liviu Dudau
Don't disable the vsync interrupt, as the hardware lacks hardware
counters for vsync time stamping and that breaks the DRM assumptions.

Also harden the plane_check() code to drop attempts at scaling because
that is not supported. Make hdlcd_plane_atomic_update() set the pitch
and line length registers that correctly reflect the plane's values.
And make hdlcd_crtc_mode_set_nofb() a helper function for
hdlcd_crtc_enable() rather than an exposed hook.

Cc: Daniel Vetter 
Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 44 ++--
 drivers/gpu/drm/arm/hdlcd_drv.c  | 17 +++-
 drivers/gpu/drm/arm/hdlcd_drv.h  |  1 -
 3 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index b2e894b..6037076 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -106,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
struct drm_display_mode *m = &crtc->state->adjusted_mode;
struct videomode vm;
-   unsigned int polarities, line_length, err;
+   unsigned int polarities, err;

vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end;
@@ -122,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
if (m->flags & DRM_MODE_FLAG_PVSYNC)
polarities |= HDLCD_POLARITY_VSYNC;

-   line_length = crtc->primary->state->fb->pitches[0];
-
/* Allow max number of outstanding requests and largest burst size */
hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);

-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length);
-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length);
-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1);
+   hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1);
-   hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);

err = hdlcd_set_pxl_fmt(crtc);
@@ -153,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);

clk_prepare_enable(hdlcd->clk);
+   hdlcd_crtc_mode_set_nofb(crtc);
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
-   drm_crtc_vblank_on(crtc);
 }

 static void hdlcd_crtc_disable(struct drm_crtc *crtc)
 {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);

-   if (!crtc->primary->fb)
+   if (!crtc->state->active)
return;

hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
clk_disable_unprepare(hdlcd->clk);
-   drm_crtc_vblank_off(crtc);
 }

 static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
@@ -213,6 +207,15 @@ static const struct drm_crtc_helper_funcs 
hdlcd_crtc_helper_funcs = {
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
 {
+   u32 src_w, src_h;
+
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+
+   /* we can't do any scaling of the plane source */
+   if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
+   return -EINVAL;
+
return 0;
 }

@@ -221,20 +224,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane 
*plane,
 {
struct hdlcd_drm_private *hdlcd;
struct drm_gem_cma_object *gem;
+   unsigned int depth, bpp;
+   u32 src_w, src_h, dest_w, dest_h;
dma_addr_t scanout_start;

-   if (!plane->state->crtc || !plane->state->fb)
+   if (!plane->state->fb)
return;

-   hdlcd = crtc_to_hdlcd_priv(plane->state->crtc);
+   drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp);
+   src_w = plane->state->src_w >> 16;
+   src_h = plane->state->src_h >> 16;
+   dest_w = plane->state->crtc_w;
+   dest_h = plane->state->crtc_h;
gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
-   scanout_start = gem->paddr;
+   scanout_start = gem->paddr + plane->state->fb->offsets[0] +
+   plane->state->crtc_y * plane->state->fb->pitches[0] +
+   plane->state->crtc_x * bpp / 8;
+
+   hdlcd = plane->dev->dev_private;
+

[PATCH] drm/doc: Switch to sphinx/rst fixed-width quoting

2016-06-01 Thread Daniel Vetter
On Wed, Jun 1, 2016 at 11:46 AM, Jani Nikula
 wrote:
> On Wed, 01 Jun 2016, Daniel Vetter  wrote:
>> There's still something very fishy going on with some of these, e.g.
>> the drm_modeset_lock Example: and the "Standard GTF Parameters:" Line
>> somehow get treated as heading when just appending a :: at the end of
>> those lines. But it seems to work everywhere else. Maybe the
>> kernel-doc heading generation logic is still a bit wonky?
>
> Try adding a blank line between the line with trailing :: and the actual
> preformatted text. Seems to do the right thing for me.
>
> http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#literal-blocks
>
> "Blank lines are required before and after a literal block, but these
> blank lines are not included as part of the literal block."

That's not what I've meant. The following sometimes (but not always,
only in the 2 places I've mentioned) becomes a kernel-doc directive
and not a block quote:

 * Standard GTF Parameters::
 *
 * stuff I wanted to have block quoted.

But if I switch the :: to be on a line of it's own (like in the patch)
it's totally fine.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


Fence array patchset

2016-06-01 Thread Alex Deucher
On Wed, Jun 1, 2016 at 9:10 AM, Christian König  
wrote:
> Hi guys,
>
> this is the next iteration of the fence array patch set.
>
> Daniel suggested that I provide an example on how this functionality might be
> used by a driver. So I added a few additional patches in this series to show
> what I want to do with this in the amdgpu driver.
>
> The main idea is that for each VMID we have a set of hardware fences which are
> currently using this VMID. Now when a new command submission needs a VMID we
> construct a fence array which should signal when any of the VMIDs becomes
> available and gives that back to our the scheduler.

For those that are not familiar, a VMID = Virtual Memory ID.  AMD GPUs
have multiple virtual address space contexts which can be in flight on
the GPU at any given time.  The VMID is used to select which VM
context you want to use for a specific GPU operation.

Alex

>
> This effort and my testing also found a rather stupid typo in the code and I
> also tried to incorporate the comments from Chris and Daniel as well.
>
> I think it's ready to land now, but as usual feel free to take it apart.
>
> Cheers,
> Christian.
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/doc: Switch to sphinx/rst fixed-width quoting

2016-06-01 Thread Jani Nikula
On Wed, 01 Jun 2016, Daniel Vetter  wrote:
> On Wed, Jun 1, 2016 at 11:46 AM, Jani Nikula
>  wrote:
>> On Wed, 01 Jun 2016, Daniel Vetter  wrote:
>>> There's still something very fishy going on with some of these, e.g.
>>> the drm_modeset_lock Example: and the "Standard GTF Parameters:" Line
>>> somehow get treated as heading when just appending a :: at the end of
>>> those lines. But it seems to work everywhere else. Maybe the
>>> kernel-doc heading generation logic is still a bit wonky?
>>
>> Try adding a blank line between the line with trailing :: and the actual
>> preformatted text. Seems to do the right thing for me.
>>
>> http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#literal-blocks
>>
>> "Blank lines are required before and after a literal block, but these
>> blank lines are not included as part of the literal block."
>
> That's not what I've meant. The following sometimes (but not always,
> only in the 2 places I've mentioned) becomes a kernel-doc directive

What do you mean by "kernel-doc directive" exactly?

> and not a block quote:
>
>  * Standard GTF Parameters::
>  *
>  * stuff I wanted to have block quoted.
>
> But if I switch the :: to be on a line of it's own (like in the patch)
> it's totally fine.

Odd. It does seem to work for me. What does this print near there?

$ scripts/kernel-doc -rst -function drm_gtf_mode drivers/gpu/drm/drm_modes.c



BR,
Jani.



-- 
Jani Nikula, Intel Open Source Technology Center


[PULL] drm: atmel-hlcdc: fixes for 4.7-rc2

2016-06-01 Thread Boris Brezillon
Hi Dave,

On Wed, 1 Jun 2016 14:23:27 +0200
Boris Brezillon  wrote:

> Hi Dave,
> 
> This pull request contains 2 trivial fixes for the atmel-hlcdc driver.

Please ignore this PR. The __drm_atomic_helper_crtc_destroy_state()
prototype has changed between my submission and the 4.7-rc1 release and
it no longer compiles.

Sorry for the inconvenience.

Regards,

Boris

> 
> The first one is making use of __drm_atomic_helper_crtc_destroy_state()
> instead of duplicating its logic in atmel_hlcdc_crtc_reset() and
> risking memory leaks if other objects are added to the common CRTC
> state.
> 
> The second one is fixing a possible NULL pointer dereference.
> 
> Regards,
> 
> Boris
> 
> The following changes since commit 1a695a905c18548062509178b98bc91e67510864:
> 
>   Linux 4.7-rc1 (2016-05-29 09:29:24 -0700)
> 
> are available in the git repository at:
> 
>   git at github.com:bbrezillon/linux-at91.git 
> tags/drm-atmel-hlcdc-fixes/for-4.7-rc2
> 
> for you to fetch changes up to dcd64e313ff2d2a15574cd92ec27e73194ba7537:
> 
>   drm: atmel-hlcdc: fix a NULL check (2016-06-01 13:36:26 +0200)
> 
> 
> Two trivial bugfixes on the atmel-hlcdc driver for 4.7-rc2.
> 
> The first one is making use of __drm_atomic_helper_crtc_destroy_state()
> instead of duplicating its logic in atmel_hlcdc_crtc_reset() and
> risking memory leaks if other objects are added to the common CRTC
> state.
> 
> The second one is fixing a possible NULL pointer dereference.
> 
> 
> Boris Brezillon (1):
>   drm: atmel-hlcdc: fix atmel_hlcdc_crtc_reset() implementation
> 
> Dan Carpenter (1):
>   drm: atmel-hlcdc: fix a NULL check
> 
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> 



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


[PATCH 02/11] dma-buf/fence: add fence_array fences v6

2016-06-01 Thread Gustavo Padovan
Hi Christian,

2016-06-01 Christian König :

> From: Gustavo Padovan 
> 
> struct fence_collection inherits from struct fence and carries a
> collection of fences that needs to be waited together.
> 
> It is useful to translate a sync_file to a fence to remove the complexity
> of dealing with sync_files on DRM drivers. So even if there are many
> fences in the sync_file that needs to waited for a commit to happen,
> they all get added to the fence_collection and passed for DRM use as
> a standard struct fence.
> 
> That means that no changes needed to any driver besides supporting fences.
> 
> fence_collection's fence doesn't belong to any timeline context, so
> fence_is_later() and fence_later() are not meant to be called with
> fence_collections fences.

The commit message needs to be fixed to say mention fence_array instead
of fence_collection and we do create fence contexts for fence_arrays
now.

Gustavo


[Nouveau] [PATCH 9/9] drm: Turn off crtc before tearing down its data structure

2016-06-01 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 02:36:41PM +0200, Lukas Wunner wrote:
> On Wed, May 25, 2016 at 03:43:42PM +0200, Daniel Vetter wrote:
> > On Wed, May 25, 2016 at 12:51 PM, Lukas Wunner  wrote:
> > > On Tue, May 24, 2016 at 11:30:42PM +0200, Daniel Vetter wrote:
> > >> On Tue, May 24, 2016 at 06:03:27PM +0200, Lukas Wunner wrote:
> > >> > When a drm_crtc structure is destroyed with drm_crtc_cleanup(), the DRM
> > >> > core does not turn off the crtc first and neither do the drivers. With
> > >> > nouveau, radeon and amdgpu, this causes a runtime pm ref to be leaked 
> > >> > on
> > >> > driver unload if at least one crtc was enabled.
> > >> >
> > >> > (See usage of have_disp_power_ref in nouveau_crtc_set_config(),
> > >> > radeon_crtc_set_config() and amdgpu_crtc_set_config()).
> > >> >
> > >> > Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)")
> > >> > Cc: Dave Airlie 
> > >> > Tested-by: Karol Herbst 
> > >> > Signed-off-by: Lukas Wunner 
> > >>
> > >> This is a core regression, we fixed it again. Previously when unreference
> > >> drm_planes the core made sure that it's not longer in use, which had the
> > >> side effect of shutting everything off in module unload.
> > >>
> > >> For a bunch of reasons we've stopped doing that, but that turned out to 
> > >> be
> > >> a mistake. It's fixed since
> > >>
> > >> commit f2d580b9a8149735cbc4b59c4a8df60173658140
> > >> Author: Maarten Lankhorst 
> > >> Date:   Wed May 4 14:38:26 2016 +0200
> > >>
> > >> drm/core: Do not preserve framebuffer on rmfb, v4.
> > >>
> > >> Your patch shouldn't be needed with that any more. If it still is it's
> > >> most likely the fbdev cleanup done too late, but you /should/ get a big
> > >> WARNING splat in that case from drm_mode_config_cleanup().
> > >
> > > I tested it and at least with nouveau, the above-mentioned commit does
> > > *not* solve the issue, so patch [9/9] of this series is still needed.
> > > I do not get a WARN splat when unloading nouveau.
> > 
> > With legacy kms the only way to keep a crtc enabled is to display a
> > drm_framebuffer on it. And drm_mode_config_cleanup has a WARN_ON if
> > framebuffers are left behind. There's a bunch of options:
> > - nouveau somehow manages to keep the crtc on without a framebuffer
> > - nouveau somehow leaks a drm_framebuffer, but removes it from the fb_list
> > - something else
> 
> Found it. nouveau_fbcon_destroy() doesn't call drm_framebuffer_remove().
> If I add that, the crtc gets properly disabled on unload.
> 
> It does call drm_framebuffer_cleanup(). That's why there was no WARN,
> drm_mode_config_cleanup() only WARNs if a framebuffer was left on the
> mode_config.fb_list.
> 
> radeon and amdgpu have the same problem. In fact there are very few
> drivers that call drm_framebuffer_remove(): tegra, msm, exynos, omapdrm
> and i915 (since Imre Deak's 9d6612516da0).
> 
> Should we add a WARN to prevent this? How about WARN_ON(crtc->enabled)
> in drm_crtc_cleanup()?
> 
> Also, i915 calls drm_framebuffer_unregister_private() before it calls
> drm_framebuffer_remove(). This ordering has the unfortunate side effect
> that the drm_framebuffer has ID 0 in log messages emitted by
> drm_framebuffer_remove():
> 
> [   39.680874] [drm:drm_mode_object_unreference] OBJ ID: 0 (3)
> [   39.680878] [drm:drm_mode_object_unreference] OBJ ID: 0 (2)
> [   39.680884] [drm:drm_mode_object_unreference] OBJ ID: 0 (1)

Well we must first unregister it before we can remove it, so this is
unavoidable.

Wrt switching from _cleanup to _remove, iirc there was troubles with the
later calling into the fb->funcs->destroy hook. But many drivers have
their fbdev fb embedded into some struct (instead of a pointer like i915),
and then things go sideways badly. That's why you can't just blindly
replace them.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH v2 02/21] drm: Add a callback from connector registering

2016-06-01 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 11:38:03AM +0100, Chris Wilson wrote:
> On Wed, Jun 01, 2016 at 11:57:09AM +0200, Daniel Vetter wrote:
> > On Mon, May 30, 2016 at 09:38:20AM +0100, Chris Wilson wrote:
> > > If a driver wants to more precisely control its initialisation and in
> > > particular, defer registering its interfaces with userspace until after
> > > everything is setup, it also needs to defer registering the connectors.
> > > As some devices need more work during registration, add a callback so
> > > that drivers can do additional work if required for a connector.
> > > 
> > > Correspondingly, we also require an unregister callback.
> > > 
> > > Signed-off-by: Chris Wilson 
> > > Cc: Daniel Vetter 
> > > Cc: dri-devel at lists.freedesktop.org
> > 
> > tbh I'd call these hooks simply register/unregister. There shouldn't be
> > any need for ordering every with interface registration/unregistartion,
> > assuming drivers don't fumble things.
> 
> Ah, calling it late_register had the dual purpose of avoiding the
> 'register' keyword. :|
> 
> For consistency with resume's naming scheme, it should be register_late.
> Maybe register_userspace for greater verbage? Though I like the
> shorthand that we have register as meaning expose the internal object to
> third parties, including userspace.

register_aux and unregister_aux, shorthand for auxiliary interfaces?
Slight confusion with dp aux, but hey if that tricks folks into putting
the dp aux register call in here, even better ;-)

Agreed that register_userspace is both doubly the same and not quite the
right thing (since it's also about internal pulication within the kernel).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH] drm/doc: Switch to sphinx/rst fixed-width quoting

2016-06-01 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 04:46:10PM +0300, Jani Nikula wrote:
> On Wed, 01 Jun 2016, Daniel Vetter  wrote:
> > On Wed, Jun 1, 2016 at 11:46 AM, Jani Nikula
> >  wrote:
> >> On Wed, 01 Jun 2016, Daniel Vetter  wrote:
> >>> There's still something very fishy going on with some of these, e.g.
> >>> the drm_modeset_lock Example: and the "Standard GTF Parameters:" Line
> >>> somehow get treated as heading when just appending a :: at the end of
> >>> those lines. But it seems to work everywhere else. Maybe the
> >>> kernel-doc heading generation logic is still a bit wonky?
> >>
> >> Try adding a blank line between the line with trailing :: and the actual
> >> preformatted text. Seems to do the right thing for me.
> >>
> >> http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#literal-blocks
> >>
> >> "Blank lines are required before and after a literal block, but these
> >> blank lines are not included as part of the literal block."
> >
> > That's not what I've meant. The following sometimes (but not always,
> > only in the 2 places I've mentioned) becomes a kernel-doc directive
> 
> What do you mean by "kernel-doc directive" exactly?
> 
> > and not a block quote:
> >
> >  * Standard GTF Parameters::
> >  *
> >  * stuff I wanted to have block quoted.
> >
> > But if I switch the :: to be on a line of it's own (like in the patch)
> > it's totally fine.
> 
> Odd. It does seem to work for me. What does this print near there?
> 
> $ scripts/kernel-doc -rst -function drm_gtf_mode drivers/gpu/drm/drm_modes.c

Tried again, it works now. Probably fixed through some rebasing and me
being on an older version of your toolchain. I'll send out v3.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH] drm/doc: Switch to sphinx/rst fixed-width quoting

2016-06-01 Thread Daniel Vetter
Just fallout from switching from asciidoc to sphinx/rst.

v2: Found more. Also s/\//#/ in the vgpu ascii-art - sphinx treats
those as comments and switch to variable-width, which wreaks the
layout.

v3: Undo some of the hacks, rebasing onto latest version of Jani's
series fixed it.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_bridge.c|  2 +-
 drivers/gpu/drm/drm_fb_cma_helper.c |  2 +-
 drivers/gpu/drm/drm_fops.c  |  2 +-
 drivers/gpu/drm/drm_modes.c |  3 ++-
 drivers/gpu/drm/drm_modeset_lock.c  |  2 +-
 drivers/gpu/drm/drm_vma_manager.c   |  3 +++
 drivers/gpu/drm/i915/i915_reg.h |  2 +-
 drivers/gpu/drm/i915/i915_vgpu.c| 24 
 include/drm/drm_modes.h |  2 ++
 9 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index b3654404abd0..255543086590 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -36,7 +36,7 @@
  * encoder chain.
  *
  * A bridge is always attached to a single &drm_encoder at a time, but can be
- * either connected to it directly, or through an intermediate bridge:
+ * either connected to it directly, or through an intermediate bridge::
  *
  * encoder ---> bridge B ---> bridge A
  *
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c 
b/drivers/gpu/drm/drm_fb_cma_helper.c
index 2b33b191a172..c50a0ba6fdba 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -52,7 +52,7 @@ struct drm_fbdev_cma {
  * will be set up automatically. dirty() is called by
  * drm_fb_helper_deferred_io() in process context (struct delayed_work).
  *
- * Example fbdev deferred io code:
+ * Example fbdev deferred io code::
  *
  * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb,
  *  struct drm_file *file_priv,
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 5921b203503a..323c238fcac7 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -68,7 +68,7 @@ DEFINE_MUTEX(drm_global_mutex);
  * specific implementations. For GEM-based drivers this is drm_gem_mmap().
  *
  * No other file operations are supported by the DRM userspace API. Overall the
- * following is an example #file_operations structure:
+ * following is an example #file_operations structure::
  *
  * static const example_drm_fops = {
  * .owner = THIS_MODULE,
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index e5e6f504d8cc..1eb679e5fbb1 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -552,7 +552,8 @@ EXPORT_SYMBOL(drm_gtf_mode_complex);
  * I also refer to the function of fb_get_mode in the file of
  * drivers/video/fbmon.c
  *
- * Standard GTF parameters:
+ * Standard GTF parameters::
+ *
  * M = 600
  * C = 40
  * K = 128
diff --git a/drivers/gpu/drm/drm_modeset_lock.c 
b/drivers/gpu/drm/drm_modeset_lock.c
index f33ebe638a28..61146f5b4f56 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -37,7 +37,7 @@
  *
  * For basic principles of &ww_mutex, see: 
Documentation/locking/ww-mutex-design.txt
  *
- * The basic usage pattern is to:
+ * The basic usage pattern is to::
  *
  * drm_modeset_acquire_init(&ctx)
  * retry:
diff --git a/drivers/gpu/drm/drm_vma_manager.c 
b/drivers/gpu/drm/drm_vma_manager.c
index 2f2ecde8285b..f306c8855978 100644
--- a/drivers/gpu/drm/drm_vma_manager.c
+++ b/drivers/gpu/drm/drm_vma_manager.c
@@ -127,6 +127,9 @@ EXPORT_SYMBOL(drm_vma_offset_manager_destroy);
  * used to implement weakly referenced lookups using kref_get_unless_zero().
  *
  * Example:
+ *
+ * ::
+ *
  * drm_vma_offset_lock_lookup(mgr);
  * node = drm_vma_offset_lookup_locked(mgr);
  * if (node)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 216cc4ba74ee..d25dd1d694bc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -886,7 +886,7 @@ enum skl_disp_power_wells {
  * PLLs can be routed to any transcoder A/B/C.
  *
  * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is
- * digital port D (CHV) or port A (BXT).
+ * digital port D (CHV) or port A (BXT). ::
  *
  *
  * Dual channel PHY (VLV/CHV/BXT)
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index d5a7a5e7ee7e..004326291854 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -150,28 +150,28 @@ static int vgt_balloon_space(struct drm_mm *mm,
  * of its graphic space being zero. Yet there are some portions ballooned out(
  * the shadow part, which are marked as reserved by drm allocator). From the
  * host point of view, the graphic address space is partitioned by multiple
- * vGPUs in different VMs.
+ * vGPUs in different VMs. ::
  *
  *vGPU1 view Host view
  *

[PATCH v2 1/5] drm: hdlcd: Revamp runtime power management

2016-06-01 Thread Liviu Dudau
Because the HDLCD driver acts as a component master it can end
up enabling the runtime PM functionality before the encoders
are initialised. This can cause crashes if the component slave
never probes (missing module) or if the PM operations kick in
before the probe finishes.

Move the enabling of the runtime PM after the component master
has finished collecting the slave components and use the DRM
atomic helpers to suspend and resume the device.

Tested-by: Robin Murphy 
Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 23 +--
 drivers/gpu/drm/arm/hdlcd_drv.c  | 48 ++--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  3 +--
 3 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index fef1b04..d1e8d31 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -33,8 +33,17 @@
  *
  */

+static void hdlcd_crtc_cleanup(struct drm_crtc *crtc)
+{
+   struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
+
+   /* stop the controller on cleanup */
+   hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
+   drm_crtc_cleanup(crtc);
+}
+
 static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
-   .destroy = drm_crtc_cleanup,
+   .destroy = hdlcd_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
.reset = drm_atomic_helper_crtc_reset,
@@ -155,8 +164,8 @@ static void hdlcd_crtc_disable(struct drm_crtc *crtc)
if (!crtc->primary->fb)
return;

-   clk_disable_unprepare(hdlcd->clk);
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
+   clk_disable_unprepare(hdlcd->clk);
drm_crtc_vblank_off(crtc);
 }

@@ -294,16 +303,6 @@ static struct drm_plane *hdlcd_plane_init(struct 
drm_device *drm)
return plane;
 }

-void hdlcd_crtc_suspend(struct drm_crtc *crtc)
-{
-   hdlcd_crtc_disable(crtc);
-}
-
-void hdlcd_crtc_resume(struct drm_crtc *crtc)
-{
-   hdlcd_crtc_enable(crtc);
-}
-
 int hdlcd_setup_crtc(struct drm_device *drm)
 {
struct hdlcd_drm_private *hdlcd = drm->dev_private;
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index b987c63..21b1427 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -84,11 +84,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long 
flags)
goto setup_fail;
}

-   pm_runtime_enable(drm->dev);
-
-   pm_runtime_get_sync(drm->dev);
ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
-   pm_runtime_put_sync(drm->dev);
if (ret < 0) {
DRM_ERROR("failed to install IRQ handler\n");
goto irq_fail;
@@ -357,6 +353,8 @@ static int hdlcd_drm_bind(struct device *dev)
return -ENOMEM;

drm->dev_private = hdlcd;
+   dev_set_drvdata(dev, drm);
+
hdlcd_setup_mode_config(drm);
ret = hdlcd_load(drm, 0);
if (ret)
@@ -366,14 +364,18 @@ static int hdlcd_drm_bind(struct device *dev)
if (ret)
goto err_unload;

-   dev_set_drvdata(dev, drm);
-
ret = component_bind_all(dev, drm);
if (ret) {
DRM_ERROR("Failed to bind all components\n");
goto err_unregister;
}

+   ret = pm_runtime_set_active(dev);
+   if (ret)
+   goto err_pm_active;
+
+   pm_runtime_enable(dev);
+
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (ret < 0) {
DRM_ERROR("failed to initialise vblank\n");
@@ -399,16 +401,16 @@ err_fbdev:
drm_mode_config_cleanup(drm);
drm_vblank_cleanup(drm);
 err_vblank:
+   pm_runtime_disable(drm->dev);
+err_pm_active:
component_unbind_all(dev, drm);
 err_unregister:
drm_dev_unregister(drm);
 err_unload:
-   pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm);
-   pm_runtime_put_sync(drm->dev);
-   pm_runtime_disable(drm->dev);
of_reserved_mem_device_release(drm->dev);
 err_free:
+   dev_set_drvdata(dev, NULL);
drm_dev_unref(drm);

return ret;
@@ -495,30 +497,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match);
 static int __maybe_unused hdlcd_pm_suspend(struct device *dev)
 {
struct drm_device *drm = dev_get_drvdata(dev);
-   struct drm_crtc *crtc;
+   struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;

-   if (pm_runtime_suspended(dev))
+   if (!hdlcd)
return 0;

-   drm_modeset_lock_all(drm);
-   list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
-   hdlcd_crtc_suspend(crtc);
-   drm_modeset_unlock_all(drm);
+   drm_kms_helper_poll_disable(drm);
+
+   hdlcd->state = drm_atomic_helper_suspend(drm);
+   if (IS_ERR(hdlcd->state)) {
+   drm_kms_helper_poll_enable(drm);
+

[PATCH v2 0/5] HDLCD cleanups for v4.7

2016-06-01 Thread Liviu Dudau
Hello,

Here are a series of patches that I would like to add to v4.7. It fixes issues
with suspend/resume on Juno (support for which has been added in v4.7-rc1).
When doing the work I've noticed some breakage on the vsync behaviour so I've
fixed that as well. In order to ease the introduction of Daniel Vetter's series
that adds support for non-blocking atomic operations I also picked up his patch
that cleans up the crtc->state->event handling.

The final patch adds support for dumping information from the CMA allocator on
the underlying framebuffers that I found useful while debugging the non-blocking
atomic operations.

A copy of the series has been pushed to git://linux-arm.org/linux-ld 
for-upstream/hdlcd

Best regards,
Liviu

Daniel Vetter (1):
  drm/hdlcd: Fix up crtc_state->event handling

Liviu Dudau (4):
  drm: hdlcd: Revamp runtime power management
  drm: hdlcd: Cleanup the atomic plane operations
  drm: hdlcd: Don't touch vsync interrupts during vblank enable/disable.
  drm: hdlcd: Add information about the underlying framebuffers in debugfs

 drivers/gpu/drm/arm/hdlcd_crtc.c | 85 +++-
 drivers/gpu/drm/arm/hdlcd_drv.c  | 83 ---
 drivers/gpu/drm/arm/hdlcd_drv.h  |  5 +--
 3 files changed, 83 insertions(+), 90 deletions(-)

-- 
2.8.2



[PATCH v2 3/5] drm: hdlcd: Cleanup the atomic plane operations

2016-06-01 Thread Liviu Dudau
Harden the plane_check() code to drop attempts at scaling because
that is not supported. Make hdlcd_plane_atomic_update() set the pitch
and line length registers that correctly reflect the plane's values.
And make hdlcd_crtc_mode_set_nofb() a helper function for
hdlcd_crtc_enable() rather than an exposed hook.

Cc: Daniel Vetter 
Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 44 ++--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  1 -
 2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 97326c3..31426ba 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -106,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
struct drm_display_mode *m = &crtc->state->adjusted_mode;
struct videomode vm;
-   unsigned int polarities, line_length, err;
+   unsigned int polarities, err;

vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end;
@@ -122,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
if (m->flags & DRM_MODE_FLAG_PVSYNC)
polarities |= HDLCD_POLARITY_VSYNC;

-   line_length = crtc->primary->state->fb->pitches[0];
-
/* Allow max number of outstanding requests and largest burst size */
hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);

-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length);
-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length);
-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1);
+   hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1);
-   hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);

err = hdlcd_set_pxl_fmt(crtc);
@@ -153,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);

clk_prepare_enable(hdlcd->clk);
+   hdlcd_crtc_mode_set_nofb(crtc);
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
-   drm_crtc_vblank_on(crtc);
 }

 static void hdlcd_crtc_disable(struct drm_crtc *crtc)
 {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);

-   if (!crtc->primary->fb)
+   if (!crtc->state->active)
return;

hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
clk_disable_unprepare(hdlcd->clk);
-   drm_crtc_vblank_off(crtc);
 }

 static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
@@ -232,6 +226,15 @@ static const struct drm_crtc_helper_funcs 
hdlcd_crtc_helper_funcs = {
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
 {
+   u32 src_w, src_h;
+
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+
+   /* we can't do any scaling of the plane source */
+   if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
+   return -EINVAL;
+
return 0;
 }

@@ -240,20 +243,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane 
*plane,
 {
struct hdlcd_drm_private *hdlcd;
struct drm_gem_cma_object *gem;
+   unsigned int depth, bpp;
+   u32 src_w, src_h, dest_w, dest_h;
dma_addr_t scanout_start;

-   if (!plane->state->crtc || !plane->state->fb)
+   if (!plane->state->fb)
return;

-   hdlcd = crtc_to_hdlcd_priv(plane->state->crtc);
+   drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp);
+   src_w = plane->state->src_w >> 16;
+   src_h = plane->state->src_h >> 16;
+   dest_w = plane->state->crtc_w;
+   dest_h = plane->state->crtc_h;
gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
-   scanout_start = gem->paddr;
+   scanout_start = gem->paddr + plane->state->fb->offsets[0] +
+   plane->state->crtc_y * plane->state->fb->pitches[0] +
+   plane->state->crtc_x * bpp / 8;
+
+   hdlcd = plane->dev->dev_private;
+   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, 
plane->state->fb->pitches[0]);
+   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, 
plane->state->fb->pitches[0]);
+   hdlcd_write(hdlcd, HDLCD_R

[PATCH v2 4/5] drm: hdlcd: Don't touch vsync interrupts during vblank enable/disable.

2016-06-01 Thread Liviu Dudau
Because the HDLCD lacks a hardware counter for vsync signal, the DRM
framework expects that the vsync interrupts are left running to feed
the internal software counter. Currently the HDLCD is masking/unmasking
the vsync interrupt on vblank enable/disable calls, which break that
expectation. Fix that.

Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index fb172d2..3f92dfa 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -183,9 +183,13 @@ static int hdlcd_irq_postinstall(struct drm_device *drm)

/* enable debug interrupts */
irq_mask |= HDLCD_DEBUG_INT_MASK;
+#endif
+
+   /* enable vsync interrupts */
+   irq_mask |= HDLCD_INTERRUPT_VSYNC;

hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
-#endif
+
return 0;
 }

@@ -208,20 +212,11 @@ static void hdlcd_irq_uninstall(struct drm_device *drm)

 static int hdlcd_enable_vblank(struct drm_device *drm, unsigned int crtc)
 {
-   struct hdlcd_drm_private *hdlcd = drm->dev_private;
-   unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
-
-   hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask | HDLCD_INTERRUPT_VSYNC);
-
return 0;
 }

 static void hdlcd_disable_vblank(struct drm_device *drm, unsigned int crtc)
 {
-   struct hdlcd_drm_private *hdlcd = drm->dev_private;
-   unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
-
-   hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask & ~HDLCD_INTERRUPT_VSYNC);
 }

 #ifdef CONFIG_DEBUG_FS
-- 
2.8.2



[PATCH v2 5/5] drm: hdlcd: Add information about the underlying framebuffers in debugfs

2016-06-01 Thread Liviu Dudau
drm_fb_cma code has a nice helper function to display in the debugfs
information about the underlying framebuffers used by HDLCD:

$ cat /sys/kernel/debug/dri/0/fb
fb: 1920x1200 at XR24
   0: offset=0 pitch=7680, obj:  0 ( 2) 001011ba 0xfc30 
ff800a27c000 9338880
fb: 1920x1200 at XR24
   0: offset=0 pitch=7680, obj:  0 ( 2) 001008ca 0xfba0 
ff8009987000 9338880
fb: 1920x1200 at XR24
   0: offset=0 pitch=7680, obj:  0 ( 1) 0010 0xfb10 
ff8008fdc000 9216000

Add the entry in HDLCD's debugfs node.

Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 3f92dfa..6f389e6 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -249,6 +249,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void 
*arg)
 static struct drm_info_list hdlcd_debugfs_list[] = {
{ "interrupt_count", hdlcd_show_underrun_count, 0 },
{ "clocks", hdlcd_show_pxlclock, 0 },
+   { "fb", drm_fb_cma_debugfs_show, 0 },
 };

 static int hdlcd_debugfs_init(struct drm_minor *minor)
-- 
2.8.2



[PATCH v2 2/5] drm/hdlcd: Fix up crtc_state->event handling

2016-06-01 Thread Liviu Dudau
From: Daniel Vetter 

event_list just reimplemented what drm_crtc_arm_vblank_event does. And
we also need to send out drm events when shutting down a pipe.

With this it's possible to use the new nonblocking commit support in
the helpers.

Signed-off-by: Daniel Vetter 
Acked-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 18 --
 drivers/gpu/drm/arm/hdlcd_drv.c  | 19 +--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  1 -
 3 files changed, 9 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index d1e8d31..97326c3 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -189,19 +189,17 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *state)
 {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
-   unsigned long flags;
-
-   if (crtc->state->event) {
-   struct drm_pending_vblank_event *event = crtc->state->event;
+   struct drm_pending_vblank_event *event = crtc->state->event;

+   if (event) {
crtc->state->event = NULL;
-   event->pipe = drm_crtc_index(crtc);
-
-   WARN_ON(drm_crtc_vblank_get(crtc) != 0);

-   spin_lock_irqsave(&crtc->dev->event_lock, flags);
-   list_add_tail(&event->base.link, &hdlcd->event_list);
-   spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+   spin_lock_irq(&crtc->dev->event_lock);
+   if (drm_crtc_vblank_get(crtc) == 0)
+   drm_crtc_arm_vblank_event(crtc, event);
+   else
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irq(&crtc->dev->event_lock);
}
 }

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 21b1427..fb172d2 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long 
flags)
atomic_set(&hdlcd->dma_end_count, 0);
 #endif

-   INIT_LIST_HEAD(&hdlcd->event_list);
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
if (IS_ERR(hdlcd->mmio)) {
@@ -160,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg)
atomic_inc(&hdlcd->vsync_count);

 #endif
-   if (irq_status & HDLCD_INTERRUPT_VSYNC) {
-   bool events_sent = false;
-   unsigned long flags;
-   struct drm_pending_vblank_event *e, *t;
-
+   if (irq_status & HDLCD_INTERRUPT_VSYNC)
drm_crtc_handle_vblank(&hdlcd->crtc);

-   spin_lock_irqsave(&drm->event_lock, flags);
-   list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) {
-   list_del(&e->base.link);
-   drm_crtc_send_vblank_event(&hdlcd->crtc, e);
-   events_sent = true;
-   }
-   if (events_sent)
-   drm_crtc_vblank_put(&hdlcd->crtc);
-   spin_unlock_irqrestore(&drm->event_lock, flags);
-   }
-
/* acknowledge interrupt(s) */
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index e7cea82..922a1dc 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -10,7 +10,6 @@ struct hdlcd_drm_private {
struct clk  *clk;
struct drm_fbdev_cma*fbdev;
struct drm_framebuffer  *fb;
-   struct list_headevent_list;
struct drm_crtc crtc;
struct drm_plane*plane;
struct drm_atomic_state *state;
-- 
2.8.2



[PATCH v2 4/5] drm: hdlcd: Don't touch vsync interrupts during vblank enable/disable.

2016-06-01 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 03:48:38PM +0100, Liviu Dudau wrote:
> Because the HDLCD lacks a hardware counter for vsync signal, the DRM
> framework expects that the vsync interrupts are left running to feed
> the internal software counter. Currently the HDLCD is masking/unmasking
> the vsync interrupt on vblank enable/disable calls, which break that
> expectation. Fix that.
> 
> Signed-off-by: Liviu Dudau 

As discussed, this is actually not needed. The only thing you need to do
is set max_vblank_count = 0. If vblank enable/disable is causing problems,
then that would indicate an issue in the core drm_irq.c code, and should
be fixed there.

And if the docs are confusion, then please update those insted. This patch
here shouldn't be needed at all.
-Daniel

> ---
>  drivers/gpu/drm/arm/hdlcd_drv.c | 15 +--
>  1 file changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index fb172d2..3f92dfa 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -183,9 +183,13 @@ static int hdlcd_irq_postinstall(struct drm_device *drm)
>  
>   /* enable debug interrupts */
>   irq_mask |= HDLCD_DEBUG_INT_MASK;
> +#endif
> +
> + /* enable vsync interrupts */
> + irq_mask |= HDLCD_INTERRUPT_VSYNC;
>  
>   hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
> -#endif
> +
>   return 0;
>  }
>  
> @@ -208,20 +212,11 @@ static void hdlcd_irq_uninstall(struct drm_device *drm)
>  
>  static int hdlcd_enable_vblank(struct drm_device *drm, unsigned int crtc)
>  {
> - struct hdlcd_drm_private *hdlcd = drm->dev_private;
> - unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
> -
> - hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask | HDLCD_INTERRUPT_VSYNC);
> -
>   return 0;
>  }
>  
>  static void hdlcd_disable_vblank(struct drm_device *drm, unsigned int crtc)
>  {
> - struct hdlcd_drm_private *hdlcd = drm->dev_private;
> - unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
> -
> - hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask & ~HDLCD_INTERRUPT_VSYNC);
>  }
>  
>  #ifdef CONFIG_DEBUG_FS
> -- 
> 2.8.2
> 
> ___
> 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


[RESEND PATCH 4/6] Documentation: bindings: add dt documentation for cdn DP controller

2016-06-01 Thread Rob Herring
On Fri, May 27, 2016 at 06:45:40PM +0800, Chris Zhong wrote:
> This patch adds a binding that describes the cdn DP controller for
> rk3399.
> 
> Signed-off-by: Chris Zhong 
> ---
> 
>  .../bindings/display/rockchip/cdn-dp-rockchip.txt  | 57 
> ++
>  1 file changed, 57 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
> b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
> new file mode 100644
> index 000..60795c2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
> @@ -0,0 +1,57 @@
> +Rockchip RK3399 specific extensions to the cdn Display Port
> +
> +
> +Required properties:
> +- compatible: "rockchip,cdn-dp"

Needs to be more specific.

> +
> +- reg: physical base address of the controller and length
> +
> +- clocks: from common clock binding: handle to dp clock.
> +
> +- clock-names: from common clock binding:
> +Required elements: "core_clk" "pclk" "spdif"
> +
> +- rockchip,grf: this soc should set GRF regs, so need get grf here.
> +
> +- ports: contain a port nodes with endpoint definitions as defined in
> +  Documentation/devicetree/bindings/media/video-interfaces.txt.
> +  contained 2 endpoints, connecting to the output of vop.
> +
> +- phys: from general PHY binding: the phandle for the PHY device.
> +
> +---
> +
> +Example:
> + cdn_dp: dp at fec0 {
> + compatible = "rockchip,cdn-dp";
> + reg = <0x0 0xfec0 0x0 0x10>;
> + interrupts = ;
> + clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>,
> +  <&cru SCLK_SPDIF_REC_DPTX>;
> + clock-names = "core_clk", "pclk", "spdif";
> + phys = <&tcphy0>;
> + rockchip,grf = <&grf>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + status = "disabled";
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
> +
> + dp_in: port {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + dp_in_vopb: endpoint at 0 {
> + reg = <0>;
> + remote-endpoint = <&vopb_out_dp>;
> + };
> +
> + dp_in_vopl: endpoint at 1 {
> + reg = <1>;
> + remote-endpoint = <&vopl_out_dp>;
> + };
> + };
> + };
> + };
> -- 
> 2.6.3
> 


[PATCH] drm/amdgpu: fix fw leak in non-powerplay dpm code

2016-06-01 Thread Alex Deucher
We need to release the firmware on driver tear down.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/ci_dpm.c  | 3 +++
 drivers/gpu/drm/amd/amdgpu/fiji_dpm.c| 5 +
 drivers/gpu/drm/amd/amdgpu/iceland_dpm.c | 5 +
 drivers/gpu/drm/amd/amdgpu/tonga_dpm.c   | 5 +
 4 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c 
b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
index 671d032..523ddbfc 100644
--- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
@@ -6225,6 +6225,9 @@ static int ci_dpm_sw_fini(void *handle)
ci_dpm_fini(adev);
mutex_unlock(&adev->pm.mutex);

+   release_firmware(adev->pm.fw);
+   adev->pm.fw = NULL;
+
return 0;
 }

diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c 
b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
index 245cabf..ed03b75 100644
--- a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
@@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle)

 static int fiji_dpm_sw_fini(void *handle)
 {
+   struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+   release_firmware(adev->pm.fw);
+   adev->pm.fw = NULL;
+
return 0;
 }

diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c 
b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c
index 460bc8a..825ccd6 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c
@@ -72,6 +72,11 @@ static int iceland_dpm_sw_init(void *handle)

 static int iceland_dpm_sw_fini(void *handle)
 {
+   struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+   release_firmware(adev->pm.fw);
+   adev->pm.fw = NULL;
+
return 0;
 }

diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c 
b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
index b7615ce..f06f6f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
@@ -71,6 +71,11 @@ static int tonga_dpm_sw_init(void *handle)

 static int tonga_dpm_sw_fini(void *handle)
 {
+   struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+   release_firmware(adev->pm.fw);
+   adev->pm.fw = NULL;
+
return 0;
 }

-- 
2.5.5



[PATCH v3 1/4] drm: hdlcd: Revamp runtime power management

2016-06-01 Thread Liviu Dudau
Because the HDLCD driver acts as a component master it can end
up enabling the runtime PM functionality before the encoders
are initialised. This can cause crashes if the component slave
never probes (missing module) or if the PM operations kick in
before the probe finishes.

Move the enabling of the runtime PM after the component master
has finished collecting the slave components and use the DRM
atomic helpers to suspend and resume the device.

Tested-by: Robin Murphy 
Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 23 +--
 drivers/gpu/drm/arm/hdlcd_drv.c  | 48 ++--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  3 +--
 3 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index fef1b04..d1e8d31 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -33,8 +33,17 @@
  *
  */

+static void hdlcd_crtc_cleanup(struct drm_crtc *crtc)
+{
+   struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
+
+   /* stop the controller on cleanup */
+   hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
+   drm_crtc_cleanup(crtc);
+}
+
 static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
-   .destroy = drm_crtc_cleanup,
+   .destroy = hdlcd_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
.reset = drm_atomic_helper_crtc_reset,
@@ -155,8 +164,8 @@ static void hdlcd_crtc_disable(struct drm_crtc *crtc)
if (!crtc->primary->fb)
return;

-   clk_disable_unprepare(hdlcd->clk);
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
+   clk_disable_unprepare(hdlcd->clk);
drm_crtc_vblank_off(crtc);
 }

@@ -294,16 +303,6 @@ static struct drm_plane *hdlcd_plane_init(struct 
drm_device *drm)
return plane;
 }

-void hdlcd_crtc_suspend(struct drm_crtc *crtc)
-{
-   hdlcd_crtc_disable(crtc);
-}
-
-void hdlcd_crtc_resume(struct drm_crtc *crtc)
-{
-   hdlcd_crtc_enable(crtc);
-}
-
 int hdlcd_setup_crtc(struct drm_device *drm)
 {
struct hdlcd_drm_private *hdlcd = drm->dev_private;
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index b987c63..21b1427 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -84,11 +84,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long 
flags)
goto setup_fail;
}

-   pm_runtime_enable(drm->dev);
-
-   pm_runtime_get_sync(drm->dev);
ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
-   pm_runtime_put_sync(drm->dev);
if (ret < 0) {
DRM_ERROR("failed to install IRQ handler\n");
goto irq_fail;
@@ -357,6 +353,8 @@ static int hdlcd_drm_bind(struct device *dev)
return -ENOMEM;

drm->dev_private = hdlcd;
+   dev_set_drvdata(dev, drm);
+
hdlcd_setup_mode_config(drm);
ret = hdlcd_load(drm, 0);
if (ret)
@@ -366,14 +364,18 @@ static int hdlcd_drm_bind(struct device *dev)
if (ret)
goto err_unload;

-   dev_set_drvdata(dev, drm);
-
ret = component_bind_all(dev, drm);
if (ret) {
DRM_ERROR("Failed to bind all components\n");
goto err_unregister;
}

+   ret = pm_runtime_set_active(dev);
+   if (ret)
+   goto err_pm_active;
+
+   pm_runtime_enable(dev);
+
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (ret < 0) {
DRM_ERROR("failed to initialise vblank\n");
@@ -399,16 +401,16 @@ err_fbdev:
drm_mode_config_cleanup(drm);
drm_vblank_cleanup(drm);
 err_vblank:
+   pm_runtime_disable(drm->dev);
+err_pm_active:
component_unbind_all(dev, drm);
 err_unregister:
drm_dev_unregister(drm);
 err_unload:
-   pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm);
-   pm_runtime_put_sync(drm->dev);
-   pm_runtime_disable(drm->dev);
of_reserved_mem_device_release(drm->dev);
 err_free:
+   dev_set_drvdata(dev, NULL);
drm_dev_unref(drm);

return ret;
@@ -495,30 +497,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match);
 static int __maybe_unused hdlcd_pm_suspend(struct device *dev)
 {
struct drm_device *drm = dev_get_drvdata(dev);
-   struct drm_crtc *crtc;
+   struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;

-   if (pm_runtime_suspended(dev))
+   if (!hdlcd)
return 0;

-   drm_modeset_lock_all(drm);
-   list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
-   hdlcd_crtc_suspend(crtc);
-   drm_modeset_unlock_all(drm);
+   drm_kms_helper_poll_disable(drm);
+
+   hdlcd->state = drm_atomic_helper_suspend(drm);
+   if (IS_ERR(hdlcd->state)) {
+   drm_kms_helper_poll_enable(drm);
+

[PATCH v3 0/4] HDLCD cleanups for v4.7

2016-06-01 Thread Liviu Dudau
Hello,

Here are a series of patches that I would like to add to v4.7. It fixes issues
with suspend/resume on Juno (support for which has been added in v4.7-rc1).
When doing the work I've noticed some breakage on the vsync behaviour so I've
fixed that as well. In order to ease the introduction of Daniel Vetter's series
that adds support for non-blocking atomic operations I also picked up his patch
that cleans up the crtc->state->event handling.

The final patch adds support for dumping information from the CMA allocator on
the underlying framebuffers that I found useful while debugging the non-blocking
atomic operations.

A copy of the series has been pushed to git://linux-arm.org/linux-ld 
for-upstream/hdlcd

v3: drop the vsync disabling patch
v2: collect the individual patches into a series


Best regards,
Liviu


Daniel Vetter (1):
  drm/hdlcd: Fix up crtc_state->event handling

Liviu Dudau (3):
  drm: hdlcd: Revamp runtime power management
  drm: hdlcd: Cleanup the atomic plane operations
  drm: hdlcd: Add information about the underlying framebuffers in debugfs

 drivers/gpu/drm/arm/hdlcd_crtc.c | 85 +++-
 drivers/gpu/drm/arm/hdlcd_drv.c  | 68 ++--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  5 +--
 3 files changed, 78 insertions(+), 80 deletions(-)

-- 
2.8.2



[PATCH v3 3/4] drm: hdlcd: Cleanup the atomic plane operations

2016-06-01 Thread Liviu Dudau
Harden the plane_check() code to drop attempts at scaling because
that is not supported. Make hdlcd_plane_atomic_update() set the pitch
and line length registers that correctly reflect the plane's values.
And make hdlcd_crtc_mode_set_nofb() a helper function for
hdlcd_crtc_enable() rather than an exposed hook.

Cc: Daniel Vetter 
Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 44 ++--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  1 -
 2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 97326c3..31426ba 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -106,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
struct drm_display_mode *m = &crtc->state->adjusted_mode;
struct videomode vm;
-   unsigned int polarities, line_length, err;
+   unsigned int polarities, err;

vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end;
@@ -122,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
if (m->flags & DRM_MODE_FLAG_PVSYNC)
polarities |= HDLCD_POLARITY_VSYNC;

-   line_length = crtc->primary->state->fb->pitches[0];
-
/* Allow max number of outstanding requests and largest burst size */
hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);

-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length);
-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length);
-   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1);
+   hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1);
-   hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);

err = hdlcd_set_pxl_fmt(crtc);
@@ -153,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);

clk_prepare_enable(hdlcd->clk);
+   hdlcd_crtc_mode_set_nofb(crtc);
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
-   drm_crtc_vblank_on(crtc);
 }

 static void hdlcd_crtc_disable(struct drm_crtc *crtc)
 {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);

-   if (!crtc->primary->fb)
+   if (!crtc->state->active)
return;

hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
clk_disable_unprepare(hdlcd->clk);
-   drm_crtc_vblank_off(crtc);
 }

 static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
@@ -232,6 +226,15 @@ static const struct drm_crtc_helper_funcs 
hdlcd_crtc_helper_funcs = {
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
 {
+   u32 src_w, src_h;
+
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+
+   /* we can't do any scaling of the plane source */
+   if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
+   return -EINVAL;
+
return 0;
 }

@@ -240,20 +243,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane 
*plane,
 {
struct hdlcd_drm_private *hdlcd;
struct drm_gem_cma_object *gem;
+   unsigned int depth, bpp;
+   u32 src_w, src_h, dest_w, dest_h;
dma_addr_t scanout_start;

-   if (!plane->state->crtc || !plane->state->fb)
+   if (!plane->state->fb)
return;

-   hdlcd = crtc_to_hdlcd_priv(plane->state->crtc);
+   drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp);
+   src_w = plane->state->src_w >> 16;
+   src_h = plane->state->src_h >> 16;
+   dest_w = plane->state->crtc_w;
+   dest_h = plane->state->crtc_h;
gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
-   scanout_start = gem->paddr;
+   scanout_start = gem->paddr + plane->state->fb->offsets[0] +
+   plane->state->crtc_y * plane->state->fb->pitches[0] +
+   plane->state->crtc_x * bpp / 8;
+
+   hdlcd = plane->dev->dev_private;
+   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, 
plane->state->fb->pitches[0]);
+   hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, 
plane->state->fb->pitches[0]);
+   hdlcd_write(hdlcd, HDLCD_R

[PATCH v3 2/4] drm/hdlcd: Fix up crtc_state->event handling

2016-06-01 Thread Liviu Dudau
From: Daniel Vetter 

event_list just reimplemented what drm_crtc_arm_vblank_event does. And
we also need to send out drm events when shutting down a pipe.

With this it's possible to use the new nonblocking commit support in
the helpers.

Signed-off-by: Daniel Vetter 
Acked-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 18 --
 drivers/gpu/drm/arm/hdlcd_drv.c  | 19 +--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  1 -
 3 files changed, 9 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index d1e8d31..97326c3 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -189,19 +189,17 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *state)
 {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
-   unsigned long flags;
-
-   if (crtc->state->event) {
-   struct drm_pending_vblank_event *event = crtc->state->event;
+   struct drm_pending_vblank_event *event = crtc->state->event;

+   if (event) {
crtc->state->event = NULL;
-   event->pipe = drm_crtc_index(crtc);
-
-   WARN_ON(drm_crtc_vblank_get(crtc) != 0);

-   spin_lock_irqsave(&crtc->dev->event_lock, flags);
-   list_add_tail(&event->base.link, &hdlcd->event_list);
-   spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+   spin_lock_irq(&crtc->dev->event_lock);
+   if (drm_crtc_vblank_get(crtc) == 0)
+   drm_crtc_arm_vblank_event(crtc, event);
+   else
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irq(&crtc->dev->event_lock);
}
 }

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 21b1427..fb172d2 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long 
flags)
atomic_set(&hdlcd->dma_end_count, 0);
 #endif

-   INIT_LIST_HEAD(&hdlcd->event_list);
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
if (IS_ERR(hdlcd->mmio)) {
@@ -160,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg)
atomic_inc(&hdlcd->vsync_count);

 #endif
-   if (irq_status & HDLCD_INTERRUPT_VSYNC) {
-   bool events_sent = false;
-   unsigned long flags;
-   struct drm_pending_vblank_event *e, *t;
-
+   if (irq_status & HDLCD_INTERRUPT_VSYNC)
drm_crtc_handle_vblank(&hdlcd->crtc);

-   spin_lock_irqsave(&drm->event_lock, flags);
-   list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) {
-   list_del(&e->base.link);
-   drm_crtc_send_vblank_event(&hdlcd->crtc, e);
-   events_sent = true;
-   }
-   if (events_sent)
-   drm_crtc_vblank_put(&hdlcd->crtc);
-   spin_unlock_irqrestore(&drm->event_lock, flags);
-   }
-
/* acknowledge interrupt(s) */
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index e7cea82..922a1dc 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -10,7 +10,6 @@ struct hdlcd_drm_private {
struct clk  *clk;
struct drm_fbdev_cma*fbdev;
struct drm_framebuffer  *fb;
-   struct list_headevent_list;
struct drm_crtc crtc;
struct drm_plane*plane;
struct drm_atomic_state *state;
-- 
2.8.2



[PATCH v3 4/4] drm: hdlcd: Add information about the underlying framebuffers in debugfs

2016-06-01 Thread Liviu Dudau
drm_fb_cma code has a nice helper function to display in the debugfs
information about the underlying framebuffers used by HDLCD:

$ cat /sys/kernel/debug/dri/0/fb
fb: 1920x1200 at XR24
   0: offset=0 pitch=7680, obj:  0 ( 2) 001011ba 0xfc30 
ff800a27c000 9338880
fb: 1920x1200 at XR24
   0: offset=0 pitch=7680, obj:  0 ( 2) 001008ca 0xfba0 
ff8009987000 9338880
fb: 1920x1200 at XR24
   0: offset=0 pitch=7680, obj:  0 ( 1) 0010 0xfb10 
ff8008fdc000 9216000

Add the entry in HDLCD's debugfs node.

Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index fb172d2..a6ca36f 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -254,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void 
*arg)
 static struct drm_info_list hdlcd_debugfs_list[] = {
{ "interrupt_count", hdlcd_show_underrun_count, 0 },
{ "clocks", hdlcd_show_pxlclock, 0 },
+   { "fb", drm_fb_cma_debugfs_show, 0 },
 };

 static int hdlcd_debugfs_init(struct drm_minor *minor)
-- 
2.8.2



[PATCH] drm/rockchip: vop: do axi reset in vop initial time

2016-06-01 Thread Thierry Reding
On Wed, Jun 01, 2016 at 05:19:12PM +0800, Yakir Yang wrote:
> There is a bug in RK3399 VOP, when bootloader/kernel only enable
> VOP Big or VOP Little to display, then VOP IOMMU would failed to
> reset at the initial time and VOP register couldn't write rightly.
> 
> After do the pure reset of VOP module, then things back to right.
> 
> Signed-off-by: Yakir Yang 
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 ++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 1c4d5b5..4150323 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -1292,7 +1292,7 @@ static int vop_initial(struct vop *vop)
>  {
>   const struct vop_data *vop_data = vop->data;
>   const struct vop_reg_data *init_table = vop_data->init_table;
> - struct reset_control *ahb_rst;
> + struct reset_control *ahb_rst, *axi_rst;
>   int i, ret;
>  
>   vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
> @@ -1331,6 +1331,19 @@ static int vop_initial(struct vop *vop)
>   }
>  
>   /*
> +  * do aclk_reset, reset all vop registers.
> +  */
> + axi_rst = devm_reset_control_get(vop->dev, "axi");

I don't think you want the managed version here since you only store
this in a local variable and hence aren't going to need it afterwards.
Just use reset_control_get() and ...

> + if (IS_ERR(axi_rst)) {
> + dev_err(vop->dev, "failed to get axi reset\n");
> + ret = PTR_ERR(axi_rst);
> + goto err_disable_aclk;
> + }
> + reset_control_assert(axi_rst);
> + usleep_range(10, 20);
> + reset_control_deassert(axi_rst);

call reset_control_put() here.

> +
> + /*
>* do hclk_reset, reset all vop registers.
>*/
>   ahb_rst = devm_reset_control_get(vop->dev, "ahb");

This uses the same pattern, so you might want to consider reworking this
as well, though it should be a separate patch.

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


[PATCH 01/11] dma-buf/fence: make fence context 64 bit v2

2016-06-01 Thread Gustavo Padovan
2016-06-01 Christian König :

> From: Christian König 
> 
> Fence contexts are created on the fly (for example) by the GPU scheduler used
> in the amdgpu driver as a result of an userspace request. Because of this
> userspace could in theory force a wrap around of the 32bit context number
> if it doesn't behave well.
> 
> Avoid this by increasing the context number to 64bits. This way even when
> userspace manages to allocate a billion contexts per second it takes more
> than 500 years for the context number to wrap around.
> 
> v2: fix printf formats as well.
> 
> Signed-off-by: Christian König 
> ---
>  drivers/dma-buf/fence.c |  8 
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h |  2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c  |  2 +-
>  drivers/gpu/drm/etnaviv/etnaviv_gpu.h   |  2 +-
>  drivers/gpu/drm/nouveau/nouveau_fence.h |  3 ++-
>  drivers/gpu/drm/qxl/qxl_release.c   |  2 +-
>  drivers/gpu/drm/radeon/radeon.h |  2 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_fence.c   |  2 +-
>  drivers/staging/android/sync.h  |  3 ++-
>  include/linux/fence.h   | 13 +++--
>  10 files changed, 21 insertions(+), 18 deletions(-)

Reviewed-by: Gustavo Padovan 

Gustavo


[RFC PATCH 2/4] clk: rockchip: rk3399: add ddrc clock support

2016-06-01 Thread Doug Anderson
Lin Huang,

On Wed, Jun 1, 2016 at 2:35 AM, Lin Huang  wrote:
> add ddrc clock setting, so we can do ddr frequency
> scaling on rk3399 platform in future.
>
> Signed-off-by: Lin Huang 
> ---
>  drivers/clk/rockchip/clk-rk3399.c  | 16 
>  include/dt-bindings/clock/rk3399-cru.h |  1 +
>  2 files changed, 17 insertions(+)
>
> diff --git a/drivers/clk/rockchip/clk-rk3399.c 
> b/drivers/clk/rockchip/clk-rk3399.c
> index f1d8e44..749ea59 100644
> --- a/drivers/clk/rockchip/clk-rk3399.c
> +++ b/drivers/clk/rockchip/clk-rk3399.c
> @@ -118,6 +118,10 @@ PNAME(mux_armclkb_p)   = { 
> "clk_core_b_lpll_src",
> "clk_core_b_bpll_src",
> "clk_core_b_dpll_src",
> "clk_core_b_gpll_src" };
> +PNAME(mux_ddrclk_p)= { "clk_ddrc_lpll_src",
> +   "clk_ddrc_bpll_src",
> +   "clk_ddrc_dpll_src",
> +   "clk_ddrc_gpll_src" };
>  PNAME(mux_aclk_cci_p)  = { "cpll_aclk_cci_src",
> "gpll_aclk_cci_src",
> "npll_aclk_cci_src",
> @@ -1377,6 +1381,18 @@ static struct rockchip_clk_branch 
> rk3399_clk_branches[] __initdata = {
> COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
> RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
> RK3368_CLKGATE_CON(13), 11, GFLAGS),
> +
> +   /* ddrc */
> +   GATE(0, "clk_ddrc_lpll_src", "lpll", CLK_IGNORE_UNUSED,
> +RK3399_CLKGATE_CON(3), 0, GFLAGS),
> +   GATE(0, "clk_ddrc_bpll_src", "bpll", CLK_IGNORE_UNUSED,
> +RK3399_CLKGATE_CON(3), 1, GFLAGS),
> +   GATE(0, "clk_ddrc_dpll_src", "dpll", CLK_IGNORE_UNUSED,
> +RK3399_CLKGATE_CON(3), 2, GFLAGS),
> +   GATE(0, "clk_ddrc_gpll_src", "gpll", CLK_IGNORE_UNUSED,
> +RK3399_CLKGATE_CON(3), 3, GFLAGS),
> +   COMPOSITE_DDRC(SCLK_DDRCLK, "clk_ddrc", mux_ddrclk_p, 
> CLK_IGNORE_UNUSED,
> +  RK3399_CLKSEL_CON(6), 4, 2, MFLAGS, 0, 3, DFLAGS),

It seems slightly unfortunate that we need CLK_IGNORE_UNUSED on these.
Only one of these will ever be used at once and it would be awfully
nice if the others could get gated, right?

...presumably this is needed because we might not have an actual
driver for DDR Freq and we definitely want to make sure that clk_ddrc
is enabled in that case.  I guess what we really want is something
like CLK_ENABLE_HAND_OFF eventually, but until then I think you might
get slightly better behavior by getting rid of all of these
CLK_IGNORE_UNUSED and setting "clk_ddrc" as a critical clock, either
using the table in this file or the new flag.

>  };
>
>  static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
> diff --git a/include/dt-bindings/clock/rk3399-cru.h 
> b/include/dt-bindings/clock/rk3399-cru.h
> index 50a44cf..8a0f0442 100644
> --- a/include/dt-bindings/clock/rk3399-cru.h
> +++ b/include/dt-bindings/clock/rk3399-cru.h
> @@ -131,6 +131,7 @@
>  #define SCLK_DPHY_RX0_CFG  165
>  #define SCLK_RMII_SRC  166
>  #define SCLK_PCIEPHY_REF100M   167
> +#define SCLK_DDRCLK168

Almost certainly you'll want to create a separate patch for the
dt-bindings change since it will need to land in a different tree so
it can be pulled into both Heiko's clock topic branch and dts64 topic
branch.



-Doug


[PATCH 02/11] dma-buf/fence: add fence_array fences v6

2016-06-01 Thread Gustavo Padovan
2016-06-01 Christian König :

> From: Gustavo Padovan 
> 
> struct fence_collection inherits from struct fence and carries a
> collection of fences that needs to be waited together.
> 
> It is useful to translate a sync_file to a fence to remove the complexity
> of dealing with sync_files on DRM drivers. So even if there are many
> fences in the sync_file that needs to waited for a commit to happen,
> they all get added to the fence_collection and passed for DRM use as
> a standard struct fence.
> 
> That means that no changes needed to any driver besides supporting fences.
> 
> fence_collection's fence doesn't belong to any timeline context, so
> fence_is_later() and fence_later() are not meant to be called with
> fence_collections fences.
> 
> v2: Comments by Daniel Vetter:
>   - merge fence_collection_init() and fence_collection_add()
>   - only add callbacks at ->enable_signalling()
>   - remove fence_collection_put()
>   - check for type on to_fence_collection()
>   - adjust fence_is_later() and fence_later() to WARN_ON() if they
>   are used with collection fences.
> 
> v3: - Initialize fence_cb.node at fence init.
> 
> Comments by Chris Wilson:
>   - return "unbound" on fence_collection_get_timeline_name()
>   - don't stop adding callbacks if one fails
>   - remove redundant !! on fence_collection_enable_signaling()
>   - remove redundant () on fence_collection_signaled
>   - use fence_default_wait() instead
> 
> v4 (chk): Rework, simplification and cleanup:
>   - Drop FENCE_NO_CONTEXT handling, always allocate a context.
>   - Rename to fence_array.
>   - Return fixed driver name.
>   - Register only one callback at a time.
>   - Document that create function takes ownership of array.
> 
> v5 (chk): More work and fixes:
>   - Avoid deadlocks by adding all callbacks at once again.
>   - Stop trying to remove the callbacks.
>   - Provide context and sequence number for the array fence.
> 
> v6 (chk): Fixes found during testing
>   - Fix stupid typo in _enable_signaling().
> 
> Signed-off-by: Gustavo Padovan 
> Signed-off-by: Christian König 
> ---
>  drivers/dma-buf/Makefile  |   2 +-
>  drivers/dma-buf/fence-array.c | 127 
> ++
>  include/linux/fence-array.h   |  72 
>  3 files changed, 200 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/dma-buf/fence-array.c
>  create mode 100644 include/linux/fence-array.h

This is working fine to me. Once the commit message is fixed:

Reviewed-by: Gustavo Padovan 

You need to Cc Sumit here to decide who is picking these patches.
It would be better to get them through the drm trees so we would need
his Ack at least.

Gustavo


[PATCH 03/11] dma-buf/fence: add signal_on_any to the fence array v2

2016-06-01 Thread Gustavo Padovan
2016-06-01 Christian König :

> From: Christian König 
> 
> If @signal_on_any is true the fence array signals if any fence in the array
> signals, otherwise it signals when all fences in the array signal.
> 
> v2: fix signaled test and add comment suggested by Chris Wilson.
> 
> Signed-off-by: Christian König 
> ---
>  drivers/dma-buf/fence-array.c | 33 +
>  include/linux/fence-array.h   |  3 ++-
>  2 files changed, 27 insertions(+), 9 deletions(-)

Reviewed-by: Gustavo Padovan 

Gustavo


[PULL v2] drm: atmel-hlcdc: fixes for 4.7-rc2

2016-06-01 Thread Boris Brezillon
Hi Dave,

Same pull request but after fixing the prototype mismatch in patch 1
(this time I tested it).

This pull request contains 2 trivial fixes for the atmel-hlcdc driver.

The first one is making use of __drm_atomic_helper_crtc_destroy_state()
instead of duplicating its logic in atmel_hlcdc_crtc_reset() and
risking memory leaks if other objects are added to the common CRTC
state.

The second one is fixing a possible NULL pointer dereference.

Regards,

Boris

The following changes since commit 1a695a905c18548062509178b98bc91e67510864:

  Linux 4.7-rc1 (2016-05-29 09:29:24 -0700)

are available in the git repository at:

  git at github.com:bbrezillon/linux-at91.git 
tags/drm-atmel-hlcdc-fixes/for-4.7-rc2

for you to fetch changes up to 58a2ab3af722550b2e4e8155eb08660e16c20ee6:

  drm: atmel-hlcdc: fix a NULL check (2016-06-01 15:59:36 +0200)


Two trivial bugfixes for the atmel-hlcdc driver.

The first one is making use of __drm_atomic_helper_crtc_destroy_state()
instead of duplicating its logic in atmel_hlcdc_crtc_reset() and
risking memory leaks if other objects are added to the common CRTC
state.

The second one is fixing a possible NULL pointer dereference.


Boris Brezillon (1):
  drm: atmel-hlcdc: fix atmel_hlcdc_crtc_reset() implementation

Dan Carpenter (1):
  drm: atmel-hlcdc: fix a NULL check

 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)


[PATCH] drm: Update obsolete information from {enable/disable}_vblank hooks.

2016-06-01 Thread Liviu Dudau
Since commit 4dfd64862ff8 ("drm: Use vblank timestamps to guesstimate
how many vblanks were missed"), the DRM framework can cope with devices
that don't have a hardware counter for vsync events without having
to keep the vsync interrupts enabled all the time. Drivers handling
such hardware should use drm_vblank_no_hw_counter() function for
their ->get_vblank_counter hook.

Cc: Daniel Vetter 
Cc: Ville Syrjälä 
Signed-off-by: Liviu Dudau 
---
 include/drm/drmP.h | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 84f1a8e..d486118 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -434,7 +434,7 @@ struct drm_driver {
 *
 * Driver callback for fetching a raw hardware vblank counter for @crtc.
 * If a device doesn't have a hardware counter, the driver can simply
-* return the value of drm_vblank_count. The DRM core will account for
+* use drm_vblank_no_hw_counter() function. The DRM core will account 
for
 * missed vblank events while interrupts where disabled based on system
 * timestamps.
 *
@@ -452,8 +452,8 @@ struct drm_driver {
 * @pipe: which irq to enable
 *
 * Enable vblank interrupts for @crtc.  If the device doesn't have
-* a hardware vblank counter, this routine should be a no-op, since
-* interrupts will have to stay on to keep the count accurate.
+* a hardware vblank counter, the driver should use the
+* drm_vblank_no_hw_counter() function that keeps a virtual counter.
 *
 * RETURNS
 * Zero on success, appropriate errno if the given @crtc's vblank
@@ -467,8 +467,8 @@ struct drm_driver {
 * @pipe: which irq to enable
 *
 * Disable vblank interrupts for @crtc.  If the device doesn't have
-* a hardware vblank counter, this routine should be a no-op, since
-* interrupts will have to stay on to keep the count accurate.
+* a hardware vblank counter, the driver should use the
+* drm_vblank_no_hw_counter() function that keeps a virtual counter.
 */
void (*disable_vblank) (struct drm_device *dev, unsigned int pipe);

-- 
2.8.2



[RFC PATCH 2/4] clk: rockchip: rk3399: add ddrc clock support

2016-06-01 Thread Heiko Stübner
Am Mittwoch, 1. Juni 2016, 08:24:48 schrieb Doug Anderson:
> Lin Huang,
> 
> On Wed, Jun 1, 2016 at 2:35 AM, Lin Huang  wrote:
> > add ddrc clock setting, so we can do ddr frequency
> > scaling on rk3399 platform in future.
> > 
> > Signed-off-by: Lin Huang 
> > ---
> > 
> >  drivers/clk/rockchip/clk-rk3399.c  | 16 
> >  include/dt-bindings/clock/rk3399-cru.h |  1 +
> >  2 files changed, 17 insertions(+)
> > 
> > diff --git a/drivers/clk/rockchip/clk-rk3399.c
> > b/drivers/clk/rockchip/clk-rk3399.c index f1d8e44..749ea59 100644
> > --- a/drivers/clk/rockchip/clk-rk3399.c
> > +++ b/drivers/clk/rockchip/clk-rk3399.c
> > @@ -118,6 +118,10 @@ PNAME(mux_armclkb_p)   =
> > { "clk_core_b_lpll_src",> 
> > "clk_core_b_bpll_src",
> > "clk_core_b_dpll_src",
> > "clk_core_b_gpll_src"
> > };
> > 
> > +PNAME(mux_ddrclk_p)= { "clk_ddrc_lpll_src",
> > +   "clk_ddrc_bpll_src",
> > +   "clk_ddrc_dpll_src",
> > +   "clk_ddrc_gpll_src" };
> > 
> >  PNAME(mux_aclk_cci_p)  = { "cpll_aclk_cci_src",
> >  
> > "gpll_aclk_cci_src",
> > "npll_aclk_cci_src",
> > 
> > @@ -1377,6 +1381,18 @@ static struct rockchip_clk_branch
> > rk3399_clk_branches[] __initdata = {> 
> > COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
> > 
> > RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
> > RK3368_CLKGATE_CON(13), 11, GFLAGS),
> > 
> > +
> > +   /* ddrc */
> > +   GATE(0, "clk_ddrc_lpll_src", "lpll", CLK_IGNORE_UNUSED,
> > +RK3399_CLKGATE_CON(3), 0, GFLAGS),
> > +   GATE(0, "clk_ddrc_bpll_src", "bpll", CLK_IGNORE_UNUSED,
> > +RK3399_CLKGATE_CON(3), 1, GFLAGS),
> > +   GATE(0, "clk_ddrc_dpll_src", "dpll", CLK_IGNORE_UNUSED,
> > +RK3399_CLKGATE_CON(3), 2, GFLAGS),
> > +   GATE(0, "clk_ddrc_gpll_src", "gpll", CLK_IGNORE_UNUSED,
> > +RK3399_CLKGATE_CON(3), 3, GFLAGS),
> > +   COMPOSITE_DDRC(SCLK_DDRCLK, "clk_ddrc", mux_ddrclk_p,
> > CLK_IGNORE_UNUSED, +  RK3399_CLKSEL_CON(6), 4, 2,
> > MFLAGS, 0, 3, DFLAGS),
> It seems slightly unfortunate that we need CLK_IGNORE_UNUSED on these.
> Only one of these will ever be used at once and it would be awfully
> nice if the others could get gated, right?
> 
> ...presumably this is needed because we might not have an actual
> driver for DDR Freq and we definitely want to make sure that clk_ddrc
> is enabled in that case.  I guess what we really want is something
> like CLK_ENABLE_HAND_OFF eventually, but until then I think you might
> get slightly better behavior by getting rid of all of these
> CLK_IGNORE_UNUSED and setting "clk_ddrc" as a critical clock, either
> using the table in this file or the new flag.

My current feeling is that staying with the homegrown solution for critical 
clocks might be preferable until the clk-handoff mechanism lands as well, as 
our critical clocks fall into both categories and I'd like to not touch 
everything twice.

The clock above should be controlled by the dcf, so falls into the handoff 
category (critical until a driver picks up the clock).

Also mixing both new and old approach might get confusing.

But I'm definitly open to counter-arguments :-)


> >  };
> >  
> >  static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata =
> >  {
> > 
> > diff --git a/include/dt-bindings/clock/rk3399-cru.h
> > b/include/dt-bindings/clock/rk3399-cru.h index 50a44cf..8a0f0442 100644
> > --- a/include/dt-bindings/clock/rk3399-cru.h
> > +++ b/include/dt-bindings/clock/rk3399-cru.h
> > @@ -131,6 +131,7 @@
> > 
> >  #define SCLK_DPHY_RX0_CFG  165
> >  #define SCLK_RMII_SRC  166
> >  #define SCLK_PCIEPHY_REF100M   167
> > 
> > +#define SCLK_DDRCLK168
> 
> Almost certainly you'll want to create a separate patch for the
> dt-bindings change since it will need to land in a different tree so
> it can be pulled into both Heiko's clock topic branch and dts64 topic
> branch.

correct.


[PATCH v4 1/2] drm: bridge: Add sii902x driver

2016-06-01 Thread Boris Brezillon
On Tue, 17 May 2016 08:47:11 +0200
Daniel Vetter  wrote:

> > +static struct drm_encoder *sii902x_best_encoder(struct drm_connector 
> > *connector)
> > +{
> > +   struct sii902x *sii902x = connector_to_sii902x(connector);
> > +
> > +   return sii902x->bridge.encoder;
> > +}  
> 
> drm_atomic_helper_best_encoder should do exactly this for you. If you feel
> board pimp the atomic helpers to call that one by default to even remove
> the vfunc assingment line ;-)

Just to be sure, is that what you had in mind?

--->8---


[PATCH] drm: atomic: Handle funcs->best_encoder == NULL case

2016-06-01 Thread Boris Brezillon
Fallback drm_atomic_helper_best_encoder() is funcs->best_encoder() is NULL
so that DRM drivers can leave this hook unassigned if they know they want
to use drm_atomic_helper_best_encoder().

Signed-off-by: Boris Brezillon 
---
 drivers/gpu/drm/drm_atomic_helper.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index ddfa0d1..f6a3350 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -110,8 +110,10 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,

if (funcs->atomic_best_encoder)
new_encoder = funcs->atomic_best_encoder(connector, 
conn_state);
-   else
+   else if (funcs->best_encoder)
new_encoder = funcs->best_encoder(connector);
+   else
+   new_encoder = drm_atomic_helper_best_encoder(connector);

if (new_encoder) {
if (encoder_mask & (1 << 
drm_encoder_index(new_encoder))) {





[PATCH 19/26] drm/sun4i: Implement some semblance of vblank event handling

2016-06-01 Thread Maxime Ripard
Hi Daniel,

On Sun, May 29, 2016 at 08:35:16PM +0200, Daniel Vetter wrote:
> atomic_flush seems to be the right place, right after we commit the
> plane updates. Again use the fullproof version, since the pipe might
> be off.

This looks fine.

How can that be tested? modetest requires async vblank, which is not
there yet, and X doesn't seem to use it at all (since it works fine
without it).

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160601/51ed5154/attachment-0001.sig>


[PATCH 23/27] drm/sun4i: Use lockless gem BO free callback

2016-06-01 Thread Maxime Ripard
On Mon, May 30, 2016 at 07:53:15PM +0200, Daniel Vetter wrote:
> No dev->struct_mutex anywhere to be seen.
> 
> Cc: Maxime Ripard 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c 
> b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index 76e922bb60e5..68e9d85085fb 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -103,7 +103,7 @@ static struct drm_driver sun4i_drv_driver = {
>   .dumb_create= drm_gem_cma_dumb_create,
>   .dumb_destroy   = drm_gem_dumb_destroy,
>   .dumb_map_offset= drm_gem_cma_dumb_map_offset,
> - .gem_free_object= drm_gem_cma_free_object,
> + .gem_free_object_unlocked = drm_gem_cma_free_object,
>   .gem_vm_ops = &drm_gem_cma_vm_ops,

It doesn't compile here, it seems I need some additional patch?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160601/aa4d3560/attachment.sig>


[PATCH 02/11] dma-buf/fence: add fence_array fences v6

2016-06-01 Thread Sumit Semwal
Hi Christian, Gustavo,

Thanks for these patches.

On 1 June 2016 at 20:55, Gustavo Padovan  wrote:
> 2016-06-01 Christian König :
>
>> From: Gustavo Padovan 
>>
>> struct fence_collection inherits from struct fence and carries a
>> collection of fences that needs to be waited together.
>>
>> It is useful to translate a sync_file to a fence to remove the complexity
>> of dealing with sync_files on DRM drivers. So even if there are many
>> fences in the sync_file that needs to waited for a commit to happen,
>> they all get added to the fence_collection and passed for DRM use as
>> a standard struct fence.
>>
>> That means that no changes needed to any driver besides supporting fences.
>>
>> fence_collection's fence doesn't belong to any timeline context, so
>> fence_is_later() and fence_later() are not meant to be called with
>> fence_collections fences.
>>
>> v2: Comments by Daniel Vetter:
>>   - merge fence_collection_init() and fence_collection_add()
>>   - only add callbacks at ->enable_signalling()
>>   - remove fence_collection_put()
>>   - check for type on to_fence_collection()
>>   - adjust fence_is_later() and fence_later() to WARN_ON() if they
>>   are used with collection fences.
>>
>> v3: - Initialize fence_cb.node at fence init.
>>
>> Comments by Chris Wilson:
>>   - return "unbound" on fence_collection_get_timeline_name()
>>   - don't stop adding callbacks if one fails
>>   - remove redundant !! on fence_collection_enable_signaling()
>>   - remove redundant () on fence_collection_signaled
>>   - use fence_default_wait() instead
>>
>> v4 (chk): Rework, simplification and cleanup:
>>   - Drop FENCE_NO_CONTEXT handling, always allocate a context.
>>   - Rename to fence_array.
>>   - Return fixed driver name.
>>   - Register only one callback at a time.
>>   - Document that create function takes ownership of array.
>>
>> v5 (chk): More work and fixes:
>>   - Avoid deadlocks by adding all callbacks at once again.
>>   - Stop trying to remove the callbacks.
>>   - Provide context and sequence number for the array fence.
>>
>> v6 (chk): Fixes found during testing
>>   - Fix stupid typo in _enable_signaling().
>>
>> Signed-off-by: Gustavo Padovan 
>> Signed-off-by: Christian König 
>> ---
>>  drivers/dma-buf/Makefile  |   2 +-
>>  drivers/dma-buf/fence-array.c | 127 
>> ++
>>  include/linux/fence-array.h   |  72 
>>  3 files changed, 200 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/dma-buf/fence-array.c
>>  create mode 100644 include/linux/fence-array.h
>
> This is working fine to me. Once the commit message is fixed:
>
> Reviewed-by: Gustavo Padovan 
>
> You need to Cc Sumit here to decide who is picking these patches.
> It would be better to get them through the drm trees so we would need
> his Ack at least.
>
+1 on the commit message consistency change; post that, please feel
free to add my
Acked-by: Sumit Semwal 

for the 3 dma-buf/fences patches and request to take them via DRM tree
as rightly suggested by Gustavo.

> Gustavo

BR,
Sumit.


[GIT PULL] drm/mediatek: MT8173 DSI and DPI fixes

2016-06-01 Thread Philipp Zabel
Hi Dave,

this tag contains two fixes, one each for an oversight in the DPI and
DSI driver, respectively.

regards
Philipp

The following changes since commit 1a695a905c18548062509178b98bc91e67510864:

  Linux 4.7-rc1 (2016-05-29 09:29:24 -0700)

are available in the git repository at:

  git://git.pengutronix.de/git/pza/linux.git tags/mediatek-drm-fixes-2016-06-01

for you to fetch changes up to 2ea9f31799adce35d8c9a0bb3bc1d2b515702c6f:

  drm/mediatek: mtk_dsi: Remove spurious drm_connector_unregister (2016-06-01 
16:09:56 +0200)


mediatek-drm fixes

- remove an invalid, unreachable error message and NULL pointer dereference
- remove a spurious drm_connector_unregister call from the DSI driver


Philipp Zabel (2):
  drm/mediatek: mtk_dpi: remove invalid error message
  drm/mediatek: mtk_dsi: Remove spurious drm_connector_unregister

 drivers/gpu/drm/mediatek/mtk_dpi.c | 5 -
 drivers/gpu/drm/mediatek/mtk_dsi.c | 4 +---
 2 files changed, 1 insertion(+), 8 deletions(-)


[GIT PULL] imx-drm: LVDS updates and some cleanup

2016-06-01 Thread Philipp Zabel
Hi Dave,

this tag contains support for pixel clock polarity configuration,
LVDS panel EDID reading via DDC, video mode selection via native-mode
DT property, UYVY/YUYV plane support, and some cleanups.

regards
Philipp

The following changes since commit 1a695a905c18548062509178b98bc91e67510864:

  Linux 4.7-rc1 (2016-05-29 09:29:24 -0700)

are available in the git repository at:

  git://git.pengutronix.de/git/pza/linux.git tags/imx-drm-next-2016-06-01

for you to fetch changes up to 151787ba0562fd70e7b669a1b5a398875e4fc8e7:

  drm/imx: plane: Don't set plane->crtc in ipu_plane_update() (2016-05-30 
09:14:00 +0200)


imx-drm updates

- add support for reading LVDS panel EDID over DDC
- enable UYVY/VYUY support
- add support for pixel clock polarity configuration
- honor the native-mode DT property for LVDS
- various fixes and cleanups


Akshay Bhat (1):
  dt-bindings: imx: ldb: Add ddc-i2c-bus property

Liu Ying (2):
  drm/imx: ipuv3-plane: Constify ipu_plane_funcs
  drm/imx: plane: Don't set plane->crtc in ipu_plane_update()

Lothar Waßmann (2):
  drm/imx: parallel-display: remove dead code
  drm/imx: imx-ldb: honor 'native-mode' property when selecting video mode 
from DT

Philipp Zabel (4):
  drm/imx: imx-ldb: use of_graph_get_endpoint_by_regs helper
  drm/imx: parallel-display: use of_graph_get_endpoint_by_regs helper
  drm/imx: ipuv3-plane: enable UYVY and VYUY formats
  drm/imx: use bus_flags for pixel clock polarity

Steve Longerbeam (1):
  drm/imx: imx-ldb: Add DDC support

 .../devicetree/bindings/display/imx/ldb.txt|  1 +
 drivers/gpu/drm/imx/imx-drm-core.c | 13 ++--
 drivers/gpu/drm/imx/imx-drm.h  |  7 +-
 drivers/gpu/drm/imx/imx-ldb.c  | 78 +++---
 drivers/gpu/drm/imx/imx-tve.c  |  6 +-
 drivers/gpu/drm/imx/ipuv3-crtc.c   | 10 ++-
 drivers/gpu/drm/imx/ipuv3-plane.c  |  5 +-
 drivers/gpu/drm/imx/parallel-display.c | 40 ---
 8 files changed, 94 insertions(+), 66 deletions(-)


[Nouveau] [PATCH 4/4] drm/nouveau/acpi: fix lockup with PCIe runtime PM

2016-06-01 Thread Lukas Wunner
On Wed, Jun 01, 2016 at 06:51:51PM +0200, Peter Wu wrote:
> On Tue, May 31, 2016 at 02:20:26PM +0200, Lukas Wunner wrote:
> > On Mon, May 30, 2016 at 06:13:51PM +0200, Peter Wu wrote:
> > > Do you have any suggestions for the case where the pcieport driver
> > > refuses to put the bridge in D3 (because the BIOS is too old)? In that
> > > case the nouveau driver needs to fallback to the DSM method (but not
> > > when runtime PM is deliberately disabled by writing control=on).
> > 
> > The BIOS cut-off date is meant to avoid issues when suspending ports
> > on older chipsets. However if the port is used for an Optimus GPU
> > and we can clearly identify that, and there's a _PR3 method provided,
> > it's probably safe to say that the port is *intended* to be suspended.
> > 
> > So you may want to consider amending pci_bridge_d3_possible() to
> > allow D3 for such ports regardless of the BIOS date, as I've done
> > for Thunderbolt in this commit:
> > https://github.com/l1k/linux/commit/3cb8549cd4e5
> 
> Then we have heuristics based on BIOS year, on whether it is TB or not,
> and next to it whether it is an Optimus laptop? Maybe the PCI core needs
> to export a function that allows drivers to override the detection if
> this becomes more common.

Well I consider the TB and Optimus whitelisting as a stop-gap until
the BIOS date is lowered. Rafael wrote:

Some time around when machines with Windows 10 started to ship should be
relatively safe.
I guess we can just pick a reasonable date in the initial patch and then
try to move it back to the past subsequently and see if that breaks things
for anyone.

Source: http://permalink.gmane.org/gmane.linux.power-management.general/75133

> 
> > Not sure how to uniquely identify such ports though. Perhaps check
> > if there's a device in slot 0 below the port which has
> > (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY &&
> > (pdev->vendor == PCI_VENDOR_ID_NVIDIA ||
> >  pdev->vendor == PCI_VENDOR_ID_ATI)
> 
> Seems fragile, there are desktop setups satisfying this match.

Of course, I didn't mean this to be used as is, you'd have to augment
this with checks e.g. for presence of _PR3 and (if possible) Optimus,
but I'm not familiar enough with Optimus to write down working code
for it, I'm only familiar with apple-gmux switching.

Best regards,

Lukas


[Bug 117151] amdgpu: Fails to initialize R7 260x (Bonaire)

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

Parker Reed  changed:

   What|Removed |Added

 Kernel Version|4.6 |4.7

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


[Bug 117151] amdgpu: Fails to initialize R7 260x (Bonaire)

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

--- Comment #5 from Parker Reed  ---
Compiled git today and issue persists. Log attached.

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


[Bug 117151] amdgpu: Fails to initialize R7 260x (Bonaire)

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

--- Comment #6 from Parker Reed  ---
Created attachment 218661
  --> https://bugzilla.kernel.org/attachment.cgi?id=218661&action=edit
4.7.0-rc1 log

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


[Bug 88458] The monitor turns off when playing starcraft 2 in wine

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

--- Comment #4 from Jaakko Niemi  ---
Created attachment 124241
  --> https://bugs.freedesktop.org/attachment.cgi?id=124241&action=edit
kernel log

-- 
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/20160601/d7f1cc00/attachment.html>


[Bug 88458] The monitor turns off when playing starcraft 2 in wine

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

--- Comment #5 from Jaakko Niemi  ---
I can repro this reliably.

[AMD/ATI] Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280]
Kernel 4.6 drm-next, LLVM 3.8

These days I just get hung screen, audio keeps playing on background, I can ssh
in and reboot. 

This happens only with SC2, I don't see problems with other games. Typically I
don't even get halfway through campaign mission, sometimes I get crash when the
game is playing video (assuming it's done through the engine...).

--

-- 
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/20160601/8aeb71b9/attachment.html>


[Bug 88458] The monitor turns off when playing starcraft 2 in wine

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

--- Comment #6 from Jaakko Niemi  ---
(In reply to Jaakko Niemi from comment #5)
> I can repro this reliably.
> 
> [AMD/ATI] Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280]
> Kernel 4.6 drm-next, LLVM 3.8
> 
> These days I just get hung screen, audio keeps playing on background, I can
> ssh in and reboot. 
> 
> This happens only with SC2, I don't see problems with other games. Typically
> I don't even get halfway through campaign mission, sometimes I get crash
> when the game is playing video (assuming it's done through the engine...).
> 
> --

Oh, and Mesa is 12.0 rc1.

-- 
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/20160601/8c26e858/attachment.html>


[PATCH] drm/panel: Remove the get_timings() function.

2016-06-01 Thread Eric Anholt
It appears to have no callers.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/panel/panel-simple.c | 18 --
 include/drm/drm_panel.h  |  4 
 2 files changed, 22 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 3a7bdf1c842b..3c7eb0ac1298 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -265,30 +265,12 @@ static int panel_simple_get_modes(struct drm_panel *panel)
return num;
 }

-static int panel_simple_get_timings(struct drm_panel *panel,
-   unsigned int num_timings,
-   struct display_timing *timings)
-{
-   struct panel_simple *p = to_panel_simple(panel);
-   unsigned int i;
-
-   if (p->desc->num_timings < num_timings)
-   num_timings = p->desc->num_timings;
-
-   if (timings)
-   for (i = 0; i < num_timings; i++)
-   timings[i] = p->desc->timings[i];
-
-   return p->desc->num_timings;
-}
-
 static const struct drm_panel_funcs panel_simple_funcs = {
.disable = panel_simple_disable,
.unprepare = panel_simple_unprepare,
.prepare = panel_simple_prepare,
.enable = panel_simple_enable,
.get_modes = panel_simple_get_modes,
-   .get_timings = panel_simple_get_timings,
 };

 static int panel_simple_probe(struct device *dev, const struct panel_desc 
*desc)
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 220d1e2b3db1..f1dfee3e97c6 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -39,8 +39,6 @@ struct display_timing;
  * @enable: enable panel (turn on back light, etc.)
  * @get_modes: add modes to the connector that the panel is attached to and
  * return the number of modes added
- * @get_timings: copy display timings into the provided array and return
- * the number of display timings available
  *
  * The .prepare() function is typically called before the display controller
  * starts to transmit video data. Panel drivers can use this to turn the panel
@@ -71,8 +69,6 @@ struct drm_panel_funcs {
int (*prepare)(struct drm_panel *panel);
int (*enable)(struct drm_panel *panel);
int (*get_modes)(struct drm_panel *panel);
-   int (*get_timings)(struct drm_panel *panel, unsigned int num_timings,
-  struct display_timing *timings);
 };

 /**
-- 
2.8.0.rc3



  1   2   >