[RFC 5/5] dma-buf/sync_file: rework fence storage in struct file

2016-06-23 Thread Chris Wilson
On Thu, Jun 23, 2016 at 12:29:50PM -0300, Gustavo Padovan wrote:
> -static void sync_file_add_pt(struct sync_file *sync_file, int *i,
> +static int sync_file_set_fence(struct sync_file *sync_file,
> +struct fence **fences)
> +{
> + struct fence_array *array;
> +
> + if (sync_file->num_fences == 1) {
> + sync_file->fence = fences[0];

Straightforward pointer assignment.

> + } else {
> + array = fence_array_create(sync_file->num_fences, fences,
> +fence_context_alloc(1), 1, false);
> + if (!array)
> + return -ENOMEM;
> +
> + sync_file->fence = >base;

New reference.

Imbalance will promptly go bang after we release the single fence[0].

Would fence_array_create(1, fence) returning fence_get(fence) be too
much of a hack?

I would suggest dropping the exported fence_get_fences() and use a local
instead that could avoid the copy, e.g.

static struct fence *get_fences(struct fence **fence,
unsigned int *num_fences)
{
if (fence_is_array(*fence)) {
struct fence_array *array = to_fence_array(*fence);
*num_fences = array->num_fences;
return array->fences;
} else {
*num_fences = 1;
return fence;
}
}

sync_file_merge() {
int num_fences, num_a_fences, num_b_fences;
struct fence **fences, **a_fences, **b_fences;

a_fences = get_fences(, _a_fences);
b_fences = get_fences(, _b_fences);

num_fences = num_a_fences + num_b_fences;

>  static void sync_file_free(struct kref *kref)
>  {
>   struct sync_file *sync_file = container_of(kref, struct sync_file,
>kref);
> - int i;
> -
> - for (i = 0; i < sync_file->num_fences; ++i) {
> - fence_remove_callback(sync_file->cbs[i].fence,
> -   _file->cbs[i].cb);
> - fence_put(sync_file->cbs[i].fence);
> - }
>  
> + fence_remove_callback(sync_file->fence, _file->cb);
> + fence_teardown(sync_file->fence);

Hmm. Could we detect the removal of the last callback and propagate that
to the fence_array? (Rather then introduce a manual call to
fence_teardown.)

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 1/3] RFC: drm: Restrict vblank ioctl to master

2016-06-23 Thread Rainer Hochecker
I spent some time reading and investigating on this. Bear with me, I am
doing Kodi development in my spare time and may not be up-to-date on all
platforms. Seems Wayland is much better suited to serve as reference
platform as X11 does. Is that correct? If so I don't request OML_sync_control
for EGL. Don't waste resources and let the old crap die.

Rainer

On Tue, Jun 21, 2016 at 7:15 AM, Rainer Hochecker 
wrote:

> Thanks for clarification. That changes my view on Wayland.
>
> Cheers,
> Rainer
>
> On Tue, Jun 21, 2016 at 7:01 AM, Daniel Stone 
> wrote:
>
>> Hi,
>>
>> On 21 June 2016 at 14:57, Rainer Hochecker  wrote:
>> > Are you saying that this is outdated:
>> > https://wayland.freedesktop.org/faq.html#heading_toc_j_12
>> >
>> > A more subtle point is that libGL.so includes the GLX symbols, so
>> linking to
>> > that library will pull in all the X dependencies. This means that we
>> can't
>> > link to full GL without pulling in the client side of X, so we're using
>> > GLES2 for now. Longer term, we'll need a way to use full GL under
>> Wayland.
>>
>> Badly worded, really.
>>
>> libGL.so includes the GLX API entrypoints, so your libGL will link to
>> X11. For that reason - and because there's no need for it to use full
>> GL - Weston uses GLES2 for its own composition. For clients, if you
>> don't care about this, then you can use libGL + EGL (this has always
>> worked), or there's also libglvnd's libOpenGL (this is new). Given
>> that, it should be reworded.
>>
>> Cheers,
>> Daniel
>>
>
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160623/c08e8fa8/attachment-0001.html>


[PATCH] drm/amdkfd: destroy mutex if process creation fails

2016-06-23 Thread Oded Gabbay
Signed-off-by: Oded Gabbay 
---
 drivers/gpu/drm/amd/amdkfd/kfd_process.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 6482fee..771a18a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -323,6 +323,7 @@ err_process_pqm_init:
synchronize_rcu();
mmu_notifier_unregister_no_release(>mmu_notifier, process->mm);
 err_mmu_notifier:
+   mutex_destroy(>mutex);
kfd_pasid_free(process->pasid);
 err_alloc_pasid:
kfree(process->queues);
-- 
2.5.5



[RFC 1/5] dma-buf/fence: add .teardown() ops

2016-06-23 Thread Chris Wilson
On Thu, Jun 23, 2016 at 12:29:46PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> fence_array requires a function to clean up its state before we
> are able to call fence_put() and release it.

An explanation along the lines of:

As the array of fence callbacks held by an active struct fence_array
each has a reference to the struct fence_array, when the owner of the
fence_array is freed it must dispose of the callback references before
it can free the fence_array. This can not happen simply during
fence_release() because of the extra references and so we need a new
function to run before the final fence_put().

would help, it is not until you use it in 5/5 that it becomes apparent
why it is needed.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[RFC 3/5] dma-buf/fence: add .get_fences() ops

2016-06-23 Thread Chris Wilson
On Thu, Jun 23, 2016 at 12:29:48PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> get_fences() should return a copy of all fences in the fence as some
> fence subclass (such as fence_array) can store more than one fence at
> time.
> 
> Signed-off-by: Gustavo Padovan 
> ---
>  drivers/dma-buf/fence.c | 14 ++
>  include/linux/fence.h   |  3 +++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
> index 4e61afb..f4094fd 100644
> --- a/drivers/dma-buf/fence.c
> +++ b/drivers/dma-buf/fence.c
> @@ -185,6 +185,20 @@ void fence_release(struct kref *kref)
>  }
>  EXPORT_SYMBOL(fence_release);
>  
> +struct fence **fence_get_fences(struct fence *fence)

Returning an array, but not telling the caller how many elements in the
array?

> +{
> + if (fence->ops->get_fences) {
> + return fence->ops->get_fences(fence);
> + } else {
> + struct fence **fences = kmalloc(sizeof(**fences), GFP_KERNEL);

One too many * (=> sizeof(struct fence), not sizeof(struct fence *))

return kmemdup(, sizeof(fence), GFP_KERNEL);

The documentation should emphasize that the fences in the
returned array have a "borrowed" reference (i.e. it does not return a
new reference to each fence).
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[RFC 4/5] dma-buf/fence-array: add fence_array_get_fences()

2016-06-23 Thread Chris Wilson
On Thu, Jun 23, 2016 at 12:29:49PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> This function returns a copy of the array of fences.
> 
> Signed-off-by: Gustavo Padovan 
> ---
>  drivers/dma-buf/fence-array.c | 14 ++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
> index 601448a..ce98249 100644
> --- a/drivers/dma-buf/fence-array.c
> +++ b/drivers/dma-buf/fence-array.c
> @@ -33,6 +33,19 @@ static const char *fence_array_get_timeline_name(struct 
> fence *fence)
>   return "unbound";
>  }
>  
> +static struct fence **fence_array_get_fences(struct fence *fence)
> +{
> + struct fence_array *array = to_fence_array(fence);
> + struct fence **fences;
> +
> + fences = kmalloc(array->num_fences * sizeof(*fences), GFP_KERNEL);
> + if (!fences)
> + return NULL;
> +
> + memcpy(fences, array->fences, array->num_fences * sizeof(*fences));
> + return fences;

return kmemdup(array->fences,
   array->num_fences * sizeof(*array->fences),
   GFP_KERNEL);

-- 
Chris Wilson, Intel Open Source Technology Centre


[v3 PATCH 5/5] drm/rockchip: cdn-dp: add cdn DP support for rk3399

2016-06-23 Thread Chris Zhong
Add support for cdn DP controller which is embedded in the rk3399
SoCs. The DP is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work,
please put the firmware file to /lib/firmware/cdn/dptx.bin. The
uCPU in charge of aux communication and link training, the host use
mailbox to communicate with the ucpu.
The dclk pin_pol of vop must not be invert for DP.

Signed-off-by: Chris Zhong 

---

Changes in v3:
- use EXTCON_DISP_DP and EXTCON_DISP_DP_ALT cable to get dp port state.
- reset spdif before config it
- modify the firmware clk to 100Mhz
- retry load firmware if fw file is requested too early

Changes in v2:
- Alphabetic order
- remove excess error message
- use define clk_rate
- check all return value
- remove dev_set_name(dp->dev, "cdn-dp");
- use schedule_delayed_work
- remove never-called functions
- remove some unnecessary ()

Changes in v1:
- use extcon API
- use hdmi-codec for the DP Asoc
- do not initialize the "ret"
- printk a err log when drm_of_encoder_active_endpoint_id
- modify the dclk pin_pol to a single line

 drivers/gpu/drm/rockchip/Kconfig|   9 +
 drivers/gpu/drm/rockchip/Makefile   |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 722 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.h  | 108 
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   | 731 
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   | 404 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   6 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |   2 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |   2 +
 9 files changed, 1984 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index d30bdc3..20da9a8 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,6 +25,15 @@ config ROCKCHIP_ANALOGIX_DP
  for the Analogix Core DP driver. If you want to enable DP
  on RK3288 based SoC, you should selet this option.

+config ROCKCHIP_CDN_DP
+tristate "Rockchip cdn DP"
+depends on DRM_ROCKCHIP
+help
+ This selects support for Rockchip SoC specific extensions
+ for the cdn Dp driver. If you want to enable Dp on
+ RK3399 based SoC, you should selet this
+ option.
+
 config ROCKCHIP_DW_HDMI
 tristate "Rockchip specific extensions for Synopsys DW HDMI"
 depends on DRM_ROCKCHIP
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 05d0713..abdecd5 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -7,6 +7,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o

 obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
+obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
 obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
new file mode 100644
index 000..5409a9e
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -0,0 +1,722 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include "cdn-dp-reg.h"
+#include "cdn-dp-core.h"
+#include "rockchip_drm_vop.h"
+
+#define connector_to_dp(c) \
+   container_of(c, struct cdn_dp_device, connector)
+
+#define encoder_to_dp(c) \
+   container_of(c, struct cdn_dp_device, encoder)
+
+/* dp grf register offset */
+#define DP_VOP_SEL 0x6224
+#define DP_SEL_VOP_LIT BIT(12)
+#define DP_CLK_RATE1
+#define WAIT_HPD_STABLE1000
+
+static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
+{
+   int ret;
+
+   ret = clk_prepare_enable(dp->pclk);
+   if (ret < 0) {
+   

[v3 PATCH 4/5] Documentation: bindings: add dt documentation for cdn DP controller

2016-06-23 Thread Chris Zhong
This patch adds a binding that describes the cdn DP controller for
rk3399.

Signed-off-by: Chris Zhong 

---

Changes in v3:
- add SoC specific compatible string
- remove reg = <1>;

Changes in v2: None
Changes in v1:
- add extcon node description
- add #sound-dai-cells description

 .../bindings/display/rockchip/cdn-dp-rockchip.txt  | 61 ++
 1 file changed, 61 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..b14b2b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
@@ -0,0 +1,61 @@
+Rockchip RK3399 specific extensions to the cdn Display Port
+
+
+Required properties:
+- compatible: must be "rockchip,rk3399-cdn-dp"
+
+- 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.
+
+- extcon: extcon specifier for the Power Delivery
+
+- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
+
+---
+
+Example:
+   cdn_dp: dp at fec0 {
+   compatible = "rockchip,rk3399-cdn-dp";
+   reg = <0x0 0xfec0 0x0 0x10>;
+   interrupts = ;
+   clocks = < SCLK_DP_CORE>, < PCLK_DP_CTRL>,
+< SCLK_SPDIF_REC_DPTX>;
+   clock-names = "core-clk", "pclk", "spdif";
+   phys = <>;
+   extcon = <>;
+   rockchip,grf = <>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   #sound-dai-cells = <1>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   dp_in: port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   dp_in_vopb: endpoint at 0 {
+   reg = <0>;
+   remote-endpoint = <_out_dp>;
+   };
+
+   dp_in_vopl: endpoint at 1 {
+   reg = <1>;
+   remote-endpoint = <_out_dp>;
+   };
+   };
+   };
+   };
-- 
2.6.3



[v3 PATCH 0/5] Rockchip Type-C and DispplayPort driver

2016-06-23 Thread Chris Zhong

Hi all

This series patch is for rockchip Type-C phy and DisplayPort controller
driver.

The USB Type-C PHY is designed to support the USB3 and DP applications.
The PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and HBR2
data rates. The Type-C cable orientation detection and Power Delivery
(PD) is accomplished using a PD PHY or a exernal PD chip.

The DP controller is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work, please
put the firmware file to /lib/firmware/cdn/dptx.bin. The uCPU in charge
of aux communication and link training, the host use mailbox to
communicate with the ucpu.

The PHY driver has register a notification with extcon API, to get the
alt mode from PD, the PD driver need call the devm_extcon_dev_allocate
to create a extcon device and use extcon_set_state to notify PHY and
DP controller.

About the DP audio, cdn-dp registered 2 DAIs: 0 is I2S, 1 is SPDIF.
We can reference them in simple-card.

This series is based on Mark Yao's branch:
https://github.com/markyzq/kernel-drm-rockchip/tree/drm-rockchip-next-2016-05-23

I test this patches on the rk3399-evb board, with a fusb302 driver,
this branch has no rk3399.dtsi, so the patch about dts is not included
in this series.


Changes in v3:
- use compatible: rockchip,rk3399-typec-phy
- use dashes instead of underscores.
- remove the phy framework(Kishon Vijay Abraham I)
- add parentheses around the macro
- use a single space between type and name
- add spaces after opening and before closing braces.
- use u16 for register value
- remove type-c phy header file
- CodingStyle optimization
- use some cable extcon to get type-c port information
- add a extcon to notify Display Port
- add SoC specific compatible string
- remove reg = <1>;
- use EXTCON_DISP_DP and EXTCON_DISP_DP_ALT cable to get dp port state.
- reset spdif before config it
- modify the firmware clk to 100Mhz
- retry load firmware if fw file is requested too early

Changes in v2:
- add some registers description
- select RESET_CONTROLLER
- alphabetic order
- modify some spelling mistakes
- make mode cleaner
- use bool for enable/disable
- check all of the return value
- return a better err number
- use more readx_poll_timeout()
- clk_disable_unprepare(tcphy->clk_ref);
- remove unuse functions, rockchip_typec_phy_power_on/off
- remove unnecessary typecast from void *
- use dts node to distinguish between phys.
- Alphabetic order
- remove excess error message
- use define clk_rate
- check all return value
- remove dev_set_name(dp->dev, "cdn-dp");
- use schedule_delayed_work
- remove never-called functions
- remove some unnecessary ()

Changes in v1:
- add extcon node description
- move the registers in phy driver
- remove the suffix of reset
- update the licence note
- init core clock to 50MHz
- use extcon API
- remove unused global
- add some comments for magic num
- change usleep_range(1000, 2000) tousleep_range(1000, 1050)
- remove __func__ from dev_err
- return err number when get clk failed
- remove ADDR_ADJ define
- use devm_clk_get(>dev, "tcpdcore")
- add extcon node description
- add #sound-dai-cells description
- use extcon API
- use hdmi-codec for the DP Asoc
- do not initialize the "ret"
- printk a err log when drm_of_encoder_active_endpoint_id
- modify the dclk pin_pol to a single line

Chris Zhong (5):
  extcon: Add Type-C and DP support
  Documentation: bindings: add dt doc for Rockchip USB Type-C PHY
  phy: Add USB Type-C PHY driver for rk3399
  Documentation: bindings: add dt documentation for cdn DP controller
  drm/rockchip: cdn-dp: add cdn DP support for rk3399

 .../bindings/display/rockchip/cdn-dp-rockchip.txt  |   61 ++
 .../devicetree/bindings/phy/phy-rockchip-typec.txt |   74 ++
 drivers/extcon/extcon.c|6 +
 drivers/gpu/drm/rockchip/Kconfig   |9 +
 drivers/gpu/drm/rockchip/Makefile  |1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c |  722 ++
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  108 ++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c  |  731 ++
 drivers/gpu/drm/rockchip/cdn-dp-reg.h  |  404 
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c|6 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h|2 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c|2 +
 drivers/phy/Kconfig|8 +
 drivers/phy/Makefile   |1 +
 drivers/phy/phy-rockchip-typec.c   | 1027 
 include/linux/extcon.h |6 +
 16 files changed, 3167 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 

[Bug 96492] Running Opera web-browser with forced hardware rendering cause GPU lockup

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

--- Comment #3 from russianneuromancer at ya.ru ---
Same issue is reproducible with running Opera on dGPU via DRI_PRIME.

-- 
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/20160623/83ac784c/attachment.html>


[Bug 96492] Running Opera web-browser with forced hardware rendering cause GPU lockup

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

russianneuromancer at ya.ru changed:

   What|Removed |Added

Summary|[SUMO] Running Opera|Running Opera web-browser
   |web-browser with forced |with forced hardware
   |hardware rendering cause|rendering cause GPU lockup
   |GPU lockup  |

-- 
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/20160623/4d3aa170/attachment.html>


[Bug 94445] Tonga llvm assert since RegisterCoalescer: Need to check DstReg+SrcReg for missing undef flags

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

Nicolai Hähnle  changed:

   What|Removed |Added

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

--- Comment #11 from Nicolai Hähnle  ---
This has been fixed for some time.

-- 
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/20160623/f204f39f/attachment.html>


[PATCH v2 25/25] arm64: dts: apq8016-sbc: Add HDMI display support

2016-06-23 Thread Archit Taneja
The APQ8016-sbc provides a HDMI output. The APQ8016 display block only
provides a MIPI DSI output. So, the board has a ADV7533 DSI to HDMI
encoder chip that sits between the DSI PHY output and the HDMI
connector.

Add the ADV7533 DT node under its I2C control bus, and tie the DSI
output port to the ADV7533's input port.

Cc: Andy Gross 
Cc: Rob Herring 
Cc: devicetree at vger.kernel.org

Signed-off-by: Archit Taneja 
---
 arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi | 48 +
 arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi  | 82 ++
 2 files changed, 130 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi 
b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
index ee828a8..e1e6c6b 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
@@ -24,4 +24,52 @@
bias-pull-up;
};
};
+
+   adv7533_int_active: adv533_int_active {
+   pinmux {
+   function = "gpio";
+   pins = "gpio31";
+   };
+   pinconf {
+   pins = "gpio31";
+   drive-strength = <16>;
+   bias-disable;
+   };
+   };
+
+   adv7533_int_suspend: adv7533_int_suspend {
+   pinmux {
+   function = "gpio";
+   pins = "gpio31";
+   };
+   pinconf {
+   pins = "gpio31";
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
+
+   adv7533_switch_active: adv7533_switch_active {
+   pinmux {
+   function = "gpio";
+   pins = "gpio32";
+   };
+   pinconf {
+   pins = "gpio32";
+   drive-strength = <16>;
+   bias-disable;
+   };
+   };
+
+   adv7533_switch_suspend: adv7533_switch_suspend {
+   pinmux {
+   function = "gpio";
+   pins = "gpio32";
+   };
+   pinconf {
+   pins = "gpio32";
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
 };
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi 
b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index 205ef89..5045695 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -59,6 +59,47 @@
/* On High speed expansion */
label = "HS-I2C2";
status = "okay";
+
+   adv_bridge: bridge at 39 {
+   status = "okay";
+
+   compatible = "adi,adv7533";
+   reg = <0x39>;
+
+   interrupt-parent = <>;
+   interrupts = <31 2>;
+
+   adi,dsi-lanes = <4>;
+
+   pd-gpios = < 32 0>;
+
+   avdd-supply = <_l6>;
+   v1p2-supply = <_l6>;
+   v3p3-supply = <_l17>;
+
+   pinctrl-names = "default","sleep";
+   pinctrl-0 = <_int_active 
_switch_active>;
+   pinctrl-1 = <_int_suspend 
_switch_suspend>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port at 0 {
+   reg = <0>;
+   adv7533_in: endpoint {
+   remote-endpoint = 
<_out>;
+   };
+   };
+
+   port at 1 {
+   reg = <1>;
+   adv7533_out: endpoint {
+   remote-endpoint = 
<_con>;
+   };
+   };
+   };
+   };
};

i2c at 78ba000 {
@@ -164,6 +205,36 @@
lpass at 07708000 {
status = "okay";
};
+
+   mdss at 1a0 {
+   status = "okay";
+
+   mdp at 1a01000 {
+   status = "okay";
+   };
+
+   dsi at 1a98000 {
+   

[PATCH v2 24/25] arm64: dts: msm8916: Add display support

2016-06-23 Thread Archit Taneja
The MSM8916 SoC contains a MDP5 based display block, and one DSI output.
Add the top level MDSS DT node, and the MDP5, DSI and DSI PHY children
sub-blocks. Establish the link between MDP5's INTF1 output port and DSI's
input port.

Cc: Andy Gross 
Cc: Rob Herring 
Cc: devicetree at vger.kernel.org

Signed-off-by: Archit Taneja 
---
v2:
 - Removed "qcom,dsi-host-index" and "qcom,dsi-phy-index" props

 arch/arm64/boot/dts/qcom/msm8916.dtsi | 117 ++
 1 file changed, 117 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 9681200..fe74fea 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -537,6 +537,123 @@
clocks = < GCC_PRNG_AHB_CLK>;
clock-names = "core";
};
+
+   mdss: mdss at 1a0 {
+   compatible = "qcom,mdss";
+   reg = <0x1a0 0x1000>,
+ <0x1ac8000 0x3000>;
+   reg-names = "mdss_phys", "vbif_phys";
+
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < GCC_MDSS_AHB_CLK>,
+< GCC_MDSS_AXI_CLK>,
+< GCC_MDSS_VSYNC_CLK>;
+   clock-names = "iface_clk",
+ "bus_clk",
+ "vsync_clk";
+
+   interrupts = <0 72 0>;
+
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mdp: mdp at 1a01000 {
+   compatible = "qcom,mdp5";
+   reg = <0x1a01000 0x9>;
+   reg-names = "mdp_phys";
+
+   interrupt-parent = <>;
+   interrupts = <0 0>;
+
+   clocks = < GCC_MDSS_AHB_CLK>,
+< GCC_MDSS_AXI_CLK>,
+< GCC_MDSS_MDP_CLK>,
+< GCC_MDSS_VSYNC_CLK>;
+   clock-names = "iface_clk",
+ "bus_clk",
+ "core_clk",
+ "vsync_clk";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port at 0 {
+   reg = <0>;
+   mdp5_intf1_out: endpoint {
+   remote-endpoint = 
<_in>;
+   };
+   };
+   };
+   };
+
+   dsi0: dsi at 1a98000 {
+   compatible = "qcom,mdss-dsi-ctrl";
+   reg = <0x1a98000 0x25c>;
+   reg-names = "dsi_ctrl";
+
+   interrupt-parent = <>;
+   interrupts = <4 0>;
+
+   assigned-clocks = < BYTE0_CLK_SRC>,
+ < PCLK0_CLK_SRC>;
+   assigned-clock-parents = <_phy0 0>,
+<_phy0 1>;
+
+   clocks = < GCC_MDSS_MDP_CLK>,
+< GCC_MDSS_AHB_CLK>,
+< GCC_MDSS_AXI_CLK>,
+< GCC_MDSS_BYTE0_CLK>,
+< GCC_MDSS_PCLK0_CLK>,
+< GCC_MDSS_ESC0_CLK>;
+   clock-names = "mdp_core_clk",
+ "iface_clk",
+ "bus_clk",
+ "byte_clk",
+ "pixel_clk",
+ "core_clk";
+   phys = <_phy0>;
+   phy-names = "dsi-phy";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port at 0 {
+   reg = <0>;
+   dsi0_in: endpoint {
+   

[PATCH v2 23/25] dt-bindings: display/msm: Remove power domain property from encoder nodes

2016-06-23 Thread Archit Taneja
Remove the power-domain property from the DSI, HDMI and eDP dt-binding
docs. The power domain only needs to be specified in the parent MDSS
device node (that too only for SoCs which contain MDSS).

Signed-off-by: Archit Taneja 
---
 Documentation/devicetree/bindings/display/msm/dsi.txt  | 3 ---
 Documentation/devicetree/bindings/display/msm/edp.txt  | 2 --
 Documentation/devicetree/bindings/display/msm/hdmi.txt | 4 
 3 files changed, 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dsi.txt 
b/Documentation/devicetree/bindings/display/msm/dsi.txt
index e6933a8..c1ef181 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi.txt
+++ b/Documentation/devicetree/bindings/display/msm/dsi.txt
@@ -8,7 +8,6 @@ Required properties:
 - reg-names: The names of register regions. The following regions are required:
   * "dsi_ctrl"
 - interrupts: The interrupt signal from the DSI block.
-- power-domains: Should be < MDSS_GDSC>.
 - clocks: Phandles to device clocks.
 - clock-names: the following clocks are required:
   * "mdp_core_clk"
@@ -94,7 +93,6 @@ Required properties:
   * "dsi_phy_regulator"
 - clock-cells: Must be 1. The DSI PHY block acts as a clock provider, creating
   2 clocks: A byte clock (index 0), and a pixel clock (index 1).
-- power-domains: Should be < MDSS_GDSC>.
 - clocks: Phandles to device clocks. See [1] for details on clock bindings.
 - clock-names: the following clocks are required:
   * "iface_clk"
@@ -116,7 +114,6 @@ Example:
interrupts = <4 0>;
reg-names = "dsi_ctrl";
reg = <0xfd922800 0x200>;
-   power-domains = < MDSS_GDSC>;
clock-names =
"bus_clk",
"byte_clk",
diff --git a/Documentation/devicetree/bindings/display/msm/edp.txt 
b/Documentation/devicetree/bindings/display/msm/edp.txt
index 3a20f6e..e712dfa 100644
--- a/Documentation/devicetree/bindings/display/msm/edp.txt
+++ b/Documentation/devicetree/bindings/display/msm/edp.txt
@@ -8,7 +8,6 @@ Required properties:
   * "edp"
   * "pll_base"
 - interrupts: The interrupt signal from the eDP block.
-- power-domains: Should be < MDSS_GDSC>.
 - clocks: device clocks
   See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
 - clock-names: the following clocks are required:
@@ -39,7 +38,6 @@ Example:
<0xfd923a00 0xd4>;
interrupt-parent = <_mdp>;
interrupts = <12 0>;
-   power-domains = < MDSS_GDSC>;
clock-names =
"core_clk",
"pixel_clk",
diff --git a/Documentation/devicetree/bindings/display/msm/hdmi.txt 
b/Documentation/devicetree/bindings/display/msm/hdmi.txt
index b63f614..ce84459 100644
--- a/Documentation/devicetree/bindings/display/msm/hdmi.txt
+++ b/Documentation/devicetree/bindings/display/msm/hdmi.txt
@@ -11,7 +11,6 @@ Required properties:
 - reg: Physical base address and length of the controller's registers
 - reg-names: "core_physical"
 - interrupts: The interrupt signal from the hdmi block.
-- power-domains: Should be < MDSS_GDSC>.
 - clocks: device clocks
   See ../clocks/clock-bindings.txt for details.
 - qcom,hdmi-tx-ddc-clk-gpio: ddc clk pin
@@ -48,7 +47,6 @@ Required properties:
 * "hdmi_tx_l1"
 * "hdmi_tx_l3"
 * "hdmi_tx_l4"
-- power-domains: Should be < MDSS_GDSC>.
 - clocks: device clocks
   See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
 - core-vdda-supply: phandle to vdda regulator device node
@@ -63,7 +61,6 @@ Example:
reg-names = "core_physical";
reg = <0x04a0 0x2f0>;
interrupts = ;
-   power-domains = < MDSS_GDSC>;
clock-names =
"core_clk",
"master_iface_clk",
@@ -92,7 +89,6 @@ Example:
reg = <0x4a00400 0x60>,
  <0x4a00500 0x100>;
#phy-cells = <0>;
-   power-domains = < MDSS_GDSC>;
clock-names = "slave_iface_clk";
clocks = < HDMI_S_AHB_CLK>;
core-vdda-supply = <_hdmi_mvs>;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 22/25] dt-bindings: msm/dsi: Remove unused properties

2016-06-23 Thread Archit Taneja
Remove the DSI index properties from the DSI host and PHY binding
documentation. The indices aren't a valid property and shouldn't
be a part of the DT binding.

Signed-off-by: Archit Taneja 
---
 Documentation/devicetree/bindings/display/msm/dsi.txt | 6 --
 1 file changed, 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dsi.txt 
b/Documentation/devicetree/bindings/display/msm/dsi.txt
index 6b1cab1..e6933a8 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi.txt
+++ b/Documentation/devicetree/bindings/display/msm/dsi.txt
@@ -7,8 +7,6 @@ Required properties:
 - reg: Physical base address and length of the registers of controller
 - reg-names: The names of register regions. The following regions are required:
   * "dsi_ctrl"
-- qcom,dsi-host-index: The ID of DSI controller hardware instance. This should
-  be 0 or 1, since we have 2 DSI controllers at most for now.
 - interrupts: The interrupt signal from the DSI block.
 - power-domains: Should be < MDSS_GDSC>.
 - clocks: Phandles to device clocks.
@@ -96,8 +94,6 @@ Required properties:
   * "dsi_phy_regulator"
 - clock-cells: Must be 1. The DSI PHY block acts as a clock provider, creating
   2 clocks: A byte clock (index 0), and a pixel clock (index 1).
-- qcom,dsi-phy-index: The ID of DSI PHY hardware instance. This should
-  be 0 or 1, since we have 2 DSI PHYs at most for now.
 - power-domains: Should be < MDSS_GDSC>.
 - clocks: Phandles to device clocks. See [1] for details on clock bindings.
 - clock-names: the following clocks are required:
@@ -116,7 +112,6 @@ Optional properties:
 Example:
dsi0: dsi at fd922800 {
compatible = "qcom,mdss-dsi-ctrl";
-   qcom,dsi-host-index = <0>;
interrupt-parent = <>;
interrupts = <4 0>;
reg-names = "dsi_ctrl";
@@ -199,7 +194,6 @@ Example:

dsi_phy0: dsi-phy at fd922a00 {
compatible = "qcom,dsi-phy-28nm-hpm";
-   qcom,dsi-phy-index = <0>;
reg-names =
"dsi_pll",
"dsi_phy",
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 21/25] dt-bindings: msm/mdp: Provide details on MDP interface ports

2016-06-23 Thread Archit Taneja
The MDP4/5 DT node now contains a list of ports that describe how it
connects to external encoder interfaces like DSI and HDMI. These follow
the standard of_graph bindings, and allow us to get rid of the 'connectors'
phandle that contained a list of all the external encoders connected to
MDP.

Acked-by: Rob Herring 
Signed-off-by: Archit Taneja 
---
 .../devicetree/bindings/display/msm/mdp4.txt   | 68 --
 .../devicetree/bindings/display/msm/mdp5.txt   | 48 ++-
 2 files changed, 110 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/mdp4.txt 
b/Documentation/devicetree/bindings/display/msm/mdp4.txt
index 1de9b17..3c341a1 100644
--- a/Documentation/devicetree/bindings/display/msm/mdp4.txt
+++ b/Documentation/devicetree/bindings/display/msm/mdp4.txt
@@ -10,7 +10,6 @@ Required properties:
   * "qcom,mdp4" - mdp4
 - reg: Physical base address and length of the controller's registers.
 - interrupts: The interrupt signal from the display controller.
-- connectors: array of phandles for output device(s)
 - clocks: device clocks
   See ../clocks/clock-bindings.txt for details.
 - clock-names: the following clocks are required.
@@ -20,9 +19,23 @@ Required properties:
   * "lut_clk"
   * "hdmi_clk"
   * "tv_clk"
+- ports: contains the list of output ports from MDP. These connect to 
interfaces
+  that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is a
+  special case since it is a part of the MDP block itself).
+
+  Each output port contains an endpoint that describes how it is connected to 
an
+  external interface. These are described by the standard properties documented
+  here:
+   Documentation/devicetree/bindings/graph.txt
+   Documentation/devicetree/bindings/media/video-interfaces.txt
+
+  The output port mappings are:
+   Port 0 -> LCDC/LVDS
+   Port 1 -> DSI1 Cmd/Video
+   Port 2 -> DSI2 Cmd/Video
+   Port 3 -> DTV

 Optional properties:
-- gpus: phandle for gpu device
 - clock-names: the following clocks are optional:
   * "lut_clk"

@@ -31,12 +44,27 @@ Example:
 / {
...

-   mdp: qcom,mdp at 510 {
+   hdmi: hdmi at 4a0 {
+   ...
+   ports {
+   ...
+   port at 0 {
+   reg = <0>;
+   hdmi_in: endpoint {
+   remote-endpoint = <_dtv_out>;
+   };
+   };
+   ...
+   };
+   ...
+   };
+
+   ...
+
+   mdp: mdp at 510 {
compatible = "qcom,mdp4";
reg = <0x0510 0xf>;
interrupts = ;
-   connectors = <>;
-   gpus = <>;
clock-names =
"core_clk",
"iface_clk",
@@ -50,5 +78,35 @@ Example:
< MDP_LUT_CLK>,
< HDMI_TV_CLK>,
< MDP_TV_CLK>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port at 0 {
+   reg = <0>;
+   mdp_lvds_out: endpoint {
+   };
+   };
+
+   port at 1 {
+   reg = <1>;
+   mdp_dsi1_out: endpoint {
+   };
+   };
+
+   port at 2 {
+   reg = <2>;
+   mdp_dsi2_out: endpoint {
+   };
+   };
+
+   port at 3 {
+   reg = <3>;
+   mdp_dtv_out: endpoint {
+   remote-endpoint = <_in>;
+   };
+   };
+   };
};
 };
diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt 
b/Documentation/devicetree/bindings/display/msm/mdp5.txt
index b395905..30c11ea 100644
--- a/Documentation/devicetree/bindings/display/msm/mdp5.txt
+++ b/Documentation/devicetree/bindings/display/msm/mdp5.txt
@@ -49,12 +49,36 @@ Required properties:
 -   * "iface_clk"
 -   * "core_clk"
 -   * "vsync_clk"
+- ports: contains the list of output ports from MDP. These connect to 
interfaces
+  that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is a
+  special case since it is a part of the MDP block itself).
+
+  Each output port contains an endpoint that describes how it is connected to 
an
+  external interface. These are described by the standard 

[PATCH v2 20/25] dt-bindings: msm/mdp5: Add MDP5 display bindings

2016-06-23 Thread Archit Taneja
Add a new doc for DT bindings for platforms that contain MDP5 display
controller hardware. The doc describes bindings for the top level
MDSS wrapper hardware and MDP5 itself.

Add an example for the bindings as found in MSM8916.

Acked-by: Rob Herring 
Signed-off-by: Archit Taneja 
---
 .../devicetree/bindings/display/msm/mdp5.txt   | 114 +
 1 file changed, 114 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/msm/mdp5.txt

diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt 
b/Documentation/devicetree/bindings/display/msm/mdp5.txt
new file mode 100644
index 000..b395905
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/mdp5.txt
@@ -0,0 +1,114 @@
+Qualcomm adreno/snapdragon MDP5 display controller
+
+Description:
+
+This is the bindings documentation for the Mobile Display Subsytem(MDSS) that
+encapsulates sub-blocks like MDP5, DSI, HDMI, eDP etc, and the MDP5 display
+controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996.
+
+MDSS:
+Required properties:
+- compatible:
+  * "qcom,mdss" - MDSS
+- reg: Physical base address and length of the controller's registers.
+- reg-names: The names of register regions. The following regions are required:
+  * "mdss_phys"
+  * "vbif_phys"
+- interrupts: The interrupt signal from MDSS.
+- interrupt-controller: identifies the node as an interrupt controller.
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt
+  source, should be 1.
+- power-domains: a power domain consumer specifier according to
+  Documentation/devicetree/bindings/power/power_domain.txt
+- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
+- clock-names: the following clocks are required.
+  * "iface_clk"
+  * "bus_clk"
+  * "vsync_clk"
+- #address-cells: number of address cells for the MDSS children. Should be 1.
+- #size-cells: Should be 1.
+- ranges: parent bus address space is the same as the child bus address space.
+
+Optional properties:
+- clock-names: the following clocks are optional:
+  * "lut_clk"
+
+MDP5:
+Required properties:
+- compatible:
+  * "qcom,mdp5" - MDP5
+- reg: Physical base address and length of the controller's registers.
+- reg-names: The names of register regions. The following regions are required:
+  * "mdp_phys"
+- interrupts: Interrupt line from MDP5 to MDSS interrupt controller.
+- interrupt-parent: phandle to the MDSS block
+  through MDP block
+- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
+- clock-names: the following clocks are required.
+-   * "bus_clk"
+-   * "iface_clk"
+-   * "core_clk"
+-   * "vsync_clk"
+
+Optional properties:
+- clock-names: the following clocks are optional:
+  * "lut_clk"
+
+
+Example:
+
+/ {
+   ...
+
+   mdss: mdss at 1a0 {
+   compatible = "qcom,mdss";
+   reg = <0x1a0 0x1000>,
+ <0x1ac8000 0x3000>;
+   reg-names = "mdss_phys", "vbif_phys";
+
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < GCC_MDSS_AHB_CLK>,
+< GCC_MDSS_AXI_CLK>,
+< GCC_MDSS_VSYNC_CLK>;
+   clock-names = "iface_clk",
+ "bus_clk",
+ "vsync_clk"
+
+   interrupts = <0 72 0>;
+
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mdp: mdp at 1a01000 {
+   compatible = "qcom,mdp5";
+   reg = <0x1a01000 0x9>;
+   reg-names = "mdp_phys";
+
+   interrupt-parent = <>;
+   interrupts = <0 0>;
+
+   clocks = < GCC_MDSS_AHB_CLK>,
+< GCC_MDSS_AXI_CLK>,
+< GCC_MDSS_MDP_CLK>,
+< GCC_MDSS_VSYNC_CLK>;
+   clock-names = "iface_clk",
+ "bus_clk",
+ "core_clk",
+ "vsync_clk";
+
+   };
+
+   dsi0: dsi at 1a98000 {
+   ...
+   };
+
+   dsi_phy0: dsi-phy at 1a98300 {
+   ...
+   };
+   };
+};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 19/25] dt-bindings: msm/mdp4: Create a separate binding doc for MDP4

2016-06-23 Thread Archit Taneja
MDP4 and MDP5 vary a bit in terms of device hierarchy and the properties
they require. Rename the binding doc to mdp4.txt and remove MDP5 specific
pieces. A separate document will be created for MDP5

Acked-by: Rob Herring 
Signed-off-by: Archit Taneja 
---
 .../devicetree/bindings/display/msm/mdp.txt| 57 --
 .../devicetree/bindings/display/msm/mdp4.txt   | 54 
 2 files changed, 54 insertions(+), 57 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/msm/mdp.txt
 create mode 100644 Documentation/devicetree/bindings/display/msm/mdp4.txt

diff --git a/Documentation/devicetree/bindings/display/msm/mdp.txt 
b/Documentation/devicetree/bindings/display/msm/mdp.txt
deleted file mode 100644
index ebfe016..000
--- a/Documentation/devicetree/bindings/display/msm/mdp.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-Qualcomm adreno/snapdragon display controller
-
-Required properties:
-- compatible:
-  * "qcom,mdp4" - mdp4
-  * "qcom,mdp5" - mdp5
-- reg: Physical base address and length of the controller's registers.
-- interrupts: The interrupt signal from the display controller.
-- connectors: array of phandles for output device(s)
-- clocks: device clocks
-  See ../clocks/clock-bindings.txt for details.
-- clock-names: the following clocks are required.
-  For MDP4:
-   * "core_clk"
-   * "iface_clk"
-   * "bus_clk"
-   * "lut_clk"
-   * "hdmi_clk"
-   * "tv_clk"
-  For MDP5:
-   * "bus_clk"
-   * "iface_clk"
-   * "core_clk"
-   * "lut_clk" (some MDP5 versions may not need this)
-   * "vsync_clk"
-
-Optional properties:
-- gpus: phandle for gpu device
-- clock-names: the following clocks are optional:
-  * "lut_clk"
-
-Example:
-
-/ {
-   ...
-
-   mdp: qcom,mdp at 510 {
-   compatible = "qcom,mdp4";
-   reg = <0x0510 0xf>;
-   interrupts = ;
-   connectors = <>;
-   gpus = <>;
-   clock-names =
-   "core_clk",
-   "iface_clk",
-   "lut_clk",
-   "hdmi_clk",
-   "tv_clk";
-   clocks =
-   < MDP_CLK>,
-   < MDP_AHB_CLK>,
-   < MDP_AXI_CLK>,
-   < MDP_LUT_CLK>,
-   < HDMI_TV_CLK>,
-   < MDP_TV_CLK>;
-   };
-};
diff --git a/Documentation/devicetree/bindings/display/msm/mdp4.txt 
b/Documentation/devicetree/bindings/display/msm/mdp4.txt
new file mode 100644
index 000..1de9b17
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/mdp4.txt
@@ -0,0 +1,54 @@
+Qualcomm adreno/snapdragon MDP4 display controller
+
+Description:
+
+This is the bindings documentation for the MDP4 display controller found in
+SoCs like MSM8960, APQ8064 and MSM8660.
+
+Required properties:
+- compatible:
+  * "qcom,mdp4" - mdp4
+- reg: Physical base address and length of the controller's registers.
+- interrupts: The interrupt signal from the display controller.
+- connectors: array of phandles for output device(s)
+- clocks: device clocks
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: the following clocks are required.
+  * "core_clk"
+  * "iface_clk"
+  * "bus_clk"
+  * "lut_clk"
+  * "hdmi_clk"
+  * "tv_clk"
+
+Optional properties:
+- gpus: phandle for gpu device
+- clock-names: the following clocks are optional:
+  * "lut_clk"
+
+Example:
+
+/ {
+   ...
+
+   mdp: qcom,mdp at 510 {
+   compatible = "qcom,mdp4";
+   reg = <0x0510 0xf>;
+   interrupts = ;
+   connectors = <>;
+   gpus = <>;
+   clock-names =
+   "core_clk",
+   "iface_clk",
+   "lut_clk",
+   "hdmi_clk",
+   "tv_clk";
+   clocks =
+   < MDP_CLK>,
+   < MDP_AHB_CLK>,
+   < MDP_AXI_CLK>,
+   < MDP_LUT_CLK>,
+   < HDMI_TV_CLK>,
+   < MDP_TV_CLK>;
+   };
+};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 18/25] drm/msm/dsi: Don't get DSI index from DT

2016-06-23 Thread Archit Taneja
The DSI host and PHY driver currently expects the DT bindings to provide
custom properties "qcom,dsi-host-index" and "qcom,dsi-phy-index" so that
the driver can identify which DSI instance it is.

The binding isn't acceptable, but the driver still needs to figure out
what its instance id. This is now done by storing the mmio starting
addresses for each DSI instance in every SoC version in the driver. The
driver then identifies the index number by trying to match the stored
address with comparing the resource start address we get from DT.

We don't have compatible strings for DSI PHY on each SoC, but only the
DSI PHY type. We only support one SoC version for each PHY type, so we
get away doing the same thing above for the PHY driver. We can revisit
this when we support two SoCs with the same DSI PHY.

Signed-off-by: Archit Taneja 
---
v2:
 - New patch

 drivers/gpu/drm/msm/dsi/dsi_cfg.c   |  8 ++
 drivers/gpu/drm/msm/dsi/dsi_cfg.h   |  2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c  | 33 +++--
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c   | 32 +---
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.h   |  2 ++
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c  |  4 ++-
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c  |  4 +++
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c |  2 ++
 8 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 93c1ee0..63436d8 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -29,6 +29,8 @@ static const struct msm_dsi_config apq8064_dsi_cfg = {
},
.bus_clk_names = dsi_v2_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_v2_bus_clk_names),
+   .io_start = { 0x470, 0x580 },
+   .num_dsi = 2,
 };

 static const char * const dsi_6g_bus_clk_names[] = {
@@ -48,6 +50,8 @@ static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = {
},
.bus_clk_names = dsi_6g_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
+   .io_start = { 0xfd922800, 0xfd922b00 },
+   .num_dsi = 2,
 };

 static const char * const dsi_8916_bus_clk_names[] = {
@@ -66,6 +70,8 @@ static const struct msm_dsi_config msm8916_dsi_cfg = {
},
.bus_clk_names = dsi_8916_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_8916_bus_clk_names),
+   .io_start = { 0x1a98000 },
+   .num_dsi = 1,
 };

 static const struct msm_dsi_config msm8994_dsi_cfg = {
@@ -84,6 +90,8 @@ static const struct msm_dsi_config msm8994_dsi_cfg = {
},
.bus_clk_names = dsi_6g_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
+   .io_start = { 0xfd998000, 0xfd9a },
+   .num_dsi = 2,
 };

 static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index a68c836..eeacc323 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -34,6 +34,8 @@ struct msm_dsi_config {
struct dsi_reg_config reg_cfg;
const char * const *bus_clk_names;
const int num_bus_clks;
+   const resource_size_t io_start[DSI_MAX];
+   const int num_dsi;
 };

 struct msm_dsi_cfg_handler {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e6a8cd1..80d8594 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1605,13 +1605,6 @@ static int dsi_host_parse_dt(struct msm_dsi_host 
*msm_host)
struct device_node *endpoint, *device_node;
int ret;

-   ret = of_property_read_u32(np, "qcom,dsi-host-index", _host->id);
-   if (ret) {
-   dev_err(dev, "%s: host index not specified, ret=%d\n",
-   __func__, ret);
-   return ret;
-   }
-
/*
 * Get the endpoint of the output port of the DSI host. In our case,
 * this is mapped to port number with reg = 1. Don't return an error if
@@ -1659,6 +1652,25 @@ err:
return ret;
 }

+static int dsi_host_get_id(struct msm_dsi_host *msm_host)
+{
+   struct platform_device *pdev = msm_host->pdev;
+   const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
+   struct resource *res;
+   int i;
+
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dsi_ctrl");
+   if (!res)
+   return -EINVAL;
+
+   for (i = 0; i < cfg->num_dsi; i++) {
+   if (cfg->io_start[i] == res->start)
+   return i;
+   }
+
+   return -EINVAL;
+}
+
 int msm_dsi_host_init(struct msm_dsi *msm_dsi)
 {
struct msm_dsi_host *msm_host = NULL;
@@ -1695,6 +1707,13 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
goto fail;
}

+   msm_host->id = dsi_host_get_id(msm_host);
+   if (msm_host->id < 0) {

[PATCH v2 17/25] drm/msm/mdp5: Update compatible strings for MDSS/MDP5

2016-06-23 Thread Archit Taneja
Introduce new compatible strings for the top level MDSS wrapper device,
and the MDP5 device.

Previously, the "qcom,mdp5" and "qcom,mdss_mdp" compatible strings
were used to match the top level platform_device (which was also tied
to the top level drm_device struct). Now, these strings are used
to match the MDP5 platform device.

Use "qcom,mdss" as the compatible string for top level MDSS device.
This is now used to match the top level platform_device (which is
tied to the drm_device struct).

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 10 +-
 drivers/gpu/drm/msm/msm_drv.c   |  6 ++
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 174d7e7..a2bd6a4 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -809,12 +809,20 @@ static int mdp5_dev_remove(struct platform_device *pdev)
return 0;
 }

+static const struct of_device_id dt_match[] = {
+   { .compatible = "qcom,mdp5", },
+   /* to support downstream DT files */
+   { .compatible = "qcom,mdss_mdp", },
+   {}
+};
+MODULE_DEVICE_TABLE(of, dt_match);
+
 static struct platform_driver mdp5_driver = {
.probe = mdp5_dev_probe,
.remove = mdp5_dev_remove,
.driver = {
.name = "msm_mdp",
-   /* Add a DT match field once we move to new hierarchy */
+   .of_match_table = dt_match,
},
 };

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index be8f73a..f133dd5 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -992,10 +992,8 @@ static int msm_pdev_remove(struct platform_device *pdev)
 }

 static const struct of_device_id dt_match[] = {
-   { .compatible = "qcom,mdp4", .data = (void *) 4 },  /* mdp4 */
-   { .compatible = "qcom,mdp5", .data = (void *) 5 },  /* mdp5 */
-   /* to support downstream DT files */
-   { .compatible = "qcom,mdss_mdp", .data = (void *) 5 },  /* mdp5 */
+   { .compatible = "qcom,mdp4", .data = (void *)4 },   /* MDP4 */
+   { .compatible = "qcom,mdss", .data = (void *)5 },   /* MDP5 MDSS */
{}
 };
 MODULE_DEVICE_TABLE(of, dt_match);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 16/25] drm/msm: Drop the gpu binding

2016-06-23 Thread Archit Taneja
The driver currently identifies the GPU components it needs by parsing
a phandle list from the 'gpus' DT property.

This isn't the right binding to go with. So, for now, just search all
device nodes and find the gpu node we need by parsing a list of
compatible strings.

Once we know how to link the kms and gpu drivers, we'll drop this method
and use the correct binding.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/msm_drv.c | 42 ++
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 79437f9..be8f73a 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -804,25 +804,6 @@ static int compare_of(struct device *dev, void *data)
return dev->of_node == data;
 }

-static int add_components(struct device *dev, struct component_match 
**matchptr,
-   const char *name)
-{
-   struct device_node *np = dev->of_node;
-   unsigned i;
-
-   for (i = 0; ; i++) {
-   struct device_node *node;
-
-   node = of_parse_phandle(np, name, i);
-   if (!node)
-   break;
-
-   component_match_add(dev, matchptr, compare_of, node);
-   }
-
-   return 0;
-}
-
 /*
  * Identify what components need to be added by parsing what remote-endpoints
  * our MDP output ports are connected to. In the case of LVDS on MDP4, there
@@ -939,10 +920,31 @@ static int add_display_components(struct device *dev,
return ret;
 }

+/*
+ * We don't know what's the best binding to link the gpu with the drm device.
+ * Fow now, we just hunt for all the possible gpus that we support, and add 
them
+ * as components.
+ */
+static const struct of_device_id msm_gpu_match[] = {
+   { .compatible = "qcom,adreno-3xx" },
+   { .compatible = "qcom,kgsl-3d0" },
+   { },
+};
+
 static int add_gpu_components(struct device *dev,
  struct component_match **matchptr)
 {
-   return add_components(>dev, matchptr, "gpus");
+   struct device_node *np;
+
+   np = of_find_matching_node(NULL, msm_gpu_match);
+   if (!np)
+   return 0;
+
+   of_node_put(np);
+
+   component_match_add(dev, matchptr, compare_of, np);
+
+   return 0;
 }

 static int msm_drm_bind(struct device *dev)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 15/25] drm/msm: Add components for MDP5

2016-06-23 Thread Archit Taneja
For MDP5 based platforms, the master device isn't the MDP5 platform
device, but the top level MDSS device, which is a parent to MDP5 and
interface (DSI, HDMI, eDP etc) devices.

In order to add components on MDP5 platforms, we first need to populate
the MDSS children, locate the MDP5 child, and then parse its ports to
get the display interfaces.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/msm_drv.c | 61 +--
 1 file changed, 59 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index ce43c85..79437f9 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -834,6 +834,20 @@ static int add_components_mdp(struct device *mdp_dev,
 {
struct device_node *np = mdp_dev->of_node;
struct device_node *ep_node;
+   struct device *master_dev;
+
+   /*
+* on MDP4 based platforms, the MDP platform device is the component
+* master that adds other display interface components to itself.
+*
+* on MDP5 based platforms, the MDSS platform device is the component
+* master that adds MDP5 and other display interface components to
+* itself.
+*/
+   if (of_device_is_compatible(np, "qcom,mdp4"))
+   master_dev = mdp_dev;
+   else
+   master_dev = mdp_dev->parent;

for_each_endpoint_of_node(np, ep_node) {
struct device_node *intf;
@@ -868,7 +882,7 @@ static int add_components_mdp(struct device *mdp_dev,
continue;
}

-   component_match_add(mdp_dev, matchptr, compare_of, intf);
+   component_match_add(master_dev, matchptr, compare_of, intf);

of_node_put(intf);
of_node_put(ep_node);
@@ -877,10 +891,52 @@ static int add_components_mdp(struct device *mdp_dev,
return 0;
 }

+static int compare_name_mdp(struct device *dev, void *data)
+{
+   return (strstr(dev_name(dev), "mdp") != NULL);
+}
+
 static int add_display_components(struct device *dev,
  struct component_match **matchptr)
 {
-   return add_components_mdp(dev, matchptr);
+   struct device *mdp_dev;
+   int ret;
+
+   /*
+* MDP5 based devices don't have a flat hierarchy. There is a top level
+* parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate the
+* children devices, find the MDP5 node, and then add the interfaces
+* to our components list.
+*/
+   if (of_device_is_compatible(dev->of_node, "qcom,mdss")) {
+   ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+   if (ret) {
+   dev_err(dev, "failed to populate children devices\n");
+   return ret;
+   }
+
+   mdp_dev = device_find_child(dev, NULL, compare_name_mdp);
+   if (!mdp_dev) {
+   dev_err(dev, "failed to find MDSS MDP node\n");
+   of_platform_depopulate(dev);
+   return -ENODEV;
+   }
+
+   put_device(mdp_dev);
+
+   /* add the MDP component itself */
+   component_match_add(dev, matchptr, compare_of,
+   mdp_dev->of_node);
+   } else {
+   /* MDP4 */
+   mdp_dev = dev;
+   }
+
+   ret = add_components_mdp(mdp_dev, matchptr);
+   if (ret)
+   of_platform_depopulate(dev);
+
+   return ret;
 }

 static int add_gpu_components(struct device *dev,
@@ -928,6 +984,7 @@ static int msm_pdev_probe(struct platform_device *pdev)
 static int msm_pdev_remove(struct platform_device *pdev)
 {
component_master_del(>dev, _drm_ops);
+   of_platform_depopulate(>dev);

return 0;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 14/25] drm/msm: Add display components by parsing MDP ports

2016-06-23 Thread Archit Taneja
The kms driver currently identifies all the mdss components it needs by
parsing a phandle list from the 'connectors' DT property.

Instead of this, describe a list of ports that the MDP hardware provides
to the external world. These ports are linked to external encoder
interfaces such as DSI, HDMI. These are also the subcomponent devices
that we need add. This description of ports complies with the generic
graph bindings.

The LVDS port is a special case since it is a part of MDP4 itself, and
its output connects directly to the LVDS panel. In this case, we don't
try to add it as a component.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/msm_drv.c | 56 ++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1b8b915..ce43c85 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -823,10 +823,64 @@ static int add_components(struct device *dev, struct 
component_match **matchptr,
return 0;
 }

+/*
+ * Identify what components need to be added by parsing what remote-endpoints
+ * our MDP output ports are connected to. In the case of LVDS on MDP4, there
+ * is no external component that we need to add since LVDS is within MDP4
+ * itself.
+ */
+static int add_components_mdp(struct device *mdp_dev,
+ struct component_match **matchptr)
+{
+   struct device_node *np = mdp_dev->of_node;
+   struct device_node *ep_node;
+
+   for_each_endpoint_of_node(np, ep_node) {
+   struct device_node *intf;
+   struct of_endpoint ep;
+   int ret;
+
+   ret = of_graph_parse_endpoint(ep_node, );
+   if (ret) {
+   dev_err(mdp_dev, "unable to parse port endpoint\n");
+   of_node_put(ep_node);
+   return ret;
+   }
+
+   /*
+* The LCDC/LVDS port on MDP4 is a speacial case where the
+* remote-endpoint isn't a component that we need to add
+*/
+   if (of_device_is_compatible(np, "qcom,mdp4") &&
+   ep.port == 0) {
+   of_node_put(ep_node);
+   continue;
+   }
+
+   /*
+* It's okay if some of the ports don't have a remote endpoint
+* specified. It just means that the port isn't connected to
+* any external interface.
+*/
+   intf = of_graph_get_remote_port_parent(ep_node);
+   if (!intf) {
+   of_node_put(ep_node);
+   continue;
+   }
+
+   component_match_add(mdp_dev, matchptr, compare_of, intf);
+
+   of_node_put(intf);
+   of_node_put(ep_node);
+   }
+
+   return 0;
+}
+
 static int add_display_components(struct device *dev,
  struct component_match **matchptr)
 {
-   return add_components(>dev, matchptr, "connectors");
+   return add_components_mdp(dev, matchptr);
 }

 static int add_gpu_components(struct device *dev,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 13/25] drm/msm: Create separate funcs for adding display/gpu components

2016-06-23 Thread Archit Taneja
Simplifies some of the code that we'll add later.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/msm_drv.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1c18690..1b8b915 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -823,6 +823,18 @@ static int add_components(struct device *dev, struct 
component_match **matchptr,
return 0;
 }

+static int add_display_components(struct device *dev,
+ struct component_match **matchptr)
+{
+   return add_components(>dev, matchptr, "connectors");
+}
+
+static int add_gpu_components(struct device *dev,
+ struct component_match **matchptr)
+{
+   return add_components(>dev, matchptr, "gpus");
+}
+
 static int msm_drm_bind(struct device *dev)
 {
return msm_drm_init(dev, _driver);
@@ -845,9 +857,15 @@ static const struct component_master_ops msm_drm_ops = {
 static int msm_pdev_probe(struct platform_device *pdev)
 {
struct component_match *match = NULL;
+   int ret;
+
+   ret = add_display_components(>dev, );
+   if (ret)
+   return ret;

-   add_components(>dev, , "connectors");
-   add_components(>dev, , "gpus");
+   ret = add_gpu_components(>dev, );
+   if (ret)
+   return ret;

pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
return component_master_add_with_match(>dev, _drm_ops, match);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 12/25] drm/msm/mdp5: Add missing mdp5_enable/disable calls

2016-06-23 Thread Archit Taneja
Since runtime PM isn't implemented yet, we need to call
mdp5_enable/disable in a few more places. These would later be
replaced by runtime PM get/put calls.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 2 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
index 1c3c909..d53e551 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
@@ -54,7 +54,9 @@ int mdp5_irq_postinstall(struct msm_kms *kms)
MDP5_IRQ_INTF2_UNDER_RUN |
MDP5_IRQ_INTF3_UNDER_RUN;

+   mdp5_enable(mdp5_kms);
mdp_irq_register(mdp_kms, error_handler);
+   mdp5_disable(mdp5_kms);

return 0;
 }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 5d6d9e1..174d7e7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -33,6 +33,7 @@ static int mdp5_hw_init(struct msm_kms *kms)
unsigned long flags;

pm_runtime_get_sync(>dev);
+   mdp5_enable(mdp5_kms);

/* Magic unknown register writes:
 *
@@ -64,6 +65,7 @@ static int mdp5_hw_init(struct msm_kms *kms)

mdp5_ctlm_hw_reset(mdp5_kms->ctlm);

+   mdp5_disable(mdp5_kms);
pm_runtime_put_sync(>dev);

return 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 11/25] drm/msm: Call pm_runtime_enable/disable for newly created devices

2016-06-23 Thread Archit Taneja
With the new device hierarchy for MDP5, we need to enable runtime PM
for both the toplevel MDSS device and the MDP5 device itself. Enable
runtime PM for the new devices.

Since MDP4 and MDP5 now have different places where runtime PM is
enabled, remove the previous pm_runtime_enable/disable calls, and
squash them in the respective kms drivers.

The new device hierarchy (as expressed in the DT bindings) has the GDSC
tied only to the MDSS wrapper device. This GDSC needs to be enabled for
accessing any register in the MDSS sub-blocks. Once every driver is
runtime adapted, the GDSC will be enabled when any sub-block device
calls runtime_get because of the parent-child relationship with MDSS.

Until then, we call pm_runtime_get_sync() once for the MDSS device to
ensure the GDSC is never disabled. This will be removed once all the
drivers are runtime PM adapted.

The error handling paths become a bit tricky when we call these runtime
PM funcs. There doesn't seem to be any helper that checks if runtime PM
is enabled already. Add bool variables in mdp4_kms/mdp5_kms structs to
check if the driver had managed to call pm_runtime_enable before bailing
out.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c  |  8 
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h  |  2 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c  |  6 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h  |  2 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c | 12 
 drivers/gpu/drm/msm/msm_drv.c|  5 +
 6 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index 0e751c0..70b96bb 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -158,6 +158,7 @@ static const char * const iommu_ports[] = {
 static void mdp4_destroy(struct msm_kms *kms)
 {
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+   struct device *dev = mdp4_kms->dev->dev;
struct msm_mmu *mmu = mdp4_kms->mmu;

if (mmu) {
@@ -169,6 +170,10 @@ static void mdp4_destroy(struct msm_kms *kms)
msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id);
if (mdp4_kms->blank_cursor_bo)
drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo);
+
+   if (mdp4_kms->rpm_enabled)
+   pm_runtime_disable(dev);
+
kfree(mdp4_kms);
 }

@@ -515,6 +520,9 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
clk_set_rate(mdp4_kms->clk, config->max_clk);
clk_set_rate(mdp4_kms->lut_clk, config->max_clk);

+   pm_runtime_enable(dev->dev);
+   mdp4_kms->rpm_enabled = true;
+
/* make sure things are off before attaching iommu (bootloader could
 * have left things on, in which case we'll start getting faults if
 * we don't disable):
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h 
b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
index c5d045d..25fb839 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
@@ -47,6 +47,8 @@ struct mdp4_kms {

struct mdp_irq error_handler;

+   bool rpm_enabled;
+
/* empty/blank cursor bo to use when cursor is "disabled" */
struct drm_gem_object *blank_cursor_bo;
uint32_t blank_cursor_iova;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index a0b9747..5d6d9e1 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -668,6 +668,9 @@ static void mdp5_destroy(struct platform_device *pdev)
mdp5_smp_destroy(mdp5_kms->smp);
if (mdp5_kms->cfg)
mdp5_cfg_destroy(mdp5_kms->cfg);
+
+   if (mdp5_kms->rpm_enabled)
+   pm_runtime_disable(>dev);
 }

 static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
@@ -720,6 +723,9 @@ static int mdp5_init(struct platform_device *pdev, struct 
drm_device *dev)
 */
clk_set_rate(mdp5_kms->core_clk, 2);

+   pm_runtime_enable(>dev);
+   mdp5_kms->rpm_enabled = true;
+
read_mdp_hw_revision(mdp5_kms, , );

mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index d214d50..0373892 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -59,6 +59,8 @@ struct mdp5_kms {
 */
spinlock_t resource_lock;

+   bool rpm_enabled;
+
struct mdp_irq error_handler;
 };
 #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
index 871c442..d444a69 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
@@ -152,6 +152,10 @@ void 

[PATCH v2 10/25] drm/msm/mdp5: Update the register offsets of MDP5 sub-blocks

2016-06-23 Thread Archit Taneja
The MDP5 sub-block register offsets are relative to the top level
MDSS register address.

Now that we have the start of MDP5 register address space, provide
the offsets relative to that. This involves subtracting the offsets
with 0x1000 or 0x100 depending on the MDP5 version.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 113 +++-
 1 file changed, 54 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
index 57f73f0..ac9e4cd 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
@@ -26,7 +26,6 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
.name = "msm8x74v1",
.mdp = {
.count = 1,
-   .base = { 0x00100 },
.caps = MDP_CAP_SMP |
0,
},
@@ -41,12 +40,12 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
},
.ctl = {
.count = 5,
-   .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+   .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
.flush_hw_mask = 0x0003,
},
.pipe_vig = {
.count = 3,
-   .base = { 0x01200, 0x01600, 0x01a00 },
+   .base = { 0x01100, 0x01500, 0x01900 },
.caps = MDP_PIPE_CAP_HFLIP |
MDP_PIPE_CAP_VFLIP |
MDP_PIPE_CAP_SCALE |
@@ -55,7 +54,7 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
},
.pipe_rgb = {
.count = 3,
-   .base = { 0x01e00, 0x02200, 0x02600 },
+   .base = { 0x01d00, 0x02100, 0x02500 },
.caps = MDP_PIPE_CAP_HFLIP |
MDP_PIPE_CAP_VFLIP |
MDP_PIPE_CAP_SCALE |
@@ -63,26 +62,26 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
},
.pipe_dma = {
.count = 2,
-   .base = { 0x02a00, 0x02e00 },
+   .base = { 0x02900, 0x02d00 },
.caps = MDP_PIPE_CAP_HFLIP |
MDP_PIPE_CAP_VFLIP |
0,
},
.lm = {
.count = 5,
-   .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 },
+   .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
.nb_stages = 5,
},
.dspp = {
.count = 3,
-   .base = { 0x04600, 0x04a00, 0x04e00 },
+   .base = { 0x04500, 0x04900, 0x04d00 },
},
.pp = {
.count = 3,
-   .base = { 0x21b00, 0x21c00, 0x21d00 },
+   .base = { 0x21a00, 0x21b00, 0x21c00 },
},
.intf = {
-   .base = { 0x21100, 0x21300, 0x21500, 0x21700 },
+   .base = { 0x21000, 0x21200, 0x21400, 0x21600 },
.connect = {
[0] = INTF_eDP,
[1] = INTF_DSI,
@@ -97,7 +96,6 @@ const struct mdp5_cfg_hw msm8x74v2_config = {
.name = "msm8x74",
.mdp = {
.count = 1,
-   .base = { 0x00100 },
.caps = MDP_CAP_SMP |
0,
},
@@ -112,48 +110,48 @@ const struct mdp5_cfg_hw msm8x74v2_config = {
},
.ctl = {
.count = 5,
-   .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+   .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
.flush_hw_mask = 0x0003,
},
.pipe_vig = {
.count = 3,
-   .base = { 0x01200, 0x01600, 0x01a00 },
+   .base = { 0x01100, 0x01500, 0x01900 },
.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
MDP_PIPE_CAP_DECIMATION,
},
.pipe_rgb = {
.count = 3,
-   .base = { 0x01e00, 0x02200, 0x02600 },
+   .base = { 0x01d00, 0x02100, 0x02500 },
.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
},
.pipe_dma = {
.count = 2,
-   .base = { 0x02a00, 0x02e00 },
+   .base = { 0x02900, 0x02d00 },
.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
},
.lm = {
.count = 5,
-   .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 },
+   .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
.nb_stages = 5,
.max_width = 2048,
.max_height = 0x,
},
.dspp = {
.count = 3,
-   .base = { 0x04600, 0x04a00, 0x04e00 },
+   .base = { 0x04500, 0x04900, 

[PATCH v2 09/25] drm/msm/mdp5: Use updated MDP5 register names

2016-06-23 Thread Archit Taneja
Since MDSS registers were stuffed within the the MDP5 register
space, we had an __offset_MDP() macro to identify the offset
between the start of MDSS and MDP5 address spaces. This offset
macro expected a MDP index argument, which didn't make much
sense since we don't have multiple MDPs.

The offset is no longer needed now that we have devices for the 2
different register address spaces. Also, remove the "REG_MDP5_MDP_"
prefix to "REG_MDP5_".

Update the generated headers in mdp5.xml.h

We generally update headers as a separate patch, but we need to
do these together to prevent breaking build.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 203 +++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c |  14 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c |  26 +--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  10 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c |  18 +--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c |   8 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h |   2 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c |  22 +--
 8 files changed, 143 insertions(+), 160 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
index b275ce1..ca6ca30 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
@@ -8,19 +8,11 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git

 The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml (
676 bytes, from 2015-05-20 20:03:14)
-- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   
1572 bytes, from 2016-02-10 17:07:21)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml(  
20915 bytes, from 2015-05-20 20:03:14)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml  (   
2849 bytes, from 2015-09-18 12:07:28)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml(  
37194 bytes, from 2015-09-18 12:07:28)
-- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml (  
27887 bytes, from 2015-10-22 16:34:52)
-- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml(
602 bytes, from 2015-10-22 16:35:02)
-- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml (   
1686 bytes, from 2015-05-20 20:03:14)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml (
600 bytes, from 2015-05-20 20:03:07)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml   (  
41472 bytes, from 2016-01-22 18:18:18)
-- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml (  
10416 bytes, from 2015-05-20 20:03:14)
-
-Copyright (C) 2013-2015 by the following authors:
+- /local/mnt/workspace/source_trees/envytools/rnndb/../rnndb/mdp/mdp5.xml   (  
36965 bytes, from 2016-05-10 05:06:30)
+- /local/mnt/workspace/source_trees/envytools/rnndb/freedreno_copyright.xml (  
 1572 bytes, from 2016-05-09 06:32:54)
+- /local/mnt/workspace/source_trees/envytools/rnndb/mdp/mdp_common.xml  (  
 2849 bytes, from 2016-01-07 08:45:55)
+
+Copyright (C) 2013-2016 by the following authors:
 - Rob Clark  (robclark)
 - Ilia Mirkin  (imirkin)

@@ -198,118 +190,109 @@ static inline uint32_t MDSS_HW_VERSION_MAJOR(uint32_t 
val)
 #define MDSS_HW_INTR_STATUS_INTR_HDMI  0x0100
 #define MDSS_HW_INTR_STATUS_INTR_EDP   0x1000

-static inline uint32_t __offset_MDP(uint32_t idx)
-{
-   switch (idx) {
-   case 0: return (mdp5_cfg->mdp.base[0]);
-   default: return INVALID_IDX(idx);
-   }
-}
-static inline uint32_t REG_MDP5_MDP(uint32_t i0) { return 0x + 
__offset_MDP(i0); }
-
-static inline uint32_t REG_MDP5_MDP_HW_VERSION(uint32_t i0) { return 
0x + __offset_MDP(i0); }
-#define MDP5_MDP_HW_VERSION_STEP__MASK 0x
-#define MDP5_MDP_HW_VERSION_STEP__SHIFT0
-static inline uint32_t MDP5_MDP_HW_VERSION_STEP(uint32_t val)
+#define REG_MDP5_HW_VERSION0x
+#define MDP5_HW_VERSION_STEP__MASK 0x
+#define MDP5_HW_VERSION_STEP__SHIFT0
+static inline uint32_t MDP5_HW_VERSION_STEP(uint32_t val)
 {
-   return ((val) << MDP5_MDP_HW_VERSION_STEP__SHIFT) & 
MDP5_MDP_HW_VERSION_STEP__MASK;
+   return ((val) << MDP5_HW_VERSION_STEP__SHIFT) & 
MDP5_HW_VERSION_STEP__MASK;
 }
-#define MDP5_MDP_HW_VERSION_MINOR__MASK
0x0fff
-#define MDP5_MDP_HW_VERSION_MINOR__SHIFT   16
-static inline uint32_t MDP5_MDP_HW_VERSION_MINOR(uint32_t val)
+#define MDP5_HW_VERSION_MINOR__MASK0x0fff
+#define MDP5_HW_VERSION_MINOR__SHIFT 

[PATCH v2 08/25] drm/msm/mdp5: Remove old kms init/destroy funcs

2016-06-23 Thread Archit Taneja
With the new kms_init/destroy funcs in place for MDP5, we can get rid of
the old kms funcs. Some members of the mdp5_kms struct also become
redundant, so we remove those too.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 228 +---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h |   9 +-
 drivers/gpu/drm/msm/msm_drv.c   |   2 +-
 drivers/gpu/drm/msm/msm_kms.h   |   1 -
 4 files changed, 4 insertions(+), 236 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 52d756d..e2caa87 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -121,26 +121,6 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
mmu->funcs->destroy(mmu);
}
-
-   if (mdp5_kms->ctlm)
-   mdp5_ctlm_destroy(mdp5_kms->ctlm);
-   if (mdp5_kms->smp)
-   mdp5_smp_destroy(mdp5_kms->smp);
-   if (mdp5_kms->cfg)
-   mdp5_cfg_destroy(mdp5_kms->cfg);
-
-   kfree(mdp5_kms);
-}
-
-static void mdp5_kms_destroy2(struct msm_kms *kms)
-{
-   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-   struct msm_mmu *mmu = mdp5_kms->mmu;
-
-   if (mmu) {
-   mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
-   mmu->funcs->destroy(mmu);
-   }
 }

 static const struct mdp_kms_funcs kms_funcs = {
@@ -158,7 +138,7 @@ static const struct mdp_kms_funcs kms_funcs = {
.get_format  = mdp_get_format,
.round_pixclk= mdp5_round_pixclk,
.set_split_display = mdp5_set_split_display,
-   .destroy = mdp5_kms_destroy2,
+   .destroy = mdp5_kms_destroy,
},
.set_irqmask = mdp5_set_irqmask,
 };
@@ -422,21 +402,6 @@ fail:
return ret;
 }

-static void read_hw_revision(struct mdp5_kms *mdp5_kms,
-   uint32_t *major, uint32_t *minor)
-{
-   uint32_t version;
-
-   mdp5_enable(mdp5_kms);
-   version = mdp5_read(mdp5_kms, REG_MDSS_HW_VERSION);
-   mdp5_disable(mdp5_kms);
-
-   *major = FIELD(version, MDSS_HW_VERSION_MAJOR);
-   *minor = FIELD(version, MDSS_HW_VERSION_MINOR);
-
-   DBG("MDP5 version v%d.%d", *major, *minor);
-}
-
 static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms,
 u32 *major, u32 *minor)
 {
@@ -592,195 +557,6 @@ static u32 mdp5_get_vblank_counter(struct drm_device 
*dev, unsigned int pipe)

 struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 {
-   struct platform_device *pdev = dev->platformdev;
-   struct mdp5_cfg *config;
-   struct mdp5_kms *mdp5_kms;
-   struct msm_kms *kms = NULL;
-   struct msm_mmu *mmu;
-   uint32_t major, minor;
-   int irq, i, ret;
-
-   mdp5_kms = kzalloc(sizeof(*mdp5_kms), GFP_KERNEL);
-   if (!mdp5_kms) {
-   dev_err(dev->dev, "failed to allocate kms\n");
-   ret = -ENOMEM;
-   goto fail;
-   }
-
-   spin_lock_init(_kms->resource_lock);
-
-   mdp_kms_init(_kms->base, _funcs);
-
-   kms = _kms->base.base;
-
-   mdp5_kms->dev = dev;
-
-   /* mdp5_kms->mmio actually represents the MDSS base address */
-   mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
-   if (IS_ERR(mdp5_kms->mmio)) {
-   ret = PTR_ERR(mdp5_kms->mmio);
-   goto fail;
-   }
-
-   mdp5_kms->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF");
-   if (IS_ERR(mdp5_kms->vbif)) {
-   ret = PTR_ERR(mdp5_kms->vbif);
-   goto fail;
-   }
-
-   irq = platform_get_irq(pdev, 0);
-   if (irq < 0) {
-   ret = irq;
-   dev_err(dev->dev, "failed to get irq: %d\n", ret);
-   goto fail;
-   }
-
-   kms->irq = irq;
-
-   mdp5_kms->vdd = devm_regulator_get(>dev, "vdd");
-   if (IS_ERR(mdp5_kms->vdd)) {
-   ret = PTR_ERR(mdp5_kms->vdd);
-   goto fail;
-   }
-
-   ret = regulator_enable(mdp5_kms->vdd);
-   if (ret) {
-   dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret);
-   goto fail;
-   }
-
-   /* mandatory clocks: */
-   ret = get_clk(pdev, _kms->axi_clk, "bus_clk", true);
-   if (ret)
-   goto fail;
-   ret = get_clk(pdev, _kms->ahb_clk, "iface_clk", true);
-   if (ret)
-   goto fail;
-   ret = get_clk(pdev, _kms->core_clk, "core_clk", true);
-   if (ret)
-   goto fail;
-   ret = get_clk(pdev, _kms->vsync_clk, "vsync_clk", true);
-   if (ret)
-   goto fail;
-
-   /* optional clocks: */
-   get_clk(pdev, _kms->lut_clk, "lut_clk", false);
-
-   /* we need to set a default rate before enabling.  Set a safe
-   

[PATCH v2 07/25] drm/msm/mdp5: Use the new hierarchy and drop old irq management

2016-06-23 Thread Archit Taneja
Call msm_mdss_init in msm_drv to set up top level registers/irq line.
Start using the new kms_init2/destroy2 funcs to inititalize MDP5 KMS.

With the MDSS interrupt and irqdomain set up, the old MDP5 irq code
can be dropped.

The mdp5_hw_init kms func now uses the platform device tied to MDP5
instead of the one tied to the drm_device/MDSS.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 105 +---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c |  17 ++
 drivers/gpu/drm/msm/msm_drv.c   |  15 -
 3 files changed, 18 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
index 73bc3e3..c6562d1 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
@@ -15,7 +15,6 @@
  * this program.  If not, see .
  */

-#include 
 #include 

 #include "msm_drv.h"
@@ -68,8 +67,9 @@ void mdp5_irq_uninstall(struct msm_kms *kms)
mdp5_disable(mdp5_kms);
 }

-static void mdp5_irq_mdp(struct mdp_kms *mdp_kms)
+irqreturn_t mdp5_irq(struct msm_kms *kms)
 {
+   struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private;
@@ -87,29 +87,6 @@ static void mdp5_irq_mdp(struct mdp_kms *mdp_kms)
for (id = 0; id < priv->num_crtcs; id++)
if (status & mdp5_crtc_vblank(priv->crtcs[id]))
drm_handle_vblank(dev, id);
-}
-
-irqreturn_t mdp5_irq(struct msm_kms *kms)
-{
-   struct mdp_kms *mdp_kms = to_mdp_kms(kms);
-   struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
-   uint32_t intr;
-
-   intr = mdp5_read(mdp5_kms, REG_MDSS_HW_INTR_STATUS);
-
-   VERB("intr=%08x", intr);
-
-   if (intr & MDSS_HW_INTR_STATUS_INTR_MDP) {
-   mdp5_irq_mdp(mdp_kms);
-   intr &= ~MDSS_HW_INTR_STATUS_INTR_MDP;
-   }
-
-   while (intr) {
-   irq_hw_number_t hwirq = fls(intr) - 1;
-   generic_handle_irq(irq_find_mapping(
-   mdp5_kms->irqcontroller.domain, hwirq));
-   intr &= ~(1 << hwirq);
-   }

return IRQ_HANDLED;
 }
@@ -135,81 +112,3 @@ void mdp5_disable_vblank(struct msm_kms *kms, struct 
drm_crtc *crtc)
mdp5_crtc_vblank(crtc), false);
mdp5_disable(mdp5_kms);
 }
-
-/*
- * interrupt-controller implementation, so sub-blocks (hdmi/eDP/dsi/etc)
- * can register to get their irq's delivered
- */
-
-#define VALID_IRQS  (MDSS_HW_INTR_STATUS_INTR_DSI0 | \
-   MDSS_HW_INTR_STATUS_INTR_DSI1 | \
-   MDSS_HW_INTR_STATUS_INTR_HDMI | \
-   MDSS_HW_INTR_STATUS_INTR_EDP)
-
-static void mdp5_hw_mask_irq(struct irq_data *irqd)
-{
-   struct mdp5_kms *mdp5_kms = irq_data_get_irq_chip_data(irqd);
-   smp_mb__before_atomic();
-   clear_bit(irqd->hwirq, _kms->irqcontroller.enabled_mask);
-   smp_mb__after_atomic();
-}
-
-static void mdp5_hw_unmask_irq(struct irq_data *irqd)
-{
-   struct mdp5_kms *mdp5_kms = irq_data_get_irq_chip_data(irqd);
-   smp_mb__before_atomic();
-   set_bit(irqd->hwirq, _kms->irqcontroller.enabled_mask);
-   smp_mb__after_atomic();
-}
-
-static struct irq_chip mdp5_hw_irq_chip = {
-   .name   = "mdp5",
-   .irq_mask   = mdp5_hw_mask_irq,
-   .irq_unmask = mdp5_hw_unmask_irq,
-};
-
-static int mdp5_hw_irqdomain_map(struct irq_domain *d,
-   unsigned int irq, irq_hw_number_t hwirq)
-{
-   struct mdp5_kms *mdp5_kms = d->host_data;
-
-   if (!(VALID_IRQS & (1 << hwirq)))
-   return -EPERM;
-
-   irq_set_chip_and_handler(irq, _hw_irq_chip, handle_level_irq);
-   irq_set_chip_data(irq, mdp5_kms);
-
-   return 0;
-}
-
-static struct irq_domain_ops mdp5_hw_irqdomain_ops = {
-   .map = mdp5_hw_irqdomain_map,
-   .xlate = irq_domain_xlate_onecell,
-};
-
-
-int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms)
-{
-   struct device *dev = mdp5_kms->dev->dev;
-   struct irq_domain *d;
-
-   d = irq_domain_add_linear(dev->of_node, 32,
-   _hw_irqdomain_ops, mdp5_kms);
-   if (!d) {
-   dev_err(dev, "mdp5 irq domain add failed\n");
-   return -ENXIO;
-   }
-
-   mdp5_kms->irqcontroller.enabled_mask = 0;
-   mdp5_kms->irqcontroller.domain = d;
-
-   return 0;
-}
-
-void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms)
-{
-   if (mdp5_kms->irqcontroller.domain) {
-   irq_domain_remove(mdp5_kms->irqcontroller.domain);
-   mdp5_kms->irqcontroller.domain = NULL;
-   }
-}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 9f69924..52d756d 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ 

[PATCH v2 06/25] drm/msm/mdp5: Prepare new kms_init funcs

2016-06-23 Thread Archit Taneja
With MDP5 as a new device, we need to do less for MDP when initializing
modeset after all the components are bound.

Create mdp5_kms_init2/destroy2 funcs that inits modeset. These will
eventually replace the older kms_init/destroy funcs.

In the new kms_init2, the platform_device used is the one corresponding
to the new MDP5 platform_device. The new change here is that the irq is
now retrieved using irq_of_parse_and_map(), since MDP5 is a child interrupt
of the MDSS interrupt controller.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 115 
 drivers/gpu/drm/msm/msm_kms.h   |   1 +
 2 files changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index fcb1bf4..9f69924 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -16,6 +16,7 @@
  * this program.  If not, see .
  */

+#include 

 #include "msm_drv.h"
 #include "msm_mmu.h"
@@ -133,6 +134,17 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
kfree(mdp5_kms);
 }

+static void mdp5_kms_destroy2(struct msm_kms *kms)
+{
+   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+   struct msm_mmu *mmu = mdp5_kms->mmu;
+
+   if (mmu) {
+   mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
+   mmu->funcs->destroy(mmu);
+   }
+}
+
 static const struct mdp_kms_funcs kms_funcs = {
.base = {
.hw_init = mdp5_hw_init,
@@ -776,6 +788,109 @@ fail:
return ERR_PTR(ret);
 }

+struct msm_kms *mdp5_kms_init2(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct platform_device *pdev;
+   struct mdp5_kms *mdp5_kms;
+   struct mdp5_cfg *config;
+   struct msm_kms *kms;
+   struct msm_mmu *mmu;
+   int irq, i, ret;
+
+   /* priv->kms would have been populated by the MDP5 driver */
+   kms = priv->kms;
+   if (!kms)
+   return NULL;
+
+   mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+
+   mdp_kms_init(_kms->base, _funcs);
+
+   pdev = mdp5_kms->pdev;
+
+   irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+   if (irq < 0) {
+   ret = irq;
+   dev_err(>dev, "failed to get irq: %d\n", ret);
+   goto fail;
+   }
+
+   kms->irq = irq;
+
+   config = mdp5_cfg_get_config(mdp5_kms->cfg);
+
+   /* make sure things are off before attaching iommu (bootloader could
+* have left things on, in which case we'll start getting faults if
+* we don't disable):
+*/
+   mdp5_enable(mdp5_kms);
+   for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
+   if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
+   !config->hw->intf.base[i])
+   continue;
+   mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
+
+   mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3);
+   }
+   mdp5_disable(mdp5_kms);
+   mdelay(16);
+
+   if (config->platform.iommu) {
+   mmu = msm_iommu_new(>dev, config->platform.iommu);
+   if (IS_ERR(mmu)) {
+   ret = PTR_ERR(mmu);
+   dev_err(>dev, "failed to init iommu: %d\n", ret);
+   iommu_domain_free(config->platform.iommu);
+   goto fail;
+   }
+
+   ret = mmu->funcs->attach(mmu, iommu_ports,
+   ARRAY_SIZE(iommu_ports));
+   if (ret) {
+   dev_err(>dev, "failed to attach iommu: %d\n",
+   ret);
+   mmu->funcs->destroy(mmu);
+   goto fail;
+   }
+   } else {
+   dev_info(>dev,
+"no iommu, fallback to phys contig buffers for 
scanout\n");
+   mmu = NULL;
+   }
+   mdp5_kms->mmu = mmu;
+
+   mdp5_kms->id = msm_register_mmu(dev, mmu);
+   if (mdp5_kms->id < 0) {
+   ret = mdp5_kms->id;
+   dev_err(>dev, "failed to register mdp5 iommu: %d\n", ret);
+   goto fail;
+   }
+
+   ret = modeset_init(mdp5_kms);
+   if (ret) {
+   dev_err(>dev, "modeset_init failed: %d\n", ret);
+   goto fail;
+   }
+
+   dev->mode_config.min_width = 0;
+   dev->mode_config.min_height = 0;
+   dev->mode_config.max_width = config->hw->lm.max_width;
+   dev->mode_config.max_height = config->hw->lm.max_height;
+
+   dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp;
+   dev->driver->get_scanout_position = mdp5_get_scanoutpos;
+   dev->driver->get_vblank_counter = mdp5_get_vblank_counter;
+   dev->max_vblank_count = 0x;
+   

[PATCH v2 05/25] drm/msm/mdp5: Create a separate MDP5 device

2016-06-23 Thread Archit Taneja
In order to have a tree-like device hierarchy between MDSS and its
sub-blocks (MDP5, DSI, HDMI, eDP etc), we need to create a separate
device/driver for MDP5. Currently, MDP5 and MDSS are squashed
together are are tied to the top level platform_device, which is
also the one used to create drm_device.

The mdp5_kms_init code is split into two parts. The part where device
resources are allocated are associated with the MDP5 driver's probe,
the rest is executed later when we initialize modeset.

With this change, unlike MDP4, the MDP5 platform_device isn't tied to
the top level drm_device anymore. The top level drm_device is now
associated with a platform device that corresponds to MDSS wrapper
hardware.

Create mdp5_init/destroy funcs that will be used by the MDP5 driver
probe/remove. Use the HW_VERSION register in the MDP5 register address
space. Both the MDSS and MDP VERSION registers give out identical
version info.

The older mdp5_kms_init code is left as is for now, this would be removed
later when we have all the pieces to support the new device hierarchy.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 185 +++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h |   2 +
 drivers/gpu/drm/msm/msm_drv.c   |   2 +
 drivers/gpu/drm/msm/msm_drv.h   |   3 +
 4 files changed, 189 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index e5b6361..fcb1bf4 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -111,7 +111,7 @@ static int mdp5_set_split_display(struct msm_kms *kms,
return mdp5_encoder_set_split_display(encoder, slave_encoder);
 }

-static void mdp5_destroy(struct msm_kms *kms)
+static void mdp5_kms_destroy(struct msm_kms *kms)
 {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
struct msm_mmu *mmu = mdp5_kms->mmu;
@@ -148,7 +148,7 @@ static const struct mdp_kms_funcs kms_funcs = {
.get_format  = mdp_get_format,
.round_pixclk= mdp5_round_pixclk,
.set_split_display = mdp5_set_split_display,
-   .destroy = mdp5_destroy,
+   .destroy = mdp5_kms_destroy,
},
.set_irqmask = mdp5_set_irqmask,
 };
@@ -434,6 +434,21 @@ static void read_hw_revision(struct mdp5_kms *mdp5_kms,
DBG("MDP5 version v%d.%d", *major, *minor);
 }

+static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms,
+u32 *major, u32 *minor)
+{
+   u32 version;
+
+   mdp5_enable(mdp5_kms);
+   version = mdp5_read(mdp5_kms, REG_MDP5_MDP_HW_VERSION(0));
+   mdp5_disable(mdp5_kms);
+
+   *major = FIELD(version, MDP5_MDP_HW_VERSION_MAJOR);
+   *minor = FIELD(version, MDP5_MDP_HW_VERSION_MINOR);
+
+   DBG("MDP5 version v%d.%d", *major, *minor);
+}
+
 static int get_clk(struct platform_device *pdev, struct clk **clkp,
const char *name, bool mandatory)
 {
@@ -757,6 +772,170 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)

 fail:
if (kms)
-   mdp5_destroy(kms);
+   mdp5_kms_destroy(kms);
return ERR_PTR(ret);
 }
+
+static void mdp5_destroy(struct platform_device *pdev)
+{
+   struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+
+   if (mdp5_kms->ctlm)
+   mdp5_ctlm_destroy(mdp5_kms->ctlm);
+   if (mdp5_kms->smp)
+   mdp5_smp_destroy(mdp5_kms->smp);
+   if (mdp5_kms->cfg)
+   mdp5_cfg_destroy(mdp5_kms->cfg);
+}
+
+static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct mdp5_kms *mdp5_kms;
+   struct mdp5_cfg *config;
+   u32 major, minor;
+   int ret;
+
+   mdp5_kms = devm_kzalloc(>dev, sizeof(*mdp5_kms), GFP_KERNEL);
+   if (!mdp5_kms) {
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   platform_set_drvdata(pdev, mdp5_kms);
+
+   spin_lock_init(_kms->resource_lock);
+
+   mdp5_kms->dev = dev;
+   mdp5_kms->pdev = pdev;
+
+   mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
+   if (IS_ERR(mdp5_kms->mmio)) {
+   ret = PTR_ERR(mdp5_kms->mmio);
+   goto fail;
+   }
+
+   /* mandatory clocks: */
+   ret = get_clk(pdev, _kms->axi_clk, "bus_clk", true);
+   if (ret)
+   goto fail;
+   ret = get_clk(pdev, _kms->ahb_clk, "iface_clk", true);
+   if (ret)
+   goto fail;
+   ret = get_clk(pdev, _kms->core_clk, "core_clk", true);
+   if (ret)
+   goto fail;
+   ret = get_clk(pdev, _kms->vsync_clk, "vsync_clk", true);
+   if (ret)
+   goto fail;
+
+   /* optional clocks: */
+   get_clk(pdev, _kms->lut_clk, "lut_clk", false);
+
+   /* we need to set a 

[PATCH v2 04/25] drm/msm/mdp5: Add MDSS top level driver

2016-06-23 Thread Archit Taneja
SoCs that contain MDP5 have a top level wrapper called MDSS that manages
clocks, power and irq for the sub-blocks within it.

Currently, the MDSS portions are stuffed into the MDP5 driver. This makes
it hard to represent the DT bindings in the correct way. We create a top
level MDSS helper that handles these parts. This is essentially moving out
some of the mdp5_kms irq code and MDSS register space and keeping it as a
separate entity. We haven't given any clocks to the top level MDSS yet,
but a AHB clock would be added in the future to access registers.

One thing to note is that the resources allocated by this helper are
tied to the top level platform_device (the one that allocates the
drm_device struct too). This device would be the parent to MDSS
sub-blocks like MDP5, DSI, eDP etc.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/Makefile |   1 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c | 223 +++
 drivers/gpu/drm/msm/msm_drv.h|   4 +
 drivers/gpu/drm/msm/msm_kms.h|   2 +
 4 files changed, 230 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 60cb026..4727d04 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -35,6 +35,7 @@ msm-y := \
mdp/mdp5/mdp5_crtc.o \
mdp/mdp5/mdp5_encoder.o \
mdp/mdp5/mdp5_irq.o \
+   mdp/mdp5/mdp5_mdss.o \
mdp/mdp5/mdp5_kms.o \
mdp/mdp5/mdp5_plane.o \
mdp/mdp5/mdp5_smp.o \
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
new file mode 100644
index 000..871c442
--- /dev/null
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include 
+#include 
+
+#include "msm_drv.h"
+#include "mdp5_kms.h"
+
+/*
+ * If needed, this can become more specific: something like struct mdp5_mdss,
+ * which contains a 'struct msm_mdss base' member.
+ */
+struct msm_mdss {
+   struct drm_device *dev;
+
+   void __iomem *mmio, *vbif;
+
+   struct regulator *vdd;
+
+   struct {
+   volatile unsigned long enabled_mask;
+   struct irq_domain *domain;
+   } irqcontroller;
+};
+
+static inline void mdss_write(struct msm_mdss *mdss, u32 reg, u32 data)
+{
+   msm_writel(data, mdss->mmio + reg);
+}
+
+static inline u32 mdss_read(struct msm_mdss *mdss, u32 reg)
+{
+   return msm_readl(mdss->mmio + reg);
+}
+
+static irqreturn_t mdss_irq(int irq, void *arg)
+{
+   struct msm_mdss *mdss = arg;
+   u32 intr;
+
+   intr = mdss_read(mdss, REG_MDSS_HW_INTR_STATUS);
+
+   VERB("intr=%08x", intr);
+
+   while (intr) {
+   irq_hw_number_t hwirq = fls(intr) - 1;
+
+   generic_handle_irq(irq_find_mapping(
+   mdss->irqcontroller.domain, hwirq));
+   intr &= ~(1 << hwirq);
+   }
+
+   return IRQ_HANDLED;
+}
+
+/*
+ * interrupt-controller implementation, so sub-blocks (MDP/HDMI/eDP/DSI/etc)
+ * can register to get their irq's delivered
+ */
+
+#define VALID_IRQS  (MDSS_HW_INTR_STATUS_INTR_MDP | \
+   MDSS_HW_INTR_STATUS_INTR_DSI0 | \
+   MDSS_HW_INTR_STATUS_INTR_DSI1 | \
+   MDSS_HW_INTR_STATUS_INTR_HDMI | \
+   MDSS_HW_INTR_STATUS_INTR_EDP)
+
+static void mdss_hw_mask_irq(struct irq_data *irqd)
+{
+   struct msm_mdss *mdss = irq_data_get_irq_chip_data(irqd);
+
+   smp_mb__before_atomic();
+   clear_bit(irqd->hwirq, >irqcontroller.enabled_mask);
+   smp_mb__after_atomic();
+}
+
+static void mdss_hw_unmask_irq(struct irq_data *irqd)
+{
+   struct msm_mdss *mdss = irq_data_get_irq_chip_data(irqd);
+
+   smp_mb__before_atomic();
+   set_bit(irqd->hwirq, >irqcontroller.enabled_mask);
+   smp_mb__after_atomic();
+}
+
+static struct irq_chip mdss_hw_irq_chip = {
+   .name   = "mdss",
+   .irq_mask   = mdss_hw_mask_irq,
+   .irq_unmask = mdss_hw_unmask_irq,
+};
+
+static int mdss_hw_irqdomain_map(struct irq_domain *d, unsigned int irq,
+irq_hw_number_t hwirq)
+{
+   struct msm_mdss *mdss = d->host_data;
+
+   if (!(VALID_IRQS & (1 << hwirq)))
+   return 

[PATCH v2 03/25] drm/msm: Get irq number within kms driver itself

2016-06-23 Thread Archit Taneja
The driver gets the irq number using platform_get_irq on the main kms
platform device. This works fine since both MDP4 and MDP5 currently
have a flat device hierarchy. The platform device tied with the
drm_device points to the MDP DT node in both cases.

This won't work when MDP5 supports a tree-like hierarchy. In this
case, the platform device tied to the top level drm_device is the
MDSS DT node, and the irq we need for KMS is the one generated by
MDP5, not MDSS.

Get the irq number from the MDP4/5 kms driver itself. Each driver
can later provide the irq number based on what device hierarchy it
uses.

While we're at it, call drm_irq_install only when we have a valid KMS
driver.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 11 ++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 11 ++-
 drivers/gpu/drm/msm/msm_drv.c   | 14 --
 drivers/gpu/drm/msm/msm_kms.h   |  3 +++
 4 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index eb21bcf..0e751c0 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -440,7 +440,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
struct mdp4_kms *mdp4_kms;
struct msm_kms *kms = NULL;
struct msm_mmu *mmu;
-   int ret;
+   int irq, ret;

mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL);
if (!mdp4_kms) {
@@ -461,6 +461,15 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
goto fail;
}

+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
+   ret = irq;
+   dev_err(dev->dev, "failed to get irq: %d\n", ret);
+   goto fail;
+   }
+
+   kms->irq = irq;
+
/* NOTE: driver for this regulator still missing upstream.. use
 * _get_exclusive() and ignore the error if it does not exist
 * (and hope that the bootloader left it on for us)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 16316bc..e5b6361 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -580,7 +580,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
struct msm_kms *kms = NULL;
struct msm_mmu *mmu;
uint32_t major, minor;
-   int i, ret;
+   int irq, i, ret;

mdp5_kms = kzalloc(sizeof(*mdp5_kms), GFP_KERNEL);
if (!mdp5_kms) {
@@ -610,6 +610,15 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
goto fail;
}

+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
+   ret = irq;
+   dev_err(dev->dev, "failed to get irq: %d\n", ret);
+   goto fail;
+   }
+
+   kms->irq = irq;
+
mdp5_kms->vdd = devm_regulator_get(>dev, "vdd");
if (IS_ERR(mdp5_kms->vdd)) {
ret = PTR_ERR(mdp5_kms->vdd);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 476eafe..092926b 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -417,12 +417,14 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
goto fail;
}

-   pm_runtime_get_sync(dev);
-   ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
-   pm_runtime_put_sync(dev);
-   if (ret < 0) {
-   dev_err(dev, "failed to install IRQ handler\n");
-   goto fail;
+   if (kms) {
+   pm_runtime_get_sync(dev);
+   ret = drm_irq_install(ddev, kms->irq);
+   pm_runtime_put_sync(dev);
+   if (ret < 0) {
+   dev_err(dev, "failed to install IRQ handler\n");
+   goto fail;
+   }
}

ret = drm_dev_register(ddev, 0);
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 00998f9..0452856 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -60,6 +60,9 @@ struct msm_kms_funcs {

 struct msm_kms {
const struct msm_kms_funcs *funcs;
+
+   /* irq number to be passed on to drm_irq_install */
+   int irq;
 };

 static inline void msm_kms_init(struct msm_kms *kms,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 02/25] drm/msm: Remove unused fields

2016-06-23 Thread Archit Taneja
These aren't used. Probably left overs when driver was refactored to
support both MDP4 and MDP5.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/msm_kms.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index e3c..00998f9 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -60,11 +60,6 @@ struct msm_kms_funcs {

 struct msm_kms {
const struct msm_kms_funcs *funcs;
-
-   /* irq handling: */
-   bool in_irq;
-   struct list_head irq_list;/* list of mdp4_irq */
-   uint32_t vblank_mask; /* irq bits set for userspace vblank */
 };

 static inline void msm_kms_init(struct msm_kms *kms,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 01/25] drm/msm: Drop the id_table in platform_driver

2016-06-23 Thread Archit Taneja
This isn't needed as we only support OF.

Signed-off-by: Archit Taneja 
---
 drivers/gpu/drm/msm/msm_drv.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index a02dc2b..476eafe 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -852,11 +852,6 @@ static int msm_pdev_remove(struct platform_device *pdev)
return 0;
 }

-static const struct platform_device_id msm_id[] = {
-   { "mdp", 0 },
-   { }
-};
-
 static const struct of_device_id dt_match[] = {
{ .compatible = "qcom,mdp4", .data = (void *) 4 },  /* mdp4 */
{ .compatible = "qcom,mdp5", .data = (void *) 5 },  /* mdp5 */
@@ -874,7 +869,6 @@ static struct platform_driver msm_platform_driver = {
.of_match_table = dt_match,
.pm = _pm_ops,
},
-   .id_table   = msm_id,
 };

 static int __init msm_drm_register(void)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH v2 00/25] drm/msm: Enable DT support

2016-06-23 Thread Archit Taneja
This patchset adds the last bits needed for getting the MSM display
bindings in correct shape, and as an example, adds display support for
MSM8916.

One problem with the MDP5 driver was that device hierarchy didn't match
with the hardware. All MDP5 based display blocks contain a top-level
MDSS wrapper hardware that manages IRQs, power and some clocks for
the sub-blocks (MDP5, DSI, HDMI, eDP etc) within it. The driver stuffs
this functionality within the MDP5 driver itself, which results in
probably not the cleanest design, and forces us to repeat some
resources (like, power domain, some top level clocks) across all the
sub-blocks. This is fixed by creating separate MDP5 and MDSS platform
devices, and making each piece manage its own resources. MDP4 still
continues to have the flat device hierarchy.

The second problem was the non-standard connector and gpu DT properites.
The former was needed to bind all the external components (DSI, HDMI etc)
before we started with intializing modeset. This is fixed by representing
the MDP interface outputs as ports, and linking them to the ports of the
encoders they are connected to. The 'gpu' property is removed in a
hack-ish way. The driver contains a list of all the compatible strings
for gpus, and searches the entire OF firmware for a matching node. Once
we know what's the right way to link the gpu and display nodes together
(if needed at all), we can add the required binding.

The device hierarchy for MDP5 platforms fits well for runtime PM
adaptation too. Although, for it to work correctly, all the encoder
drivers need to adapt to runtime PM too. With that in place, we still
hit issues in some usecases where the entire register context isn't
correctly restored during resume. It finally boils down to the helpers
we use for implementing atomic_commit. This will take some more time
to solve. For now, we just enable runtime PM early and leave it enabled.
This is necessary for MDP5 based SoCs since Qcom GDSCs are tied to power
domains. This will be fixed once we get all paths working properly with
runtime PM. 

This patchset will break bisectability, in the sense that both the
downstream and proposed DT bindings won't work if we apply only a partial
set of patches. With this series applied, only the proposed bindings will
work. Downstream dtsi files from older kernels will have to be adapted
slightly to get it running with these changes.

This series depends on two patchsets posted before:

drm/msm DT prep work:
http://www.spinics.net/lists/dri-devel/msg110197.html

ADV7533 support+DT bindings:
http://www.spinics.net/lists/linux-arm-msm/msg21085.html

Changes in v2:
- Drop the "qcom,dsi-host-index" and "qcom,dsi-phy-index" props
- Remove some power domain props in the binding docs that got
  missed out.

Archit Taneja (25):
  drm/msm: Drop the id_table in platform_driver
  drm/msm: Remove unused fields
  drm/msm: Get irq number within kms driver itself
  drm/msm/mdp5: Add MDSS top level driver
  drm/msm/mdp5: Create a separate MDP5 device
  drm/msm/mdp5: Prepare new kms_init funcs
  drm/msm/mdp5: Use the new hierarchy and drop old irq management
  drm/msm/mdp5: Remove old kms init/destroy funcs
  drm/msm/mdp5: Use updated MDP5 register names
  drm/msm/mdp5: Update the register offsets of MDP5 sub-blocks
  drm/msm: Call pm_runtime_enable/disable for newly created devices
  drm/msm/mdp5: Add missing mdp5_enable/disable calls
  drm/msm: Create separate funcs for adding display/gpu components
  drm/msm: Add display components by parsing MDP ports
  drm/msm: Add components for MDP5
  drm/msm: Drop the gpu binding
  drm/msm/mdp5: Update compatible strings for MDSS/MDP5
  drm/msm/dsi: Don't get DSI index from DT
  dt-bindings: msm/mdp4: Create a separate binding doc for MDP4
  dt-bindings: msm/mdp5: Add MDP5 display bindings
  dt-bindings: msm/mdp: Provide details on MDP interface ports
  dt-bindings: msm/dsi: Remove unused properties
  dt-bindings: display/msm: Remove power domain property from encoder
nodes
  arm64: dts: msm8916: Add display support
  arm64: dts: apq8016-sbc: Add HDMI display support

 .../devicetree/bindings/display/msm/dsi.txt|   9 -
 .../devicetree/bindings/display/msm/edp.txt|   2 -
 .../devicetree/bindings/display/msm/hdmi.txt   |   4 -
 .../devicetree/bindings/display/msm/mdp.txt|  57 
 .../devicetree/bindings/display/msm/mdp4.txt   | 112 
 .../devicetree/bindings/display/msm/mdp5.txt   | 160 +++
 arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi |  48 
 arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi  |  82 ++
 arch/arm64/boot/dts/qcom/msm8916.dtsi  | 117 
 drivers/gpu/drm/msm/Makefile   |   1 +
 drivers/gpu/drm/msm/dsi/dsi_cfg.c  |   8 +
 drivers/gpu/drm/msm/dsi/dsi_cfg.h  |   2 +
 drivers/gpu/drm/msm/dsi/dsi_host.c |  33 ++-
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c  |  32 ++-
 

[PATCH v3 02/10] drm/rockchip: analogix_dp: split the lcdc select setting into device data

2016-06-23 Thread Heiko Stuebner
Am Donnerstag, 23. Juni 2016, 10:32:53 schrieb Sean Paul:
> On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> > eDP controller need to declare which vop provide the video source,
> > and it's defined in GRF registers.
> > 
> > But different chips have different GRF register address, so we need to
> > create a device data to declare the GRF messages for each chips.
> > 
> > Signed-off-by: Yakir Yang 
> > Acked-by: Mark Yao 
> > ---
> > Changes in v3:
> > - Write a kerneldoc-style comment explaining the chips data fields
> > (Tomasz, reviewed at Google Gerrit)> 
> > [https://chromium-review.googlesource.com/#/c/346313/10/drivers/gpu/
> > drm/rockchip/analogix_dp-rockchip.c at 39]> 
> > - Drop the '.lcdcsel_mask' number in chips data field (Tomasz, reviewed
> > at Google Gerrit)> 
> > [https://chromium-review.googlesource.com/#/c/346313/10/drivers/gpu/
> > drm/rockchip/analogix_dp-rockchip.c at 382]> 
> > - Add acked flag from Mark.
> > 
> > Changes in v2: None
> > 
> >  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 39
> >  +++-- 1 file changed, 30 insertions(+), 9
> >  deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index
> > 2bc8a7e..3855f46 100644
> > --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > @@ -14,6 +14,7 @@
> > 
> >  #include 
> >  #include 
> > 
> > +#include 
> > 
> >  #include 
> >  #include 
> >  #include 
> > 
> > @@ -35,11 +36,17 @@
> > 
> >  #define to_dp(nm)  container_of(nm, struct rockchip_dp_device, nm)
> > 
> > -/* dp grf register offset */
> > -#define GRF_SOC_CON60x025c
> > -#define GRF_EDP_LCD_SEL_MASKBIT(5)
> > -#define GRF_EDP_SEL_VOP_LIT BIT(5)
> > -#define GRF_EDP_SEL_VOP_BIG 0
> > +/**
> > + * struct rockchip_dp_chip_data - splite the grf setting of kind of
> > chips + * @lcdsel_grf_reg: grf register offset of lcdc select
> > + * @lcdsel_big: reg value of selecting vop big for eDP
> > + * @lcdsel_lit: reg value of selecting vop little for eDP
> > + */
> > +struct rockchip_dp_chip_data {
> > +   u32 lcdsel_grf_reg;
> > +   u32 lcdsel_big;
> > +   u32 lcdsel_lit;
> > +};
> > 
> >  struct rockchip_dp_device {
> >  
> > struct drm_device*drm_dev;
> > 
> > @@ -51,6 +58,8 @@ struct rockchip_dp_device {
> > 
> > struct regmap*grf;
> > struct reset_control *rst;
> > 
> > +   const struct rockchip_dp_chip_data *data;
> > +
> > 
> > struct analogix_dp_plat_data plat_data;
> >  
> >  };
> > 
> > @@ -119,13 +128,13 @@ static void rockchip_dp_drm_encoder_enable(struct
> > drm_encoder *encoder)> 
> > return;
> > 
> > if (ret)
> > 
> > -   val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK <<
> > 16);
> > +   val = dp->data->lcdsel_lit;
> > 
> > else
> > 
> > -   val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK <<
> > 16);
> > +   val = dp->data->lcdsel_big;
> > 
> > dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" :
> > "BIG");
> > 
> > -   ret = regmap_write(dp->grf, GRF_SOC_CON6, val);
> > +   ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
> > 
> > if (ret != 0) {
> > 
> > dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
> > return;
> > 
> > @@ -246,6 +255,7 @@ static int rockchip_dp_bind(struct device *dev,
> > struct device *master,> 
> > void *data)
> >  
> >  {
> >  
> > struct rockchip_dp_device *dp = dev_get_drvdata(dev);
> > 
> > +   const struct rockchip_dp_chip_data *dp_data;
> > 
> > struct drm_device *drm_dev = data;
> > int ret;
> > 
> > @@ -256,10 +266,15 @@ static int rockchip_dp_bind(struct device *dev,
> > struct device *master,> 
> >  */
> > 
> > dev_set_drvdata(dev, NULL);
> > 
> > +   dp_data = of_device_get_match_data(dev);
> > +   if (!dp_data)
> > +   return -ENODEV;
> > +
> > 
> > ret = rockchip_dp_init(dp);
> > if (ret < 0)
> > 
> > return ret;
> > 
> > +   dp->data = dp_data;
> > 
> > dp->drm_dev = drm_dev;
> > 
> > ret = rockchip_dp_drm_create_encoder(dp);
> > 
> > @@ -365,8 +380,14 @@ static const struct dev_pm_ops rockchip_dp_pm_ops =
> > {> 
> > SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
> >  
> >  };
> > 
> > +static const struct rockchip_dp_chip_data rk3288_dp = {
> > +   .lcdsel_grf_reg = 0x025c,
> > +   .lcdsel_big = 0 | BIT(21),
> > +   .lcdsel_lit = BIT(5) | BIT(21),
> 
> I'm not sure what convention is in other drivers, but this seems less
> readable to me.
> 
> I'd prefer that the magic numbers 

[PATCH 12/12] arm64: tegra: Add DPAUX pinctrl bindings

2016-06-23 Thread Jon Hunter
Add the DPAUX pinctrl states for the DPAUX nodes defining all three
possible states of "aux", "i2c" and "off". Also add the 'i2c-bus'
node for the DPAUX nodes so that the I2C driver core does not attempt
to parse the pinctrl state nodes.

Populate the nodes for the pinctrl clients of the DPAUX pin controller.
There are two clients for each DPAUX instance, namely the SOR and one of
the I2C adapters. The SOR clients may used the DPAUX pins in either AUX
or I2C modes and so for these devices we don't define any of the generic
pinctrl states (default, idle, etc) because the SOR driver will directly
set the state needed. For I2C clients only the I2C mode is used and so
we can simplify matters by using the generic pinctrl states for default
and idle.

Signed-off-by: Jon Hunter 
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 54 
 1 file changed, 54 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index ef317f0d773f..32af84e404d6 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -36,6 +36,26 @@
reset-names = "dpaux";
power-domains = <_sor>;
status = "disabled";
+
+   state_dpaux1_aux: pinmux_aux {
+   groups = "dpaux-io";
+   function = "aux";
+   };
+
+   state_dpaux1_i2c: pinmux_i2c {
+   groups = "dpaux-io";
+   function = "i2c";
+   };
+
+   state_dpaux1_off: pinmux_off {
+   groups = "dpaux-io";
+   function = "off";
+   };
+
+   i2c-bus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
};

vi at 5408 {
@@ -155,6 +175,10 @@
clock-names = "sor", "parent", "dp", "safe";
resets = <_car 182>;
reset-names = "sor";
+   pinctrl-0 = <_dpaux_aux>;
+   pinctrl-1 = <_dpaux_i2c>;
+   pinctrl-2 = <_dpaux_off>;
+   pinctrl-names = "aux", "i2c", "off";
power-domains = <_sor>;
status = "disabled";
};
@@ -170,6 +194,10 @@
clock-names = "sor", "parent", "dp", "safe";
resets = <_car 183>;
reset-names = "sor";
+   pinctrl-0 = <_dpaux1_aux>;
+   pinctrl-1 = <_dpaux1_i2c>;
+   pinctrl-2 = <_dpaux1_off>;
+   pinctrl-names = "aux", "i2c", "off";
power-domains = <_sor>;
status = "disabled";
};
@@ -185,6 +213,26 @@
reset-names = "dpaux";
power-domains = <_sor>;
status = "disabled";
+
+   state_dpaux_aux: pinmux_aux {
+   groups = "dpaux-io";
+   function = "aux";
+   };
+
+   state_dpaux_i2c: pinmux_i2c {
+   groups = "dpaux-io";
+   function = "i2c";
+   };
+
+   state_dpaux_off: pinmux_off {
+   groups = "dpaux-io";
+   function = "off";
+   };
+
+   i2c-bus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
};

isp at 5460 {
@@ -482,6 +530,9 @@
reset-names = "i2c";
dmas = < 26>, < 26>;
dma-names = "rx", "tx";
+   pinctrl-0 = <_dpaux1_i2c>;
+   pinctrl-1 = <_dpaux1_off>;
+   pinctrl-names = "default", "idle";
status = "disabled";
};

@@ -512,6 +563,9 @@
reset-names = "i2c";
dmas = < 30>, < 30>;
dma-names = "rx", "tx";
+   pinctrl-0 = <_dpaux_i2c>;
+   pinctrl-1 = <_dpaux_off>;
+   pinctrl-names = "default", "idle";
status = "disabled";
};

-- 
2.1.4



[PATCH 11/12] arm64: tegra: Add SOR power-domain node

2016-06-23 Thread Jon Hunter
Add node for SOR power-domain for Tegra210 and populate the SOR
power-domain phandle for SOR and DPAUX nodes that are dependent
on this power-domain.

Please note that although neither the SOR or DPAUX drivers currently
support runtime power-management, by populating the power-domain node
the SOR power-domain will be turned on before probing SOR or DPAUX
devices and kept on while the devices are bound.

Signed-off-by: Jon Hunter 
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index ebf44f4059f8..ef317f0d773f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -34,6 +34,7 @@
clock-names = "dpaux", "parent";
resets = <_car 207>;
reset-names = "dpaux";
+   power-domains = <_sor>;
status = "disabled";
};

@@ -154,6 +155,7 @@
clock-names = "sor", "parent", "dp", "safe";
resets = <_car 182>;
reset-names = "sor";
+   power-domains = <_sor>;
status = "disabled";
};

@@ -168,6 +170,7 @@
clock-names = "sor", "parent", "dp", "safe";
resets = <_car 183>;
reset-names = "sor";
+   power-domains = <_sor>;
status = "disabled";
};

@@ -180,6 +183,7 @@
clock-names = "dpaux", "parent";
resets = <_car 181>;
reset-names = "dpaux";
+   power-domains = <_sor>;
status = "disabled";
};

@@ -592,6 +596,26 @@
resets = <_car 198>;
#power-domain-cells = <0>;
};
+
+   pd_sor: sor {
+   clocks = <_car TEGRA210_CLK_SOR0>,
+<_car TEGRA210_CLK_SOR1>,
+<_car TEGRA210_CLK_CSI>,
+<_car TEGRA210_CLK_DSIA>,
+<_car TEGRA210_CLK_DSIB>,
+<_car TEGRA210_CLK_DPAUX>,
+<_car TEGRA210_CLK_DPAUX1>,
+<_car TEGRA210_CLK_MIPI_CAL>;
+   resets = <_car TEGRA210_CLK_SOR0>,
+<_car TEGRA210_CLK_SOR1>,
+<_car TEGRA210_CLK_CSI>,
+<_car TEGRA210_CLK_DSIA>,
+<_car TEGRA210_CLK_DSIB>,
+<_car TEGRA210_CLK_DPAUX>,
+<_car TEGRA210_CLK_DPAUX1>,
+<_car TEGRA210_CLK_MIPI_CAL>;
+   #power-domain-cells = <0>;
+   };
};
};

-- 
2.1.4



[PATCH 10/12] drm/tegra: Add pinctrl support for DPAUX

2016-06-23 Thread Jon Hunter
The DPAUX pins are shared with an internal I2C controller. To allow
these pins to be muxed to the I2C controller, register a pinctrl device
for the DPAUX device. Make Tegra DRM support dependent on PINCTRL to
avoid any compilation issues.

This is based upon work by Thierry Reding .

Signed-off-by: Jon Hunter 
---
 drivers/gpu/drm/tegra/dpaux.c | 122 --
 1 file changed, 119 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 61821f457209..7b2abaf33a7a 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -12,6 +12,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -44,6 +47,11 @@ struct tegra_dpaux {
struct completion complete;
struct work_struct work;
struct list_head list;
+
+#ifdef CONFIG_PINCTRL
+   struct pinctrl_dev *pinctrl;
+   struct pinctrl_desc desc;
+#endif
 };

 static inline struct tegra_dpaux *to_dpaux(struct drm_dp_aux *aux)
@@ -267,6 +275,12 @@ static irqreturn_t tegra_dpaux_irq(int irq, void *data)
return ret;
 }

+enum tegra_dpaux_functions {
+   DPAUX_PADCTL_FUNC_AUX,
+   DPAUX_PADCTL_FUNC_I2C,
+   DPAUX_PADCTL_FUNC_OFF,
+};
+
 static void tegra_dpaux_pad_power_down(struct tegra_dpaux *dpaux)
 {
u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
@@ -290,18 +304,21 @@ static int tegra_dpaux_pad_config(struct tegra_dpaux 
*dpaux, unsigned function)
u32 value;

switch (function) {
-   case DPAUX_HYBRID_PADCTL_MODE_AUX:
+   case DPAUX_PADCTL_FUNC_AUX:
value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) |
DPAUX_HYBRID_PADCTL_AUX_DRVZ(4) |
DPAUX_HYBRID_PADCTL_AUX_DRVI(0x18) |
DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV |
DPAUX_HYBRID_PADCTL_MODE_AUX;
break;
-   case DPAUX_HYBRID_PADCTL_MODE_I2C:
+   case DPAUX_PADCTL_FUNC_I2C:
value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV |
DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
DPAUX_HYBRID_PADCTL_MODE_I2C;
break;
+   case DPAUX_PADCTL_FUNC_OFF:
+   tegra_dpaux_pad_power_down(dpaux);
+   return 0;
default:
return -ENOTSUPP;
}
@@ -312,6 +329,91 @@ static int tegra_dpaux_pad_config(struct tegra_dpaux 
*dpaux, unsigned function)
return 0;
 }

+#ifdef CONFIG_PINCTRL
+static const struct pinctrl_pin_desc tegra_dpaux_pins[] = {
+   PINCTRL_PIN(0, "DP_AUX_CHx_P"),
+   PINCTRL_PIN(1, "DP_AUX_CHx_N"),
+};
+
+static const unsigned tegra_dpaux_pin_numbers[] = { 0, 1 };
+
+static const char * const tegra_dpaux_groups[] = {
+   "dpaux-io",
+};
+
+static const char * const tegra_dpaux_functions[] = {
+   "aux",
+   "i2c",
+   "off",
+};
+
+static int tegra_dpaux_get_groups_count(struct pinctrl_dev *pinctrl)
+{
+   return ARRAY_SIZE(tegra_dpaux_groups);
+}
+
+static const char *tegra_dpaux_get_group_name(struct pinctrl_dev *pinctrl,
+ unsigned int group)
+{
+   return tegra_dpaux_groups[group];
+}
+
+static int tegra_dpaux_get_group_pins(struct pinctrl_dev *pinctrl,
+ unsigned group, const unsigned **pins,
+ unsigned *num_pins)
+{
+   *pins = tegra_dpaux_pin_numbers;
+   *num_pins = ARRAY_SIZE(tegra_dpaux_pin_numbers);
+
+   return 0;
+}
+
+static const struct pinctrl_ops tegra_dpaux_pinctrl_ops = {
+   .get_groups_count = tegra_dpaux_get_groups_count,
+   .get_group_name = tegra_dpaux_get_group_name,
+   .get_group_pins = tegra_dpaux_get_group_pins,
+   .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
+   .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int tegra_dpaux_get_functions_count(struct pinctrl_dev *pinctrl)
+{
+   return ARRAY_SIZE(tegra_dpaux_functions);
+}
+
+static const char *tegra_dpaux_get_function_name(struct pinctrl_dev *pinctrl,
+unsigned int function)
+{
+   return tegra_dpaux_functions[function];
+}
+
+static int tegra_dpaux_get_function_groups(struct pinctrl_dev *pinctrl,
+  unsigned int function,
+  const char * const **groups,
+  unsigned * const num_groups)
+{
+   *num_groups = ARRAY_SIZE(tegra_dpaux_groups);
+   *groups = tegra_dpaux_groups;
+
+   return 0;
+}
+
+static int tegra_dpaux_set_mux(struct pinctrl_dev *pinctrl,
+  unsigned int function, unsigned int group)
+{
+   struct tegra_dpaux *dpaux = pinctrl_dev_get_drvdata(pinctrl);
+
+   return tegra_dpaux_pad_config(dpaux, function);
+}
+
+static const 

[PATCH 09/12] dt-bindings: Add bindings for Tegra DPAUX pinctrl driver

2016-06-23 Thread Jon Hunter
On Tegra124, Tegra132 and Tegra210 devices the pads used by the Display
Port Auxiliary (DPAUX) channel are multiplexed such that they can also
be used by one of the internal I2C controllers. Note that this is
different from I2C-over-AUX supported by the DPAUX controller. The
register that configures these pads is part of the DPAUX controllers
register set and so a pinctrl driver is being added for the DPAUX device
to share these pads. Add the device-tree binding documentation for the
DPAUX pad controller.

Although there is only one group of pads associated with the DPAUX that
can be multiplexed, the group still needs to be described by the binding.
If the 'groups' property is not present in the binding, then the pads
will not be allocated by the pinctrl core for a client and this would
allow another client to re-configure the same pads that may already be
in-use.

Please note that although the "off" function for the DPAUX pads is not
technically a pin-mux setting but more of a pin-conf setting it is
simpler to expose these as a function so that the user can simply select
either "aux", "i2c" or "off" as the current function/mode.

Update the main DPAUX binding documentation to reference the DPAUX pad
controller binding document and add the 'i2c-bus' subnode. The 'i2c-bus'
subnode is used for populating I2C slaves for the DPAUX device so that
the I2C driver core does not attempt to add the DPAUX pad controller
nodes as I2C slaves.

Signed-off-by: Jon Hunter 
---
 .../display/tegra/nvidia,tegra20-host1x.txt|  6 +++
 .../pinctrl/nvidia,tegra124-dpaux-padctl.txt   | 60 ++
 2 files changed, 66 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt

diff --git 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index 275f45680892..d0f1dc62550a 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -241,6 +241,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
 - dpaux
   - vdd-supply: phandle of a supply that powers the DisplayPort link
+  - i2c-bus: Subnode where I2C slave devices are listed. This subnode
+must be always present. If there are no I2C slave devices, an empty
+node should be added. See ../../i2c/i2c.txt for more information.
+
+  See ../pinctrl/nvidia,tegra124-dpaux-padctl.txt for information
+  regarding the DPAUX pad controller bindings.

 Example:

diff --git 
a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt 
b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt
new file mode 100644
index ..656e0a04be8f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt
@@ -0,0 +1,60 @@
+Device tree binding for NVIDIA Tegra DPAUX pad controller
+
+
+The Tegra Display Port Auxiliary (DPAUX) pad controller manages two pins
+which can be assigned to either the DPAUX channel or to an I2C
+controller.
+
+This document defines the device-specific binding for the DPAUX pad
+controller. Refer to pinctrl-bindings.txt in this directory for generic
+information about pin controller device tree bindings. Please refer to
+the binding document ../display/tegra/nvidia,tegra20-host1x.txt for more
+details on the DPAUX binding.
+
+Pin muxing:
+---
+
+Child nodes contain the pinmux configurations following the conventions
+from the pinctrl-bindings.txt document.
+
+Since only three configurations are possible, only three child nodes are
+needed to describe the pin mux'ing options for the DPAUX pads.
+Furthermore, given that the pad functions are only applicable to a
+single set of pads, the child nodes only need to describe the pad group
+the functions are being applied to rather than the individual pads.
+
+Required properties:
+- groups: Must be "dpaux-io"
+- function: Must be either "aux", "i2c" or "off".
+
+Example:
+
+
+   dpaux at 545c {
+   ...
+
+   state_dpaux_aux: pinmux_aux {
+   groups = "dpaux-io";
+   function = "aux";
+   };
+
+   state_dpaux_i2c: pinmux_i2c {
+   groups = "dpaux-io";
+   function = "i2c";
+   };
+
+   state_dpaux_off: pinmux_off {
+   groups = "dpaux-io";
+   function = "off";
+   };
+   };
+
+   ...
+
+   i2c at 7000d100 {
+   ...
+   pinctrl-0 = <_dpaux_i2c>;
+   pinctrl-1 = <_dpaux_off>;
+   pinctrl-names = "default", "idle";
+   status = "disabled";
+   };
-- 
2.1.4



[PATCH 08/12] i2c: core: Add support for 'i2c-bus' subnode

2016-06-23 Thread Jon Hunter
If the 'i2c-bus' device-tree node is present for an I2C adapter then
parse this subnode for I2C slaves.

Signed-off-by: Jon Hunter 
---
 drivers/i2c/i2c-core.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 952d2f0c02c5..71ad532be1d8 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1452,7 +1452,7 @@ static struct i2c_client *of_i2c_register_device(struct 
i2c_adapter *adap,

 static void of_i2c_register_devices(struct i2c_adapter *adap)
 {
-   struct device_node *node;
+   struct device_node *bus, *node;

/* Only register child devices if the adapter has a node pointer set */
if (!adap->dev.of_node)
@@ -1460,11 +1460,17 @@ static void of_i2c_register_devices(struct i2c_adapter 
*adap)

dev_dbg(>dev, "of_i2c: walking child nodes\n");

-   for_each_available_child_of_node(adap->dev.of_node, node) {
+   bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus");
+   if (!bus)
+   bus = of_node_get(adap->dev.of_node);
+
+   for_each_available_child_of_node(bus, node) {
if (of_node_test_and_set_flag(node, OF_POPULATED))
continue;
of_i2c_register_device(adap, node);
}
+
+   of_node_put(bus);
 }

 static int of_dev_node_match(struct device *dev, void *data)
-- 
2.1.4



[PATCH 07/12] dt-bindings: i2c: Add support for 'i2c-bus' subnode

2016-06-23 Thread Jon Hunter
The I2C driver core for boards using device-tree assumes any subnode of
an I2C adapter in the device-tree blob as being a I2C slave device.
Although this makes complete sense, some I2C adapters may have subnodes
which are not I2C slaves but subnodes presenting other features. For
example some Tegra devices have an I2C interface which may share its
pins with other devices and to share these pins subnodes for
representing these pins so they have be shared via the pinctrl framework
are needed.

To allow I2C adapters to have non-I2C specific subnodes in device-tree
that are not parsed by the I2C driver core by adding support for a
'i2c-bus' subnode where I2C slaves can be placed. If the 'i2c-bus'
subnode is present then all I2C slaves must be placed under this subnode.

Signed-off-by: Jon Hunter 
Acked-by: Thierry Reding 
---
 Documentation/devicetree/bindings/i2c/i2c.txt | 8 
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt 
b/Documentation/devicetree/bindings/i2c/i2c.txt
index f31b2ad1552b..71bea55d4c1b 100644
--- a/Documentation/devicetree/bindings/i2c/i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c.txt
@@ -32,6 +32,14 @@ wants to support one of the below features, it should adapt 
the bindings below.
 - clock-frequency
frequency of bus clock in Hz.

+- i2c-bus
+   For I2C adapters that have child nodes that are a mixture of both I2C
+   devices and non-I2C devices (such as a pin controller), the 'i2c-bus'
+   subnode can be used for populating I2C devices. If the 'i2c-bus'
+   subnode is present, only subnodes of this will be considered as I2C
+   slaves. The properties, '#address-cells' and '#size-cells' must be
+   defined under this subnode if present.
+
 - i2c-scl-falling-time-ns
Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C
specification.
-- 
2.1.4



[PATCH 06/12] pinctrl: pinconf: Add generic helper function for freeing mappings

2016-06-23 Thread Jon Hunter
The pinconf-generic.h file exposes functions for creating generic mappings
but it does not expose a function for freeing the mappings. Add a function
for freeing generic mappings.

Signed-off-by: Jon Hunter 
Acked-by: Linus Walleij 
---
 drivers/pinctrl/pinconf-generic.c   | 8 
 include/linux/pinctrl/pinconf-generic.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/pinctrl/pinconf-generic.c 
b/drivers/pinctrl/pinconf-generic.c
index 34b601b06764..5020ae534479 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -395,4 +395,12 @@ exit:
 }
 EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map);

+void pinconf_generic_dt_free_map(struct pinctrl_dev *pctldev,
+struct pinctrl_map *map,
+unsigned num_maps)
+{
+   pinctrl_utils_free_map(pctldev, map, num_maps);
+}
+EXPORT_SYMBOL_GPL(pinconf_generic_dt_free_map);
+
 #endif
diff --git a/include/linux/pinctrl/pinconf-generic.h 
b/include/linux/pinctrl/pinconf-generic.h
index d921afd5f109..12343caa114e 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -175,6 +175,8 @@ int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev 
*pctldev,
 int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np_config, struct pinctrl_map **map,
unsigned *num_maps, enum pinctrl_map_type type);
+void pinconf_generic_dt_free_map(struct pinctrl_dev *pctldev,
+   struct pinctrl_map *map, unsigned num_maps);

 static inline int pinconf_generic_dt_node_to_map_group(
struct pinctrl_dev *pctldev, struct device_node *np_config,
-- 
2.1.4



[PATCH 05/12] drm/tegra: Prepare DPAUX for supporting generic PM domains

2016-06-23 Thread Jon Hunter
To utilise the DPAUX on Tegra, the SOR power partition must be enabled.
Now that Tegra supports the generic PM domain framework we manage the
SOR power partition via this framework for DPAUX. However, the sequence
for gating/ungating the SOR power partition requires that the DPAUX
reset is asserted/de-asserted at the time the SOR power partition is
gated/ungated, respectively. Now that the reset control core assumes
that resets are exclusive, the Tegra generic PM domain code and the
DPAUX driver cannot request the same reset unless we mark the resets as
shared. Sharing resets we will not work in this case because we cannot
guarantee that the reset is asserted/de-asserted at the appropriate
time. Therefore, given that the Tegra generic PM domain code will handle
the DPAUX reset, do not request the reset in the DPAUX driver if the
DPAUX device has a PM domain associated.

Signed-off-by: Jon Hunter 
---
 drivers/gpu/drm/tegra/dpaux.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 4014ec57ed31..61821f457209 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -339,11 +339,14 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
return -ENXIO;
}

-   dpaux->rst = devm_reset_control_get(>dev, "dpaux");
-   if (IS_ERR(dpaux->rst)) {
-   dev_err(>dev, "failed to get reset control: %ld\n",
-   PTR_ERR(dpaux->rst));
-   return PTR_ERR(dpaux->rst);
+   if (!pdev->dev.pm_domain) {
+   dpaux->rst = devm_reset_control_get(>dev, "dpaux");
+   if (IS_ERR(dpaux->rst)) {
+   dev_err(>dev,
+   "failed to get reset control: %ld\n",
+   PTR_ERR(dpaux->rst));
+   return PTR_ERR(dpaux->rst);
+   }
}

dpaux->clk = devm_clk_get(>dev, NULL);
@@ -360,7 +363,8 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
return err;
}

-   reset_control_deassert(dpaux->rst);
+   if (dpaux->rst)
+   reset_control_deassert(dpaux->rst);

dpaux->clk_parent = devm_clk_get(>dev, "parent");
if (IS_ERR(dpaux->clk_parent)) {
@@ -438,7 +442,8 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 disable_parent_clk:
clk_disable_unprepare(dpaux->clk_parent);
 assert_reset:
-   reset_control_assert(dpaux->rst);
+   if (dpaux->rst)
+   reset_control_assert(dpaux->rst);
clk_disable_unprepare(dpaux->clk);

return err;
@@ -460,7 +465,8 @@ static int tegra_dpaux_remove(struct platform_device *pdev)
cancel_work_sync(>work);

clk_disable_unprepare(dpaux->clk_parent);
-   reset_control_assert(dpaux->rst);
+   if (dpaux->rst)
+   reset_control_assert(dpaux->rst);
clk_disable_unprepare(dpaux->clk);

return 0;
-- 
2.1.4



[PATCH 04/12] dt-bindings: display: Update Tegra DPAUX documentation

2016-06-23 Thread Jon Hunter
Update the DPAUX compatibility string information for Tegra124, Tegra132
and Tegra210.

Signed-off-by: Jon Hunter 
---
 .../devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index a3bd8c050c4e..275f45680892 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -226,9 +226,9 @@ of the following host1x client modules:
   - nvidia,dpaux: phandle to a DispayPort AUX interface

 - dpaux: DisplayPort AUX interface
-  - compatible: For Tegra124, must contain "nvidia,tegra124-dpaux".  Otherwise,
-must contain '"nvidia,-dpaux", "nvidia,tegra124-dpaux"', where
- is tegra132.
+  - compatible : Should contain one of the following:
+- "nvidia,tegra124-dpaux": for Tegra124 and Tegra132
+- "nvidia,tegra210-dpaux": for Tegra210
   - reg: Physical base address and length of the controller's registers.
   - interrupts: The interrupt outputs from the controller.
   - clocks: Must contain an entry for each entry in clock-names.
-- 
2.1.4



[PATCH 03/12] drm/tegra: Add helper functions for setting up DPAUX pads

2016-06-23 Thread Jon Hunter
In preparation for adding pinctrl support for the DPAUX pads, add
helpers functions for configuring the pads and controlling the power
for the pads.

Please note that although a simple if-statement could be used instead
of a case statement for configuring the pads as there are only two
possible modes, a case statement is used because when integrating with
the pinctrl framework, we need to be able to handle invalid modes that
could be passed.

Signed-off-by: Jon Hunter 
---
 drivers/gpu/drm/tegra/dpaux.c | 81 +++
 1 file changed, 51 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 0874a7e5b37b..4014ec57ed31 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -267,6 +267,51 @@ static irqreturn_t tegra_dpaux_irq(int irq, void *data)
return ret;
 }

+static void tegra_dpaux_pad_power_down(struct tegra_dpaux *dpaux)
+{
+   u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
+
+   value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
+
+   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
+}
+
+static void tegra_dpaux_pad_power_up(struct tegra_dpaux *dpaux)
+{
+   u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
+
+   value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
+
+   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
+}
+
+static int tegra_dpaux_pad_config(struct tegra_dpaux *dpaux, unsigned function)
+{
+   u32 value;
+
+   switch (function) {
+   case DPAUX_HYBRID_PADCTL_MODE_AUX:
+   value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) |
+   DPAUX_HYBRID_PADCTL_AUX_DRVZ(4) |
+   DPAUX_HYBRID_PADCTL_AUX_DRVI(0x18) |
+   DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV |
+   DPAUX_HYBRID_PADCTL_MODE_AUX;
+   break;
+   case DPAUX_HYBRID_PADCTL_MODE_I2C:
+   value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV |
+   DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
+   DPAUX_HYBRID_PADCTL_MODE_I2C;
+   break;
+   default:
+   return -ENOTSUPP;
+   }
+
+   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL);
+   tegra_dpaux_pad_power_up(dpaux);
+
+   return 0;
+}
+
 static int tegra_dpaux_probe(struct platform_device *pdev)
 {
struct tegra_dpaux *dpaux;
@@ -372,15 +417,9 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 * is no possibility to perform the I2C mode configuration in the
 * HDMI path.
 */
-   value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
-   value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
-   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
-
-   value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_PADCTL);
-   value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV |
-   DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
-   DPAUX_HYBRID_PADCTL_MODE_I2C;
-   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL);
+   err = tegra_dpaux_pad_config(dpaux, DPAUX_HYBRID_PADCTL_MODE_I2C);
+   if (err < 0)
+   return err;

/* enable and clear all interrupts */
value = DPAUX_INTR_AUX_DONE | DPAUX_INTR_IRQ_EVENT |
@@ -408,12 +447,9 @@ assert_reset:
 static int tegra_dpaux_remove(struct platform_device *pdev)
 {
struct tegra_dpaux *dpaux = platform_get_drvdata(pdev);
-   u32 value;

/* make sure pads are powered down when not in use */
-   value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
-   value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
-   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
+   tegra_dpaux_pad_power_down(dpaux);

drm_dp_aux_unregister(>aux);

@@ -538,30 +574,15 @@ enum drm_connector_status drm_dp_aux_detect(struct 
drm_dp_aux *aux)
 int drm_dp_aux_enable(struct drm_dp_aux *aux)
 {
struct tegra_dpaux *dpaux = to_dpaux(aux);
-   u32 value;
-
-   value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) |
-   DPAUX_HYBRID_PADCTL_AUX_DRVZ(4) |
-   DPAUX_HYBRID_PADCTL_AUX_DRVI(0x18) |
-   DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV |
-   DPAUX_HYBRID_PADCTL_MODE_AUX;
-   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL);

-   value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
-   value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
-   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
-
-   return 0;
+   return tegra_dpaux_pad_config(dpaux, DPAUX_HYBRID_PADCTL_MODE_AUX);
 }

 int drm_dp_aux_disable(struct drm_dp_aux *aux)
 {
struct tegra_dpaux *dpaux = to_dpaux(aux);
-   u32 value;

-   value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
-   value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
-   tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
+   tegra_dpaux_pad_power_down(dpaux);

return 0;
 }
-- 

[PATCH 02/12] drm/tegra: Clean-up if probing DPAUX fails

2016-06-23 Thread Jon Hunter
If the probing of the DPAUX fails, then clocks are left enabled and the
DPAUX reset de-asserted. Add code to perform the necessary clean-up on
probe failure by disabling clocks and asserting the reset.

Signed-off-by: Jon Hunter 
---
 drivers/gpu/drm/tegra/dpaux.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index b24a0f14821a..0874a7e5b37b 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -321,28 +321,30 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
if (IS_ERR(dpaux->clk_parent)) {
dev_err(>dev, "failed to get parent clock: %ld\n",
PTR_ERR(dpaux->clk_parent));
-   return PTR_ERR(dpaux->clk_parent);
+   err = PTR_ERR(dpaux->clk_parent);
+   goto assert_reset;
}

err = clk_prepare_enable(dpaux->clk_parent);
if (err < 0) {
dev_err(>dev, "failed to enable parent clock: %d\n",
err);
-   return err;
+   goto assert_reset;
}

err = clk_set_rate(dpaux->clk_parent, 27000);
if (err < 0) {
dev_err(>dev, "failed to set clock to 270 MHz: %d\n",
err);
-   return err;
+   goto disable_parent_clk;
}

dpaux->vdd = devm_regulator_get(>dev, "vdd");
if (IS_ERR(dpaux->vdd)) {
dev_err(>dev, "failed to get VDD supply: %ld\n",
PTR_ERR(dpaux->vdd));
-   return PTR_ERR(dpaux->vdd);
+   err = PTR_ERR(dpaux->vdd);
+   goto disable_parent_clk;
}

err = devm_request_irq(dpaux->dev, dpaux->irq, tegra_dpaux_irq, 0,
@@ -350,7 +352,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
if (err < 0) {
dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
dpaux->irq, err);
-   return err;
+   goto disable_parent_clk;
}

disable_irq(dpaux->irq);
@@ -360,7 +362,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)

err = drm_dp_aux_register(>aux);
if (err < 0)
-   return err;
+   goto disable_parent_clk;

/*
 * Assume that by default the DPAUX/I2C pads will be used for HDMI,
@@ -393,6 +395,14 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dpaux);

return 0;
+
+disable_parent_clk:
+   clk_disable_unprepare(dpaux->clk_parent);
+assert_reset:
+   reset_control_assert(dpaux->rst);
+   clk_disable_unprepare(dpaux->clk);
+
+   return err;
 }

 static int tegra_dpaux_remove(struct platform_device *pdev)
-- 
2.1.4



[PATCH 01/12] soc/tegra: pmc: Initialise resets associated with a power partition

2016-06-23 Thread Jon Hunter
When registering the Tegra power partitions with the generic PM domain
framework, the current state of the each partition is checked and used
as the default state for the partition. However, the state of each reset
associated with the partition is not initialised and so it is possible
that the state of the resets are not in the expected state. For example,
if a partition is on, then the resets should be de-asserted and if the
partition is off, the resets should be asserted.

There have been cases where the bootloader has powered on a partition
and only de-asserted some of the resets to some of the devices in the
partition. This can cause accesses to these devices to hang the system
when the kernel boots and attempts to probe these devices.

Ideally, the driver for the device should ensure the reset has been
de-asserted when probing, but the resets cannot be shared between the
PMC driver (that needs to de-assert/assert the reset when turning the
partition on or off) and another driver because we cannot ensure the
reset is in the correct state.

To ensure the resets are in the correct state, when using the generic
PM domain framework, put each reset associated with the partition in
the correct state (based upon the partition's current state) when
obtaining the resets for a partition.

Signed-off-by: Jon Hunter 
---
 drivers/soc/tegra/pmc.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index d13516981629..8a421a0b1ece 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -738,7 +738,7 @@ err:
 }

 static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
-struct device_node *np)
+struct device_node *np, bool off)
 {
struct reset_control *rst;
unsigned int i, count;
@@ -758,6 +758,16 @@ static int tegra_powergate_of_get_resets(struct 
tegra_powergate *pg,
err = PTR_ERR(pg->resets[i]);
goto error;
}
+
+   if (off)
+   err = reset_control_assert(pg->resets[i]);
+   else
+   err = reset_control_deassert(pg->resets[i]);
+
+   if (err) {
+   reset_control_put(pg->resets[i]);
+   goto error;
+   }
}

pg->num_resets = count;
@@ -798,14 +808,14 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, 
struct device_node *np)
pg->genpd.power_on = tegra_genpd_power_on;
pg->pmc = pmc;

+   off = !tegra_powergate_is_powered(pg->id);
+
if (tegra_powergate_of_get_clks(pg, np))
goto set_available;

-   if (tegra_powergate_of_get_resets(pg, np))
+   if (tegra_powergate_of_get_resets(pg, np, off))
goto remove_clks;

-   off = !tegra_powergate_is_powered(pg->id);
-
pm_genpd_init(>genpd, NULL, off);

if (of_genpd_add_provider_simple(np, >genpd))
-- 
2.1.4



[PATCH 00/12] Add support for Tegra DPAUX pinctrl

2016-06-23 Thread Jon Hunter
The Display Port Auxiliary (DPAUX) channel pads can be shared with an
internal I2C controller. Add pinctrl support for these pads so that the
I2C controller can request and use these pads.

This series has been tested with Thierry's patches for correcting the
parent clock for the DPAUX devices [0].

Please note that I have kept the patch that adds the pinctrl function,
pinconf_generic_dt_free_map(), in this series for completeness, although
Linus W has already picked this up (as it is not in -next AFAICT yet).

Changes from initial RFC:
- Dropped patches for adding sor-safe clocks to DPAUX in favour of the
  patches from Thierry [0].
- Split the DPAUX function to enable the DPAUX pads into two functions:
  one for turning on and one for turning off the pads.
- Updated the description for the 'i2c-bus' node based upon Mark R's
  feedback.
- Dropped the second test if the i2c-core when checking for the presence
  of the 'i2c-bus' node based upon Thierry's feedback.
- Removed depedency on CONFIG_PINCTRL in the DPAUX driver in favour of
  using #ifdef's per Thierry's feedback (note by removing the dependency
  on CONFIG_PINCTRL I had to use #ifdefs as all the structures, function
  tables, and functions may not be defined).
- Updated SOR power partition device-tree node to include all clocks and
  resets as described in the Tegra210 TRM.

[0] http://marc.info/?l=linux-tegra=146667915802019=2

Jon Hunter (12):
  soc/tegra: pmc: Initialise resets associated with a power partition
  drm/tegra: Clean-up if probing DPAUX fails
  drm/tegra: Add helper functions for setting up DPAUX pads
  dt-bindings: display: Update Tegra DPAUX documentation
  drm/tegra: Prepare DPAUX for supporting generic PM domains
  pinctrl: pinconf: Add generic helper function for freeing mappings
  dt-bindings: i2c: Add support for 'i2c-bus' subnode
  i2c: core: Add support for 'i2c-bus' subnode
  dt-bindings: Add bindings for Tegra DPAUX pinctrl driver
  drm/tegra: Add pinctrl support for DPAUX
  arm64: tegra: Add SOR power-domain node
  arm64: tegra: Add DPAUX pinctrl bindings

 .../display/tegra/nvidia,tegra20-host1x.txt|  12 +-
 Documentation/devicetree/bindings/i2c/i2c.txt  |   8 +
 .../pinctrl/nvidia,tegra124-dpaux-padctl.txt   |  60 ++
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |  78 +++
 drivers/gpu/drm/tegra/dpaux.c  | 239 +
 drivers/i2c/i2c-core.c |  10 +-
 drivers/pinctrl/pinconf-generic.c  |   8 +
 drivers/soc/tegra/pmc.c|  18 +-
 include/linux/pinctrl/pinconf-generic.h|   2 +
 9 files changed, 383 insertions(+), 52 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt

-- 
2.1.4



Precise vblank timestamping for VC4 kms.

2016-06-23 Thread Ville Syrjälä
On Thu, Jun 23, 2016 at 08:17:49AM +0200, Mario Kleiner wrote:
> The following patch implements precise vblank timestamping
> for RaspberryPi's VC4, at least for standard progressive
> scan display modes.
> 
> It has been tested on the HDMI output with half a dozen different
> video modes using special hardware measurement equipment to compare
> generated time stamps against reality. According to the tests it
> works well in its current form.
> 
> Due to hw limitations of the VC4, timestamps can't be scanline
> accurate when taken within vblank, as explained in the patch,
> but at least they will never be off by more than 1 vblank
> duration, and are typically still accurate to ~0.1 msecs
> for the common case when the timestamping is triggered from
> vblank interrupt.
> 
> The patch exposed some problems with how the drm core handles
> calculation of vblank timestamping constants for interlaced
> video modes in drm_calc_timestamping_constants(). Seems it cuts
> the expected frame duration framedur_ns into half for interlaced
> modes two times, so it ends up expecting a field duration half
> of what it should be and then miscalculates vblank counter increments
> as soon as vblank timestamping is supported and the core tries to
> derive vblank counts from it. To work around this bug, for the
> moment the vblank timestamping will disable itself for interlaced
> modes and only work for regular progressive scan.

The code should be correct for i915. The framedur_ns is actually the
duration of a single field (since we get a vblank interrupt for each
field). But it's going to be wrong for anyone that populates the
crtc_ timings with CRTC_INTERLACE_HALVE_V. So to fix it, you'd need
the driver to tell drm_calc_timestamping_constants() whether the
vertical timings were already halved or not.

-- 
Ville Syrjälä
Intel OTC


[Intel-gfx] Bad flicker on skylake HQD due to code in the 4.7 merge window

2016-06-23 Thread Jani Nikula
On Thu, 23 Jun 2016, Steven Newbury  wrote:
> [ Unknown signature status ]
> On Sun, 2016-06-19 at 14:53 -0700, James Bottomley wrote:
>> On Fri, 2016-06-17 at 16:06 -0700, James Bottomley wrote:
>> > On Fri, 2016-06-17 at 16:34 +0300, Jani Nikula wrote:
>> > > On Fri, 17 Jun 2016, Daniel Vetter  wrote:
>> > > > On Thu, Jun 16, 2016 at 03:42:12PM -0700, James Bottomley
>> > > > wrote:
>> > > > > On Thu, 2016-06-16 at 14:29 -0700, James Bottomley wrote:
>> > > > > > On Thu, 2016-06-16 at 23:24 +0200, Daniel Vetter wrote:
>> > > > > > > I guess we'll need the bisect on this one to make
>> > > > > > > progress.
>> > > > > > 
>> > > > > > Sigh, I was afraid that might be the next step.
>> > > > > 
>> > > > > OK, I have a curious data point.  I assumed the problem would
>> > > > > be
>> > > > > somewhere in the drm update, so I started bisecting that at
>> > > > > the
>> > > > > top. 
>> > > > >  However, the top most commit:
>> > > > > 
>> > > > > commit 1d6da87a3241deb13d073c4125d19ed0e5a0c62c
>> > > > > Merge: 1f40c49 a39ed68
>> > > > > Author: Linus Torvalds 
>> > > > > Date:   Mon May 23 11:48:48 2016 -0700
>> > > > > 
>> > > > >     Merge branch 'drm-next' of
>> > > > > git://people.freedesktop.org/~airlied/linux
>> > > > > 
>> > > > > Isn't actually bad.  There's no flicker here, so whatever
>> > > > > caused
>> > > > > the
>> > > > > problem came from some update after this.
>> > > > 
>> > > > There was a fixes pull after this. Might be worth it to
>> > > > restrict
>> > > > to
>> > > > just
>> > > > the i915 changes, which are just
>> > > > 5b4fd5bb1230cd037..157d2c7fad0863222
>> > > > 
>> > > > Looking at those nothing seems to stick out which might explain
>> > > > what's
>> > > > happening for you.
>> > 
>> > OK, so just on the firmware, the system seems less flickery with
>> > the
>> > new 1.4.3 UEFI, so I'm starting to think it is a Skylake errata 
>> > issue.  The flicker isn't gone for good, but seems to be reboot 
>> > dependent (it's there in some boots, but gone on a reboot).
>> > 
>> > > This should be easy enough to try before bisecting:
>> > > http://patchwork.freedesktop.org/patch/msgid/1466162081-12042-1-g
>> > > it
>> > > -s
>> > > end-email-mika.kahola at intel.com
>> > 
>> > Applying this didn't seem to make a difference: still there on
>> > some 
>> > and gone on other reboots.
>> 
>> OK, my candidate bad commit is this one:
>> 
>> commit a05628195a0d9f3173dd9aa76f482aef692e46ee
>> Author: Ville Syrjälä 
>> Date:   Mon Apr 11 10:23:51 2016 +0300
>> 
>>     drm/i915: Get panel_type from OpRegion panel details
>> 
>> After being more careful about waiting to identify flicker, this one
>> seems to be the one the bisect finds.  I'm now running v4.7-rc3 with
>> this one reverted and am currently seeing no flicker problems.  It
>> is,
>> however, early days because the flicker can hide for long periods, so
>> I
>> 'll wait until Monday evening and a few reboots before declaring
>> victory.
>> 
>> 
> I'm seeing this on my IvyBridge.  I'll try reverting the commit here
> too, to see if it's the same issue.

IvyBridge doesn't have low vswing for eDP. If reverting helps, it's a
different failure mode.

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Technology Center


[Intel-gfx] [PATCH] drm/atomic: Make drm_atomic_legacy_backoff reset crtc->acquire_ctx

2016-06-23 Thread Daniel Vetter
On Thu, Jun 23, 2016 at 01:45:06PM +0200, Maarten Lankhorst wrote:
> Atomic updates may acquire more state than initially locked through
> drm_modeset_lock_crtc, running with heavy stress can cause a
> WARN_ON(crtc->acquire_ctx) in drm_modeset_lock_crtc:
> 
> [  601.491296] [ cut here ]
> [  601.491366] WARNING: CPU: 0 PID: 2411 at
> drivers/gpu/drm/drm_modeset_lock.c:191 drm_modeset_lock_crtc+0xeb/0xf0 [drm]
> [  601.491369] Modules linked in: drm i915 drm_kms_helper
> [  601.491414] CPU: 0 PID: 2411 Comm: kms_cursor_lega Tainted: G U 
> 4.7.0-rc4-patser+ #4798
> [  601.491417] Hardware name: Intel Corporation Skylake Client
> [  601.491420]   88044d153c98 812ead28 
> 
> [  601.491425]   88044d153cd8 810868e6 
> 00bf58058030
> [  601.491431]  880088b415e8 880458058030 88008a271548 
> 88008a271568
> [  601.491436] Call Trace:
> [  601.491443]  [] dump_stack+0x4d/0x65
> [  601.491447]  [] __warn+0xc6/0xe0
> [  601.491452]  [] warn_slowpath_null+0x18/0x20
> [  601.491472]  [] drm_modeset_lock_crtc+0xeb/0xf0 [drm]
> [  601.491491]  [] drm_mode_cursor_common+0x66/0x180 [drm]
> [  601.491509]  [] drm_mode_cursor_ioctl+0x3c/0x40 [drm]
> [  601.491524]  [] drm_ioctl+0x14d/0x530 [drm]
> [  601.491540]  [] ? drm_mode_setcrtc+0x520/0x520 [drm]
> [  601.491545]  [] ? handle_mm_fault+0x106b/0x1430
> [  601.491550]  [] ? stop_one_cpu+0x61/0x70
> [  601.491556]  [] do_vfs_ioctl+0x8d/0x570
> [  601.491560]  [] ? security_file_ioctl+0x3e/0x60
> [  601.491565]  [] SyS_ioctl+0x74/0x80
> [  601.491571]  [] ? posix_get_monotonic_raw+0xc/0x10
> [  601.491576]  [] entry_SYSCALL_64_fastpath+0x13/0x8f
> [  601.491581] ---[ end trace 56f3d3d85f000d00 ]---
> 
> For good measure, test mode_config.acquire_ctx too, although this should
> never happen.
> 
> Testcase: kms_cursor_legacy
> Signed-off-by: Maarten Lankhorst 

It's kinda a bug in the skl wm code which unecessarily looks at other
plane state.

Reviewed-by: Daniel Vetter 

Given that this is fairly hard to hit, but will blow in really strange
ways in practice I think also justified for backporting.

Cc: stable at vger.kernel.org

Dave, can you pls pick up for -fixes directly?

Thanks, Daniel

> ---
>  drivers/gpu/drm/drm_atomic.c | 27 ++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index d99ab2f6663f..3cee084e9d28 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1299,14 +1299,39 @@ EXPORT_SYMBOL(drm_atomic_add_affected_planes);
>   */
>  void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
>  {
> + struct drm_device *dev = state->dev;
> + unsigned crtc_mask = 0;
> + struct drm_crtc *crtc;
>   int ret;
> + bool global = false;
> +
> + drm_for_each_crtc(crtc, dev) {
> + if (crtc->acquire_ctx != state->acquire_ctx)
> + continue;
> +
> + crtc_mask |= drm_crtc_mask(crtc);
> + crtc->acquire_ctx = NULL;
> + }
> +
> + if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
> + global = true;
> +
> + dev->mode_config.acquire_ctx = NULL;
> + }
>  
>  retry:
>   drm_modeset_backoff(state->acquire_ctx);
>  
> - ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
> + ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
>   if (ret)
>   goto retry;
> +
> + drm_for_each_crtc(crtc, dev)
> + if (drm_crtc_mask(crtc) & crtc_mask)
> + crtc->acquire_ctx = state->acquire_ctx;
> +
> + if (global)
> + dev->mode_config.acquire_ctx = state->acquire_ctx;
>  }
>  EXPORT_SYMBOL(drm_atomic_legacy_backoff);
>  
> -- 
> 2.5.5
> 
> ___
> 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 3/3] drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)

2016-06-23 Thread Chris Wilson
vGEM buffers are useful for passing data between software clients and
hardware renders. By allowing the user to create and attach fences to
the exported vGEM buffers (on the dma-buf), the user can implement a
deferred renderer and queue hardware operations like flipping and then
signal the buffer readiness (i.e. this allows the user to schedule
operations out-of-order, but have them complete in-order).

This also makes it much easier to write tightly controlled testcases for
dma-buf fencing and signaling between hardware drivers.

Testcase: igt/vgem_basic/dmabuf-fence
Signed-off-by: Chris Wilson 
Cc: Sean Paul 
Cc: Zach Reizner 
---
 drivers/gpu/drm/vgem/Makefile |   2 +-
 drivers/gpu/drm/vgem/vgem_drv.c   |  34 ++
 drivers/gpu/drm/vgem/vgem_drv.h   |  18 
 drivers/gpu/drm/vgem/vgem_fence.c | 217 ++
 include/uapi/drm/vgem_drm.h   |  62 +++
 5 files changed, 332 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/vgem/vgem_fence.c
 create mode 100644 include/uapi/drm/vgem_drm.h

diff --git a/drivers/gpu/drm/vgem/Makefile b/drivers/gpu/drm/vgem/Makefile
index 3f4c7b842028..bfcdea1330e6 100644
--- a/drivers/gpu/drm/vgem/Makefile
+++ b/drivers/gpu/drm/vgem/Makefile
@@ -1,4 +1,4 @@
 ccflags-y := -Iinclude/drm
-vgem-y := vgem_drv.o
+vgem-y := vgem_drv.o vgem_fence.o

 obj-$(CONFIG_DRM_VGEM) += vgem.o
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 69468b5f3d82..56e348701382 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -83,6 +83,34 @@ static const struct vm_operations_struct vgem_gem_vm_ops = {
.close = drm_gem_vm_close,
 };

+static int vgem_open(struct drm_device *dev, struct drm_file *file)
+{
+   struct vgem_file *vfile;
+   int ret;
+
+   vfile = kzalloc(sizeof(*vfile), GFP_KERNEL);
+   if (!vfile)
+   return -ENOMEM;
+
+   file->driver_priv = vfile;
+
+   ret = vgem_fence_open(vfile);
+   if (ret) {
+   kfree(vfile);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void vgem_preclose(struct drm_device *dev, struct drm_file *file)
+{
+   struct vgem_file *vfile = file->driver_priv;
+
+   vgem_fence_close(vfile);
+   kfree(vfile);
+}
+
 /* ioctls */

 static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
@@ -164,6 +192,8 @@ unref:
 }

 static struct drm_ioctl_desc vgem_ioctls[] = {
+   DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW),
 };

 static int vgem_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -286,9 +316,12 @@ static int vgem_prime_mmap(struct drm_gem_object *obj,

 static struct drm_driver vgem_driver = {
.driver_features= DRIVER_GEM | DRIVER_PRIME,
+   .open   = vgem_open,
+   .preclose   = vgem_preclose,
.gem_free_object_unlocked   = vgem_gem_free_object,
.gem_vm_ops = _gem_vm_ops,
.ioctls = vgem_ioctls,
+   .num_ioctls = ARRAY_SIZE(vgem_ioctls),
.fops   = _driver_fops,

.dumb_create= vgem_gem_dumb_create,
@@ -343,5 +376,6 @@ module_init(vgem_init);
 module_exit(vgem_exit);

 MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_AUTHOR("Intel Corporation");
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h
index 988cbaae7588..88ce21010e28 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.h
+++ b/drivers/gpu/drm/vgem/vgem_drv.h
@@ -32,9 +32,27 @@
 #include 
 #include 

+#include 
+
+struct vgem_file {
+   struct idr fence_idr;
+   struct mutex fence_mutex;
+   u64 fence_context;
+   atomic_t fence_seqno;
+};
+
 #define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base)
 struct drm_vgem_gem_object {
struct drm_gem_object base;
 };

+int vgem_fence_open(struct vgem_file *file);
+int vgem_fence_attach_ioctl(struct drm_device *dev,
+   void *data,
+   struct drm_file *file);
+int vgem_fence_signal_ioctl(struct drm_device *dev,
+   void *data,
+   struct drm_file *file);
+void vgem_fence_close(struct vgem_file *file);
+
 #endif
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c 
b/drivers/gpu/drm/vgem/vgem_fence.c
new file mode 100644
index ..46130e4a3506
--- /dev/null
+++ b/drivers/gpu/drm/vgem/vgem_fence.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software")
+ * to deal in the 

[PATCH 2/3] drm/vgem: Enable dmabuf interface for export

2016-06-23 Thread Chris Wilson
Enable the standard GEM dma-buf interface provided by the DRM core, but
only for exporting the VGEM object. This allows passing around the VGEM
objects created from the dumb interface and using them as sources
elsewhere. Creating a VGEM object for a foriegn handle is not supported.

v2: With additional completeness.
v3: Need to clear the CPU cache upon exporting the dma-addresses.
v4: Use drm_gem_put_pages() as well.

Testcase: igt/vgem_basic/dmabuf-*
Testcase: igt/prime_vgem
Signed-off-by: Chris Wilson 
Cc: Sean Paul 
Cc: Zach Reizner 
---
 drivers/gpu/drm/vgem/vgem_drv.c | 104 +++-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index c161b6d7e427..69468b5f3d82 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -192,14 +192,116 @@ static const struct file_operations vgem_driver_fops = {
.release= drm_release,
 };

+static int vgem_prime_pin(struct drm_gem_object *obj)
+{
+   long n_pages = obj->size >> PAGE_SHIFT;
+   struct page **pages;
+
+   /* Flush the object from the CPU cache so that importers can rely
+* on coherent indirect access via the exported dma-address.
+*/
+   pages = drm_gem_get_pages(obj);
+   if (IS_ERR(pages))
+   return PTR_ERR(pages);
+
+   drm_clflush_pages(pages, n_pages);
+   drm_gem_put_pages(obj, pages, true, false);
+
+   return 0;
+}
+
+static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+   long n_pages = obj->size >> PAGE_SHIFT;
+   struct sg_table *st;
+   struct page **pages;
+   int ret;
+
+   st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+   if (st == NULL)
+   return ERR_PTR(-ENOMEM);
+
+   pages = drm_gem_get_pages(obj);
+   if (IS_ERR(pages)) {
+   ret = PTR_ERR(pages);
+   goto err;
+   }
+
+   ret = sg_alloc_table_from_pages(st, pages, n_pages,
+   0, obj->size, GFP_KERNEL);
+   drm_gem_put_pages(obj, pages, false, false);
+   if (ret)
+   goto err;
+
+   return st;
+
+err:
+   kfree(st);
+   return ERR_PTR(ret);
+}
+
+static void *vgem_prime_vmap(struct drm_gem_object *obj)
+{
+   long n_pages = obj->size >> PAGE_SHIFT;
+   struct page **pages;
+   void *addr;
+
+   pages = drm_gem_get_pages(obj);
+   if (IS_ERR(pages))
+   return NULL;
+
+   addr = vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL_IO));
+   drm_gem_put_pages(obj, pages, false, false);
+
+   return addr;
+}
+
+static void vgem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+   vunmap(vaddr);
+}
+
+static int vgem_prime_mmap(struct drm_gem_object *obj,
+  struct vm_area_struct *vma)
+{
+   int ret;
+
+   if (obj->size < vma->vm_end - vma->vm_start)
+   return -EINVAL;
+
+   if (!obj->filp)
+   return -ENODEV;
+
+   ret = obj->filp->f_op->mmap(obj->filp, vma);
+   if (ret)
+   return ret;
+
+   fput(vma->vm_file);
+   vma->vm_file = get_file(obj->filp);
+   vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+   vma->vm_page_prot = 
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+
+   return 0;
+}
+
 static struct drm_driver vgem_driver = {
-   .driver_features= DRIVER_GEM,
+   .driver_features= DRIVER_GEM | DRIVER_PRIME,
.gem_free_object_unlocked   = vgem_gem_free_object,
.gem_vm_ops = _gem_vm_ops,
.ioctls = vgem_ioctls,
.fops   = _driver_fops,
+
.dumb_create= vgem_gem_dumb_create,
.dumb_map_offset= vgem_gem_dumb_map,
+
+   .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+   .gem_prime_pin = vgem_prime_pin,
+   .gem_prime_export = drm_gem_prime_export,
+   .gem_prime_get_sg_table = vgem_prime_get_sg_table,
+   .gem_prime_vmap = vgem_prime_vmap,
+   .gem_prime_vunmap = vgem_prime_vunmap,
+   .gem_prime_mmap = vgem_prime_mmap,
+
.name   = DRIVER_NAME,
.desc   = DRIVER_DESC,
.date   = DRIVER_DATE,
-- 
2.8.1



[PATCH 1/3] drm/vgem: Fix mmaping

2016-06-23 Thread Chris Wilson
The vGEM mmap code has bitrotted slightly and now immediately BUGs.
Since vGEM was last updated, there are new core GEM facilities to
provide more common functions, so let's use those here.

v2: drm_gem_free_mmap_offset() is performed from
drm_gem_object_release() so we can remove the redundant call.

Testcase: igt/vgem_basic/mmap
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96603
Signed-off-by: Chris Wilson 
Cc: Sean Paul 
Cc: Zach Reizner 
Cc: Matthew Auld 
Tested-by: Humberto Israel Perez Rodriguez 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/vgem/vgem_drv.c | 164 +++-
 drivers/gpu/drm/vgem/vgem_drv.h |   6 --
 2 files changed, 61 insertions(+), 109 deletions(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 35ea5d02a827..c161b6d7e427 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -42,81 +42,38 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0

-void vgem_gem_put_pages(struct drm_vgem_gem_object *obj)
-{
-   drm_gem_put_pages(>base, obj->pages, false, false);
-   obj->pages = NULL;
-}
-
 static void vgem_gem_free_object(struct drm_gem_object *obj)
 {
struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj);

-   drm_gem_free_mmap_offset(obj);
-
-   if (vgem_obj->use_dma_buf && obj->dma_buf) {
-   dma_buf_put(obj->dma_buf);
-   obj->dma_buf = NULL;
-   }
-
drm_gem_object_release(obj);
-
-   if (vgem_obj->pages)
-   vgem_gem_put_pages(vgem_obj);
-
-   vgem_obj->pages = NULL;
-
kfree(vgem_obj);
 }

-int vgem_gem_get_pages(struct drm_vgem_gem_object *obj)
-{
-   struct page **pages;
-
-   if (obj->pages || obj->use_dma_buf)
-   return 0;
-
-   pages = drm_gem_get_pages(>base);
-   if (IS_ERR(pages)) {
-   return PTR_ERR(pages);
-   }
-
-   obj->pages = pages;
-
-   return 0;
-}
-
 static int vgem_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
struct drm_vgem_gem_object *obj = vma->vm_private_data;
-   loff_t num_pages;
-   pgoff_t page_offset;
-   int ret;
-
/* We don't use vmf->pgoff since that has the fake offset */
-   page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >>
-   PAGE_SHIFT;
-
-   num_pages = DIV_ROUND_UP(obj->base.size, PAGE_SIZE);
-
-   if (page_offset > num_pages)
-   return VM_FAULT_SIGBUS;
-
-   ret = vm_insert_page(vma, (unsigned long)vmf->virtual_address,
-obj->pages[page_offset]);
-   switch (ret) {
-   case 0:
-   return VM_FAULT_NOPAGE;
-   case -ENOMEM:
-   return VM_FAULT_OOM;
-   case -EBUSY:
-   return VM_FAULT_RETRY;
-   case -EFAULT:
-   case -EINVAL:
-   return VM_FAULT_SIGBUS;
-   default:
-   WARN_ON(1);
-   return VM_FAULT_SIGBUS;
+   unsigned long vaddr = (unsigned long)vmf->virtual_address;
+   struct page *page;
+
+   page = shmem_read_mapping_page(file_inode(obj->base.filp)->i_mapping,
+  (vaddr - vma->vm_start) >> PAGE_SHIFT);
+   if (!IS_ERR(page)) {
+   vmf->page = page;
+   return 0;
+   } else switch (PTR_ERR(page)) {
+   case -ENOSPC:
+   case -ENOMEM:
+   return VM_FAULT_OOM;
+   case -EBUSY:
+   return VM_FAULT_RETRY;
+   case -EFAULT:
+   case -EINVAL:
+   return VM_FAULT_SIGBUS;
+   default:
+   WARN_ON_ONCE(PTR_ERR(page));
+   return VM_FAULT_SIGBUS;
}
 }

@@ -134,57 +91,43 @@ static struct drm_gem_object *vgem_gem_create(struct 
drm_device *dev,
  unsigned long size)
 {
struct drm_vgem_gem_object *obj;
-   struct drm_gem_object *gem_object;
-   int err;
-
-   size = roundup(size, PAGE_SIZE);
+   int ret;

obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (!obj)
return ERR_PTR(-ENOMEM);

-   gem_object = >base;
-
-   err = drm_gem_object_init(dev, gem_object, size);
-   if (err)
-   goto out;
-
-   err = vgem_gem_get_pages(obj);
-   if (err)
-   goto out;
-
-   err = drm_gem_handle_create(file, gem_object, handle);
-   if (err)
-   goto handle_out;
+   ret = drm_gem_object_init(dev, >base, roundup(size, PAGE_SIZE));
+   if (ret)
+   goto err_free;

-   drm_gem_object_unreference_unlocked(gem_object);
+   ret = drm_gem_handle_create(file, >base, handle);
+   drm_gem_object_unreference_unlocked(>base);
+   if (ret)
+   goto err;

-   return gem_object;
+   return >base;

-handle_out:
-   

[Bug 96625] GPU lockup when using r600g VDPAU on powerpc

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

--- Comment #10 from Alex Deucher  ---
(In reply to Rui Salvaterra from comment #9)
> (In reply to Christian König from comment #3)
> > Well feel free to provide patches. The relevant source is in
> > src/gallium/drivers/radeon/radeon_uvd.c.
> > 
> > Probably all the 32 and 16 bit fields set into the message and feedback
> > buffer in get_h264_msg(), get_h265_msg(), get_vc1_msg(), get_mpeg2_msg(),
> > get_mpeg4_msg() and ruvd_end_frame() needs to be byte swapped.
> > 
> > It should actually be pretty trivial to do so, it's just a huge bunch of
> > work nobody so far has time to work on.
> 
> Hi, Christian,
> 
> I'm not at all familiar with the Mesa codebase, but doesn't it provide
> arch-specific endian helpers, akin to the Linux kernel ({b,l}e_to_cpu and
> friends)? If not, maybe it would be an interesting GSoC project, assuming
> such patches were accepted?

Yes, endian swap helpers exist in mesa.

-- 
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/20160623/e7ecfd16/attachment.html>


[PATCH v4 1/4] drm: add generic zpos property

2016-06-23 Thread Benjamin Gaignard
2016-06-22 1:45 GMT+02:00 Laurent Pinchart :
> Hi Benjamin,
>
> Thank you for the patch.
>
> Could you please reply to Ville's comment to v1 of this patch (posted on April
> the 25th) ?
>

For each iteration of the patches we have swap between two solutions:
- have normalization done between 0 to N-1 without taking care of zpos
property range
- take care of zpos property range while computing normalized zpos

First the solution is the most simple and the more robust so I will
definitively go for it.

[snip]
>> + sort(states, n, sizeof(*states), drm_atomic_state_zpos_cmp, NULL);
>> +
>> + for (i = 0, zpos = 0; i < n; i++, zpos++) {
>> + plane = states[i]->plane;
>> +
>> + zpos = max_t(int, zpos, states[i]->zpos);
>> +
>> + WARN_ON(zpos > plane->zpos_property->values[1]);
>
> This crashes if the plane doesn't have a zpos property. The simplest fix is to
> write the check as
>
> WARN_ON(plane->zpos_property &&
> zpos > plane->zpos_property->values[1]);

Thanks I will add that in v5

> but I wonder how we should handle drivers that instantiate a zpos property for
> a subdev of the planes only. For drivers that don't use zpos at all you could
> maybe avoid calling this function.
>

I think it will be difficult to mix planes with and without zpos property.
My suggestion is to use immutable zpos property for primary and cursor plane.
drm_atomic_helper_crtc_normalize_zpos() is only called if plane zpos
value change
so if driver don't use it normalization will not be done.

> Additionally, this check is triggered with the rcar-du-drm driver when
> performing the following operations:
>
> - Perform a mode set with the CRTC primary plane only (that plane doesn't have
> a zpos property)
>
> - Add 7 overlay planes with zpos values 1 to 7 (their zpos property range is
> 1-7)
>
> - Modify the zpos value of all overlay planes one by one to 7 to 1 (setting
> zpos 7 for plane 1 first, then zpos 6 for plane 2, ...)
>
> I get normalized zpos values such as
>
> [   84.892927] [PLANE:39:plane-8] normalized zpos value 9
> [   85.899284] [PLANE:25:plane-0] normalized zpos value 0
> [   85.904488] [PLANE:37:plane-7] normalized zpos value 2
> [   85.909633] [PLANE:35:plane-6] normalized zpos value 3
> [   85.914793] [PLANE:33:plane-5] normalized zpos value 4
> [   85.919936] [PLANE:31:plane-4] normalized zpos value 5
> [   85.925100] [PLANE:29:plane-3] normalized zpos value 6
> [   85.930245] [PLANE:27:plane-2] normalized zpos value 7
>
> (plane 25 is the primary plane, all other planes are the overlay planes, added
> in the order 27, 29, 31, 33, 35, 37, 37 in the sequence above)
>
I'm not able to reproduce you problem on my setup with one primary and
two overlay.
When back to 0 to N-1 normalization algo you should see the problem anymore

[snip]
> --
> Regards,
>
> Laurent Pinchart
>



-- 
Benjamin Gaignard

Graphic Working Group

Linaro.org │ Open source software for ARM SoCs

Follow Linaro: Facebook | Twitter | Blog


[Bug 96625] GPU lockup when using r600g VDPAU on powerpc

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

--- Comment #9 from Rui Salvaterra  ---
(In reply to Christian König from comment #3)
> Well feel free to provide patches. The relevant source is in
> src/gallium/drivers/radeon/radeon_uvd.c.
> 
> Probably all the 32 and 16 bit fields set into the message and feedback
> buffer in get_h264_msg(), get_h265_msg(), get_vc1_msg(), get_mpeg2_msg(),
> get_mpeg4_msg() and ruvd_end_frame() needs to be byte swapped.
> 
> It should actually be pretty trivial to do so, it's just a huge bunch of
> work nobody so far has time to work on.

Hi, Christian,

I'm not at all familiar with the Mesa codebase, but doesn't it provide
arch-specific endian helpers, akin to the Linux kernel ({b,l}e_to_cpu and
friends)? If not, maybe it would be an interesting GSoC project, assuming such
patches were accepted?

Best regards,

Rui

-- 
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/20160623/96be1485/attachment.html>


[Intel-gfx] Bad flicker on skylake HQD due to code in the 4.7 merge window

2016-06-23 Thread Steven Newbury
On Thu, 2016-06-23 at 15:59 +0300, Jani Nikula wrote:
> On Thu, 23 Jun 2016, Steven Newbury  wrote:
> > [ Unknown signature status ]
> > On Sun, 2016-06-19 at 14:53 -0700, James Bottomley wrote:
> > > On Fri, 2016-06-17 at 16:06 -0700, James Bottomley wrote:
> > > > On Fri, 2016-06-17 at 16:34 +0300, Jani Nikula wrote:
> > > > > On Fri, 17 Jun 2016, Daniel Vetter  wrote:
> > > > > > On Thu, Jun 16, 2016 at 03:42:12PM -0700, James Bottomley
> > > > > > wrote:
> > > > > > > On Thu, 2016-06-16 at 14:29 -0700, James Bottomley wrote:
> > > > > > > > On Thu, 2016-06-16 at 23:24 +0200, Daniel Vetter wrote:
> > > > > > > > > I guess we'll need the bisect on this one to make
> > > > > > > > > progress.
> > > > > > > > 
> > > > > > > > Sigh, I was afraid that might be the next step.
> > > > > > > 
> > > > > > > OK, I have a curious data point.  I assumed the problem
> > > > > > > would
> > > > > > > be
> > > > > > > somewhere in the drm update, so I started bisecting that
> > > > > > > at
> > > > > > > the
> > > > > > > top. 
> > > > > > >  However, the top most commit:
> > > > > > > 
> > > > > > > commit 1d6da87a3241deb13d073c4125d19ed0e5a0c62c
> > > > > > > Merge: 1f40c49 a39ed68
> > > > > > > Author: Linus Torvalds 
> > > > > > > Date:   Mon May 23 11:48:48 2016 -0700
> > > > > > > 
> > > > > > >     Merge branch 'drm-next' of
> > > > > > > git://people.freedesktop.org/~airlied/linux
> > > > > > > 
> > > > > > > Isn't actually bad.  There's no flicker here, so whatever
> > > > > > > caused
> > > > > > > the
> > > > > > > problem came from some update after this.
> > > > > > 
> > > > > > There was a fixes pull after this. Might be worth it to
> > > > > > restrict
> > > > > > to
> > > > > > just
> > > > > > the i915 changes, which are just
> > > > > > 5b4fd5bb1230cd037..157d2c7fad0863222
> > > > > > 
> > > > > > Looking at those nothing seems to stick out which might
> > > > > > explain
> > > > > > what's
> > > > > > happening for you.
> > > > 
> > > > OK, so just on the firmware, the system seems less flickery
> > > > with
> > > > the
> > > > new 1.4.3 UEFI, so I'm starting to think it is a Skylake
> > > > errata 
> > > > issue.  The flicker isn't gone for good, but seems to be
> > > > reboot 
> > > > dependent (it's there in some boots, but gone on a reboot).
> > > > 
> > > > > This should be easy enough to try before bisecting:
> > > > > http://patchwork.freedesktop.org/patch/msgid/1466162081-12042
> > > > > -1-g
> > > > > it
> > > > > -s
> > > > > end-email-mika.kahola at intel.com
> > > > 
> > > > Applying this didn't seem to make a difference: still there on
> > > > some 
> > > > and gone on other reboots.
> > > 
> > > OK, my candidate bad commit is this one:
> > > 
> > > commit a05628195a0d9f3173dd9aa76f482aef692e46ee
> > > Author: Ville Syrjälä 
> > > Date:   Mon Apr 11 10:23:51 2016 +0300
> > > 
> > >     drm/i915: Get panel_type from OpRegion panel details
> > > 
> > > After being more careful about waiting to identify flicker, this
> > > one
> > > seems to be the one the bisect finds.  I'm now running v4.7-rc3
> > > with
> > > this one reverted and am currently seeing no flicker
> > > problems.  It
> > > is,
> > > however, early days because the flicker can hide for long
> > > periods, so
> > > I
> > > 'll wait until Monday evening and a few reboots before declaring
> > > victory.
> > > 
> > >  
> > I'm seeing this on my IvyBridge.  I'll try reverting the commit
> > here
> > too, to see if it's the same issue.
> 
> IvyBridge doesn't have low vswing for eDP. If reverting helps, it's a
> different failure mode.
> 
It must be something else then.  Actually, in my case linus/master is
okay.  I saw the subject and though it must be the same issue.  I'm
seeing it with drm-intel nightly/next branches.  Shall I try to bisect
it?  Symptoms are similar, although I would describe it more like
flashes of a different buffer across parts of the screen.


-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: This is a digitally signed message part
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160623/1f99b976/attachment.sig>


[RFC PATCH] drm/nouveau/fb/nv50: set DMA mask before mapping scratch page

2016-06-23 Thread Punit Agrawal
Ard Biesheuvel  writes:

> On 23 June 2016 at 11:55, Punit Agrawal  wrote:
>> Ard Biesheuvel  writes:
>>
>>> The 100c08 scratch page is mapped using dma_map_page() before the TTM
>>> layer has had a chance to set the DMA mask. This means we are still
>>> running with the default of 32 when this code executes, and this causes
>>> problems for platforms with no memory below 4 GB (such as AMD Seattle)
>>>
>>> So move the dma_map_page() to the .init hook, and set the streaming DMA
>>> mask based on the MMU subdev parameters before performing the call.
>>>
>>> Signed-off-by: Ard Biesheuvel 
>>
>> Hi Ard,
>>
>> Thanks for posting this patch.
>>
>> With the patch, I am able to see console output on a screen attached to
>> the NVS 300 PCIe card in an AMD Seattle system. It was failing with
>> a message similar to what you've posted below.
>>
>
> Thanks for the report. May I take it as a tested-by?

Sure.

Punit


[...]



[Intel-gfx] Bad flicker on skylake HQD due to code in the 4.7 merge window

2016-06-23 Thread Steven Newbury
On Sun, 2016-06-19 at 14:53 -0700, James Bottomley wrote:
> On Fri, 2016-06-17 at 16:06 -0700, James Bottomley wrote:
> > On Fri, 2016-06-17 at 16:34 +0300, Jani Nikula wrote:
> > > On Fri, 17 Jun 2016, Daniel Vetter  wrote:
> > > > On Thu, Jun 16, 2016 at 03:42:12PM -0700, James Bottomley
> > > > wrote:
> > > > > On Thu, 2016-06-16 at 14:29 -0700, James Bottomley wrote:
> > > > > > On Thu, 2016-06-16 at 23:24 +0200, Daniel Vetter wrote:
> > > > > > > I guess we'll need the bisect on this one to make
> > > > > > > progress.
> > > > > > 
> > > > > > Sigh, I was afraid that might be the next step.
> > > > > 
> > > > > OK, I have a curious data point.  I assumed the problem would
> > > > > be
> > > > > somewhere in the drm update, so I started bisecting that at
> > > > > the
> > > > > top. 
> > > > >  However, the top most commit:
> > > > > 
> > > > > commit 1d6da87a3241deb13d073c4125d19ed0e5a0c62c
> > > > > Merge: 1f40c49 a39ed68
> > > > > Author: Linus Torvalds 
> > > > > Date:   Mon May 23 11:48:48 2016 -0700
> > > > > 
> > > > >     Merge branch 'drm-next' of
> > > > > git://people.freedesktop.org/~airlied/linux
> > > > > 
> > > > > Isn't actually bad.  There's no flicker here, so whatever
> > > > > caused
> > > > > the
> > > > > problem came from some update after this.
> > > > 
> > > > There was a fixes pull after this. Might be worth it to
> > > > restrict
> > > > to
> > > > just
> > > > the i915 changes, which are just
> > > > 5b4fd5bb1230cd037..157d2c7fad0863222
> > > > 
> > > > Looking at those nothing seems to stick out which might explain
> > > > what's
> > > > happening for you.
> > 
> > OK, so just on the firmware, the system seems less flickery with
> > the
> > new 1.4.3 UEFI, so I'm starting to think it is a Skylake errata 
> > issue.  The flicker isn't gone for good, but seems to be reboot 
> > dependent (it's there in some boots, but gone on a reboot).
> > 
> > > This should be easy enough to try before bisecting:
> > > http://patchwork.freedesktop.org/patch/msgid/1466162081-12042-1-g
> > > it
> > > -s
> > > end-email-mika.kahola at intel.com
> > 
> > Applying this didn't seem to make a difference: still there on
> > some 
> > and gone on other reboots.
> 
> OK, my candidate bad commit is this one:
> 
> commit a05628195a0d9f3173dd9aa76f482aef692e46ee
> Author: Ville Syrjälä 
> Date:   Mon Apr 11 10:23:51 2016 +0300
> 
>     drm/i915: Get panel_type from OpRegion panel details
> 
> After being more careful about waiting to identify flicker, this one
> seems to be the one the bisect finds.  I'm now running v4.7-rc3 with
> this one reverted and am currently seeing no flicker problems.  It
> is,
> however, early days because the flicker can hide for long periods, so
> I
> 'll wait until Monday evening and a few reboots before declaring
> victory.
> 
> 
I'm seeing this on my IvyBridge.  I'll try reverting the commit here
too, to see if it's the same issue.
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: This is a digitally signed message part
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160623/c628480a/attachment-0001.sig>


[PATCH] drm/atomic: Make drm_atomic_legacy_backoff reset crtc->acquire_ctx

2016-06-23 Thread Maarten Lankhorst
Atomic updates may acquire more state than initially locked through
drm_modeset_lock_crtc, running with heavy stress can cause a
WARN_ON(crtc->acquire_ctx) in drm_modeset_lock_crtc:

[  601.491296] [ cut here ]
[  601.491366] WARNING: CPU: 0 PID: 2411 at
drivers/gpu/drm/drm_modeset_lock.c:191 drm_modeset_lock_crtc+0xeb/0xf0 [drm]
[  601.491369] Modules linked in: drm i915 drm_kms_helper
[  601.491414] CPU: 0 PID: 2411 Comm: kms_cursor_lega Tainted: G U 
4.7.0-rc4-patser+ #4798
[  601.491417] Hardware name: Intel Corporation Skylake Client
[  601.491420]   88044d153c98 812ead28 

[  601.491425]   88044d153cd8 810868e6 
00bf58058030
[  601.491431]  880088b415e8 880458058030 88008a271548 
88008a271568
[  601.491436] Call Trace:
[  601.491443]  [] dump_stack+0x4d/0x65
[  601.491447]  [] __warn+0xc6/0xe0
[  601.491452]  [] warn_slowpath_null+0x18/0x20
[  601.491472]  [] drm_modeset_lock_crtc+0xeb/0xf0 [drm]
[  601.491491]  [] drm_mode_cursor_common+0x66/0x180 [drm]
[  601.491509]  [] drm_mode_cursor_ioctl+0x3c/0x40 [drm]
[  601.491524]  [] drm_ioctl+0x14d/0x530 [drm]
[  601.491540]  [] ? drm_mode_setcrtc+0x520/0x520 [drm]
[  601.491545]  [] ? handle_mm_fault+0x106b/0x1430
[  601.491550]  [] ? stop_one_cpu+0x61/0x70
[  601.491556]  [] do_vfs_ioctl+0x8d/0x570
[  601.491560]  [] ? security_file_ioctl+0x3e/0x60
[  601.491565]  [] SyS_ioctl+0x74/0x80
[  601.491571]  [] ? posix_get_monotonic_raw+0xc/0x10
[  601.491576]  [] entry_SYSCALL_64_fastpath+0x13/0x8f
[  601.491581] ---[ end trace 56f3d3d85f000d00 ]---

For good measure, test mode_config.acquire_ctx too, although this should
never happen.

Testcase: kms_cursor_legacy
Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/drm_atomic.c | 27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index d99ab2f6663f..3cee084e9d28 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1299,14 +1299,39 @@ EXPORT_SYMBOL(drm_atomic_add_affected_planes);
  */
 void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
 {
+   struct drm_device *dev = state->dev;
+   unsigned crtc_mask = 0;
+   struct drm_crtc *crtc;
int ret;
+   bool global = false;
+
+   drm_for_each_crtc(crtc, dev) {
+   if (crtc->acquire_ctx != state->acquire_ctx)
+   continue;
+
+   crtc_mask |= drm_crtc_mask(crtc);
+   crtc->acquire_ctx = NULL;
+   }
+
+   if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
+   global = true;
+
+   dev->mode_config.acquire_ctx = NULL;
+   }

 retry:
drm_modeset_backoff(state->acquire_ctx);

-   ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
+   ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
if (ret)
goto retry;
+
+   drm_for_each_crtc(crtc, dev)
+   if (drm_crtc_mask(crtc) & crtc_mask)
+   crtc->acquire_ctx = state->acquire_ctx;
+
+   if (global)
+   dev->mode_config.acquire_ctx = state->acquire_ctx;
 }
 EXPORT_SYMBOL(drm_atomic_legacy_backoff);

-- 
2.5.5



[Bug 96625] GPU lockup when using r600g VDPAU on powerpc

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

--- Comment #8 from Alex Deucher  ---
We are happy to apply good patches.

-- 
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/20160623/9c612d16/attachment.html>


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

2016-06-23 Thread Stephen Rothwell
Hi Maxime,

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

  drivers/gpu/drm/sun4i/sun4i_drv.c

between commit:

  366e292df678 ("drm/sun4i: Remove open-coded drm_connector_register_all()")

from the drm-misc tree and commit:

  7aa2e2b731b3 ("drm/sun4i: Convert to connector register helpers")

from the sunxi tree.

I fixed it up (I just removed the drm_connector_register_all call as
in the former) and can carry the fix as necessary. This is now fixed as
far as linux-next is concerned, but any non trivial conflicts should be
mentioned to your upstream maintainer when your tree is submitted for
merging.  You may also want to consider cooperating with the maintainer
of the conflicting tree to minimise any particularly complex conflicts.

-- 
Cheers,
Stephen Rothwell


[RFC 5/5] dma-buf/sync_file: rework fence storage in struct file

2016-06-23 Thread Gustavo Padovan
From: Gustavo Padovan 

Create sync_file->fence to abstract the type of fence we are using for
each sync_file. If only one fence is present we use a normal struct fence
but if there is more fences to be added to the sync_file a fence_array
is created.

This behaviour is transparent all sync_file functions, but
sync_file_set_fence() which sets the fence in the sync_file_merge(). It
is this functions that decides to use a fence or fence_array based on
num_fences.

This change cleans up sync_file a bit. We don't need to have sync_file_cb
array anymore. Instead, as we always have  one fence, only one fence
callback is registered per sync_file.

Signed-off-by: Gustavo Padovan 
---
 drivers/dma-buf/sync_file.c  | 129 +--
 drivers/staging/android/sync_debug.c |   5 +-
 include/linux/sync_file.h|  12 ++--
 3 files changed, 100 insertions(+), 46 deletions(-)

diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 9aaa608..5044ef2 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -25,14 +25,15 @@
 #include 
 #include 
 #include 
+#include 

 static const struct file_operations sync_file_fops;

-static struct sync_file *sync_file_alloc(int size)
+static struct sync_file *sync_file_alloc(void)
 {
struct sync_file *sync_file;

-   sync_file = kzalloc(size, GFP_KERNEL);
+   sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL);
if (!sync_file)
return NULL;

@@ -45,6 +46,8 @@ static struct sync_file *sync_file_alloc(int size)

init_waitqueue_head(_file->wq);

+   INIT_LIST_HEAD(_file->cb.node);
+
return sync_file;

 err:
@@ -54,11 +57,9 @@ err:

 static void fence_check_cb_func(struct fence *f, struct fence_cb *cb)
 {
-   struct sync_file_cb *check;
struct sync_file *sync_file;

-   check = container_of(cb, struct sync_file_cb, cb);
-   sync_file = check->sync_file;
+   sync_file = container_of(cb, struct sync_file, cb);

if (atomic_dec_and_test(_file->status))
wake_up_all(_file->wq);
@@ -76,21 +77,20 @@ struct sync_file *sync_file_create(struct fence *fence)
 {
struct sync_file *sync_file;

-   sync_file = sync_file_alloc(offsetof(struct sync_file, cbs[1]));
+   sync_file = sync_file_alloc();
if (!sync_file)
return NULL;

+   sync_file->fence = fence;
sync_file->num_fences = 1;
+
atomic_set(_file->status, 1);
snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d",
 fence->ops->get_driver_name(fence),
 fence->ops->get_timeline_name(fence), fence->context,
 fence->seqno);

-   sync_file->cbs[0].fence = fence;
-   sync_file->cbs[0].sync_file = sync_file;
-   if (fence_add_callback(fence, _file->cbs[0].cb,
-  fence_check_cb_func))
+   if (fence_add_callback(fence, _file->cb, fence_check_cb_func))
atomic_dec(_file->status);

return sync_file;
@@ -121,14 +121,31 @@ err:
return NULL;
 }

-static void sync_file_add_pt(struct sync_file *sync_file, int *i,
+static int sync_file_set_fence(struct sync_file *sync_file,
+  struct fence **fences)
+{
+   struct fence_array *array;
+
+   if (sync_file->num_fences == 1) {
+   sync_file->fence = fences[0];
+   } else {
+   array = fence_array_create(sync_file->num_fences, fences,
+  fence_context_alloc(1), 1, false);
+   if (!array)
+   return -ENOMEM;
+
+   sync_file->fence = >base;
+   }
+
+   return 0;
+}
+
+static void fences_add_fence(struct fence **fences, int *i,
 struct fence *fence)
 {
-   sync_file->cbs[*i].fence = fence;
-   sync_file->cbs[*i].sync_file = sync_file;
+   fences[*i] = fence;

-   if (!fence_add_callback(fence, _file->cbs[*i].cb,
-   fence_check_cb_func)) {
+   if (!fence_is_signaled(fence)) {
fence_get(fence);
(*i)++;
}
@@ -149,14 +166,31 @@ static struct sync_file *sync_file_merge(const char 
*name, struct sync_file *a,
 {
int num_fences = a->num_fences + b->num_fences;
struct sync_file *sync_file;
+   struct fence **fences, **a_fences, **b_fences;
int i, i_a, i_b;
-   unsigned long size = offsetof(struct sync_file, cbs[num_fences]);

-   sync_file = sync_file_alloc(size);
+   sync_file = sync_file_alloc();
if (!sync_file)
return NULL;

-   atomic_set(_file->status, num_fences);
+   fences = kcalloc(num_fences, sizeof(**fences), GFP_KERNEL);
+   if (!fences)
+   goto err;
+
+   atomic_set(_file->status, 1);
+
+   a_fences = fence_get_fences(a->fence);
+   if 

[RFC 4/5] dma-buf/fence-array: add fence_array_get_fences()

2016-06-23 Thread Gustavo Padovan
From: Gustavo Padovan 

This function returns a copy of the array of fences.

Signed-off-by: Gustavo Padovan 
---
 drivers/dma-buf/fence-array.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
index 601448a..ce98249 100644
--- a/drivers/dma-buf/fence-array.c
+++ b/drivers/dma-buf/fence-array.c
@@ -33,6 +33,19 @@ static const char *fence_array_get_timeline_name(struct 
fence *fence)
return "unbound";
 }

+static struct fence **fence_array_get_fences(struct fence *fence)
+{
+   struct fence_array *array = to_fence_array(fence);
+   struct fence **fences;
+
+   fences = kmalloc(array->num_fences * sizeof(*fences), GFP_KERNEL);
+   if (!fences)
+   return NULL;
+
+   memcpy(fences, array->fences, array->num_fences * sizeof(*fences));
+   return fences;
+}
+
 static void fence_array_cb_func(struct fence *f, struct fence_cb *cb)
 {
struct fence_array_cb *array_cb =
@@ -109,6 +122,7 @@ static void fence_array_release(struct fence *fence)
 const struct fence_ops fence_array_ops = {
.get_driver_name = fence_array_get_driver_name,
.get_timeline_name = fence_array_get_timeline_name,
+   .get_fences = fence_array_get_fences,
.enable_signaling = fence_array_enable_signaling,
.signaled = fence_array_signaled,
.wait = fence_default_wait,
-- 
2.5.5



[RFC 3/5] dma-buf/fence: add .get_fences() ops

2016-06-23 Thread Gustavo Padovan
From: Gustavo Padovan 

get_fences() should return a copy of all fences in the fence as some
fence subclass (such as fence_array) can store more than one fence at
time.

Signed-off-by: Gustavo Padovan 
---
 drivers/dma-buf/fence.c | 14 ++
 include/linux/fence.h   |  3 +++
 2 files changed, 17 insertions(+)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 4e61afb..f4094fd 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -185,6 +185,20 @@ void fence_release(struct kref *kref)
 }
 EXPORT_SYMBOL(fence_release);

+struct fence **fence_get_fences(struct fence *fence)
+{
+   if (fence->ops->get_fences) {
+   return fence->ops->get_fences(fence);
+   } else {
+   struct fence **fences = kmalloc(sizeof(**fences), GFP_KERNEL);
+   if (!fences)
+   return NULL;
+   fences[0] = fence;
+   return fences;
+   }
+}
+EXPORT_SYMBOL(fence_get_fences);
+
 void fence_teardown(struct fence *fence)
 {
if (fence->ops->teardown)
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 1d3b671..a7a2fbc 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -111,6 +111,7 @@ struct fence_cb {
  * struct fence_ops - operations implemented for fence
  * @get_driver_name: returns the driver name.
  * @get_timeline_name: return the name of the context this fence belongs to.
+ * @get_fences: return an array with a copy of all fences in the fence.
  * @enable_signaling: enable software signaling of fence.
  * @signaled: [optional] peek whether the fence is signaled, can be null.
  * @wait: custom wait implementation, or fence_default_wait.
@@ -175,6 +176,7 @@ struct fence_cb {
 struct fence_ops {
const char * (*get_driver_name)(struct fence *fence);
const char * (*get_timeline_name)(struct fence *fence);
+   struct fence ** (*get_fences)(struct fence *fence);
bool (*enable_signaling)(struct fence *fence);
bool (*signaled)(struct fence *fence);
signed long (*wait)(struct fence *fence, bool intr, signed long 
timeout);
@@ -189,6 +191,7 @@ struct fence_ops {
 void fence_init(struct fence *fence, const struct fence_ops *ops,
spinlock_t *lock, u64 context, unsigned seqno);

+struct fence **fence_get_fences(struct fence *fence);
 void fence_release(struct kref *kref);
 void fence_teardown(struct fence *fence);
 void fence_free(struct fence *fence);
-- 
2.5.5



[RFC 2/5] dma-buf/fence-array: add fence_array_teardown()

2016-06-23 Thread Gustavo Padovan
From: Gustavo Padovan 

When using fences in sync files we need to clean up everything when
the sync file needs to be freed, thus we need to teardown fence_array,
by removing the callback of its fences and putting extra references to the
fence_array base fence.

Signed-off-by: Gustavo Padovan 
---
 drivers/dma-buf/fence-array.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
index a8731c8..601448a 100644
--- a/drivers/dma-buf/fence-array.c
+++ b/drivers/dma-buf/fence-array.c
@@ -79,6 +79,21 @@ static bool fence_array_signaled(struct fence *fence)
return atomic_read(>num_pending) <= 0;
 }

+static void fence_array_teardown(struct fence *fence)
+{
+   struct fence_array *array = to_fence_array(fence);
+   struct fence_array_cb *cb = (void *)([1]);
+   int i;
+
+   for (i = 0; i < array->num_fences; i++) {
+   if (fence_is_signaled(array->fences[i]))
+   continue;
+
+   fence_remove_callback(array->fences[i], [i].cb);
+   fence_put(>base);
+   }
+}
+
 static void fence_array_release(struct fence *fence)
 {
struct fence_array *array = to_fence_array(fence);
@@ -97,6 +112,7 @@ const struct fence_ops fence_array_ops = {
.enable_signaling = fence_array_enable_signaling,
.signaled = fence_array_signaled,
.wait = fence_default_wait,
+   .teardown = fence_array_teardown,
.release = fence_array_release,
 };

-- 
2.5.5



[RFC 1/5] dma-buf/fence: add .teardown() ops

2016-06-23 Thread Gustavo Padovan
From: Gustavo Padovan 

fence_array requires a function to clean up its state before we
are able to call fence_put() and release it.

Signed-off-by: Gustavo Padovan 
---
 drivers/dma-buf/fence.c | 7 +++
 include/linux/fence.h   | 7 +++
 2 files changed, 14 insertions(+)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 4d51f9e..4e61afb 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -185,6 +185,13 @@ void fence_release(struct kref *kref)
 }
 EXPORT_SYMBOL(fence_release);

+void fence_teardown(struct fence *fence)
+{
+   if (fence->ops->teardown)
+   fence->ops->teardown(fence);
+}
+EXPORT_SYMBOL(fence_teardown);
+
 void fence_free(struct fence *fence)
 {
kfree_rcu(fence, rcu);
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 44d945e..1d3b671 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -114,6 +114,7 @@ struct fence_cb {
  * @enable_signaling: enable software signaling of fence.
  * @signaled: [optional] peek whether the fence is signaled, can be null.
  * @wait: custom wait implementation, or fence_default_wait.
+ * @teardown: [optional] teardown fence data but not put it
  * @release: [optional] called on destruction of fence, can be null
  * @fill_driver_data: [optional] callback to fill in free-form debug info
  * Returns amount of bytes filled, or -errno.
@@ -161,6 +162,10 @@ struct fence_cb {
  * which should be treated as if the fence is signaled. For example a hardware
  * lockup could be reported like that.
  *
+ * Notes on teardown:
+ * Can be NULL, this function clean ups the fence data before the fence_put
+ * call.
+ *
  * Notes on release:
  * Can be NULL, this function allows additional commands to run on
  * destruction of the fence. Can be called from irq context.
@@ -173,6 +178,7 @@ struct fence_ops {
bool (*enable_signaling)(struct fence *fence);
bool (*signaled)(struct fence *fence);
signed long (*wait)(struct fence *fence, bool intr, signed long 
timeout);
+   void (*teardown)(struct fence *fence);
void (*release)(struct fence *fence);

int (*fill_driver_data)(struct fence *fence, void *data, int size);
@@ -184,6 +190,7 @@ void fence_init(struct fence *fence, const struct fence_ops 
*ops,
spinlock_t *lock, u64 context, unsigned seqno);

 void fence_release(struct kref *kref);
+void fence_teardown(struct fence *fence);
 void fence_free(struct fence *fence);

 /**
-- 
2.5.5



[RFC 0/5] rework fences on struct sync_file

2016-06-23 Thread Gustavo Padovan
From: Gustavo Padovan 

Hi all,

This is an attempt to improve fence support on Sync File. The basic idea
is to have only sync_file->fence and store all fences there, either as
normal fences or fence_arrays. That way we can remove some potential
duplication when using fence_array with sync_file: the duplication of the array
of fences and the duplication of fence_add_callback() for all fences. 

Now when creating a new sync_file during the merge process sync_file_set_fence()
will set sync_file->fence based on the number of fences for that sync_file. If
there is more than one fence a fence_array is created. One important advantage
approach is that we only add one fence callback now, no matter how many fences
there are in a sync_file - the individual callbacks are added by fence_array.

Two fence ops had to be created to help abstract the difference between handling
fences and fences_arrays: .teardown() and .get_fences(). The former run needed
on fence_array, and the latter just return a copy of all fences in the fence.
I'm not so sure about adding those two, speacially .get_fences(). What do you
think?

Please comment! Thanks.

Gustavo
---

Gustavo Padovan (5):
  dma-buf/fence: add .teardown() ops
  dma-buf/fence-array: add fence_array_teardown()
  dma-buf/fence: add .get_fences() ops
  dma-buf/fence-array: add fence_array_get_fences()
  dma-buf/sync_file: rework fence storage in struct file

 drivers/dma-buf/fence-array.c|  30 
 drivers/dma-buf/fence.c  |  21 ++
 drivers/dma-buf/sync_file.c  | 129 +--
 drivers/staging/android/sync_debug.c |   5 +-
 include/linux/fence.h|  10 +++
 include/linux/sync_file.h|  12 ++--
 6 files changed, 161 insertions(+), 46 deletions(-)

-- 
2.5.5



[PATCH 2/2] drm/tegra: sor: Use sor1_src clock to set parent for HDMI

2016-06-23 Thread Thierry Reding
From: Thierry Reding 

When running in HDMI mode, the sor1 IP block needs to use the sor1_src
as parent clock, and in turn configure the sor1_src to use pll_d2_out0
as its parent.

Signed-off-by: Thierry Reding 
---
 drivers/gpu/drm/tegra/sor.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 6887e52318e2..7405c39f6db3 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -172,6 +172,7 @@ struct tegra_sor {
struct clk *clk_parent;
struct clk *clk_brick;
struct clk *clk_safe;
+   struct clk *clk_src;
struct clk *clk_dp;
struct clk *clk;

@@ -2140,7 +2141,11 @@ static void tegra_sor_hdmi_enable(struct drm_encoder 
*encoder)
tegra_sor_writel(sor, 0x, SOR_XBAR_POL);

/* switch to parent clock */
-   err = tegra_sor_set_parent_clock(clk, sor->clk_parent);
+   err = clk_set_parent(sor->clk_src, sor->clk_parent);
+   if (err < 0)
+   dev_err(sor->dev, "failed to set source clock: %d\n", err);
+
+   err = tegra_sor_set_parent_clock(sor, sor->clk_src);
if (err < 0)
dev_err(sor->dev, "failed to set parent clock: %d\n", err);

@@ -2645,6 +2650,13 @@ static int tegra_sor_probe(struct platform_device *pdev)
goto remove;
}

+   sor->clk_src = devm_clk_get(>dev, "source");
+   if (IS_ERR(sor->clk_src)) {
+   err = PTR_ERR(sor->clk_src);
+   dev_err(>dev, "failed to get source clock: %d\n", err);
+   goto remove;
+   }
+
sor->clk_parent = devm_clk_get(>dev, "parent");
if (IS_ERR(sor->clk_parent)) {
err = PTR_ERR(sor->clk_parent);
-- 
2.8.3



[PATCH 1/2] dt-bindings: display: tegra: Add source clock for SOR

2016-06-23 Thread Thierry Reding
From: Thierry Reding 

The SOR clock can have various sources, with the most commonly used
being the sor_safe, pll_d2_out0, pll_dp and sor_brick clocks. These
are configured using a three level mux, of which the first 2 levels
can be treated as one. The direct parents of the SOR clock are the
sor_safe, sor_brick and sor_src clocks, whereas the pll_d2_out0 and
pll_dp clocks can be selected as parents of the sor_src clock via a
second mux.

Previous generations of Tegra have only supported eDP and LVDS with
the SOR, where LVDS was never used on publicly available hardware.
Clocking for this only ever required the first level mux (to select
between sor_safe and sor_brick).

Tegra210 has a new revision of the SOR that supports HDMI and hence
needs to support the second level mux to allow selecting pll_d2_out0
as the SOR clock's parent. This second mux is knows as sor_src, and
operating system software needs a reference to it in order to select
the proper parent.

Signed-off-by: Thierry Reding 
---
 .../devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt  | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index a3bd8c050c4e..21de27a7f0a1 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -208,6 +208,7 @@ of the following host1x client modules:
 See ../clocks/clock-bindings.txt for details.
   - clock-names: Must include the following entries:
 - sor: clock input for the SOR hardware
+- source: source clock for the SOR clock
 - parent: input for the pixel clock
 - dp: reference clock for the SOR clock
 - safe: safe reference for the SOR clock during power up
-- 
2.8.3



[RFC PATCH 1/2] drm: bridge: anx7688: Add anx7688 bridge driver support.

2016-06-23 Thread Nicolas Boichat
Hi Philipp,

On Wed, Jun 22, 2016 at 4:51 PM, Philipp Zabel  
wrote:
> Hi Nicolas,
>
> Am Mittwoch, den 22.06.2016, 14:32 +0800 schrieb Nicolas Boichat:
>> >> Actually, experimenting a bit more with the code, I realized that the
>> >> connector is always attached to the encoder, not the bridge, so the 2
>> >> layouts above are actually identical (from the userspace point of
>> >> view). Except that the connector name should be HDMI in one case, and
>> >> DP in the other. But I think that's mostly a cosmetic difference?
>> >
>> >
>> > Yeah, probably. I don't know what exactly the userspace does with
>> > the connector type, but it would be nice to represent it as a DP
>> > connector in case it makes any decisions based on it.
>>
>> AFAICT does not matter... And, in any case, USB-C to HDMI adapters are
>> far more common (so we'd do HDMI->(DP over USB-C)->HDMI), so there
>> is a high change that advertising as DP would be wrong (and
>> advertising as HDMI would be correct by chance...).
>
> If anything it should be represented as an USB-C connector, whatever
> USB-C(DP)->HDMI->VGA adapter chain is connected externally shouldn't
> matter.

Indeed, looks like we could just create a new connector type.

>> >>> One way I can think of fixing this is to make make the MTK hdmi
>> >>> encoder driver a bit smarter by observing the DT connections. If
>> >>> it's output port is connected to just a hdmi-connector, then
>> >>> things should be as before. If the output is connected to the DP
>> >>> bridge, then it should create a DP connector. The connector ops
>> >>> for the DP connector can still be the same as that of the HDMI
>> >>> connector before, but the phandle to the DDC bus would be in the
>> >>> DP device node in this case.
>> >>
>> >>
>> >> I think it'd be a bit weird to have the DDC bus phandle on the DP
>> >> connector, as we're not reading the EDID on the DP side of the bridge,
>> >> but on the HDMI side (and the bridge can do all sort of things to the
>> >> EDID: At the very least, I think it caches it).
>>>
>> > On the board, do the DDC lines join directly from the SoC pins to the
>> > DP connector, or does it go via the ANX7688 chip?
>>
>> The DDC/I2C lines go to the ANX7688 chip. (DP has AUX channel instead)
>
> The anx7688 should get the i2c-ddc-bus property then, and the driver
> should use it to implement get_modes (or its bridge API equivalent, once
> it exists).

Ok, I can do that (I tried it). It's a lot a duplication from the
existing connector in mtk-hdmi, but I understand there may not be a
better way currently.

However, the problem I'm facing is how to implement "detect" in the
connector function. I'm still getting the interrupts from the MTK cec
module (so the detect function gets called), but then I don't see a
good way to read the HPD status (ANX7688 does not have a register for
that: it passes the HPD signal downstream).

mtk_hdmi implements detect this way:
return mtk_cec_hpd_high(hdmi->cec_dev) ?
   connector_status_connected : connector_status_disconnected;

But of course I can't call this function from the ANX7688 bridge driver...

>> > Even with the current bindings (referred from the link below), the
>> > hdmi connector has the DDC node. Shouldn't it be the same in the DP
>> > case too? The DP connector, like before, is still manged by the HDMI
>> > driver, the only difference being the name and that it's two hops away
>> > in the DT bindings.
>> >
>> > https://patchwork.kernel.org/patch/9137089/
>>
>> True, the bindings say so, but the current code actually looks for
>> ddc-i2c-bus property in whatever is connected on the endpoint (be it a
>> bridge or a connector).
>
> The HDMI driver only handles this itself because there are no separate
> connector drivers (or helpers) to do this. Ideally the HDMI driver
> shouldn't have to parse the connector DT node.
>
>> And again, a bit odd as DP connector does not have true I2C lines...
>>
>> Phillip? Any opinion?
>
> Make the HDMI driver leave the bridges' DT node alone and let the bridge
> handle DDC, if that's where it is connected physically.

Again, a bit odd... AFAICT, all other bridge drivers, and encoders,
read EDID from a bus that is downstream of it. If we handle DDC in the
ANX driver, it'll have to read the EDID upstream (on the HDMI side),
as there is no way to read the EDID on the DP side on this chip.

> regards
> Philipp
>

Thanks!

Best,


[RFC PATCH] drm/nouveau/fb/nv50: set DMA mask before mapping scratch page

2016-06-23 Thread Ard Biesheuvel
On 23 June 2016 at 11:55, Punit Agrawal  wrote:
> Ard Biesheuvel  writes:
>
>> The 100c08 scratch page is mapped using dma_map_page() before the TTM
>> layer has had a chance to set the DMA mask. This means we are still
>> running with the default of 32 when this code executes, and this causes
>> problems for platforms with no memory below 4 GB (such as AMD Seattle)
>>
>> So move the dma_map_page() to the .init hook, and set the streaming DMA
>> mask based on the MMU subdev parameters before performing the call.
>>
>> Signed-off-by: Ard Biesheuvel 
>
> Hi Ard,
>
> Thanks for posting this patch.
>
> With the patch, I am able to see console output on a screen attached to
> the NVS 300 PCIe card in an AMD Seattle system. It was failing with
> a message similar to what you've posted below.
>

Thanks for the report. May I take it as a tested-by?

> For some reason, X refuses to start up but that, I think, is a problem
> with my userspace setup.
>

Good to know that you are attempting the same thing. We should take
this offline, but I'd like to compare notes regarding the Xorg
problems that you are experiencing.

Regards,
Ard.


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

2016-06-23 Thread Daniel Vetter
On Thu, Jun 23, 2016 at 10:43 AM, Thierry Reding
 wrote:
> On Thu, Jun 23, 2016 at 10:24:46AM +0200, Tomeu Vizoso wrote:
>> On 23 June 2016 at 10:21, Jani Nikula  wrote:
>> > On Wed, 22 Jun 2016, Daniel Vetter  wrote:
>> >> On Wed, Jun 22, 2016 at 4:31 PM, Thierry Reding
>> >>  wrote:
>> >>> Perhaps another way to avoid that would be to put the two files into a
>> >>> separate directory, as in:
>> >>>
>> >>> /sys/kernel/debug/dri//crtc-/crc/
>> >>> +-- control
>> >>> +-- data
>> >>>
>> >>> That's slightly on the deeply nested side, but on the other hand it
>> >>> nicely uses the filesystem for namespacing, which is what filesystems
>> >>> are really good at.
>> >>
>> >> crtc-/crc/(control|data) sounds great.
>> >
>> > Side note, we should eventually do the same for sink CRCs, but I guess
>> > under the connectors. i915 currently has a special cased version for eDP
>> > (named "i915_sink_crc_eDP1"...), reading the data from DPCD.
>>
>> Was hoping we could just add one more source to this interface to expose 
>> those.
>
> I don't think that would be easy to achieve. You'd have to determine
> that a sink source is connected to the CRTC and then ajdust the list
> of possible sources dynamically.
>
> For connectors we already have separate directories in debugfs and a
> sink can easily be found from the connector it is attached to.
>
> It's also possible, though I don't know of any that do so currently,
> that eventually sinks will support several types (i.e. "sources") of
> CRC, which will further complicate to represent this in the CRTC's
> list of CRC sources.
>
> And it may also be useful to have both CRCs at the same time. The eDP
> specification for example defines a very specific polynomial that is
> used to compute the CRC, whereas not all display hardware uses a CRC
> algorithm that's documented.
>
> Finally, the data that will be checksummed by the CRTC isn't necessarily
> the same as that arriving at the sink.

We already do all that for i915. On some platforms the normal
end-of-pipe CRC doesn't work together with DP, instead you need to use
a special port (= connector/encoder) based CRC. The "auto" one
automatically walks the modeset config on those platforms to figure
out which one to pick. It would be kinda hard for userspace to
automatically figure out when the auto CRC doesn't work on the CRTC
and it would instead need to use the connector one. I think it'd
better to hide that in the kernel driver, where it's known.

Wrt specific polynomials: We could just spec that the "eDP-sink"
source is the one with CRC computed per the eDP spec. Similar for
anything else standardize. Heck you could even do the same with vendor
specific CRCs on IP blocks by using special names.

Wrt CRC measuring different data: That's also already the case on
i915. We have CRC for pre-gamma, post-gamma, post panel-fitter, on the
port, with or without audio stream included,  And this all even
varies between platforms. The only thing that's specifified is that
"auto" should be some CRC after all the blending/color-correction has
been applied, but before any port specific scrambling happens which
might make the CRC change with each frame. E.g. on platforms where
auto aliases the DP ports we need to set a special bit to reset the
scrambler state on each vblank to ensure stable CRCs.

Given all that I think putting sink crc capture into the same
framework makes sense.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[Intel-gfx] DP link training and performance issues with HDMI USB-C dongle and Skylake

2016-06-23 Thread Jani Nikula
On Thu, 23 Jun 2016, Andy Lutomirski  wrote:
> I have a Dell XPS 13 9350 (Skylake) and a Dell DA200 adapter.  The
> latter is a Thunderbolt device that includes an HDMI port and connects
> over USB Type C.  I believe that it's internally using DP Alternate
> Mode.

> I don't know whether this is a hardware issue, an Alpine Ridge
> firmware issue (mine is out of date because it appears to be
> impossible to update it on Linux for now), or an i915 driver issue.

At least a driver issue. The support is not there yet. Bug at [1].

BR,
Jani.


[1] https://bugs.freedesktop.org/show_bug.cgi?id=93578



-- 
Jani Nikula, Intel Open Source Technology Center


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

2016-06-23 Thread Jani Nikula
On Wed, 22 Jun 2016, Daniel Vetter  wrote:
> On Wed, Jun 22, 2016 at 4:31 PM, Thierry Reding
>  wrote:
>> Perhaps another way to avoid that would be to put the two files into a
>> separate directory, as in:
>>
>> /sys/kernel/debug/dri//crtc-/crc/
>> +-- control
>> +-- data
>>
>> That's slightly on the deeply nested side, but on the other hand it
>> nicely uses the filesystem for namespacing, which is what filesystems
>> are really good at.
>
> crtc-/crc/(control|data) sounds great.

Side note, we should eventually do the same for sink CRCs, but I guess
under the connectors. i915 currently has a special cased version for eDP
(named "i915_sink_crc_eDP1"...), reading the data from DPCD.

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Technology Center


[RFC PATCH 00/13] Add support for Tegra DPAUX pinctrl

2016-06-23 Thread Linus Walleij
On Thu, Jun 23, 2016 at 10:04 AM, Thierry Reding
 wrote:
> On Thu, Jun 23, 2016 at 09:49:20AM +0200, Linus Walleij wrote:
>> On Fri, Jun 17, 2016 at 6:58 PM, Thierry Reding
>>  wrote:
>>
>> > Oh wait... there's the pinctrl helper function that is a build-
>> > dependency. Linus, would you be okay if I took that through the
>> > drm-tegra tree along with the DPAUX driver change, and provide a
>> > stable branch for you to resolve conflicts against if needed?
>>
>> I have already applied it, but I can rebase and pull that patch out
>> on a separate immutable branch and then  merge that branch
>> into my devel and then you can pull it too.
>>
>> Would that work?
>
> Yes, that would be just fine.

OK use this:
https://git.kernel.org/cgit/linux/kernel/git/linusw/linux-pinctrl.git/log/?h=devel-dt-free-map

I merged that into my devel branch too.

Yours,
Linus Walleij


[RFC PATCH 1/2] drm: bridge: anx7688: Add anx7688 bridge driver support.

2016-06-23 Thread Philipp Zabel
Am Donnerstag, den 23.06.2016, 12:08 +0800 schrieb Nicolas Boichat:
[...]
> >> >> I think it'd be a bit weird to have the DDC bus phandle on the DP
> >> >> connector, as we're not reading the EDID on the DP side of the bridge,
> >> >> but on the HDMI side (and the bridge can do all sort of things to the
> >> >> EDID: At the very least, I think it caches it).
> >>>
> >> > On the board, do the DDC lines join directly from the SoC pins to the
> >> > DP connector, or does it go via the ANX7688 chip?
> >>
> >> The DDC/I2C lines go to the ANX7688 chip. (DP has AUX channel instead)
> >
> > The anx7688 should get the i2c-ddc-bus property then, and the driver
> > should use it to implement get_modes (or its bridge API equivalent, once
> > it exists).
> 
> Ok, I can do that (I tried it). It's a lot a duplication from the
> existing connector in mtk-hdmi, but I understand there may not be a
> better way currently.

Is there a thread where moving connectors back out of the bridge drivers
was discussed?

> However, the problem I'm facing is how to implement "detect" in the
> connector function. I'm still getting the interrupts from the MTK cec
> module (so the detect function gets called), but then I don't see a
> good way to read the HPD status (ANX7688 does not have a register for
> that: it passes the HPD signal downstream).
> 
> mtk_hdmi implements detect this way:
> return mtk_cec_hpd_high(hdmi->cec_dev) ?
>connector_status_connected : connector_status_disconnected;
> 
> But of course I can't call this function from the ANX7688 bridge driver...

If the bridge API is extended to get a .detect equivalent, the ANX7688
could just not implement it or return -ENOTSUPP to indicate HPD
passthrough and the mtk_hdmi connector could fall back to current
behaviour.

> >> > Even with the current bindings (referred from the link below), the
> >> > hdmi connector has the DDC node. Shouldn't it be the same in the DP
> >> > case too? The DP connector, like before, is still manged by the HDMI
> >> > driver, the only difference being the name and that it's two hops away
> >> > in the DT bindings.
> >> >
> >> > https://patchwork.kernel.org/patch/9137089/
> >>
> >> True, the bindings say so, but the current code actually looks for
> >> ddc-i2c-bus property in whatever is connected on the endpoint (be it a
> >> bridge or a connector).
> >
> > The HDMI driver only handles this itself because there are no separate
> > connector drivers (or helpers) to do this. Ideally the HDMI driver
> > shouldn't have to parse the connector DT node.
> >
> >> And again, a bit odd as DP connector does not have true I2C lines...
> >>
> >> Phillip? Any opinion?
> >
> > Make the HDMI driver leave the bridges' DT node alone and let the bridge
> > handle DDC, if that's where it is connected physically.
> 
> Again, a bit odd... AFAICT, all other bridge drivers, and encoders,
> read EDID from a bus that is downstream of it. If we handle DDC in the
> ANX driver, it'll have to read the EDID upstream (on the HDMI side),
> as there is no way to read the EDID on the DP side on this chip.

Well, the chip is a bit odd in that it seems to be intended to be
transparent to the software with the EDID and HPD passthrough, but then
still needs to have a driver.

regards
Philipp



[RFC PATCH] drm/nouveau/fb/nv50: set DMA mask before mapping scratch page

2016-06-23 Thread Punit Agrawal
Ard Biesheuvel  writes:

> The 100c08 scratch page is mapped using dma_map_page() before the TTM
> layer has had a chance to set the DMA mask. This means we are still
> running with the default of 32 when this code executes, and this causes
> problems for platforms with no memory below 4 GB (such as AMD Seattle)
>
> So move the dma_map_page() to the .init hook, and set the streaming DMA
> mask based on the MMU subdev parameters before performing the call.
>
> Signed-off-by: Ard Biesheuvel 

Hi Ard,

Thanks for posting this patch.

With the patch, I am able to see console output on a screen attached to
the NVS 300 PCIe card in an AMD Seattle system. It was failing with
a message similar to what you've posted below.

For some reason, X refuses to start up but that, I think, is a problem
with my userspace setup.

Cheers,
Punit


[...]



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

2016-06-23 Thread Thierry Reding
On Thu, Jun 23, 2016 at 10:24:46AM +0200, Tomeu Vizoso wrote:
> On 23 June 2016 at 10:21, Jani Nikula  wrote:
> > On Wed, 22 Jun 2016, Daniel Vetter  wrote:
> >> On Wed, Jun 22, 2016 at 4:31 PM, Thierry Reding
> >>  wrote:
> >>> Perhaps another way to avoid that would be to put the two files into a
> >>> separate directory, as in:
> >>>
> >>> /sys/kernel/debug/dri//crtc-/crc/
> >>> +-- control
> >>> +-- data
> >>>
> >>> That's slightly on the deeply nested side, but on the other hand it
> >>> nicely uses the filesystem for namespacing, which is what filesystems
> >>> are really good at.
> >>
> >> crtc-/crc/(control|data) sounds great.
> >
> > Side note, we should eventually do the same for sink CRCs, but I guess
> > under the connectors. i915 currently has a special cased version for eDP
> > (named "i915_sink_crc_eDP1"...), reading the data from DPCD.
> 
> Was hoping we could just add one more source to this interface to expose 
> those.

I don't think that would be easy to achieve. You'd have to determine
that a sink source is connected to the CRTC and then ajdust the list
of possible sources dynamically.

For connectors we already have separate directories in debugfs and a
sink can easily be found from the connector it is attached to.

It's also possible, though I don't know of any that do so currently,
that eventually sinks will support several types (i.e. "sources") of
CRC, which will further complicate to represent this in the CRTC's
list of CRC sources.

And it may also be useful to have both CRCs at the same time. The eDP
specification for example defines a very specific polynomial that is
used to compute the CRC, whereas not all display hardware uses a CRC
algorithm that's documented.

Finally, the data that will be checksummed by the CRTC isn't necessarily
the same as that arriving at the sink.

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/20160623/b2d24dac/attachment.sig>


[PATCH 7/7] staging/android: remove sync framework TODO

2016-06-23 Thread Gustavo Padovan
2016-06-23 Emil Velikov :

> Hi Gustavo,
> 
> On 20 June 2016 at 16:53, Gustavo Padovan  wrote:
> > - - port libsync tests to kselftest
> 
> I believe the tests haven't landed yet right, so this should stay right ?

Yes, you are right. That part is still missing in upstream.

Gustavo


[PATCH v3 03/10] drm/bridge: analogix_dp: correct the register bit define error in ANALOGIX_DP_PLL_REG_1

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> There're an register define error in ANALOGIX_DP_PLL_REG_1 which introduced
> by commit bcec20fd5ad6 ("drm: bridge: analogix/dp: add some rk3288 special
> registers setting").
>
> The PHY PLL input clock source is selected by ANALOGIX_DP_PLL_REG_1
> BIT 0, not BIT 1.
>
> Signed-off-by: Yakir Yang 
> Reviewed-by: Tomasz Figa 
> Tested-by: Javier Martinez Canillas 

Reviewed-by: Sean Paul 

> ---
> Changes in v3:
> - Add reviewed flag from Tomasz.
> [https://chromium-review.googlesource.com/#/c/346315/15]
> - Add tested flag from Javier
>
> Changes in v2: None
>
>  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h 
> b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
> index 337912b..88d56ad 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
> @@ -163,8 +163,8 @@
>  #define HSYNC_POLARITY_CFG (0x1 << 0)
>
>  /* ANALOGIX_DP_PLL_REG_1 */
> -#define REF_CLK_24M(0x1 << 1)
> -#define REF_CLK_27M(0x0 << 1)
> +#define REF_CLK_24M(0x1 << 0)
> +#define REF_CLK_27M(0x0 << 0)
>
>  /* ANALOGIX_DP_LANE_MAP */
>  #define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
> --
> 1.9.1
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 02/10] drm/rockchip: analogix_dp: split the lcdc select setting into device data

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> eDP controller need to declare which vop provide the video source,
> and it's defined in GRF registers.
>
> But different chips have different GRF register address, so we need to
> create a device data to declare the GRF messages for each chips.
>
> Signed-off-by: Yakir Yang 
> Acked-by: Mark Yao 
> ---
> Changes in v3:
> - Write a kerneldoc-style comment explaining the chips data fields (Tomasz, 
> reviewed at Google Gerrit)
> 
> [https://chromium-review.googlesource.com/#/c/346313/10/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>  at 39]
> - Drop the '.lcdcsel_mask' number in chips data field (Tomasz, reviewed at 
> Google Gerrit)
> 
> [https://chromium-review.googlesource.com/#/c/346313/10/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>  at 382]
> - Add acked flag from Mark.
>
> Changes in v2: None
>
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 39 
> +++--
>  1 file changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
> b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index 2bc8a7e..3855f46 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -14,6 +14,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -35,11 +36,17 @@
>
>  #define to_dp(nm)  container_of(nm, struct rockchip_dp_device, nm)
>
> -/* dp grf register offset */
> -#define GRF_SOC_CON60x025c
> -#define GRF_EDP_LCD_SEL_MASKBIT(5)
> -#define GRF_EDP_SEL_VOP_LIT BIT(5)
> -#define GRF_EDP_SEL_VOP_BIG 0
> +/**
> + * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
> + * @lcdsel_grf_reg: grf register offset of lcdc select
> + * @lcdsel_big: reg value of selecting vop big for eDP
> + * @lcdsel_lit: reg value of selecting vop little for eDP
> + */
> +struct rockchip_dp_chip_data {
> +   u32 lcdsel_grf_reg;
> +   u32 lcdsel_big;
> +   u32 lcdsel_lit;
> +};
>
>  struct rockchip_dp_device {
> struct drm_device*drm_dev;
> @@ -51,6 +58,8 @@ struct rockchip_dp_device {
> struct regmap*grf;
> struct reset_control *rst;
>
> +   const struct rockchip_dp_chip_data *data;
> +
> struct analogix_dp_plat_data plat_data;
>  };
>
> @@ -119,13 +128,13 @@ static void rockchip_dp_drm_encoder_enable(struct 
> drm_encoder *encoder)
> return;
>
> if (ret)
> -   val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16);
> +   val = dp->data->lcdsel_lit;
> else
> -   val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16);
> +   val = dp->data->lcdsel_big;
>
> dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
>
> -   ret = regmap_write(dp->grf, GRF_SOC_CON6, val);
> +   ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
> if (ret != 0) {
> dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
> return;
> @@ -246,6 +255,7 @@ static int rockchip_dp_bind(struct device *dev, struct 
> device *master,
> void *data)
>  {
> struct rockchip_dp_device *dp = dev_get_drvdata(dev);
> +   const struct rockchip_dp_chip_data *dp_data;
> struct drm_device *drm_dev = data;
> int ret;
>
> @@ -256,10 +266,15 @@ static int rockchip_dp_bind(struct device *dev, struct 
> device *master,
>  */
> dev_set_drvdata(dev, NULL);
>
> +   dp_data = of_device_get_match_data(dev);
> +   if (!dp_data)
> +   return -ENODEV;
> +
> ret = rockchip_dp_init(dp);
> if (ret < 0)
> return ret;
>
> +   dp->data = dp_data;
> dp->drm_dev = drm_dev;
>
> ret = rockchip_dp_drm_create_encoder(dp);
> @@ -365,8 +380,14 @@ static const struct dev_pm_ops rockchip_dp_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
>  };
>
> +static const struct rockchip_dp_chip_data rk3288_dp = {
> +   .lcdsel_grf_reg = 0x025c,
> +   .lcdsel_big = 0 | BIT(21),
> +   .lcdsel_lit = BIT(5) | BIT(21),

I'm not sure what convention is in other drivers, but this seems less
readable to me.

I'd prefer that the magic numbers were assigned to a #define that
corresponds to a TRM name in some header. Then you have names in the
assignment instead of meaningless numbers.

Sean

> +};
> +
>  static const struct of_device_id rockchip_dp_dt_ids[] = {
> -   {.compatible = "rockchip,rk3288-dp",},
> +   {.compatible = "rockchip,rk3288-dp", .data = _dp },
> {}
>  };
>  MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
> --
> 1.9.1
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> 

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

2016-06-23 Thread Tomeu Vizoso
On 23 June 2016 at 10:21, Jani Nikula  wrote:
> On Wed, 22 Jun 2016, Daniel Vetter  wrote:
>> On Wed, Jun 22, 2016 at 4:31 PM, Thierry Reding
>>  wrote:
>>> Perhaps another way to avoid that would be to put the two files into a
>>> separate directory, as in:
>>>
>>> /sys/kernel/debug/dri//crtc-/crc/
>>> +-- control
>>> +-- data
>>>
>>> That's slightly on the deeply nested side, but on the other hand it
>>> nicely uses the filesystem for namespacing, which is what filesystems
>>> are really good at.
>>
>> crtc-/crc/(control|data) sounds great.
>
> Side note, we should eventually do the same for sink CRCs, but I guess
> under the connectors. i915 currently has a special cased version for eDP
> (named "i915_sink_crc_eDP1"...), reading the data from DPCD.

Was hoping we could just add one more source to this interface to expose those.

Regards,

Tomeu


[PATCH v3 10/10] drm/bridge: analogix_dp: fix no drm hpd event when panel plug in

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> The enum value of DP_IRQ_TYPE_HP_CABLE_IN is zero, but driver only
> send drm hp event when the irq_type and the enum value is true.
>
> if (irq_type & DP_IRQ_TYPE_HP_CABLE_IN || ...)
> drm_helper_hpd_irq_event(dp->drm_dev);
>
> So there would no drm hpd event when cable plug in, to fix that
> just need to assign all hotplug enum with no-zero values.
>
> Reported-by: Dan Carpenter 
> Signed-off-by: Yakir Yang 
> Reviewed-by: Stéphane Marchesin 
> Tested-by: Javier Martinez Canillas 

Reviewed-by: Sean Paul 

> ---
> Changes in v3:
> - Add reviewed flag from Stéphane.
> [https://chromium-review.googlesource.com/#/c/346319/15]
> - Add tested flag from Javier
>
> Changes in v2: None
>
>  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
> b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
> index f09275d..b456380 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
> @@ -127,10 +127,10 @@ enum analog_power_block {
>  };
>
>  enum dp_irq_type {
> -   DP_IRQ_TYPE_HP_CABLE_IN,
> -   DP_IRQ_TYPE_HP_CABLE_OUT,
> -   DP_IRQ_TYPE_HP_CHANGE,
> -   DP_IRQ_TYPE_UNKNOWN,
> +   DP_IRQ_TYPE_HP_CABLE_IN  = BIT(0),
> +   DP_IRQ_TYPE_HP_CABLE_OUT = BIT(1),
> +   DP_IRQ_TYPE_HP_CHANGE= BIT(2),
> +   DP_IRQ_TYPE_UNKNOWN  = BIT(3),
>  };
>
>  struct video_info {
> --
> 1.9.1
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 09/10] drm/rockchip: analogix_dp: update the comments about why need to hardcode VOP output mode

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> The hardware IC designed that VOP must output the RGB10 video format to
> eDP contoller, and if eDP panel only support RGB8, then eDP contoller
> should cut down the video data, not via VOP contoller, that's why we need
> to hardcode the VOP output mode to RGA10 here.
>
> Signed-off-by: Yakir Yang 
> Acked-by: Mark Yao 
> Reviewed-by: Tomasz Figa 
> ---
> Changes in v3:
> - Add the reviewed flag from Tomasz.
> [https://chromium-review.googlesource.com/#/c/346853/12]
> - Add the acked flag from Mark.
>
> Changes in v2:
> - new patch in v2
>
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 16 +---
>  1 file changed, 5 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
> b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index 95a6f60..2ceb3f9 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -173,17 +173,11 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
> *encoder,
> int ret;
>
> /*
> -* FIXME(Yakir): driver should configure the CRTC output video
> -* mode with the display information which indicated the monitor
> -* support colorimetry.
> -*
> -* But don't know why the CRTC driver seems could only output the
> -* RGBaaa rightly. For example, if connect the "innolux,n116bge"
> -* eDP screen, EDID would indicated that screen only accepted the
> -* 6bpc mode. But if I configure CRTC to RGB666 output, then eDP
> -* screen would show a blue picture (RGB888 show a green picture).
> -* But if I configure CTRC to RGBaaa, and eDP driver still keep
> -* RGB666 input video mode, then screen would works prefect.
> +* The hardware IC designed that VOP must output the RGB10 video
> +* format to eDP contoller, and if eDP panel only support RGB8,
> +* then eDP contoller should cut down the video data, not via VOP
> +* contoller, that's why we need to hardcode the VOP output mode
> +* to RGA10 here.

s/contoller/controller/

>  */
>
> ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
> --
> 1.9.1
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 08/10] drm/rockchip: analogix_dp: correct the connector display color format and bpc

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> Rockchip VOP couldn't output YUV video format for eDP controller, so
> when driver detect connector support YUV video format, we need to hack
> it down to RGB888.
>
> Signed-off-by: Yakir Yang 
> Acked-by: Mark Yao 
> ---
> Changes in v3:
> - Hook the connector's color_formats in .get_modes directly. (Tomasz, 
> reviewed at Google Gerrit)
> [https://chromium-review.googlesource.com/#/c/346317/15]
> - Add the acked flag from Mark.
>
> Changes in v2: None
>
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 17 +
>  1 file changed, 17 insertions(+)
>
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
> b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index da2e844..95a6f60 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -102,6 +102,22 @@ static int rockchip_dp_powerdown(struct 
> analogix_dp_plat_data *plat_data)
> return 0;
>  }
>
> +static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data,
> +struct drm_connector *connector)
> +{
> +   struct drm_display_info *di = >display_info;
> +
> +   if (di->color_formats & DRM_COLOR_FORMAT_YCRCB444 ||
> +   di->color_formats & DRM_COLOR_FORMAT_YCRCB422) {
> +   di->color_formats &= ~(DRM_COLOR_FORMAT_YCRCB422 |
> +  DRM_COLOR_FORMAT_YCRCB444);
> +   di->color_formats |= DRM_COLOR_FORMAT_RGB444;
> +   di->bpc = 8;

Probably a stupid question, but are you guaranteed that the panel will
support this color format?

> +   }
> +

I think this can be simplified as follows:

/* A comment here about why we're doing this */
u32 mask = DRM_COLOR_FORMAT_YCRCB444 | DRM_COLOR_FORMAT_YCRCB422;
if ((di->color_formats & mask)) {
DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n");
di->color_formats &= ~mask;
di->color_formats |= DRM_COLOR_FORMAT_RGB444;
di->bpc = 8;
}

> +   return 0;
> +}
> +
>  static bool
>  rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
>const struct drm_display_mode *mode,
> @@ -313,6 +329,7 @@ static int rockchip_dp_bind(struct device *dev, struct 
> device *master,
> dp->plat_data.subdev_type = dp_data->chip_type;
> dp->plat_data.power_on = rockchip_dp_poweron;
> dp->plat_data.power_off = rockchip_dp_powerdown;
> +   dp->plat_data.get_modes = rockchip_dp_get_modes;
>
> return analogix_dp_bind(dev, dp->drm_dev, >plat_data);
>  }
> --
> 1.9.1
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v2 6/6] drm/rockchip: Add dmc notifier in vop driver

2016-06-23 Thread Chanwoo Choi
Hi Lin,

On 2016년 06월 22일 21:25, hl wrote:
> Hi Chanwoo Choi,
> 
> On 2016年06月22日 15:11, Chanwoo Choi wrote:
>> Hi,
>>
>> On 2016년 06월 06일 19:13, Lin Huang wrote:
>>> when in ddr frequency scaling process, vop can not do
>>> enable or disable operate, since dcf will base on vop vblank
>>> time to do frequency scaling and need to get vop irq if there
>>> have vop enabled. So need register to dmc notifier, and we can
>>> get the dmc status.
>> If you want to know when ddr frequency is chanaged,
>> you can use the DEVFREQ_TRANSITION_NOTIFIER notifier[1] (merged to v4.7-rc1)
>> which includes the following notification:
>> - DEVFREQ_PRECHANGE
>> - DEVFREQ_POSTCHANGE 
>>
>> [1] "PM / devfreq: Add new DEVFREQ_TRANSITION_NOTIFIER notifier"
>> - 
>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0fe3a66410a3ba96679be903f1e287d7a0a264a9
> Check the code, if the set target fail, it will not send DEVFREQ_POSTCHANGE, 
> but in our case, whether the target
> setting sucess or fail, it should send message to vop driver,  tell vop 
> driver dmc have finish frequency setting.

I check the code when target function is failed.
DEVFREQ_TRANSITION_NOTIFIER notifier[1] is missing the error case as you 
mentioned.
So, we would add following patches to fix the problem.

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 1d6c803804d5..2bd9d4228b7b 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -268,8 +268,10 @@ int update_devfreq(struct devfreq *devfreq)
devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE);

err = devfreq->profile->target(devfreq->dev.parent, , flags);
-   if (err)
+   if (err) {
+   freqs.new = cur_freq;
+   devfreq_notify_transition(devfreq, , DEVFREQ_POSTCHANGE);
return err;
+   }

freqs.new = freq;
devfreq_notify_transition(devfreq, , DEVFREQ_POSTCHANGE);


Thanks,
Chanwoo Choi

>>
>> Thanks,
>> Chanwoo Choi
>>
>>> Signed-off-by: Lin Huang 
>>> ---
>>>
>>> Changes in v2:
>>> - None
>>>
>>> Changes in v1:
>>> - use wait_event instead usleep
>>>
>>>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 43 
>>> +++--
>>>  1 file changed, 41 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
>>> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>>> index 1c4d5b5..8286048 100644
>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>>> @@ -31,6 +31,8 @@
>>>  #include 
>>>  #include 
>>>  
>>> +#include 
>>> +
>>>  #include "rockchip_drm_drv.h"
>>>  #include "rockchip_drm_gem.h"
>>>  #include "rockchip_drm_fb.h"
>>> @@ -116,6 +118,10 @@ struct vop {
>>>  
>>> const struct vop_data *data;
>>>  
>>> +   struct notifier_block dmc_nb;
>>> +   int dmc_in_process;
>>> +   wait_queue_head_t   wait_dmc_queue;
>>> +
>>> uint32_t *regsbak;
>>> void __iomem *regs;
>>>  
>>> @@ -426,6 +432,21 @@ static void vop_dsp_hold_valid_irq_disable(struct vop 
>>> *vop)
>>> spin_unlock_irqrestore(>irq_lock, flags);
>>>  }
>>>  
>>> +static int dmc_notify(struct notifier_block *nb, unsigned long event,
>>> + void *data)
>>> +{
>>> +   struct vop *vop = container_of(nb, struct vop, dmc_nb);
>>> +
>>> +   if (event == DMCFREQ_ADJUST) {
>>> +   vop->dmc_in_process = 1;
>>> +   } else if (event == DMCFREQ_FINISH) {
>>> +   vop->dmc_in_process = 0;
>>> +   wake_up(>wait_dmc_queue);
>>> +   }
>>> +
>>> +   return NOTIFY_OK;
>>> +}
>>> +
>>>  static void vop_enable(struct drm_crtc *crtc)
>>>  {
>>> struct vop *vop = to_vop(crtc);
>>> @@ -434,6 +455,13 @@ static void vop_enable(struct drm_crtc *crtc)
>>> if (vop->is_enabled)
>>> return;
>>>  
>>> +   /*
>>> +* if in dmc scaling frequency process, wait until it finish
>>> +* use 100ms as timeout time.
>>> +*/
>>> +   wait_event_timeout(vop->wait_dmc_queue,
>>> +  !vop->dmc_in_process, HZ / 10);
>>> +
>>> ret = pm_runtime_get_sync(vop->dev);
>>> if (ret < 0) {
>>> dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
>>> @@ -485,6 +513,7 @@ static void vop_enable(struct drm_crtc *crtc)
>>> enable_irq(vop->irq);
>>>  
>>> drm_crtc_vblank_on(crtc);
>>> +   rockchip_dmc_get(>dmc_nb);
>>>  
>>> return;
>>>  
>>> @@ -505,6 +534,13 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
>>> return;
>>>  
>>> /*
>>> +* if in dmc scaling frequency process, wait until it finish
>>> +* use 100ms as timeout time.
>>> +*/
>>> +   wait_event_timeout(vop->wait_dmc_queue,
>>> +  !vop->dmc_in_process, HZ / 10);
>>> +
>>> +   /*
>>>  * We need to make sure that all windows are disabled before we
>>>  * disable that crtc. Otherwise we might try to scan from a destroyed
>>>  * buffer later.
>>> @@ -517,7 +553,7 @@ static 

[PATCH v3 07/10] drm/bridge: analogix_dp: passing the connector as an argument in .get_modes()

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> It's better to pass the connector to platform driver in .get_modes()
> callback, just like what the .get_modes() helper function designed.
>
> Signed-off-by: Yakir Yang 

Reviewed-by: Sean Paul 

> ---
> Changes in v3:
> - Avoid to change any internal driver state in .mode_valid interface. 
> (Tomasz, reviewed at Google Gerrit)
> 
> [https://chromium-review.googlesource.com/#/c/346318/10/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>  at 113]
>
> Changes in v2: None
>
>  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +-
>  drivers/gpu/drm/exynos/exynos_dp.c | 4 ++--
>  include/drm/bridge/analogix_dp.h   | 3 ++-
>  3 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
> b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index 4a1b3b8..1a890fa 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -938,7 +938,7 @@ int analogix_dp_get_modes(struct drm_connector *connector)
> num_modes += drm_panel_get_modes(dp->plat_data->panel);
>
> if (dp->plat_data->get_modes)
> -   num_modes += dp->plat_data->get_modes(dp->plat_data);
> +   num_modes += dp->plat_data->get_modes(dp->plat_data, 
> connector);
>
> return num_modes;
>  }
> diff --git a/drivers/gpu/drm/exynos/exynos_dp.c 
> b/drivers/gpu/drm/exynos/exynos_dp.c
> index 468498e..8a555ed 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp.c
> +++ b/drivers/gpu/drm/exynos/exynos_dp.c
> @@ -67,10 +67,10 @@ static int exynos_dp_poweroff(struct 
> analogix_dp_plat_data *plat_data)
> return exynos_dp_crtc_clock_enable(plat_data, false);
>  }
>
> -static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data)
> +static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
> +  struct drm_connector *connector)
>  {
> struct exynos_dp_device *dp = to_dp(plat_data);
> -   struct drm_connector *connector = >connector;
> struct drm_display_mode *mode;
> int num_modes = 0;
>
> diff --git a/include/drm/bridge/analogix_dp.h 
> b/include/drm/bridge/analogix_dp.h
> index 82b8135..181db09 100644
> --- a/include/drm/bridge/analogix_dp.h
> +++ b/include/drm/bridge/analogix_dp.h
> @@ -34,7 +34,8 @@ struct analogix_dp_plat_data {
> int (*power_off)(struct analogix_dp_plat_data *);
> int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *,
>   struct drm_connector *);
> -   int (*get_modes)(struct analogix_dp_plat_data *);
> +   int (*get_modes)(struct analogix_dp_plat_data *,
> +struct drm_connector *);
>  };
>
>  int analogix_dp_resume(struct device *dev);
> --
> 1.9.1
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 06/10] drm/rockchip: analogix_dp: make panel detect to an optional action

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> Some boards don't need to declare a panel device node, like the
> display interface is DP monitors, so it's necessary to make the
> panel detect to an optional action.
>
> Signed-off-by: Yakir Yang 
> Acked-by: Mark Yao 
> ---
> Changes in v3:
> - Add the acked flag from Mark.
>
> Changes in v2: None
>
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 48 
> -
>  1 file changed, 22 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
> b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index bcd9ecc..da2e844 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -332,38 +332,34 @@ static int rockchip_dp_probe(struct platform_device 
> *pdev)
>  {
> struct device *dev = >dev;
> struct device_node *panel_node, *port, *endpoint;
> +   struct drm_panel *panel = NULL;
> struct rockchip_dp_device *dp;
> -   struct drm_panel *panel;
>
> port = of_graph_get_port_by_id(dev->of_node, 1);
> -   if (!port) {
> -   dev_err(dev, "can't find output port\n");
> -   return -EINVAL;
> -   }
> -
> -   endpoint = of_get_child_by_name(port, "endpoint");
> -   of_node_put(port);
> -   if (!endpoint) {
> -   dev_err(dev, "no output endpoint found\n");
> -   return -EINVAL;
> -   }
> -
> -   panel_node = of_graph_get_remote_port_parent(endpoint);
> -   of_node_put(endpoint);
> -   if (!panel_node) {
> -   dev_err(dev, "no output node found\n");
> -   return -EINVAL;
> -   }
> -
> -   panel = of_drm_find_panel(panel_node);
> -   if (!panel) {
> -   DRM_ERROR("failed to find panel\n");
> +   if (port) {
> +   endpoint = of_get_child_by_name(port, "endpoint");
> +   of_node_put(port);
> +   if (!endpoint) {
> +   dev_err(dev, "no output endpoint found\n");
> +   return -EINVAL;
> +   }
> +
> +   panel_node = of_graph_get_remote_port_parent(endpoint);
> +   of_node_put(endpoint);
> +   if (!panel_node) {
> +   dev_err(dev, "no output node found\n");
> +   return -EINVAL;
> +   }
> +
> +   panel = of_drm_find_panel(panel_node);
> +   if (!panel) {
> +   DRM_ERROR("failed to find panel\n");
> +   of_node_put(panel_node);
> +   return -EPROBE_DEFER;
> +   }
> of_node_put(panel_node);

Minor nit: Move of_node_put(panel_node) directly below
of_drm_find_panel to avoid duplicating it in both error and normal
paths (like you've done above).

Sean

> -   return -EPROBE_DEFER;
> }
>
> -   of_node_put(panel_node);
> -
> dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
> if (!dp)
> return -ENOMEM;
> --
> 1.9.1
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH 00/13] Add support for Tegra DPAUX pinctrl

2016-06-23 Thread Thierry Reding
On Thu, Jun 23, 2016 at 09:49:20AM +0200, Linus Walleij wrote:
> On Fri, Jun 17, 2016 at 6:58 PM, Thierry Reding
>  wrote:
> 
> > Oh wait... there's the pinctrl helper function that is a build-
> > dependency. Linus, would you be okay if I took that through the
> > drm-tegra tree along with the DPAUX driver change, and provide a
> > stable branch for you to resolve conflicts against if needed?
> 
> I have already applied it, but I can rebase and pull that patch out
> on a separate immutable branch and then  merge that branch
> into my devel and then you can pull it too.
> 
> Would that work?

Yes, that would be just fine.

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/20160623/2c8ffcc2/attachment.sig>


[PATCH v4.1 1/2] drm/rockchip: analogix_dp: introduce the pclk for grf

2016-06-23 Thread Yakir Yang
For RK3399's GRF module, if we want to operate the graphic related grf
registers, we need to enable the pclk_vio_grf which supply power for VIO
GRF IOs, so it's better to introduce an optional grf clock in driver.

Signed-off-by: Yakir Yang 
---
Hi all,

This is an external patch for analogix_dp misc cleanup thread [0]
[0]: https://patchwork.kernel.org/patch/9175613/

BR,
- Yakir

Changes in v4.1:
- Fix compiled error, sorry.
  "dp->cgfclk"  -->  'dp->grfclk'

Changes in v4:
- Check the the error code properly, 'EPROBE_DEFER' should be returned,
  'ENOENT' should assign a NULL point to grfclk, other errors should be
  regarded as failed. (Tomasz, Doug, reviewed at Google Gerrit)

[https://chromium-review.googlesource.com/#/c/351821/20/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
 at 249]
- Add the document about optional 'grf' clock (Tomasz, Doug, reviewed at Google 
Gerrit)
[https://chromium-review.googlesource.com/#/c/351821/]

Changes in v3:
- Add this patch in v3

 .../display/rockchip/analogix_dp-rockchip.txt  |  6 ++
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 23 +++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
index 726c945..0b39256 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
@@ -28,6 +28,12 @@ Required properties:
 Port 0: contained 2 endpoints, connecting to the output of vop.
 Port 1: contained 1 endpoint, connecting to the input of panel.

+Optional property for different chips:
+- clocks: from common clock binding: handle to grf_vio clock.
+
+- clock-names: from common clock binding:
+  Required elements: "grf"
+
 For the below properties, please refer to Analogix DP binding document:
  * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
 - phys (required)
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 787dc51..864ef92 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -56,6 +56,7 @@ struct rockchip_dp_device {
struct drm_display_mode  mode;

struct clk   *pclk;
+   struct clk   *grfclk;
struct regmap*grf;
struct reset_control *rst;

@@ -151,11 +152,17 @@ static void rockchip_dp_drm_encoder_enable(struct 
drm_encoder *encoder)

dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");

-   ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
-   if (ret != 0) {
-   dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+   ret = clk_prepare_enable(dp->grfclk);
+   if (ret < 0) {
+   dev_err(dp->dev, "failed to enable grfclk %d\n", ret);
return;
}
+
+   ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
+   if (ret != 0)
+   dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+
+   clk_disable_unprepare(dp->grfclk);
 }

 static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
@@ -235,6 +242,16 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
return PTR_ERR(dp->grf);
}

+   dp->grfclk = devm_clk_get(dev, "grf");
+   if (PTR_ERR(dp->grfclk) == -ENOENT) {
+   dp->grfclk = NULL;
+   } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) {
+   return -EPROBE_DEFER;
+   } else if (IS_ERR(dp->grfclk)) {
+   dev_err(dev, "failed to get grf clock\n");
+   return PTR_ERR(dp->grfclk);
+   }
+
dp->pclk = devm_clk_get(dev, "pclk");
if (IS_ERR(dp->pclk)) {
dev_err(dev, "failed to get pclk property\n");
-- 
1.9.1




[RFC PATCH 00/13] Add support for Tegra DPAUX pinctrl

2016-06-23 Thread Linus Walleij
On Fri, Jun 17, 2016 at 6:58 PM, Thierry Reding
 wrote:

> Oh wait... there's the pinctrl helper function that is a build-
> dependency. Linus, would you be okay if I took that through the
> drm-tegra tree along with the DPAUX driver change, and provide a
> stable branch for you to resolve conflicts against if needed?

I have already applied it, but I can rebase and pull that patch out
on a separate immutable branch and then  merge that branch
into my devel and then you can pull it too.

Would that work?

Yours,
Linus Walleij


[PATCH v3 05/10] drm/rockchip: analogix_dp: add rk3399 eDP support

2016-06-23 Thread Sean Paul
On Tue, Jun 14, 2016 at 7:46 AM, Yakir Yang  wrote:
> RK3399 and RK3288 shared the same eDP IP controller, only some light
> difference with VOP configure and GRF configure.
>
> Signed-off-by: Yakir Yang 
> Acked-by: Mark Yao 
> ---
> Changes in v3:
> - Give the "rk3399-edp" a separate line for clarity in document (Tomasz, 
> reviewed at Google Gerrit)
> 
> [https://chromium-review.googlesource.com/#/c/346314/10/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
>  at 5]
> - Move 'output_type' setting before the return statement (Tomasz, reviewed at 
> Google Gerrit)
> 
> [https://chromium-review.googlesource.com/#/c/346314/10/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>  at 154]
> - Add the acked flag from Mark.
>
> Changes in v2:
> - rebase with drm-next, fix some conflicts
>
>  .../bindings/display/bridge/analogix_dp.txt|  1 +
>  .../display/rockchip/analogix_dp-rockchip.txt  |  3 +-
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 33 
> +-
>  include/drm/bridge/analogix_dp.h   |  1 +
>  4 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt 
> b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
> index 4f2ba8c..4a0f4f7 100644
> --- a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
> @@ -5,6 +5,7 @@ Required properties for dp-controller:
> platform specific such as:
>  * "samsung,exynos5-dp"
>  * "rockchip,rk3288-dp"
> +* "rockchip,rk3399-edp"
> -reg:
> physical base address of the controller and length
> of memory mapped region.
> diff --git 
> a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt 
> b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
> index e832ff9..726c945 100644
> --- 
> a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
> +++ 
> b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
> @@ -2,7 +2,8 @@ Rockchip RK3288 specific extensions to the Analogix Display 
> Port
>  
>
>  Required properties:
> -- compatible: "rockchip,rk3288-edp";
> +- compatible: "rockchip,rk3288-edp",
> + "rockchip,rk3399-edp";
>
>  - reg: physical base address of the controller and length
>
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
> b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index 315ebba..bcd9ecc 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -153,6 +153,8 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
> *encoder,
>   struct drm_connector_state *conn_state)
>  {
> struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
> +   struct rockchip_dp_device *dp = to_dp(encoder);
> +   int ret;
>
> /*
>  * FIXME(Yakir): driver should configure the CRTC output video
> @@ -167,7 +169,28 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
> *encoder,
>  * But if I configure CTRC to RGBaaa, and eDP driver still keep
>  * RGB666 input video mode, then screen would works prefect.
>  */
> -   s->output_mode = ROCKCHIP_OUT_MODE_;
> +
> +   ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
> +   if (ret < 0)
> +   return 0;

What is s->output_mode set to in the failure case? How about s->output_type?

> +
> +   switch (dp->data->chip_type) {
> +   case RK3399_EDP:
> +   /*
> +* For RK3399, VOP Lit must code the out mode to RGB888,
> +* VOP Big must code the out mode to RGB10.
> +*/
> +   if (ret)
> +   s->output_mode = ROCKCHIP_OUT_MODE_P888;
> +   else
> +   s->output_mode = ROCKCHIP_OUT_MODE_;
> +   break;
> +
> +   default:
> +   s->output_mode = ROCKCHIP_OUT_MODE_;
> +   break;
> +   }
> +

This chunk seems overly complicated. I'd suggest:

s->output_type = DRM_MODE_CONNECTOR_eDP;
s->output_mode = ROCKCHIP_OUT_MODE_;
if (dp->data->chip_type == RK3399_EDP) {
ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
if (ret > 0)
   s->output_mode = ROCKCHIP_OUT_MODE_P888;
}


> s->output_type = DRM_MODE_CONNECTOR_eDP;
>
> return 0;
> @@ -382,6 +405,13 @@ static const struct dev_pm_ops rockchip_dp_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
>  };
>
> +static const struct rockchip_dp_chip_data rk3399_edp = {
> +   .lcdsel_grf_reg = 0x6250,
> +   

[PATCH v4 2/2] dt-bindings: analogix_dp: rockchip: correct the wrong compatible name

2016-06-23 Thread Yakir Yang
The document about rockchip platform make a mistaken in available
compatible name of "rk3288-edp", we should correct it to "rk3288-dp"
which correspond to the compatible name in driver.

This mistaken was introduced in commit be91c36247089 ("dt-bindings:
add document for rockchip variant of analogix_dp").

Reported-by: Tomasz Figa 
Signed-off-by: Yakir Yang 
---
Hi all,

This is an external patch for analogix_dp misc cleanup thread [0]
[0]: https://patchwork.kernel.org/patch/9175613/

BR,
- Yakir

Changes in v4: None
Changes in v3:
- Add this patch in v3

 .../devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
index 0b39256..01cced1 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
@@ -2,7 +2,7 @@ Rockchip RK3288 specific extensions to the Analogix Display Port
 

 Required properties:
-- compatible: "rockchip,rk3288-edp",
+- compatible: "rockchip,rk3288-dp",
  "rockchip,rk3399-edp";

 - reg: physical base address of the controller and length
-- 
1.9.1




[PATCH v4 1/2] drm/rockchip: analogix_dp: introduce the pclk for grf

2016-06-23 Thread Yakir Yang
For RK3399's GRF module, if we want to operate the graphic related grf
registers, we need to enable the pclk_vio_grf which supply power for VIO
GRF IOs, so it's better to introduce an optional grf clock in driver.

Signed-off-by: Yakir Yang 
---
Hi all,

This is an external patch for analogix_dp misc cleanup thread [0]
[0]: https://patchwork.kernel.org/patch/9175613/

BR,
- Yakir

Changes in v4:
- Check the the error code properly, 'EPROBE_DEFER' should be returned,
  'ENOENT' should assign a NULL point to grfclk, other errors should be
  regarded as failed. (Tomasz, Doug, reviewed at Google Gerrit)

[https://chromium-review.googlesource.com/#/c/351821/20/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
 at 249]
- Add the document about optional 'grf' clock (Tomasz, Doug, reviewed at Google 
Gerrit)
[https://chromium-review.googlesource.com/#/c/351821/]

Changes in v3:
- Add this patch in v3

 .../display/rockchip/analogix_dp-rockchip.txt  |  6 ++
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 23 +++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
index 726c945..0b39256 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
@@ -28,6 +28,12 @@ Required properties:
 Port 0: contained 2 endpoints, connecting to the output of vop.
 Port 1: contained 1 endpoint, connecting to the input of panel.

+Optional property for different chips:
+- clocks: from common clock binding: handle to grf_vio clock.
+
+- clock-names: from common clock binding:
+  Required elements: "grf"
+
 For the below properties, please refer to Analogix DP binding document:
  * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
 - phys (required)
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 787dc51..864ef92 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -56,6 +56,7 @@ struct rockchip_dp_device {
struct drm_display_mode  mode;

struct clk   *pclk;
+   struct clk   *grfclk;
struct regmap*grf;
struct reset_control *rst;

@@ -151,11 +152,17 @@ static void rockchip_dp_drm_encoder_enable(struct 
drm_encoder *encoder)

dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");

-   ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
-   if (ret != 0) {
-   dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+   ret = clk_prepare_enable(dp->grfclk);
+   if (ret < 0) {
+   dev_err(dp->dev, "failed to enable grfclk %d\n", ret);
return;
}
+
+   ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
+   if (ret != 0)
+   dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+
+   clk_disable_unprepare(dp->grfclk);
 }

 static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
@@ -235,6 +242,16 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
return PTR_ERR(dp->grf);
}

+   dp->grfclk = devm_clk_get(dev, "grf");
+   if (PTR_ERR(dp->grfclk) == -ENOENT) {
+   dp->grfclk = NULL;
+   } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) {
+   return -EPROBE_DEFER;
+   } else if (IS_ERR(dp->grfclk)) {
+   dev_err(dev, "failed to get grf clock\n");
+   return PTR_ERR(dp->cfgclk);
+   }
+
dp->pclk = devm_clk_get(dev, "pclk");
if (IS_ERR(dp->pclk)) {
dev_err(dev, "failed to get pclk property\n");
-- 
1.9.1




  1   2   >