[Patch] x86, ia64, efifb: Move boot_vga fixup from pci to vgaarb

2014-05-14 Thread Bruno Prémont
With commit b4aa0163056b6c70029b6e8619ce07c274351f42 Matthew Garret
introduced a efifb vga_default_device() so that EFI systems that do not
load shadow VBIOS or setup VGA get proper value for boot_vga PCI sysfs
attribute on the corresponding PCI device.

Xorg is refusing to autodetect devices when boot_vga=0 which is the case
on some EFI system (e.g. MacBookAir2,1). Xorg detects the GPU and finds
the dri device but then bails out with "no devices detected".

With introduction of sysfb/simplefb/simpledrm efifb is getting obsolete
while having native drivers for the GPU also makes selecting
sysfb/efifb optional.

Remove the efifb implementation of vga_default_device() and initialize
vgaarb's vga_default_device() with the PCI GPU that matches boot
screen_info in pci_fixup_video() [x86 and ia64 pci_fixup_video merged
into common function in vgaarb.c].

Other architectures with PCI GPU might need a similar fixup.

Note: If CONFIG_VGA_ARB is unset vga_default_device() is only available
  as a stub that returns NULL, making this adjustment insufficient.
  In addition, with the merge of x86/ia64 fixup code, this would
  also result in disabled fixup.
  Unsetting CONFIG_VGA_ARB requires CONFIG_EXPERT=y though.

Signed-off-by: Bruno Pr?mont 
---
This is ported to changes in pci/fixup.c that landed in 3.15-rcs.

Is this fine to go in, if so who will take it?

I got no feedback on my last respin (on top of 3.14 a couple of weeks ago,
which added moving the ia64 pci boot_vga fixup).
I've been running this revision for a week or so on 3.15-rc kernels here
(mostly EFI-enabled system, the mentioned MBA as wells as non-Apple systems
where the patch was not required).


 arch/ia64/pci/fixup.c   | 56 ++---
 arch/x86/include/asm/vga.h  |  6 
 arch/x86/pci/fixup.c| 55 +
 drivers/gpu/vga/vgaarb.c| 75 +
 drivers/video/fbdev/efifb.c | 38 ---
 include/linux/vgaarb.h  | 37 ++
 6 files changed, 116 insertions(+), 151 deletions(-)

diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index eee069a..5df22f9 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -9,64 +9,14 @@

 #include 

-/*
- * Fixup to mark boot BIOS video selected by BIOS before it changes
- *
- * From information provided by "Jon Smirl" 
- *
- * The standard boot ROM sequence for an x86 machine uses the BIOS
- * to select an initial video card for boot display. This boot video
- * card will have it's BIOS copied to C in system RAM.
- * IORESOURCE_ROM_SHADOW is used to associate the boot video
- * card with this copy. On laptops this copy has to be used since
- * the main ROM may be compressed or combined with another image.
- * See pci_map_rom() for use of this flag. Before marking the device
- * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set
- * by either arch cde or vga-arbitration, if so only apply the fixup to this
- * already determined primary video card.
- */
-
-static void pci_fixup_video(struct pci_dev *pdev)
+static void pci_ia64_fixup_video(struct pci_dev *pdev)
 {
-   struct pci_dev *bridge;
-   struct pci_bus *bus;
-   u16 config;
-
if ((strcmp(ia64_platform_name, "dig") != 0)
&& (strcmp(ia64_platform_name, "hpzx1")  != 0))
return;
/* Maybe, this machine supports legacy memory map. */

-   /* Is VGA routed to us? */
-   bus = pdev->bus;
-   while (bus) {
-   bridge = bus->self;
-
-   /*
-* From information provided by
-* "David Miller" 
-* The bridge control register is valid for PCI header
-* type BRIDGE, or CARDBUS. Host to PCI controllers use
-* PCI header type NORMAL.
-*/
-   if (bridge
-   &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE)
-  ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) {
-   pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
-   );
-   if (!(config & PCI_BRIDGE_CTL_VGA))
-   return;
-   }
-   bus = bus->parent;
-   }
-   if (!vga_default_device() || pdev == vga_default_device()) {
-   pci_read_config_word(pdev, PCI_COMMAND, );
-   if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
-   pdev->resource[PCI_ROM_RESOURCE].flags |= 
IORESOURCE_ROM_SHADOW;
-   dev_printk(KERN_DEBUG, >dev, "Boot video 
device\n");
-   vga_set_default_device(pdev);
-   }
-   }
+   pci_fixup_video(pdev);
 }
 DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
-   PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
+  

[PATCH 11/12] drm/i915: Accurately initialize fifo underrun state on gmch platforms

2014-05-14 Thread Imre Deak
On Wed, 2014-05-14 at 20:51 +0200, Daniel Vetter wrote:
> We don't have hardware based disable bits on gmch platforms, so need
> to block spurious underrun reports in software. Which means that we
> _must_ start out with fifo underrun reporting disabled everywhere.
> 
> This is in big contrast to ilk/hsw/cpt where there's only _one_
> disable bit for all platforms and hence we must allow underrun
> reporting on disabled pipes. Otherwise nothing really works,
> especially the CRC support since that's key'ed off the same irq
> disable bit.
> 
> This allows us to ditch the fifo underrun reporting hack from the vlv
> runtime pm code and unexport the internal function from i915_irq.c
> again. Yay!
> 
> v2: Keep the display irq disabling, spotted by Imre.
> 
> Cc: Imre Deak 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/i915/i915_irq.c  | 4 ++--
>  drivers/gpu/drm/i915/intel_display.c | 9 -
>  drivers/gpu/drm/i915/intel_drv.h | 2 --
>  drivers/gpu/drm/i915/intel_pm.c  | 6 --
>  4 files changed, 10 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index afa55199b829..a502faae0d0b 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -415,8 +415,8 @@ static void cpt_set_fifo_underrun_reporting(struct 
> drm_device *dev,
>   *
>   * Returns the previous state of underrun reporting.
>   */
> -bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> -  enum pipe pipe, bool enable)
> +static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> + enum pipe pipe, bool enable)
>  {
>   struct drm_i915_private *dev_priv = dev->dev_private;
>   struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index d4abaa4bf2f4..e78003ac71a0 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11510,11 +11510,18 @@ static void intel_sanitize_crtc(struct intel_crtc 
> *crtc)
>   encoder->base.crtc = NULL;
>   }
>   }
> - if (crtc->active) {
> +
> + if (crtc->active || IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen < 5) {
>   /*
>* We start out with underrun reporting disabled to avoid races.
>* For correct bookkeeping mark this on active crtcs.
>*
> +  * Also on gmch platforms we dont have any hardware bits to
> +  * disable the underrun reporting. Which means we need to start
> +  * out with underrun reporting disabled also on inactive pipes,
> +  * since otherwise we'll complain about the garbage we read when
> +  * e.g. coming up after runtime pm.
> +  *
>* No protection against concurrent access is required - at
>* worst a fifo underrun happens which also sets this to false.
>*/
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index b885df150910..d3fa5e0a13bd 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -642,8 +642,6 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
>  /* i915_irq.c */
>  bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
>  enum pipe pipe, bool enable);
> -bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> -  enum pipe pipe, bool enable);
>  bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
>  enum transcoder pch_transcoder,
>  bool enable);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 45fa43f16bb3..08d5d4c16fdf 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5605,15 +5605,9 @@ static void vlv_display_power_well_enable(struct 
> drm_i915_private *dev_priv,
>  static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
>  struct i915_power_well *power_well)
>  {
> - struct drm_device *dev = dev_priv->dev;
> - enum pipe pipe;
> -
>   WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
>  
>   spin_lock_irq(_priv->irq_lock);
> - for_each_pipe(pipe)
> - __intel_set_cpu_fifo_underrun_reporting(dev, pipe, false);
> -

As we discussed on IRC, something like the following could be added to
the commit log:

Originally the purpose of disabling the reporting on vlv was to prevent
spurious underflow reports when the power well is turned off and the
pipestat register containing the underflow flag will read 0x.

[PATCH v3 1/3] phy: Add exynos-simple-phy driver

2014-05-14 Thread Tomasz Figa
Hi Rahul, Tomasz,

On 14.05.2014 21:17, Rahul Sharma wrote:
> From: Tomasz Stanislawski 
> 
> Add exynos-simple-phy driver to support a single register
> PHY interfaces present on Exynos4 SoC.
> 
> Signed-off-by: Tomasz Stanislawski 
> Signed-off-by: Rahul Sharma 
> 
> ---
>  .../devicetree/bindings/phy/samsung-phy.txt|   56 ++
>  drivers/phy/Kconfig|5 +
>  drivers/phy/Makefile   |1 +
>  drivers/phy/exynos-simple-phy.c|  189 
> 
>  include/dt-bindings/phy/exynos-simple-phy.h|   27 +++
>  5 files changed, 278 insertions(+)
>  create mode 100644 drivers/phy/exynos-simple-phy.c
>  create mode 100644 include/dt-bindings/phy/exynos-simple-phy.h
> 
> diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt 
> b/Documentation/devicetree/bindings/phy/samsung-phy.txt
> index 2049261..12ad9cf 100644
> --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
> +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
> @@ -161,3 +161,59 @@ Example:
>   usbdrdphy0 = _phy0;
>   usbdrdphy1 = _phy1;
>   };
> +
> +Samsung S5P/EXYNOS SoC series SIMPLE PHY
> +-
> +
> +Required properties:
> +- compatible : should be one of the listed compatibles:
> + - "samsung,exynos4210-simple-phy"
> + - "samsung,exynos4412-simple-phy"
> + - "samsung,exynos5250-simple-phy"
> + - "samsung,exynos5420-simple-phy"
> +- samsung,pmureg-phandle - handle to syscon to control PMU registers
> +- #phy-cells : from the generic phy bindings, must be 1;
> +
> +For "samsung,exynos4210-simple-phy" compatible PHYs the second cell in
> +the PHY specifier identifies the PHY and the supported phys for exynos4210
> +are:
> +  HDMI_PHY,
> +  DAC_PHY,
> +  ADC_PHY,
> +  PCIE_PHY,
> +  SATA_PHY.
> +
> +For "samsung,exynos4412-simple-phy" compatible PHYs the second cell in
> +the PHY specifier identifies the PHY and the supported phys for exynos4412
> +are:
> +  HDMI_PHY,
> +  ADC_PHY.
> +
> +For "samsung,exynos5250-simple-phy" compatible PHYs the second cell in
> +the PHY specifier identifies the PHY and the supported phys for exynos5250
> +are:
> +  HDMI_PHY,
> +  ADC_PHY,
> +  SATA_PHY.
> +
> +For "samsung,exynos5420-simple-phy" compatible PHYs the second cell in
> +the PHY specifier identifies the PHY and the supported phys for exynos5420
> +are:
> +  HDMI_PHY,
> +  ADC_PHY.
> +
> +Example:
> +Simple PHY provider node:
> +
> + simplephys: simple-phys at 1004 {
> + compatible = "samsung,exynos5250-simple-phy";

Missing reg property or unnecessary @unit-address suffix in node name.

> + samsung,pmu-syscon = <_system_controller>;
> + #phy-cells = <1>;
> + };

In general, the idea is quite good, but I think this should rather bind
to the main PMU node, since this is just a part of the PMU, not another
device in the system. This also means that the PMU node itself should be
the PHY provider.

Otherwise looks good.

Best regards,
Tomasz


[Bug 73378] [drm:radeon_uvd_send_upll_ctlreq] *ERROR* Timeout setting UVD clocks!

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=73378

--- Comment #7 from ?yvind Saether  ---
> Can you bisect?

Not sure how to do that but if you want to point me to some instructions then
please do.

Basically suspend and resume works with 3.12 kernels but in later kernels I can
suspend and then resume once but after that the system does not suspend
anymore.

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


[Bug 75992] Display freezes & corruption with an r7 260x on 3.14-rc6

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=75992

--- Comment #59 from nicolas.laplante at gmail.com ---
Well, same thing with _mc2.bin, except this line (size changed):

radeon/BONAIRE_mc2.bin: 31792 bytes

I still get the Direct firmware load error and calibrating clocksource TSC
takes a long time too. Usually I get this slowdown when the drm firmware cannot
be loaded correctly.

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


[Bug 75992] Display freezes & corruption with an r7 260x on 3.14-rc6

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=75992

--- Comment #58 from nicolas.laplante at gmail.com ---
Just saw that I'm loading the wrong firmware (_mc, not _mc2). Sorry. I'll try
this now.

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


[Bug 75992] Display freezes & corruption with an r7 260x on 3.14-rc6

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=75992

--- Comment #57 from nicolas.laplante at gmail.com ---
Ok, tried 3.15_rc5 and I get no corruption. But, booting took a long time
(calibrating clocksource TSC) and I got this message:

radeon :01:00.0: Direct firmware load failed with error -2

Here's the dmesg | grep drm:

[0.703606] [drm] Initialized drm 1.1.0 20060810
[0.703728] [drm] radeon kernel modesetting enabled.
[0.704231] [drm] initializing kernel modesetting (BONAIRE 0x1002:0x6658
0x174B:0xE253).
[0.704390] [drm] register mmio base: 0xFE9C
[0.704477] [drm] register mmio size: 262144
[0.704565] [drm] doorbell mmio base: 0xCF80
[0.704649] [drm] doorbell mmio size: 8388608
[0.707062] [drm] Detected VRAM RAM=2048M, BAR=256M
[0.707148] [drm] RAM width 128bits DDR
[0.707658] [drm] radeon: 2048M of VRAM memory ready
[0.707744] [drm] radeon: 1024M of GTT memory ready.
[0.707846] [drm] Loading BONAIRE Microcode
[   60.691462] [drm] radeon/BONAIRE_mc.bin: 31464 bytes
[   60.691551] [drm] Internal thermal controller with fan control
[   60.691679] [drm] probing gen 2 caps for device 1002:5978 = 300d02/0
[   60.699424] [drm] radeon: dpm initialized
[  120.799122] [drm] GART: num cpu pages 262144, num gpu pages 262144
[  120.801322] [drm] probing gen 2 caps for device 1002:5978 = 300d02/0
[  120.801413] [drm] PCIE gen 2 link speeds already enabled
[  120.810251] [drm] PCIE GART of 1024M enabled (table at 0x00277000).
[  120.811879] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[  120.811968] [drm] Driver supports precise vblank timestamp query.
[  120.812206] [drm] radeon: irq initialized.
[  120.814520] [drm] ring test on 0 succeeded in 3 usecs
[  120.814689] [drm] ring test on 1 succeeded in 3 usecs
[  120.814790] [drm] ring test on 2 succeeded in 3 usecs
[  120.815030] [drm] ring test on 3 succeeded in 2 usecs
[  120.815127] [drm] ring test on 4 succeeded in 2 usecs
[  120.871242] [drm] ring test on 5 succeeded in 2 usecs
[  120.891334] [drm] UVD initialized successfully.
[  120.891718] [drm] ib test on ring 0 succeeded in 0 usecs
[  120.891961] [drm] ib test on ring 1 succeeded in 0 usecs
[  120.892205] [drm] ib test on ring 2 succeeded in 0 usecs
[  120.892467] [drm] ib test on ring 3 succeeded in 0 usecs
[  120.892719] [drm] ib test on ring 4 succeeded in 0 usecs
[  120.913684] [drm] ib test on ring 5 succeeded
[  120.934151] [drm] Radeon Display Connectors
[  120.934232] [drm] Connector 0:
[  120.934318] [drm]   DP-1
[  120.934402] [drm]   HPD2
[  120.934488] [drm]   DDC: 0x6530 0x6530 0x6534 0x6534 0x6538 0x6538 0x653c
0x653c
[  120.934615] [drm]   Encoders:
[  120.934700] [drm] DFP1: INTERNAL_UNIPHY2
[  120.934786] [drm] Connector 1:
[  120.934864] [drm]   HDMI-A-1
[  120.934948] [drm]   HPD3
[  120.935033] [drm]   DDC: 0x6550 0x6550 0x6554 0x6554 0x6558 0x6558 0x655c
0x655c
[  120.935152] [drm]   Encoders:
[  120.935230] [drm] DFP2: INTERNAL_UNIPHY2
[  120.935315] [drm] Connector 2:
[  120.935394] [drm]   DVI-D-1
[  120.935479] [drm]   HPD1
[  120.935563] [drm]   DDC: 0x6560 0x6560 0x6564 0x6564 0x6568 0x6568 0x656c
0x656c
[  120.935684] [drm]   Encoders:
[  120.935763] [drm] DFP3: INTERNAL_UNIPHY1
[  120.935850] [drm] Connector 3:
[  120.935928] [drm]   DVI-I-1
[  120.936006] [drm]   HPD6
[  120.936085] [drm]   DDC: 0x6580 0x6580 0x6584 0x6584 0x6588 0x6588 0x658c
0x658c
[  120.936211] [drm]   Encoders:
[  120.936295] [drm] DFP4: INTERNAL_UNIPHY
[  120.936381] [drm] CRT1: INTERNAL_KLDSCP_DAC1
[  120.990787] [drm] fb mappable at 0xD047A000
[  120.990873] [drm] vram apper at 0xD000
[  120.990952] [drm] size 7299072
[  120.991037] [drm] fb depth is 24
[  120.991116] [drm]pitch is 6912
[  120.991261] fbcon: radeondrmfb (fb0) is primary device
[  121.025398] radeon :01:00.0: fb0: radeondrmfb frame buffer device
[  121.026375] [drm] Initialized radeon 2.38.0 20080528 for :01:00.0 on
minor

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


[Bug 76231] New: radeon: DCE2 & DCE3 HDMI setup should be updated/improved (to match fglrx)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76231

Bug ID: 76231
   Summary: radeon: DCE2 & DCE3 HDMI setup should be
updated/improved (to match fglrx)
   Product: Drivers
   Version: 2.5
Kernel Version: torvalds/linux.git
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-dri at kernel-bugs.osdl.org
  Reporter: zajec5 at gmail.com
Regression: No

Created attachment 136121
  --> https://bugzilla.kernel.org/attachment.cgi?id=136121=edit
Log of fglrx with DCE 2.0 and DCE 3.0 cards (HDMI setup)

Current code isn't based on a perfect RE method, we were mostly observing
registers, not tracing fglrx operations.
It should be a good idea to trace fglrx operations and improve radeon's code to
match it as much as possible.

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


[PATCH 04/12] drm: Add drm_vblank_on()

2014-05-14 Thread Daniel Vetter
On Wed, May 14, 2014 at 08:51:06PM +0200, Daniel Vetter wrote:
> From: Ville Syrj?l? 
> 
> drm_vblank_off() will turn off vblank interrupts, but as long as the
> refcount is elevated drm_vblank_get() will not re-enable them. This
> is a problem is someone is holding a vblank reference while a modeset is
> happening, and the driver requires vblank interrupt to work during that
> time.
> 
> Add drm_vblank_on() as a counterpart to drm_vblank_off() which will
> re-enabled vblank interrupts if the refcount is already elevated. This
> will allow drivers to choose the specific places in the modeset sequence
> at which vblank interrupts get disabled and enabled.
> 
> Testcase: igt/kms_flip/*-vs-suspend

Testcase: igt/kms_flip/*-vs-vblank-race

> Signed-off-by: Ville Syrj?l? 
> [danvet: Add Testcase tag for the igt I've written.]
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_irq.c| 72 
> ++--
>  drivers/gpu/drm/i915/intel_display.c |  8 
>  include/drm/drmP.h   |  1 +
>  3 files changed, 62 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 13d671ed3421..dd786d84daab 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -840,6 +840,41 @@ static void drm_update_vblank_count(struct drm_device 
> *dev, int crtc)
>  }
>  
>  /**
> + * drm_vblank_enable - enable the vblank interrupt on a CRTC
> + * @dev: DRM device
> + * @crtc: CRTC in question
> + */
> +static int drm_vblank_enable(struct drm_device *dev, int crtc)
> +{
> + int ret = 0;
> +
> + assert_spin_locked(>vbl_lock);
> +
> + spin_lock(>vblank_time_lock);
> +
> + if (!dev->vblank[crtc].enabled) {
> + /* Enable vblank irqs under vblank_time_lock protection.
> +  * All vblank count & timestamp updates are held off
> +  * until we are done reinitializing master counter and
> +  * timestamps. Filtercode in drm_handle_vblank() will
> +  * prevent double-accounting of same vblank interval.
> +  */
> + ret = dev->driver->enable_vblank(dev, crtc);
> + DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
> + if (ret)
> + atomic_dec(>vblank[crtc].refcount);
> + else {
> + dev->vblank[crtc].enabled = true;
> + drm_update_vblank_count(dev, crtc);
> + }
> + }
> +
> + spin_unlock(>vblank_time_lock);
> +
> + return ret;
> +}
> +
> +/**
>   * drm_vblank_get - get a reference count on vblank events
>   * @dev: DRM device
>   * @crtc: which CRTC to own
> @@ -858,25 +893,7 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
>   spin_lock_irqsave(>vbl_lock, irqflags);
>   /* Going from 0->1 means we have to enable interrupts again */
>   if (atomic_add_return(1, >vblank[crtc].refcount) == 1) {
> - spin_lock(>vblank_time_lock);
> - if (!dev->vblank[crtc].enabled) {
> - /* Enable vblank irqs under vblank_time_lock protection.
> -  * All vblank count & timestamp updates are held off
> -  * until we are done reinitializing master counter and
> -  * timestamps. Filtercode in drm_handle_vblank() will
> -  * prevent double-accounting of same vblank interval.
> -  */
> - ret = dev->driver->enable_vblank(dev, crtc);
> - DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n",
> -   crtc, ret);
> - if (ret)
> - atomic_dec(>vblank[crtc].refcount);
> - else {
> - dev->vblank[crtc].enabled = true;
> - drm_update_vblank_count(dev, crtc);
> - }
> - }
> - spin_unlock(>vblank_time_lock);
> + ret = drm_vblank_enable(dev, crtc);
>   } else {
>   if (!dev->vblank[crtc].enabled) {
>   atomic_dec(>vblank[crtc].refcount);
> @@ -946,6 +963,23 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
>  EXPORT_SYMBOL(drm_vblank_off);
>  
>  /**
> + * drm_vblank_on - enable vblank events on a CRTC
> + * @dev: DRM device
> + * @crtc: CRTC in question
> + */
> +void drm_vblank_on(struct drm_device *dev, int crtc)
> +{
> + unsigned long irqflags;
> +
> + spin_lock_irqsave(>vbl_lock, irqflags);
> + /* re-enable interrupts if there's are users left */
> + if (atomic_read(>vblank[crtc].refcount) != 0)
> + WARN_ON(drm_vblank_enable(dev, crtc));
> + spin_unlock_irqrestore(>vbl_lock, irqflags);
> +}
> +EXPORT_SYMBOL(drm_vblank_on);
> +
> +/**
>   * drm_vblank_pre_modeset - account for vblanks across mode sets
>   * @dev: DRM device
>   * @crtc: CRTC in question
> diff 

[PATCH 12/12] [RFC] drm/crtc-helper: Enforce sane vblank counter semantics

2014-05-14 Thread Daniel Vetter
It literally took us years in i915 to track down all the vblank
bogosity, which means that userspace has now code to deal with random
crap like stuck vblank waits, needless counter wraps and other
hilarity.

To make sure that all drivers are at least somewhat sane enforce
minimal standards in the crtc helpers. Note that this is not perfect
since for intermediate levels it's unclear whether the vblank will
keep on running. Modern userspace is advised to just never use those.

Totatlly untested.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_crtc_helper.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index df281b54db01..64d8797cd172 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -167,6 +167,8 @@ static void __drm_helper_disable_unused_functions(struct 
drm_device *dev)
else
(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
crtc->primary->fb = NULL;
+
+   drm_crtc_vblank_off(crtc->dev, crtc);
}
}
 }
@@ -323,6 +325,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,

crtc_funcs->prepare(crtc);

+   drm_crtc_vblank_off(dev, crtc);
+
/* Set up the DPLL and any encoders state that needs to adjust or depend
 * on the DPLL.
 */
@@ -349,6 +353,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
crtc_funcs->commit(crtc);

+   drm_crtc_vblank_on(dev, crtc);
+
list_for_each_entry(encoder, >mode_config.encoder_list, head) {

if (encoder->crtc != crtc)
@@ -767,6 +773,9 @@ void drm_helper_connector_dpms(struct drm_connector 
*connector, int mode)
if (crtc_funcs->dpms)
(*crtc_funcs->dpms) (crtc,
 
drm_helper_choose_crtc_dpms(crtc));
+
+   if (mode == DRM_MODE_DPMS_ON)
+   drm_crtc_vblank_on(crtc->dev, crtc);
}
if (encoder)
drm_helper_encoder_dpms(encoder, encoder_dpms);
@@ -781,6 +790,9 @@ void drm_helper_connector_dpms(struct drm_connector 
*connector, int mode)
if (crtc_funcs->dpms)
(*crtc_funcs->dpms) (crtc,
 
drm_helper_choose_crtc_dpms(crtc));
+
+   if (mode == DRM_MODE_DPMS_OFF)
+   drm_crtc_vblank_off(crtc->dev, crtc);
}
}

-- 
1.8.3.1



[PATCH 11/12] [RFC] drm/irq: More robustness in drm_vblank_on|off

2014-05-14 Thread Daniel Vetter
If we want to use this functionality in generic helpers to make
sure that all drivers have somewhat sane vblank handling across
modesets/dpms, we need to make it work for all drivers. But some
don't support interrupts and hence also not vblank waits.

Just return early on such drivers.

Note that with pageflips drivers are free to implement them however
they wish to.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_irq.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 51ebe9086be9..03fba43ab6be 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1020,6 +1020,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
unsigned long irqflags;
unsigned int seq;

+   if (!dev->irq_enabled)
+   return;
+
spin_lock_irqsave(>vbl_lock, irqflags);
vblank_disable_and_save(dev, crtc);
wake_up(>vblank[crtc].queue);
@@ -1080,6 +1083,9 @@ void drm_vblank_on(struct drm_device *dev, int crtc)
 {
unsigned long irqflags;

+   if (!dev->irq_enabled)
+   return;
+
spin_lock_irqsave(>vbl_lock, irqflags);
/* re-enable interrupts if there's are users left */
if (atomic_read(>vblank[crtc].refcount) != 0)
-- 
1.8.3.1



[PATCH 11/12] drm/i915: Accurately initialize fifo underrun state on gmch platforms

2014-05-14 Thread Daniel Vetter
We don't have hardware based disable bits on gmch platforms, so need
to block spurious underrun reports in software. Which means that we
_must_ start out with fifo underrun reporting disabled everywhere.

This is in big contrast to ilk/hsw/cpt where there's only _one_
disable bit for all platforms and hence we must allow underrun
reporting on disabled pipes. Otherwise nothing really works,
especially the CRC support since that's key'ed off the same irq
disable bit.

This allows us to ditch the fifo underrun reporting hack from the vlv
runtime pm code and unexport the internal function from i915_irq.c
again. Yay!

v2: Keep the display irq disabling, spotted by Imre.

Cc: Imre Deak 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_irq.c  | 4 ++--
 drivers/gpu/drm/i915/intel_display.c | 9 -
 drivers/gpu/drm/i915/intel_drv.h | 2 --
 drivers/gpu/drm/i915/intel_pm.c  | 6 --
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index afa55199b829..a502faae0d0b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -415,8 +415,8 @@ static void cpt_set_fifo_underrun_reporting(struct 
drm_device *dev,
  *
  * Returns the previous state of underrun reporting.
  */
-bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
-enum pipe pipe, bool enable)
+static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
+   enum pipe pipe, bool enable)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index d4abaa4bf2f4..e78003ac71a0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11510,11 +11510,18 @@ static void intel_sanitize_crtc(struct intel_crtc 
*crtc)
encoder->base.crtc = NULL;
}
}
-   if (crtc->active) {
+
+   if (crtc->active || IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen < 5) {
/*
 * We start out with underrun reporting disabled to avoid races.
 * For correct bookkeeping mark this on active crtcs.
 *
+* Also on gmch platforms we dont have any hardware bits to
+* disable the underrun reporting. Which means we need to start
+* out with underrun reporting disabled also on inactive pipes,
+* since otherwise we'll complain about the garbage we read when
+* e.g. coming up after runtime pm.
+*
 * No protection against concurrent access is required - at
 * worst a fifo underrun happens which also sets this to false.
 */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b885df150910..d3fa5e0a13bd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -642,8 +642,6 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
 /* i915_irq.c */
 bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
   enum pipe pipe, bool enable);
-bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
-enum pipe pipe, bool enable);
 bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
   enum transcoder pch_transcoder,
   bool enable);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 45fa43f16bb3..08d5d4c16fdf 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5605,15 +5605,9 @@ static void vlv_display_power_well_enable(struct 
drm_i915_private *dev_priv,
 static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
   struct i915_power_well *power_well)
 {
-   struct drm_device *dev = dev_priv->dev;
-   enum pipe pipe;
-
WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);

spin_lock_irq(_priv->irq_lock);
-   for_each_pipe(pipe)
-   __intel_set_cpu_fifo_underrun_reporting(dev, pipe, false);
-
valleyview_disable_display_irqs(dev_priv);
spin_unlock_irq(_priv->irq_lock);

-- 
1.8.3.1



[PATCH 10/12] drm/i915: rip our vblank reset hacks for runtime PM

2014-05-14 Thread Daniel Vetter
Now that we unconditionally dtrt when disabling/enabling crtcs we
don't need any hacks any longer to keep the vblank logic sane when
all the registers go poof. So let's rip it all out.

This essentially undoes

commit 9dbd8febb4dbc9199fcf340b882eb930e36b65b6
Author: Paulo Zanoni 
Date:   Tue Jul 23 10:48:11 2013 -0300

drm/i915: update last_vblank when disabling the power well

Apparently igt/kms_flip is already powerful enough to exercise this
properly, yay! See the reference regression report for details.

References: https://bugs.freedesktop.org/show_bug.cgi?id=66808
Testcase: igt/kms_flip/*-vs-rpm
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_pm.c | 34 --
 1 file changed, 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 75c1c766b507..45fa43f16bb3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5423,33 +5423,6 @@ static void hsw_power_well_post_enable(struct 
drm_i915_private *dev_priv)
}
 }

-static void reset_vblank_counter(struct drm_device *dev, enum pipe pipe)
-{
-   assert_spin_locked(>vbl_lock);
-
-   dev->vblank[pipe].last = 0;
-}
-
-static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
-{
-   struct drm_device *dev = dev_priv->dev;
-   enum pipe pipe;
-   unsigned long irqflags;
-
-   /*
-* After this, the registers on the pipes that are part of the power
-* well will become zero, so we have to adjust our counters according to
-* that.
-*
-* FIXME: Should we do this in general in drm_vblank_post_modeset?
-*/
-   spin_lock_irqsave(>vbl_lock, irqflags);
-   for_each_pipe(pipe)
-   if (pipe != PIPE_A)
-   reset_vblank_counter(dev, pipe);
-   spin_unlock_irqrestore(>vbl_lock, irqflags);
-}
-
 static void hsw_set_power_well(struct drm_i915_private *dev_priv,
   struct i915_power_well *power_well, bool enable)
 {
@@ -5478,8 +5451,6 @@ static void hsw_set_power_well(struct drm_i915_private 
*dev_priv,
I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
POSTING_READ(HSW_PWR_WELL_DRIVER);
DRM_DEBUG_KMS("Requesting to disable the power well\n");
-
-   hsw_power_well_post_disable(dev_priv);
}
}
 }
@@ -5646,11 +5617,6 @@ static void vlv_display_power_well_disable(struct 
drm_i915_private *dev_priv,
valleyview_disable_display_irqs(dev_priv);
spin_unlock_irq(_priv->irq_lock);

-   spin_lock_irq(>vbl_lock);
-   for_each_pipe(pipe)
-   reset_vblank_counter(dev, pipe);
-   spin_unlock_irq(>vbl_lock);
-
vlv_set_power_well(dev_priv, power_well, false);
 }

-- 
1.8.3.1



[PATCH 10/12] drm/i915: Accurately initialize fifo underrun state on gmch platforms

2014-05-14 Thread Daniel Vetter
We don't have hardware based disable bits on gmch platforms, so need
to block spurious underrun reports in software. Which means that we
_must_ start out with fifo underrun reporting disabled everywhere.

This is in big contrast to ilk/hsw/cpt where there's only _one_
disable bit for all platforms and hence we must allow underrun
reporting on disabled pipes. Otherwise nothing really works,
especially the CRC support since that's key'ed off the same irq
disable bit.

This allows us to ditch the fifo underrun reporting hack from the vlv
runtime pm code and unexport the internal function from i915_irq.c
again. Yay!

v2: Keep the display irq disabling, spotted by Imre.

Cc: Imre Deak 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_irq.c  | 4 ++--
 drivers/gpu/drm/i915/intel_display.c | 9 -
 drivers/gpu/drm/i915/intel_drv.h | 2 --
 drivers/gpu/drm/i915/intel_pm.c  | 6 --
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index afa55199b829..a502faae0d0b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -415,8 +415,8 @@ static void cpt_set_fifo_underrun_reporting(struct 
drm_device *dev,
  *
  * Returns the previous state of underrun reporting.
  */
-bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
-enum pipe pipe, bool enable)
+static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
+   enum pipe pipe, bool enable)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index d4abaa4bf2f4..e78003ac71a0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11510,11 +11510,18 @@ static void intel_sanitize_crtc(struct intel_crtc 
*crtc)
encoder->base.crtc = NULL;
}
}
-   if (crtc->active) {
+
+   if (crtc->active || IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen < 5) {
/*
 * We start out with underrun reporting disabled to avoid races.
 * For correct bookkeeping mark this on active crtcs.
 *
+* Also on gmch platforms we dont have any hardware bits to
+* disable the underrun reporting. Which means we need to start
+* out with underrun reporting disabled also on inactive pipes,
+* since otherwise we'll complain about the garbage we read when
+* e.g. coming up after runtime pm.
+*
 * No protection against concurrent access is required - at
 * worst a fifo underrun happens which also sets this to false.
 */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b885df150910..d3fa5e0a13bd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -642,8 +642,6 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
 /* i915_irq.c */
 bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
   enum pipe pipe, bool enable);
-bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
-enum pipe pipe, bool enable);
 bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
   enum transcoder pch_transcoder,
   bool enable);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 45fa43f16bb3..08d5d4c16fdf 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5605,15 +5605,9 @@ static void vlv_display_power_well_enable(struct 
drm_i915_private *dev_priv,
 static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
   struct i915_power_well *power_well)
 {
-   struct drm_device *dev = dev_priv->dev;
-   enum pipe pipe;
-
WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);

spin_lock_irq(_priv->irq_lock);
-   for_each_pipe(pipe)
-   __intel_set_cpu_fifo_underrun_reporting(dev, pipe, false);
-
valleyview_disable_display_irqs(dev_priv);
spin_unlock_irq(_priv->irq_lock);

-- 
1.8.3.1



[PATCH 09/12] drm/irq: Lack of interrupt support in drm_vblank_on|off

2014-05-14 Thread Daniel Vetter
If we want to use this functionality in generic helpers to make
sure that all drivers have somewhat sane vblank handling across
modesets/dpms, we need to make it work for all drivers. But some
don't support interrupts and hence also not vblank waits.

Just return early on such drivers.

Note that with pageflips drivers are free to implement them however
they wish to.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_irq.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 51ebe9086be9..03fba43ab6be 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1020,6 +1020,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
unsigned long irqflags;
unsigned int seq;

+   if (!dev->irq_enabled)
+   return;
+
spin_lock_irqsave(>vbl_lock, irqflags);
vblank_disable_and_save(dev, crtc);
wake_up(>vblank[crtc].queue);
@@ -1080,6 +1083,9 @@ void drm_vblank_on(struct drm_device *dev, int crtc)
 {
unsigned long irqflags;

+   if (!dev->irq_enabled)
+   return;
+
spin_lock_irqsave(>vbl_lock, irqflags);
/* re-enable interrupts if there's are users left */
if (atomic_read(>vblank[crtc].refcount) != 0)
-- 
1.8.3.1



[PATCH 09/12] drm/i915: rip our vblank reset hacks for runtime PM

2014-05-14 Thread Daniel Vetter
Now that we unconditionally dtrt when disabling/enabling crtcs we
don't need any hacks any longer to keep the vblank logic sane when
all the registers go poof. So let's rip it all out.

This essentially undoes

commit 9dbd8febb4dbc9199fcf340b882eb930e36b65b6
Author: Paulo Zanoni 
Date:   Tue Jul 23 10:48:11 2013 -0300

drm/i915: update last_vblank when disabling the power well

Apparently igt/kms_flip is already powerful enough to exercise this
properly, yay! See the reference regression report for details.

References: https://bugs.freedesktop.org/show_bug.cgi?id=66808
Testcase: igt/kms_flip/*-vs-rpm
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_pm.c | 34 --
 1 file changed, 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 75c1c766b507..45fa43f16bb3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5423,33 +5423,6 @@ static void hsw_power_well_post_enable(struct 
drm_i915_private *dev_priv)
}
 }

-static void reset_vblank_counter(struct drm_device *dev, enum pipe pipe)
-{
-   assert_spin_locked(>vbl_lock);
-
-   dev->vblank[pipe].last = 0;
-}
-
-static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
-{
-   struct drm_device *dev = dev_priv->dev;
-   enum pipe pipe;
-   unsigned long irqflags;
-
-   /*
-* After this, the registers on the pipes that are part of the power
-* well will become zero, so we have to adjust our counters according to
-* that.
-*
-* FIXME: Should we do this in general in drm_vblank_post_modeset?
-*/
-   spin_lock_irqsave(>vbl_lock, irqflags);
-   for_each_pipe(pipe)
-   if (pipe != PIPE_A)
-   reset_vblank_counter(dev, pipe);
-   spin_unlock_irqrestore(>vbl_lock, irqflags);
-}
-
 static void hsw_set_power_well(struct drm_i915_private *dev_priv,
   struct i915_power_well *power_well, bool enable)
 {
@@ -5478,8 +5451,6 @@ static void hsw_set_power_well(struct drm_i915_private 
*dev_priv,
I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
POSTING_READ(HSW_PWR_WELL_DRIVER);
DRM_DEBUG_KMS("Requesting to disable the power well\n");
-
-   hsw_power_well_post_disable(dev_priv);
}
}
 }
@@ -5646,11 +5617,6 @@ static void vlv_display_power_well_disable(struct 
drm_i915_private *dev_priv,
valleyview_disable_display_irqs(dev_priv);
spin_unlock_irq(_priv->irq_lock);

-   spin_lock_irq(>vbl_lock);
-   for_each_pipe(pipe)
-   reset_vblank_counter(dev, pipe);
-   spin_unlock_irq(>vbl_lock);
-
vlv_set_power_well(dev_priv, power_well, false);
 }

-- 
1.8.3.1



[PATCH 08/12] drm/irq: Add kms-native crtc interface functions

2014-05-14 Thread Daniel Vetter
We need to start somewhere ... With this the only places left in i915
where we use pipe integers is in the interrupt handling code. And
there it actually makes some amount of sense.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_irq.c| 81 
 drivers/gpu/drm/i915/intel_display.c | 22 +-
 include/drm/drmP.h   |  5 +++
 3 files changed, 98 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 5ff986bd4de4..51ebe9086be9 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -916,6 +916,8 @@ static int drm_vblank_enable(struct drm_device *dev, int 
crtc)
  * Acquire a reference count on vblank events to avoid having them disabled
  * while in use.
  *
+ * This is the legacy version of drm_crtc_vblank_get().
+ *
  * Returns:
  * Zero on success, nonzero on failure.
  */
@@ -941,12 +943,33 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
 EXPORT_SYMBOL(drm_vblank_get);

 /**
+ * drm_crtc_vblank_get - get a reference count on vblank events
+ * @dev: drm device
+ * @crtc: which CRTC to own
+ *
+ * Acquire a reference count on vblank events to avoid having them disabled
+ * while in use.
+ *
+ * This is the native kms version of drm_vblank_off().
+ *
+ * Returns:
+ * Zero on success, nonzero on failure.
+ */
+int drm_crtc_vblank_get(struct drm_device *dev, struct drm_crtc *crtc)
+{
+   return drm_vblank_get(dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_get);
+
+/**
  * drm_vblank_put - give up ownership of vblank events
  * @dev: drm device
  * @crtc: which counter to give up
  *
  * Release ownership of a given vblank counter, turning off interrupts
  * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
+ *
+ * This is the legacy version of drm_crtc_vblank_put().
  */
 void drm_vblank_put(struct drm_device *dev, int crtc)
 {
@@ -961,6 +984,22 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
 EXPORT_SYMBOL(drm_vblank_put);

 /**
+ * drm_crtc_vblank_put - give up ownership of vblank events
+ * @dev: drm device
+ * @crtc: which counter to give up
+ *
+ * Release ownership of a given vblank counter, turning off interrupts
+ * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
+ *
+ * This is the native kms version of drm_vblank_put().
+ */
+void drm_crtc_vblank_put(struct drm_device *dev, struct drm_crtc *crtc)
+{
+   drm_vblank_put(dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_put);
+
+/**
  * drm_vblank_off - disable vblank events on a CRTC
  * @dev: drm device
  * @crtc: CRTC in question
@@ -971,6 +1010,8 @@ EXPORT_SYMBOL(drm_vblank_put);
  *
  * Drivers must use this function when the hardware vblank counter can get
  * reset, e.g. when suspending.
+ *
+ * This is the legacy version of drm_crtc_vblank_off().
  */
 void drm_vblank_off(struct drm_device *dev, int crtc)
 {
@@ -1004,6 +1045,26 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
 EXPORT_SYMBOL(drm_vblank_off);

 /**
+ * drm_crtc_vblank_off - disable vblank events on a CRTC
+ * @dev: drm device
+ * @crtc: CRTC in question
+ *
+ * Drivers can use this function to shut down the vblank interrupt handling 
when
+ * disabling a crtc. This function ensures that the latest vblank frame count 
is
+ * stored so that drm_vblank_on can restore it again.
+ *
+ * Drivers must use this function when the hardware vblank counter can get
+ * reset, e.g. when suspending.
+ *
+ * This is the native kms version of drm_vblank_off().
+ */
+void drm_crtc_vblank_off(struct drm_device *dev, struct drm_crtc *crtc)
+{
+   drm_vblank_off(dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_off);
+
+/**
  * drm_vblank_on - enable vblank events on a CRTC
  * @dev: drm device
  * @crtc: CRTC in question
@@ -1012,6 +1073,8 @@ EXPORT_SYMBOL(drm_vblank_off);
  * drm_vblank_off() again. Note that calls to drm_vblank_on() and
  * drm_vblank_off() can be unbalanced and so can also be unconditionaly called
  * in driver load code to reflect the current hardware state of the crtc.
+ *
+ * This is the legacy version of drm_crtc_vblank_on().
  */
 void drm_vblank_on(struct drm_device *dev, int crtc)
 {
@@ -1026,6 +1089,24 @@ void drm_vblank_on(struct drm_device *dev, int crtc)
 EXPORT_SYMBOL(drm_vblank_on);

 /**
+ * drm_crtc_vblank_on - enable vblank events on a CRTC
+ * @dev: drm device
+ * @crtc: CRTC in question
+ *
+ * This functions restores the vblank interrupt state captured with
+ * drm_vblank_off() again. Note that calls to drm_vblank_on() and
+ * drm_vblank_off() can be unbalanced and so can also be unconditionaly called
+ * in driver load code to reflect the current hardware state of the crtc.
+ *
+ * This is the native kms version of drm_vblank_on().
+ */
+void drm_crtc_vblank_on(struct drm_device *dev, struct drm_crtc *crtc)
+{
+   drm_vblank_on(dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_on);
+

[PATCH 07/12] drm/irq: kerneldoc polish

2014-05-14 Thread Daniel Vetter
- Integrate into the drm DocBook
- Disable kerneldoc for functions not exported to drivers.
- Properly document the new drm_vblank_on|off and add cautious
  comments explaining when drm_vblank_pre|post_modesets shouldn't be
  used.
- General polish and OCD.

Signed-off-by: Daniel Vetter 
---
 Documentation/DocBook/drm.tmpl |   5 +-
 drivers/gpu/drm/drm_irq.c  | 181 -
 2 files changed, 129 insertions(+), 57 deletions(-)

diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index e37a77a72b8b..70ef87bcea04 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2519,6 +2519,10 @@ void (*disable_vblank) (struct drm_device *dev, int 
crtc);
   with a call to drm_vblank_cleanup in the driver
   unload operation handler.
 
+
+  Vertical Blanking and Interrupt Handling Functions 
Reference
+!Edrivers/gpu/drm/drm_irq.c
+
   

   
@@ -2870,7 +2874,6 @@ int num_ioctls;
 
   
 
-
   
 

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index dd786d84daab..5ff986bd4de4 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1,6 +1,5 @@
-/**
- * \file drm_irq.c
- * IRQ support
+/*
+ * drm_irq.c IRQ and vblank support
  *
  * \author Rickard E. (Rik) Faith 
  * \author Gareth Hughes 
@@ -156,6 +155,12 @@ static void vblank_disable_fn(unsigned long arg)
spin_unlock_irqrestore(>vbl_lock, irqflags);
 }

+/**
+ * drm_vblank_cleanup - cleanup vblank support
+ * @dev: drm device
+ *
+ * This function cleans up any resources allocated in drm_vblank_init.
+ */
 void drm_vblank_cleanup(struct drm_device *dev)
 {
int crtc;
@@ -175,6 +180,16 @@ void drm_vblank_cleanup(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_vblank_cleanup);

+/**
+ * drm_vblank_init - initialize vblank support
+ * @dev: drm_device
+ * @num_crtcs: number of crtcs supported by @dev
+ *
+ * This function initializes vblank support for @num_crtcs display pipelines.
+ *
+ * Returns:
+ * Zero on success or a negative error code on failure.
+ */
 int drm_vblank_init(struct drm_device *dev, int num_crtcs)
 {
int i, ret = -ENOMEM;
@@ -238,13 +253,21 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
 }

 /**
- * Install IRQ handler.
- *
- * \param dev DRM device.
+ * drm_irq_install - install IRQ handler
+ * @dev: drm device
+ * @irq: irq number to install the handler for
  *
  * Initializes the IRQ related data. Installs the handler, calling the driver
- * \c irq_preinstall() and \c irq_postinstall() functions
- * before and after the installation.
+ * irq_preinstall() and irq_postinstall() functions before and after the
+ * installation.
+ *
+ * This is the simplified helper interface provided for drivers with no special
+ * needs. Drivers which need to install interrupt handlers for multiple
+ * interrupts must instead set drm_device->irq_enabled to signal the drm core
+ * that vblank interrupts are available.
+ *
+ * Returns:
+ * Zero on success or a negative error code on failure.
  */
 int drm_irq_install(struct drm_device *dev, int irq)
 {
@@ -304,11 +327,20 @@ int drm_irq_install(struct drm_device *dev, int irq)
 EXPORT_SYMBOL(drm_irq_install);

 /**
- * Uninstall the IRQ handler.
+ * drm_irq_uninstall - uninstall the IRQ handler
+ * @dev: drm device
+ *
+ * Calls the driver's irq_uninstall() function and unregisters the irq handler.
+ * This should only be called by drivers which used drm_irq_install() to set up
+ * their interrupt handler. Other drivers must only reset
+ * drm_device->irq_enabled to false.
  *
- * \param dev DRM device.
+ * Note that for kernel modesetting drivers it is a bug if this function fails.
+ * The sanity checks are only to catch buggy user modesetting drivers which 
call
+ * the same function through an ioctl.
  *
- * Calls the driver's \c irq_uninstall() function, and stops the irq.
+ * Returns:
+ * Zero on success or a negative error code on failure.
  */
 int drm_irq_uninstall(struct drm_device *dev)
 {
@@ -353,7 +385,7 @@ int drm_irq_uninstall(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_irq_uninstall);

-/**
+/*
  * IRQ control ioctl.
  *
  * \param inode device inode.
@@ -406,10 +438,9 @@ int drm_control(struct drm_device *dev, void *data,
 }

 /**
- * drm_calc_timestamping_constants - Calculate vblank timestamp constants
- *
- * @crtc drm_crtc whose timestamp constants should be updated.
- * @mode display mode containing the scanout timings
+ * drm_calc_timestamping_constants - calculate vblank timestamp constants
+ * @crtc: drm_crtc whose timestamp constants should be updated.
+ * @mode: display mode containing the scanout timings
  *
  * Calculate and store various constants which are later
  * needed by vblank and swap-completion timestamping, e.g,
@@ -459,11 +490,22 @@ void drm_calc_timestamping_constants(struct drm_crtc 
*crtc,
 EXPORT_SYMBOL(drm_calc_timestamping_constants);

 /**
- * 

[PATCH 06/12] drm/doc: Discourage usage of MODESET_CTL ioctl

2014-05-14 Thread Daniel Vetter
Leftover from the old days of ums and should be used any longer. Since

commit 29935554b384b1b3a7377d6f0b03b21d18a61683
Author: Laurent Pinchart 
Date:   Wed May 30 00:58:09 2012 +0200

drm: Disallow DRM_IOCTL_MODESET_CTL for KMS drivers

it is a complete no-Op for kms drivers.

Cc: Laurent Pinchart 
Signed-off-by: Daniel Vetter 
---
 Documentation/DocBook/drm.tmpl | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 83dd0b043c28..e37a77a72b8b 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2861,12 +2861,11 @@ int num_ioctls;
 DRM_IOCTL_MODESET_CTL
 
   
-This should be called by application level drivers before and
-after mode setting, since on many devices the vertical blank
-counter is reset at that time.  Internally, the DRM snapshots
-the last vblank count when the ioctl is called with the
-_DRM_PRE_MODESET command, so that the counter won't go 
backwards
-(which is dealt with when _DRM_POST_MODESET is used).
+   This was only used for user-mode-settind drivers around
+   modesetting changes to allow the kernel to update the vblank
+   interrupt after mode setting, since on many devices the vertical
+   blank. Modern drivers should not call this any more since with
+   kernel mode setting it is a no-Op.
   
 
   
-- 
1.8.3.1



[PATCH 05/12] drm/i915: Remove drm_vblank_pre/post_modeset calls

2014-05-14 Thread Daniel Vetter
Originally these functions have been for user modesetting drivers to
ensure vblank processing doesn't fall over completely around modeset
changes. This has been carried over ever since then.

Now that Ville cleaned our vblank handling with an explicit
drm_vblank_off/on braket when disabling/enabling crtcs. So this seems
to be unnecessary now. The most important side effect was that due to
the delayed vblank disabling we have been pretty much guaranteed to
receive a vblank interrupt soonish after a crtc was enabled.

Note that our vblank handling across modeset is still fairly decent
fubar - we don't actually handle vblank counter all to well.
drm_update_vblank_count will make sure that the frame counter always
rolls forward, but userspace isn't really all to ready to cope with
the big jumps this causes.

This isn't a big mostly because the hardware retains the frame
counter. But with runtime pm and also across suspend/resume we fall
over.

Fixing this is a lot more involved and also needs som i-g-ts. So
material for another patch series.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_display.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 858c393b051f..d0eff53a8ad1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7207,15 +7207,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
struct intel_encoder *encoder;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_display_mode *mode = _crtc->config.requested_mode;
-   int pipe = intel_crtc->pipe;
int ret;

-   drm_vblank_pre_modeset(dev, pipe);
-
ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb);

-   drm_vblank_post_modeset(dev, pipe);
-
if (ret != 0)
return ret;

-- 
1.8.3.1



[PATCH 04/12] drm: Add drm_vblank_on()

2014-05-14 Thread Daniel Vetter
From: Ville Syrj?l? 

drm_vblank_off() will turn off vblank interrupts, but as long as the
refcount is elevated drm_vblank_get() will not re-enable them. This
is a problem is someone is holding a vblank reference while a modeset is
happening, and the driver requires vblank interrupt to work during that
time.

Add drm_vblank_on() as a counterpart to drm_vblank_off() which will
re-enabled vblank interrupts if the refcount is already elevated. This
will allow drivers to choose the specific places in the modeset sequence
at which vblank interrupts get disabled and enabled.

Testcase: igt/kms_flip/*-vs-suspend
Signed-off-by: Ville Syrj?l? 
[danvet: Add Testcase tag for the igt I've written.]
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_irq.c| 72 ++--
 drivers/gpu/drm/i915/intel_display.c |  8 
 include/drm/drmP.h   |  1 +
 3 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 13d671ed3421..dd786d84daab 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -840,6 +840,41 @@ static void drm_update_vblank_count(struct drm_device 
*dev, int crtc)
 }

 /**
+ * drm_vblank_enable - enable the vblank interrupt on a CRTC
+ * @dev: DRM device
+ * @crtc: CRTC in question
+ */
+static int drm_vblank_enable(struct drm_device *dev, int crtc)
+{
+   int ret = 0;
+
+   assert_spin_locked(>vbl_lock);
+
+   spin_lock(>vblank_time_lock);
+
+   if (!dev->vblank[crtc].enabled) {
+   /* Enable vblank irqs under vblank_time_lock protection.
+* All vblank count & timestamp updates are held off
+* until we are done reinitializing master counter and
+* timestamps. Filtercode in drm_handle_vblank() will
+* prevent double-accounting of same vblank interval.
+*/
+   ret = dev->driver->enable_vblank(dev, crtc);
+   DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
+   if (ret)
+   atomic_dec(>vblank[crtc].refcount);
+   else {
+   dev->vblank[crtc].enabled = true;
+   drm_update_vblank_count(dev, crtc);
+   }
+   }
+
+   spin_unlock(>vblank_time_lock);
+
+   return ret;
+}
+
+/**
  * drm_vblank_get - get a reference count on vblank events
  * @dev: DRM device
  * @crtc: which CRTC to own
@@ -858,25 +893,7 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
spin_lock_irqsave(>vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, >vblank[crtc].refcount) == 1) {
-   spin_lock(>vblank_time_lock);
-   if (!dev->vblank[crtc].enabled) {
-   /* Enable vblank irqs under vblank_time_lock protection.
-* All vblank count & timestamp updates are held off
-* until we are done reinitializing master counter and
-* timestamps. Filtercode in drm_handle_vblank() will
-* prevent double-accounting of same vblank interval.
-*/
-   ret = dev->driver->enable_vblank(dev, crtc);
-   DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n",
- crtc, ret);
-   if (ret)
-   atomic_dec(>vblank[crtc].refcount);
-   else {
-   dev->vblank[crtc].enabled = true;
-   drm_update_vblank_count(dev, crtc);
-   }
-   }
-   spin_unlock(>vblank_time_lock);
+   ret = drm_vblank_enable(dev, crtc);
} else {
if (!dev->vblank[crtc].enabled) {
atomic_dec(>vblank[crtc].refcount);
@@ -946,6 +963,23 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
 EXPORT_SYMBOL(drm_vblank_off);

 /**
+ * drm_vblank_on - enable vblank events on a CRTC
+ * @dev: DRM device
+ * @crtc: CRTC in question
+ */
+void drm_vblank_on(struct drm_device *dev, int crtc)
+{
+   unsigned long irqflags;
+
+   spin_lock_irqsave(>vbl_lock, irqflags);
+   /* re-enable interrupts if there's are users left */
+   if (atomic_read(>vblank[crtc].refcount) != 0)
+   WARN_ON(drm_vblank_enable(dev, crtc));
+   spin_unlock_irqrestore(>vbl_lock, irqflags);
+}
+EXPORT_SYMBOL(drm_vblank_on);
+
+/**
  * drm_vblank_pre_modeset - account for vblanks across mode sets
  * @dev: DRM device
  * @crtc: CRTC in question
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index b39d0367dd68..858c393b051f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ 

[PATCH 03/12] drm: Make blocking vblank wait return when the vblank interrupts get disabled

2014-05-14 Thread Daniel Vetter
From: Ville Syrj?l? 

If there's a blocking vblank wait in progress while the vblank interrupt
gets disabled, the current code will just let the vblank wait time out.
Instead make it return immediately when vblank interrupts get disabled.

Signed-off-by: Ville Syrj?l? 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_irq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 90c59a8c820f..13d671ed3421 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1189,6 +1189,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * HZ,
(((drm_vblank_count(dev, crtc) -
   vblwait->request.sequence) <= (1 << 23)) ||
+!dev->vblank[crtc].enabled ||
 !dev->irq_enabled));

if (ret != -EINTR) {
-- 
1.8.3.1



[PATCH 02/12] drm: Make the vblank disable timer per-crtc

2014-05-14 Thread Daniel Vetter
From: Ville Syrj?l? 

Currently there's one per-device vblank disable timer, and it gets
reset wheneven the vblank refcount for any crtc drops to zero. That
means that one crtc could accidentally be keeping the vblank interrupts
for other crtcs enabled even if there are no users for them. Make the
disable timer per-crtc to avoid this issue.

Signed-off-by: Ville Syrj?l? 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_irq.c | 40 +---
 include/drm/drmP.h|  4 +++-
 2 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index ea20c4aa1b6b..90c59a8c820f 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -140,33 +140,34 @@ static void vblank_disable_and_save(struct drm_device 
*dev, int crtc)

 static void vblank_disable_fn(unsigned long arg)
 {
-   struct drm_device *dev = (struct drm_device *)arg;
+   struct drm_vblank_crtc *vblank = (void *)arg;
+   struct drm_device *dev = vblank->dev;
unsigned long irqflags;
-   int i;
+   int crtc = vblank->crtc;

if (!dev->vblank_disable_allowed)
return;

-   for (i = 0; i < dev->num_crtcs; i++) {
-   spin_lock_irqsave(>vbl_lock, irqflags);
-   if (atomic_read(>vblank[i].refcount) == 0 &&
-   dev->vblank[i].enabled) {
-   DRM_DEBUG("disabling vblank on crtc %d\n", i);
-   vblank_disable_and_save(dev, i);
-   }
-   spin_unlock_irqrestore(>vbl_lock, irqflags);
+   spin_lock_irqsave(>vbl_lock, irqflags);
+   if (atomic_read(>refcount) == 0 && vblank->enabled) {
+   DRM_DEBUG("disabling vblank on crtc %d\n", crtc);
+   vblank_disable_and_save(dev, crtc);
}
+   spin_unlock_irqrestore(>vbl_lock, irqflags);
 }

 void drm_vblank_cleanup(struct drm_device *dev)
 {
+   int crtc;
+
/* Bail if the driver didn't call drm_vblank_init() */
if (dev->num_crtcs == 0)
return;

-   del_timer_sync(>vblank_disable_timer);
-
-   vblank_disable_fn((unsigned long)dev);
+   for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
+   del_timer_sync(>vblank[crtc].disable_timer);
+   vblank_disable_fn((unsigned long)>vblank[crtc]);
+   }

kfree(dev->vblank);

@@ -178,8 +179,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
 {
int i, ret = -ENOMEM;

-   setup_timer(>vblank_disable_timer, vblank_disable_fn,
-   (unsigned long)dev);
spin_lock_init(>vbl_lock);
spin_lock_init(>vblank_time_lock);

@@ -189,8 +188,13 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
if (!dev->vblank)
goto err;

-   for (i = 0; i < num_crtcs; i++)
+   for (i = 0; i < num_crtcs; i++) {
+   dev->vblank[i].dev = dev;
+   dev->vblank[i].crtc = i;
init_waitqueue_head(>vblank[i].queue);
+   setup_timer(>vblank[i].disable_timer, vblank_disable_fn,
+   (unsigned long)>vblank[i]);
+   }

DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");

@@ -900,7 +904,7 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
/* Last user schedules interrupt disable */
if (atomic_dec_and_test(>vblank[crtc].refcount) &&
(drm_vblank_offdelay > 0))
-   mod_timer(>vblank_disable_timer,
+   mod_timer(>vblank[crtc].disable_timer,
  jiffies + ((drm_vblank_offdelay * HZ)/1000));
 }
 EXPORT_SYMBOL(drm_vblank_put);
@@ -909,8 +913,6 @@ EXPORT_SYMBOL(drm_vblank_put);
  * drm_vblank_off - disable vblank events on a CRTC
  * @dev: DRM device
  * @crtc: CRTC in question
- *
- * Caller must hold event lock.
  */
 void drm_vblank_off(struct drm_device *dev, int crtc)
 {
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 12f10bc2395f..9d982d483f12 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1024,14 +1024,17 @@ struct drm_pending_vblank_event {
 };

 struct drm_vblank_crtc {
+   struct drm_device *dev; /* pointer to the drm_device */
wait_queue_head_t queue;/**< VBLANK wait queue */
struct timeval time[DRM_VBLANKTIME_RBSIZE]; /**< timestamp of 
current count */
+   struct timer_list disable_timer;/* delayed disable 
timer */
atomic_t count; /**< number of VBLANK interrupts */
atomic_t refcount;  /* number of users of vblank 
interruptsper crtc */
u32 last;   /* protected by dev->vbl_lock, used */
/* for wraparound handling */
u32 last_wait;  /* Last vblank seqno waited per CRTC */
unsigned int inmodeset; /* Display 

[PATCH 01/12] drm: Use correct spinlock flavor in drm_vblank_get()

2014-05-14 Thread Daniel Vetter
From: Peter Hurley 

The irq flags state is already established by the outer
spin_lock_irqsave(); re-disabling irqs is redundant.

Signed-off-by: Peter Hurley 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_irq.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 7583767ec619..ea20c4aa1b6b 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -848,13 +848,13 @@ static void drm_update_vblank_count(struct drm_device 
*dev, int crtc)
  */
 int drm_vblank_get(struct drm_device *dev, int crtc)
 {
-   unsigned long irqflags, irqflags2;
+   unsigned long irqflags;
int ret = 0;

spin_lock_irqsave(>vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, >vblank[crtc].refcount) == 1) {
-   spin_lock_irqsave(>vblank_time_lock, irqflags2);
+   spin_lock(>vblank_time_lock);
if (!dev->vblank[crtc].enabled) {
/* Enable vblank irqs under vblank_time_lock protection.
 * All vblank count & timestamp updates are held off
@@ -872,7 +872,7 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
drm_update_vblank_count(dev, crtc);
}
}
-   spin_unlock_irqrestore(>vblank_time_lock, irqflags2);
+   spin_unlock(>vblank_time_lock);
} else {
if (!dev->vblank[crtc].enabled) {
atomic_dec(>vblank[crtc].refcount);
-- 
1.8.3.1



[PATCH 00/12] irq vblank handling rework

2014-05-14 Thread Daniel Vetter
Hi all,

This is Ville's vblank rework series, slightly pimped. I've added kerneldoc,
some polish and also some additional nasty igt testcases for these crtc on/off
vs vblank issues. Seems all to hold together nicely.

Now one thing I wanted to do is roll this out across all drm drivers, but that
looks ugly: Many drivers don't support vblanks really, and I couldn't fully
audit whether they'd e.g. blow up when userspace tries to use the vblank wait
ioctl. But I think we want to have more sanity since otherwise userspace is
doomed to carry countless ugly hacks around forever.

The last two patches are my attempt at that. By doing the drm_vblank_on/off
dance in the crtc helpers after we know that the crtc is on/off we should have
at least a somewhat sane baseline behaviour. Note that since drm_vblank_on/off
are idempotent drivers are free to call these functions in their callback at an
earlier time, where it makes more sense. But at least it's guaranteed to happen.

Otoh drivers still need to manually complete pageflips, so this doesn't solve
all the issues. But until we have a solid cross-driver testsuite for these
corner-cases (all the interesting stuff happens when you race vblank waits
against concurrent modesets, dpms, or system/runtime suspend/resume) we're
pretty much guaranteed to have some that works at best occasionally and is
guaranteed to have different behaviour in corner cases. Note that the patches
won't degrade behaviour for existing drivers, the drm core changes simply allow
us to finally fix things up correctly.

I guess in a way this is a more generic discussion for the drm subsystem at
large.

Coments and review highly welcome.

Cheers, Daniel

Daniel Vetter (8):
  drm/i915: Remove drm_vblank_pre/post_modeset calls
  drm/doc: Discourage usage of MODESET_CTL ioctl
  drm/irq: kerneldoc polish
  drm/irq: Add kms-native crtc interface functions
  drm/i915: rip our vblank reset hacks for runtime PM
  drm/i915: Accurately initialize fifo underrun state on gmch platforms
  [RFC] drm/irq: More robustness in drm_vblank_on|off
  [RFC] drm/crtc-helper: Enforce sane vblank counter semantics

Peter Hurley (1):
  drm: Use correct spinlock flavor in drm_vblank_get()

Ville Syrj?l? (3):
  drm: Make the vblank disable timer per-crtc
  drm: Make blocking vblank wait return when the vblank interrupts get
disabled
  drm: Add drm_vblank_on()

 Documentation/DocBook/drm.tmpl   |  16 +-
 drivers/gpu/drm/drm_crtc_helper.c|  12 ++
 drivers/gpu/drm/drm_irq.c| 377 ++-
 drivers/gpu/drm/i915/i915_irq.c  |   4 +-
 drivers/gpu/drm/i915/intel_display.c |  36 ++--
 drivers/gpu/drm/i915/intel_drv.h |   2 -
 drivers/gpu/drm/i915/intel_pm.c  |  40 
 include/drm/drmP.h   |  10 +-
 8 files changed, 341 insertions(+), 156 deletions(-)

-- 
1.8.3.1



[RFC PATCH 0/8] component helper improvements

2014-05-14 Thread Thierry Reding
On Sun, Apr 27, 2014 at 12:00:25AM +0100, Russell King - ARM Linux wrote:
> A while back, Laurent raised some comments about the component helper,
> which this patch set starts to address.
> 
> The first point it addresses is the repeated parsing inefficiency when
> deferred probing occurs.  When DT is used, the structure of the
> component helper today means that masters end up parsing the device
> tree for each attempt to re-bind the driver.
> 
> We remove this inefficiency by creating an array of matching data and
> functions, which the component helper can use internally to match up
> components to their master.
> 
> The second point was the inefficiency of destroying the list of
> components each time we saw a failure.  We did this to ensure that
> we kept things correctly ordered: component bind order matters.
> As we have an array instead, the array is already ordered, so we
> use this array to store the component pointers instead of a list,
> and remember which are duplicates (and thus should be avoided.)
> Avoiding the right duplicates matters as we walk the array in the
> opposite direction at tear down.

I've been looking at converting the Tegra DRM driver to the component
helpers for a while now and had to make some changes to make it work for
that particular use-case. While updating the imx-drm and msm DRM drivers
for those changes I noticed an oddity. Both of the existing drivers use
the following pattern:

static int driver_component_bind(struct device *dev,
 struct device *master,
 void *data)
{
allocate memory
request resources
...
hook up to subsystem
...
enable hardware
}

static const struct component_ops driver_component_ops = {
.bind = driver_component_bind,
};

static int driver_probe(struct platform_device *pdev)
{
return component_add(>dev, _component_ops);
}

While converting Tegra DRM, what I intuitively did (I didn't actually
look at the other drivers for inspiration) was something more along the
lines of the following:

static int driver_component_bind(struct device *dev,
 struct device *master,
 void *data)
{
hook up to subsystem
...
enable hardware
}

static const struct component_ops driver_component_ops = {
.bind = driver_component_bind,
};

static int driver_probe(struct platform_device *pdev)
{
allocate memory
request resources
...
return component_add(>dev, _component_ops);
}

Since usually deferred probing is caused by resource allocations failing
this has the side-effect of handling deferred probing before the master
device is even bound (the component_add() happens as the very last step)
and therefore there is less risk for component_bind_all() to fail. I've
actually never seen it fail at all. Failure at that point is almost
certainly irrecoverable anyway.

It would seem to me that if other drivers followed the same pattern, the
second point above is solved by moving deferred probe handling one level
up and reduce the work of the component helpers to gluing together the
components on a subsystem level.

Another advantage to that pattern is that probe failure happens on a
much more granular level. It's handled by each component device rather
than all at once when the master is bound. By that time all components
will be ready and the heavy work of building the subsystem device will
usually not have to be undone as opposed to the former pattern where
that process is bound to be interrupted possibly many times be deferred
probing.

But perhaps I'm missing something. Was there another reason for choosing
this particular pattern?

Thierry
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140514/2cd86462/attachment-0001.sig>


[PULL] topic/core-stuff

2014-05-14 Thread Daniel Vetter
On Mon, May 5, 2014 at 11:19 AM, Daniel Vetter  
wrote:
> Hi Dave,
>
> Update pull request with drm core patches. Mostly some polish for the
> primary plane stuff and a pile of patches all over from Thierry. Has
> survived a few days in drm-intel-nightly without causing ill.
>
> I've frobbed my scripts a bit to also tag my topic branches so that you
> have something stable to pull - I've accidentally pushed a bunch more
> patches onto this branch before you've taken the old pull request.

Ping.
-Daniel

>
> Cheers, Daniel
>
>
> The following changes since commit a798c10faf62a505d24e5f6213fbaf904a39623f:
>
>   Linux 3.15-rc2 (2014-04-20 11:08:50 -0700)
>
> are available in the git repository at:
>
>   git://anongit.freedesktop.org/drm-intel tags/topic/core-stuff-2014-05-05
>
> for you to fetch changes up to a74591d781a8e445e8d5aec8a8bb9ec43a31138b:
>
>   drm: Make drm_crtc_helper_disable() return void (2014-04-29 12:34:33 +0200)
>
> 
> Andrzej Hajda (1):
>   drm: make mode_valid callback optional
>
> Daniel Vetter (4):
>   drm/plane_helper: don't disable plane in destroy function
>   drm/crtc-helper: gc usless connector loop in disable_unused_functions
>   drm: Simplify fb refcounting rules around ->update_plane
>   drm: Handle ->disable_plane failures correctly
>
> Ilija Hadzic (1):
>   drm: remove unused argument from drm_open_helper
>
> Matt Roper (1):
>   drm/plane-helper: Fix primary plane scaling check
>
> Thierry Reding (8):
>   drm: Try to acquire modeset lock on panic or sysrq
>   drm/edid: Drop revision argument for drm_mode_std()
>   drm/edid: Cleanup kerneldoc
>   drm/fb: Fix typos
>   drm: Fixup flip-work kerneldoc
>   drm/dp: Fix typo in comment
>   drm: Fix indentation of closing brace
>   drm: Make drm_crtc_helper_disable() return void
>
> Vandana Kannan (1):
>   drm/edid: Fill PAR in AVI infoframe based on CEA mode list
>
>  Documentation/DocBook/drm.tmpl |   6 +-
>  drivers/gpu/drm/ast/ast_mode.c |   7 --
>  drivers/gpu/drm/bridge/ptn3460.c   |   7 --
>  drivers/gpu/drm/cirrus/cirrus_mode.c   |   8 --
>  drivers/gpu/drm/drm_bufs.c |   2 +-
>  drivers/gpu/drm/drm_crtc.c |  27 +++--
>  drivers/gpu/drm/drm_crtc_helper.c  |  13 +--
>  drivers/gpu/drm/drm_dp_helper.c|   2 +-
>  drivers/gpu/drm/drm_edid.c | 161 
> +++--
>  drivers/gpu/drm/drm_fb_helper.c|  17 ++-
>  drivers/gpu/drm/drm_fops.c |   9 +-
>  drivers/gpu/drm/drm_plane_helper.c |  13 +--
>  drivers/gpu/drm/drm_probe_helper.c |   2 +-
>  drivers/gpu/drm/exynos/exynos_dp_core.c|   7 --
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c|   7 --
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c   |   7 --
>  drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c  |   7 --
>  drivers/gpu/drm/rcar-du/rcar_du_vgacon.c   |   7 --
>  drivers/gpu/drm/shmobile/shmob_drm_crtc.c  |   7 --
>  drivers/staging/imx-drm/imx-drm-core.c |   7 --
>  drivers/staging/imx-drm/imx-drm.h  |   2 -
>  drivers/staging/imx-drm/imx-hdmi.c |   1 -
>  drivers/staging/imx-drm/imx-ldb.c  |   1 -
>  drivers/staging/imx-drm/imx-tve.c  |   4 -
>  drivers/staging/imx-drm/parallel-display.c |   1 -
>  include/drm/drm_crtc.h |   1 +
>  include/drm/drm_crtc_helper.h  |   2 +-
>  include/drm/drm_flip_work.h|   1 +
>  28 files changed, 153 insertions(+), 183 deletions(-)
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[RFC PATCH 0/2] drm: make drm_get_{connector, encoder}_name thread safe

2014-05-14 Thread Jani Nikula
On Wed, 14 May 2014, Chris Wilson  wrote:
> On Wed, May 14, 2014 at 04:58:18PM +0300, Jani Nikula wrote:
>> Hi all -
>> 
>> This series stores connector/encoder names in the relevant structs to
>> make the name getters thread safe.
>> 
>> What say you, is the wasted memory too high a price to pay for the
>> thread safety and implementation simplicity of this approach? I think
>> making drm_get_connector_name and drm_get_encoder_name return allocated
>> buffers makes a lot of code really ugly and error prone.
>
> I thought we could use dev_set_name(connector->kdev, "foo").

Hmm, connector->kdev is created at drm_sysfs_connector_add(), and it
uses a drm_get_connector_name() prefixed with "cardN-". So there's the
naming difference and the lifetime difference, and additionally encoder
doesn't have anything similar. Unless I'm missing something, what I'm
suggesting is way simpler.

BR,
Jani.


> -Chris
>
> -- 
> Chris Wilson, Intel Open Source Technology Centre

-- 
Jani Nikula, Intel Open Source Technology Center


[PATCH] imx-drm: imx-hdmi: move memory and resource allocation into probe function

2014-05-14 Thread Fabio Estevam
Philipp,

On Wed, May 14, 2014 at 6:24 PM, Philipp Zabel  
wrote:
> Move memory allocation and resource acquisition from the bind function into
> the probe function. This calls the devres managed functions once instead of
> possibly multiple times in the bind function and avoids leaking memory (as
> long as the hdmi platform device stays bound).
>
> While at it, request the irq only after the interrupt handler mutes are
> set up, to avoid spurious interrupts.
>
> Signed-off-by: Philipp Zabel 

This one does not apply against the latest version from linux-next.


[Intel-gfx] Design review request: DRM color manager

2014-05-14 Thread Thierry Reding
On Tue, May 13, 2014 at 09:18:45AM +0530, Sharma, Shashank wrote:
> Daniel,
> Please find my comments inline.
> 
> Regards
> Shashank
> On 5/12/2014 8:58 PM, Daniel Vetter wrote:
> >On Mon, May 12, 2014 at 05:35:13PM +0530, Sharma, Shashank wrote:
> >>Thanks for your time and the comments David.
> >>please find mine inline.
> >>
> >>Regards
> >>Shashank
> >>On 5/12/2014 5:20 PM, David Herrmann wrote:
> >>>Hi
> >>>
> >>>On Mon, May 12, 2014 at 12:26 PM, Sharma, Shashank
> >>> wrote:
> >Gamma correction lut is already supported. For the other stuff we can use
> >SET_BLOB (or fix it if it doesn't work).
> >
> Current gamma correction supports only 8 bit mode, which cant do a real
> gamma correction. This is only to initialize the LUT. Actual gamma
> correction needs 10 bit support.
> 
> As discussed in design, the idea is same, ie to fix (implement) SET_BLOB.
> But see some of the requirements on LUT size of VLV:
> 
> 1. Gamma correction: 256 values
> 2. CSC : 9 values in form of 6 register
> 3. Hue : 1 value (Plane level)
> 4. Saturation: 1 value (Plane level)
> 5. Contrast: 1 value (Plane level)
> 6. Brightness: 1 value (Plane level)
> 
> For CHV, the requirement is again different.
> There are different values, which vary from platform to platform and
> property-by-property.
> Now, one method of supporting these values is create a DRM property for
> each, some blob, some single valued, set individual interface and set them
> all at random. IMHO, this looks the non-systematic way of doing it.

That's exactly what atomic modeset/pageflip is meant to address. You get
the flexibility of individual properties and on top of that a way to
apply them all atomically.

> The same thing has to be done differently for different platfroms, with some
> new color corrections added, some removed, and some no of coefficients
> changed. I can clearly see a requirement here.

Having them separated into individual properties will make it easy for
userspace to determine at runtime which of them are available and which
aren't. Also it seems to me that all of these properties should have a
unified userspace interface. Drivers would then be free to implement the
kernel side with the hardware-specific details.

> >>AFAIK color management is not a part of atomic modeset, but once we create
> >>such an interface, it would be really easy to club that in the atomic
> >>modeset.
> >
> >See above, this is a reason to _not_ add a separate color manager.
> >-Daniel
> >
> As I mentioned above, color manager is designed to be clubbed with atomic
> modeset, and will not be any blockage there.

I think the point here is that once we have atomic modesetting/pageflip
then there's no longer a need to have an "atomic" color manager
property since there will be a mechanism to atomically apply any number
of properties.

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


[RFC PATCH v1 08/16] drm/radeon: use common fence implementation for fences

2014-05-14 Thread Christian König
> + /* did fence get signaled after we enabled the sw irq? */
> + if (atomic64_read(>rdev->fence_drv[fence->ring].last_seq) >= 
> fence->seq) {
> + radeon_irq_kms_sw_irq_put(fence->rdev, fence->ring);
> + return false;
> + }
> +
> + fence->fence_wake.flags = 0;
> + fence->fence_wake.private = NULL;
> + fence->fence_wake.func = radeon_fence_check_signaled;
> + __add_wait_queue(>rdev->fence_queue, >fence_wake);
> + fence_get(f);
That looks like a race condition to me. The fence needs to be added to 
the wait queue before the check, not after.

Apart from that the whole approach looks like a really bad idea to me. 
How for example is lockup detection supposed to happen with this?

Christian.

Am 14.05.2014 16:58, schrieb Maarten Lankhorst:
> Signed-off-by: Maarten Lankhorst 
> ---
>   drivers/gpu/drm/radeon/radeon.h|   15 +--
>   drivers/gpu/drm/radeon/radeon_device.c |1
>   drivers/gpu/drm/radeon/radeon_fence.c  |  189 
> +---
>   3 files changed, 153 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 68528619834a..a7d839a158ae 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -64,6 +64,7 @@
>   #include 
>   #include 
>   #include 
> +#include 
>   
>   #include 
>   #include 
> @@ -113,9 +114,6 @@ extern int radeon_hard_reset;
>   #define RADEONFB_CONN_LIMIT 4
>   #define RADEON_BIOS_NUM_SCRATCH 8
>   
> -/* fence seq are set to this number when signaled */
> -#define RADEON_FENCE_SIGNALED_SEQ0LL
> -
>   /* internal ring indices */
>   /* r1xx+ has gfx CP ring */
>   #define RADEON_RING_TYPE_GFX_INDEX  0
> @@ -347,12 +345,15 @@ struct radeon_fence_driver {
>   };
>   
>   struct radeon_fence {
> + struct fence base;
> +
>   struct radeon_device*rdev;
> - struct kref kref;
>   /* protected by radeon_fence.lock */
>   uint64_tseq;
>   /* RB, DMA, etc. */
>   unsignedring;
> +
> + wait_queue_t fence_wake;
>   };
>   
>   int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
> @@ -2256,6 +2257,7 @@ struct radeon_device {
>   struct radeon_mman  mman;
>   struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
>   wait_queue_head_t   fence_queue;
> + unsignedfence_context;
>   struct mutexring_lock;
>   struct radeon_ring  ring[RADEON_NUM_RINGS];
>   boolib_pool_ready;
> @@ -2346,11 +2348,6 @@ u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 
> index);
>   void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v);
>   
>   /*
> - * Cast helper
> - */
> -#define to_radeon_fence(p) ((struct radeon_fence *)(p))
> -
> -/*
>* Registers read & write functions.
>*/
>   #define RREG8(reg) readb((rdev->rmmio) + (reg))
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
> b/drivers/gpu/drm/radeon/radeon_device.c
> index 0e770bbf7e29..501d0cf9eb8b 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -1175,6 +1175,7 @@ int radeon_device_init(struct radeon_device *rdev,
>   for (i = 0; i < RADEON_NUM_RINGS; i++) {
>   rdev->ring[i].idx = i;
>   }
> + rdev->fence_context = fence_context_alloc(RADEON_NUM_RINGS);
>   
>   DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 
> 0x%04X:0x%04X).\n",
>   radeon_family_name[rdev->family], pdev->vendor, pdev->device,
> diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
> b/drivers/gpu/drm/radeon/radeon_fence.c
> index a77b1c13ea43..bc844f300d3f 100644
> --- a/drivers/gpu/drm/radeon/radeon_fence.c
> +++ b/drivers/gpu/drm/radeon/radeon_fence.c
> @@ -39,6 +39,15 @@
>   #include "radeon.h"
>   #include "radeon_trace.h"
>   
> +static const struct fence_ops radeon_fence_ops;
> +
> +#define to_radeon_fence(p) \
> + ({  \
> + struct radeon_fence *__f;   \
> + __f = container_of((p), struct radeon_fence, base); \
> + __f->base.ops == _fence_ops ? __f : NULL;\
> + })
> +
>   /*
>* Fences
>* Fences mark an event in the GPUs pipeline and are used
> @@ -111,30 +120,55 @@ int radeon_fence_emit(struct radeon_device *rdev,
> struct radeon_fence **fence,
> int ring)
>   {
> + u64 seq = ++rdev->fence_drv[ring].sync_seq[ring];
> +
>   /* we are protected by the ring emission mutex */
>   *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
>   if ((*fence) == NULL) {
>   return -ENOMEM;
>   }
> - 

[PATCH v2 4/7] drivers/base: Add interface framework

2014-05-14 Thread Thierry Reding
On Wed, May 14, 2014 at 04:34:21PM +0200, Daniel Vetter wrote:
> On Tue, May 13, 2014 at 11:31:07PM +0200, Thierry Reding wrote:
> > A different solution, which seems to be fairly common for DRM drivers
> > for SoCs, is to instantiate a dummy device so that the DRM driver can
> > bind to it. This can happen in two forms: add the dummy device directly
> > in device tree (which goes against pretty much everything that's been
> > preached about device tree in the past) or the dummy device can be
> > instantiated in code, which is what the current Tegra DRM/host1x driver
> > does.
> 
> Actually the dummy device seems to be an acceptable solution and iirc was
> even acked by DT maintainers in the last KS. I'm not on top of things, but
> iirc the thinking was that a dummy device which just pulls in all the
> relevant real bits with phandles is justified in the board file since it
> tells you how the board is intended to be used. The justification was that
> on SoCs where assigning stuff between v4l and drm is really flexible (e.g.
> on omap or so where you can assign the display pipes essentially freely)
> the use-case of the board is what matters, and that's a somewhat physical
> property of it (i.e. in what kind of device it's sitting.)

I disagree. If there's a way to derive all that information within the
driver (like we do for Tegra) then there should be no need to add
redundant content to the device tree. Also note that Tegra DRM and its
device tree binding predate the last KS, and prior to that the gospel
was to *not* add this kind of data to the device tree. Hence I was
forced to spend a *lot* of time working out a solution in the driver.
Therefore I hope it's understandable that I don't take well to being
told to just go use a bloody dummy device.

> So in your case you'd have a fake display and a fake video device which
> pulls everything the drm/v4l driver need together. So if the issue is how
> to get at a master device I think that's simple to solve.

But that's completely redundant. The driver is perfectly capable of
determining what devices belong to a DRM device and which should be part
of a V4L2 device.

Fake devices are only workarounds for a problem that we currently have
no better solution for in the kernel. And as a matter of fact we already
do create a dummy device (albeit in the kernel rather than in device
tree) on Tegra. But I consider that suboptimal, hence why I want to find
a better way to do this. This interface framework is the result.

If people don't see a need to fix this then I'll just stick with what I
currently have, since it isn't any worse than what everybody else is
doing.

> If the issue otoh is how the various drivers can get at the bus-like
> services host1x exposes, then I think a real bus driver makes a lot more
> sense. And Greg seems to have ideas about that already.

There aren't really any bus-like services exposed by host1x. It really
just exposes resources such as DMA channels or syncpoints. But that's
not even a problem because we know that host1x children are always,
well, children of host1x and therefore we can simply get access to
host1x via the parent device.

Thierry
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140514/2c2e9e59/attachment.sig>


[PATCH] drm/exynos: Make exynos_drm_init() call late during the bootup

2014-05-14 Thread Naveen Krishna Chatradhi
exynos_drm_init() does probing of various drivers like dp_panel,
hdmi, fimd, mixer, etc in an order and finally binds them together.

Some of the drm devices (Eg: dp_panel) try to do regulator_get()
and enable few supplies during their probe.
Chances are that, these devices may get probed before the respective
supply/PMIC is hooked.  In such cases, dp_panel would continue with
"dummy regulator". Which is not what the system wants.

Lets give the core connectivity and regulators modules some time
to hookup the supplies before Exynos DRM devices comes into picture.

Signed-off-by: Naveen Krishna Chatradhi 
---
This change is proposed after
1. Discussing with I2C/SPI & DMA subsystem maintainers and Others
   @ https://lkml.org/lkml/2014/5/9/333
   Trying to change the I2C, SPI and DMA drivers as subsys_initcall()
   Which was strictly opposed, as a flaw was found in DRM subsystem.

2. -EPROBE_DEFER won't work well with the current sequency of
platform_driver_register()s in exynos_drm_init()

3. bridge_panel mechanism is under RFC and no conclusions were drawn yet.

We should be able to probe each DRM device independently and let PROBE_DEFER
take care of dependencies. But, this could cause lot of bootup time.

late_initcall() of DRM works well and fixes all the above issues for now.
Kindly suggest, if an alternative/better mechanism is out there.

Thanks,
 drivers/gpu/drm/exynos/exynos_drm_drv.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 4cef88f..78c185a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -692,7 +692,7 @@ static void exynos_drm_exit(void)
platform_driver_unregister(_drm_platform_driver);
 }

-module_init(exynos_drm_init);
+late_initcall(exynos_drm_init);
 module_exit(exynos_drm_exit);

 MODULE_AUTHOR("Inki Dae ");
-- 
1.7.9.5



[PATCH 4/5] drm/radeon: rework page flip handling

2014-05-14 Thread Michel Dänzer
On 05.05.2014 18:27, Michel D?nzer wrote:
> On 02.05.2014 22:29, Christian K?nig wrote:
>> Am 02.05.2014 09:25, schrieb Michel D?nzer:
>>>
>>> and asynchronous flips (not synchronized to vertical blank).
>> Actually that's one of the things I've implement in 3.15 by using the
>> pflip interrupt. All you need to do is to set the appropriate bits in
>> the hardware to sync the flip to VBLANK, HBLANK or not at all. For the
>> pflip interrupt that doesn't matter it should just fire as soon as the
>> new base address is used by the hardware.
> 
> Sounds great. :) Then we just need to expose that to userspace somehow.

Actually, looks like that should be quite simple:

git grep -i async_page_flip


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


[RFC PATCH v1 16/16] drm/ttm: use rcu in core ttm

2014-05-14 Thread Maarten Lankhorst
Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/ttm/ttm_bo.c |   76 +++---
 1 file changed, 13 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 31c4a6dd722d..6fe1f4bf37ed 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -466,66 +466,6 @@ static void ttm_bo_cleanup_refs_or_queue(struct 
ttm_buffer_object *bo)
  ((HZ / 100) < 1) ? 1 : HZ / 100);
 }

-static int ttm_bo_unreserve_and_wait(struct ttm_buffer_object *bo,
-bool interruptible)
-{
-   struct ttm_bo_global *glob = bo->glob;
-   struct reservation_object_list *fobj;
-   struct fence *excl = NULL;
-   struct fence **shared = NULL;
-   u32 shared_count = 0, i;
-   int ret = 0;
-
-   fobj = reservation_object_get_list(bo->resv);
-   if (fobj && fobj->shared_count) {
-   shared = kmalloc(sizeof(*shared) * fobj->shared_count,
-GFP_KERNEL);
-
-   if (!shared) {
-   ret = -ENOMEM;
-   __ttm_bo_unreserve(bo);
-   spin_unlock(>lru_lock);
-   return ret;
-   }
-
-   for (i = 0; i < fobj->shared_count; ++i) {
-   if (!fence_is_signaled(fobj->shared[i])) {
-   fence_get(fobj->shared[i]);
-   shared[shared_count++] = fobj->shared[i];
-   }
-   }
-   if (!shared_count) {
-   kfree(shared);
-   shared = NULL;
-   }
-   }
-
-   excl = reservation_object_get_excl(bo->resv);
-   if (excl && !fence_is_signaled(excl))
-   fence_get(excl);
-   else
-   excl = NULL;
-
-   __ttm_bo_unreserve(bo);
-   spin_unlock(>lru_lock);
-
-   if (excl) {
-   ret = fence_wait(excl, interruptible);
-   fence_put(excl);
-   }
-
-   if (shared_count > 0) {
-   for (i = 0; i < shared_count; ++i) {
-   if (!ret)
-   ret = fence_wait(shared[i], interruptible);
-   fence_put(shared[i]);
-   }
-   kfree(shared);
-   }
-
-   return ret;
-}
-
 /**
  * function ttm_bo_cleanup_refs_and_unlock
  * If bo idle, remove from delayed- and lru lists, and unref.
@@ -549,9 +489,19 @@ static int ttm_bo_cleanup_refs_and_unlock(struct 
ttm_buffer_object *bo,
ret = ttm_bo_wait(bo, false, false, true);

if (ret && !no_wait_gpu) {
-   ret = ttm_bo_unreserve_and_wait(bo, interruptible);
-   if (ret)
-   return ret;
+   long lret;
+   ww_mutex_unlock(>resv->lock);
+   spin_unlock(>lru_lock);
+
+   lret = reservation_object_wait_timeout_rcu(bo->resv,
+  true,
+  interruptible,
+  30 * HZ);
+
+   if (lret < 0)
+   return lret;
+   else if (lret == 0)
+   return -EBUSY;

spin_lock(>lru_lock);
ret = __ttm_bo_reserve(bo, false, true, false, 0);



[RFC PATCH v1 15/16] drm/vmwgfx: use rcu in vmw_user_dmabuf_synccpu_grab

2014-05-14 Thread Maarten Lankhorst
Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |   17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 20a1a866ceeb..79e950df3018 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -567,13 +567,16 @@ static int vmw_user_dmabuf_synccpu_grab(struct 
vmw_user_dma_buffer *user_bo,
int ret;

if (flags & drm_vmw_synccpu_allow_cs) {
-   ret = ttm_bo_reserve(bo, true, !!(flags & 
drm_vmw_synccpu_dontblock), false, 0);
-   if (!ret) {
-   ret = ttm_bo_wait(bo, false, true,
- !!(flags & 
drm_vmw_synccpu_dontblock));
-   ttm_bo_unreserve(bo);
-   }
-   return ret;
+   long lret;
+   if (flags & drm_vmw_synccpu_dontblock)
+   return reservation_object_test_signaled_rcu(bo->resv, 
true) ? 0 : -EBUSY;
+
+   lret = reservation_object_wait_timeout_rcu(bo->resv, true, 
true, MAX_SCHEDULE_TIMEOUT);
+   if (!lret)
+   return -EBUSY;
+   else if (lret < 0)
+   return lret;
+   return 0;
}

ret = ttm_bo_synccpu_write_grab



[RFC PATCH v1 14/16] drm/radeon: use rcu waits in some ioctls

2014-05-14 Thread Maarten Lankhorst
Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/radeon/radeon_gem.c |   19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_gem.c 
b/drivers/gpu/drm/radeon/radeon_gem.c
index d09650c1d720..7ba883843668 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -107,9 +107,12 @@ static int radeon_gem_set_domain(struct drm_gem_object 
*gobj,
}
if (domain == RADEON_GEM_DOMAIN_CPU) {
/* Asking for cpu access wait for object idle */
-   r = radeon_bo_wait(robj, NULL, false);
-   if (r) {
-   printk(KERN_ERR "Failed to wait for object !\n");
+   r = reservation_object_wait_timeout_rcu(robj->tbo.resv, true, 
true, 30 * HZ);
+   if (!r)
+   r = -EBUSY;
+
+   if (r < 0 && r != -EINTR) {
+   printk(KERN_ERR "Failed to wait for object: %i\n", r);
return r;
}
}
@@ -357,14 +360,20 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, 
void *data,
struct drm_radeon_gem_wait_idle *args = data;
struct drm_gem_object *gobj;
struct radeon_bo *robj;
-   int r;
+   int r = 0;
+   long ret;

gobj = drm_gem_object_lookup(dev, filp, args->handle);
if (gobj == NULL) {
return -ENOENT;
}
robj = gem_to_radeon_bo(gobj);
-   r = radeon_bo_wait(robj, NULL, false);
+   ret = reservation_object_wait_timeout_rcu(robj->tbo.resv, true, true, 
30 * HZ);
+   if (ret == 0)
+   r = -EBUSY;
+   else if (ret < 0)
+   r = ret;
+
/* callback hw specific functions if any */
if (rdev->asic->ioctl_wait_idle)
robj->rdev->asic->ioctl_wait_idle(rdev, robj);



[RFC PATCH v1 13/16] drm/nouveau: use rcu in nouveau_gem_ioctl_cpu_prep

2014-05-14 Thread Maarten Lankhorst
With the conversion to the reservation api this should be safe.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/nouveau/nouveau_gem.c |   28 
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c 
b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 4beaa897adad..c2ca894f6507 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -863,33 +863,29 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void 
*data,
struct drm_gem_object *gem;
struct nouveau_bo *nvbo;
bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
+   bool write = !!(req->flags & NOUVEAU_GEM_CPU_PREP_WRITE);
int ret;
-   struct nouveau_fence *fence = NULL;

gem = drm_gem_object_lookup(dev, file_priv, req->handle);
if (!gem)
return -ENOENT;
nvbo = nouveau_gem_object(gem);

-   ret = ttm_bo_reserve(>bo, true, false, false, 0);
-   if (!ret) {
-   ret = ttm_bo_wait(>bo, true, true, true);
-   if (!no_wait && ret) {
-   struct fence *excl;
-
-   excl = reservation_object_get_excl(nvbo->bo.resv);
-   fence = nouveau_fence_ref((struct nouveau_fence *)excl);
-   }
+   if (no_wait)
+   ret = reservation_object_test_signaled_rcu(nvbo->bo.resv, 
write) ? 0 : -EBUSY;
+   else {
+   long lret;

-   ttm_bo_unreserve(>bo);
+   lret = reservation_object_wait_timeout_rcu(nvbo->bo.resv, 
write, true, 30 * HZ);
+   if (!lret)
+   ret = -EBUSY;
+   else if (lret > 0)
+   ret = 0;
+   else
+   ret = lret;
}
drm_gem_object_unreference_unlocked(gem);

-   if (fence) {
-   ret = nouveau_fence_wait(fence, true, no_wait);
-   nouveau_fence_unref();
-   }
-
return ret;
 }




[RFC PATCH v1 12/16] drm/ttm: flip the switch, and convert to dma_fence

2014-05-14 Thread Maarten Lankhorst

---
 drivers/gpu/drm/nouveau/nouveau_bo.c |   48 +---
 drivers/gpu/drm/nouveau/nouveau_fence.c  |   24 +---
 drivers/gpu/drm/nouveau/nouveau_fence.h  |2 
 drivers/gpu/drm/nouveau/nouveau_gem.c|   16 ++-
 drivers/gpu/drm/qxl/qxl_debugfs.c|6 +
 drivers/gpu/drm/qxl/qxl_drv.h|2 
 drivers/gpu/drm/qxl/qxl_kms.c|1 
 drivers/gpu/drm/qxl/qxl_object.h |4 -
 drivers/gpu/drm/qxl/qxl_release.c|3 -
 drivers/gpu/drm/qxl/qxl_ttm.c|  104 --
 drivers/gpu/drm/radeon/radeon_cs.c   |   10 +-
 drivers/gpu/drm/radeon/radeon_display.c  |   18 +++
 drivers/gpu/drm/radeon/radeon_object.c   |4 -
 drivers/gpu/drm/radeon/radeon_ttm.c  |   34 --
 drivers/gpu/drm/radeon/radeon_uvd.c  |8 +
 drivers/gpu/drm/radeon/radeon_vm.c   |2 
 drivers/gpu/drm/ttm/ttm_bo.c |  171 +-
 drivers/gpu/drm/ttm/ttm_bo_util.c|   23 +---
 drivers/gpu/drm/ttm/ttm_execbuf_util.c   |   10 --
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c   |   40 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |   14 +-
 include/drm/ttm/ttm_bo_api.h |2 
 include/drm/ttm/ttm_bo_driver.h  |   26 -
 include/drm/ttm/ttm_execbuf_util.h   |   10 +-
 24 files changed, 197 insertions(+), 385 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 84aba3fa1bd0..5b8ccc39a282 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -92,13 +92,13 @@ nv10_bo_get_tile_region(struct drm_device *dev, int i)

 static void
 nv10_bo_put_tile_region(struct drm_device *dev, struct nouveau_drm_tile *tile,
-   struct nouveau_fence *fence)
+   struct fence *fence)
 {
struct nouveau_drm *drm = nouveau_drm(dev);

if (tile) {
spin_lock(>tile.lock);
-   tile->fence = nouveau_fence_ref(fence);
+   tile->fence = nouveau_fence_ref((struct nouveau_fence *)fence);
tile->used = false;
spin_unlock(>tile.lock);
}
@@ -965,7 +965,8 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int 
evict, bool intr,
if (ret == 0) {
ret = nouveau_fence_new(chan, false, );
if (ret == 0) {
-   ret = ttm_bo_move_accel_cleanup(bo, fence,
+   ret = ttm_bo_move_accel_cleanup(bo,
+   >base,
evict,
no_wait_gpu,
new_mem);
@@ -1151,8 +1152,9 @@ nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo,
 {
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct drm_device *dev = drm->dev;
+   struct fence *fence = reservation_object_get_excl(bo->resv);

-   nv10_bo_put_tile_region(dev, *old_tile, bo->sync_obj);
+   nv10_bo_put_tile_region(dev, *old_tile, fence);
*old_tile = new_tile;
 }

@@ -1423,47 +1425,14 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
ttm_pool_unpopulate(ttm);
 }

-static void
-nouveau_bo_fence_unref(void **sync_obj)
-{
-   nouveau_fence_unref((struct nouveau_fence **)sync_obj);
-}
-
 void
 nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
 {
struct reservation_object *resv = nvbo->bo.resv;

-   nouveau_bo_fence_unref(>bo.sync_obj);
-   nvbo->bo.sync_obj = nouveau_fence_ref(fence);
-
reservation_object_add_excl_fence(resv, >base);
 }

-static void *
-nouveau_bo_fence_ref(void *sync_obj)
-{
-   return nouveau_fence_ref(sync_obj);
-}
-
-static bool
-nouveau_bo_fence_signalled(void *sync_obj)
-{
-   return nouveau_fence_done(sync_obj);
-}
-
-static int
-nouveau_bo_fence_wait(void *sync_obj, bool lazy, bool intr)
-{
-   return nouveau_fence_wait(sync_obj, lazy, intr);
-}
-
-static int
-nouveau_bo_fence_flush(void *sync_obj)
-{
-   return 0;
-}
-
 struct ttm_bo_driver nouveau_bo_driver = {
.ttm_tt_create = _ttm_tt_create,
.ttm_tt_populate = _ttm_tt_populate,
@@ -1474,11 +1443,6 @@ struct ttm_bo_driver nouveau_bo_driver = {
.move_notify = nouveau_bo_move_ntfy,
.move = nouveau_bo_move,
.verify_access = nouveau_bo_verify_access,
-   .sync_obj_signaled = nouveau_bo_fence_signalled,
-   .sync_obj_wait = nouveau_bo_fence_wait,
-   .sync_obj_flush = nouveau_bo_fence_flush,
-   .sync_obj_unref = nouveau_bo_fence_unref,
-   .sync_obj_ref = nouveau_bo_fence_ref,
.fault_reserve_notify = _ttm_fault_reserve_notify,
.io_mem_reserve = _ttm_io_mem_reserve,
.io_mem_free = _ttm_io_mem_free,
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c 

[RFC PATCH v1 11/16] drm/vmwgfx: rework to new fence interface

2014-05-14 Thread Maarten Lankhorst
Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c  |2 
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c|  299 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.h|   29 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |9 -
 4 files changed, 200 insertions(+), 139 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index db30b790ad24..f3f8caa09cc8 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -2360,7 +2360,7 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
BUG_ON(fence == NULL);

fence_rep.handle = fence_handle;
-   fence_rep.seqno = fence->seqno;
+   fence_rep.seqno = fence->base.seqno;
vmw_update_seqno(dev_priv, _priv->fifo);
fence_rep.passed_seqno = dev_priv->last_read_seqno;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 05b9eea8e875..5d595ca5d82a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -46,6 +46,7 @@ struct vmw_fence_manager {
bool goal_irq_on; /* Protected by @goal_irq_mutex */
bool seqno_valid; /* Protected by @lock, and may not be set to true
 without the @goal_irq_mutex held. */
+   unsigned ctx;
 };

 struct vmw_user_fence {
@@ -80,6 +81,12 @@ struct vmw_event_fence_action {
uint32_t *tv_usec;
 };

+static struct vmw_fence_manager *
+fman_from_fence(struct vmw_fence_obj *fence)
+{
+   return container_of(fence->base.lock, struct vmw_fence_manager, lock);
+}
+
 /**
  * Note on fencing subsystem usage of irqs:
  * Typically the vmw_fences_update function is called
@@ -102,25 +109,130 @@ struct vmw_event_fence_action {
  * objects with actions attached to them.
  */

-static void vmw_fence_obj_destroy_locked(struct kref *kref)
+static void vmw_fence_obj_destroy(struct fence *f)
 {
struct vmw_fence_obj *fence =
-   container_of(kref, struct vmw_fence_obj, kref);
+   container_of(f, struct vmw_fence_obj, base);

-   struct vmw_fence_manager *fman = fence->fman;
-   unsigned int num_fences;
+   struct vmw_fence_manager *fman = fman_from_fence(fence);
+   unsigned long irq_flags;

+   spin_lock_irqsave(>lock, irq_flags);
list_del_init(>head);
-   num_fences = --fman->num_fence_objects;
-   spin_unlock_irq(>lock);
-   if (fence->destroy)
-   fence->destroy(fence);
-   else
-   kfree(fence);
+   --fman->num_fence_objects;
+   spin_unlock_irqrestore(>lock, irq_flags);
+   fence->destroy(fence);
+}

-   spin_lock_irq(>lock);
+static const char *vmw_fence_get_driver_name(struct fence *f)
+{
+   return "vmwgfx";
+}
+
+static const char *vmw_fence_get_timeline_name(struct fence *f)
+{
+   return "svga";
+}
+
+static bool vmw_fence_enable_signaling(struct fence *f)
+{
+   struct vmw_fence_obj *fence =
+   container_of(f, struct vmw_fence_obj, base);
+
+   struct vmw_fence_manager *fman = fman_from_fence(fence);
+
+   __le32 __iomem *fifo_mem = fman->dev_priv->mmio_virt;
+   u32 seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE);
+   if (seqno - fence->base.seqno < VMW_FENCE_WRAP)
+   return false;
+
+   vmw_fifo_ping_host(fman->dev_priv, SVGA_SYNC_GENERIC);
+
+   return true;
+}
+
+struct vmwgfx_wait_cb {
+   struct fence_cb base;
+   struct task_struct *task;
+};
+
+static void
+vmwgfx_wait_cb(struct fence *fence, struct fence_cb *cb)
+{
+   struct vmwgfx_wait_cb *wait =
+   container_of(cb, struct vmwgfx_wait_cb, base);
+
+   wake_up_state(wait->task, TASK_NORMAL);
 }

+static void __vmw_fences_update(struct vmw_fence_manager *fman);
+
+static long vmw_fence_wait(struct fence *f, bool intr, signed long timeout)
+{
+   struct vmw_fence_obj *fence =
+   container_of(f, struct vmw_fence_obj, base);
+
+   struct vmw_fence_manager *fman = fman_from_fence(fence);
+   struct vmw_private *dev_priv = fman->dev_priv;
+   struct vmwgfx_wait_cb cb;
+   long ret = timeout;
+   unsigned long irq_flags;
+
+   if (likely(vmw_fence_obj_signaled(fence)))
+   return timeout;
+
+   vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
+   vmw_seqno_waiter_add(dev_priv);
+
+   spin_lock_irqsave(f->lock, irq_flags);
+
+   if (intr && signal_pending(current)) {
+   ret = -ERESTARTSYS;
+   goto out;
+   }
+
+   cb.base.func = vmwgfx_wait_cb;
+   cb.task = current;
+   list_add(, >cb_list);
+
+   while (ret > 0) {
+   __vmw_fences_update(fman);
+   if (test_bit(FENCE_FLAG_SIGNALED_BIT, >flags))
+   break;
+
+   if (intr)
+   

[RFC PATCH v1 10/16] drm/vmwgfx: get rid of different types of fence_flags entirely

2014-05-14 Thread Maarten Lankhorst
Only one type was ever used. This is needed to simplify the fence
support in the next commit.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c  |5 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c |   14 ++---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c   |   50 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.h   |8 +
 5 files changed, 26 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
index 4a36bb1dc525..f15718cc631d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
@@ -792,15 +792,12 @@ static int vmw_sync_obj_flush(void *sync_obj)

 static bool vmw_sync_obj_signaled(void *sync_obj)
 {
-   return  vmw_fence_obj_signaled((struct vmw_fence_obj *) sync_obj,
-  DRM_VMW_FENCE_FLAG_EXEC);
-
+   return vmw_fence_obj_signaled((struct vmw_fence_obj *) sync_obj);
 }

 static int vmw_sync_obj_wait(void *sync_obj, bool lazy, bool interruptible)
 {
return vmw_fence_obj_wait((struct vmw_fence_obj *) sync_obj,
- DRM_VMW_FENCE_FLAG_EXEC,
  lazy, interruptible,
  VMW_FENCE_WAIT_TIMEOUT);
 }
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 6b252a887ae2..f217e9723b9e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -332,7 +332,6 @@ struct vmw_sw_context{
uint32_t *cmd_bounce;
uint32_t cmd_bounce_size;
struct list_head resource_list;
-   uint32_t fence_flags;
struct ttm_buffer_object *cur_query_bo;
struct list_head res_relocations;
uint32_t *buf_start;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index f8b25bc4e634..db30b790ad24 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -350,8 +350,6 @@ static int vmw_bo_to_validate_list(struct vmw_sw_context 
*sw_context,
vval_buf->validate_as_mob = validate_as_mob;
}

-   sw_context->fence_flags |= DRM_VMW_FENCE_FLAG_EXEC;
-
if (p_val_node)
*p_val_node = val_node;

@@ -2308,13 +2306,9 @@ int vmw_execbuf_fence_commands(struct drm_file 
*file_priv,

if (p_handle != NULL)
ret = vmw_user_fence_create(file_priv, dev_priv->fman,
-   sequence,
-   DRM_VMW_FENCE_FLAG_EXEC,
-   p_fence, p_handle);
+   sequence, p_fence, p_handle);
else
-   ret = vmw_fence_create(dev_priv->fman, sequence,
-  DRM_VMW_FENCE_FLAG_EXEC,
-  p_fence);
+   ret = vmw_fence_create(dev_priv->fman, sequence, p_fence);

if (unlikely(ret != 0 && !synced)) {
(void) vmw_fallback_wait(dev_priv, false, false,
@@ -2387,8 +2381,7 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
ttm_ref_object_base_unref(vmw_fp->tfile,
  fence_handle, TTM_REF_USAGE);
DRM_ERROR("Fence copy error. Syncing.\n");
-   (void) vmw_fence_obj_wait(fence, fence->signal_mask,
- false, false,
+   (void) vmw_fence_obj_wait(fence, false, false,
  VMW_FENCE_WAIT_TIMEOUT);
}
 }
@@ -2438,7 +2431,6 @@ int vmw_execbuf_process(struct drm_file *file_priv,
sw_context->fp = vmw_fpriv(file_priv);
sw_context->cur_reloc = 0;
sw_context->cur_val_buf = 0;
-   sw_context->fence_flags = 0;
INIT_LIST_HEAD(_context->resource_list);
sw_context->cur_query_bo = dev_priv->pinned_bo;
sw_context->last_query_ctx = NULL;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 436b013b4231..05b9eea8e875 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -207,9 +207,7 @@ void vmw_fence_manager_takedown(struct vmw_fence_manager 
*fman)
 }

 static int vmw_fence_obj_init(struct vmw_fence_manager *fman,
- struct vmw_fence_obj *fence,
- u32 seqno,
- uint32_t mask,
+ struct vmw_fence_obj *fence, u32 seqno,
  void (*destroy) (struct vmw_fence_obj *fence))
 {
unsigned long irq_flags;
@@ -220,7 +218,6 @@ static int vmw_fence_obj_init(struct vmw_fence_manager 
*fman,
INIT_LIST_HEAD(>seq_passed_actions);
fence->fman = fman;

[RFC PATCH 2/2] drm: store encoder name in encoder struct

2014-05-14 Thread Jani Nikula
This makes drm_get_encoder_name() thread safe.

Reference: http://lkml.kernel.org/r/645ee6e22cad47d38a2b35c21c8d5fe3 at 
DC1-MBX-01\
.ptsecurity.ru
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/drm_crtc.c | 31 +--
 include/drm/drm_crtc.h |  2 ++
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5781130b4126..1c4cb74ede77 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -257,21 +257,11 @@ void drm_connector_ida_destroy(void)

 /**
  * drm_get_encoder_name - return a string for encoder
- * @encoder: encoder to compute name of
- *
- * Note that the buffer used by this function is globally shared and owned by
- * the function itself.
- *
- * FIXME: This isn't really multithreading safe.
+ * @encoder: the encoder to get name for
  */
 const char *drm_get_encoder_name(const struct drm_encoder *encoder)
 {
-   static char buf[32];
-
-   snprintf(buf, 32, "%s-%d",
-drm_encoder_enum_list[encoder->encoder_type].name,
-encoder->base.id);
-   return buf;
+   return encoder->name;
 }
 EXPORT_SYMBOL(drm_get_encoder_name);

@@ -986,16 +976,27 @@ int drm_encoder_init(struct drm_device *dev,

ret = drm_mode_object_get(dev, >base, DRM_MODE_OBJECT_ENCODER);
if (ret)
-   goto out;
+   goto out_unlock;

encoder->dev = dev;
encoder->encoder_type = encoder_type;
encoder->funcs = funcs;
+   encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
+ drm_encoder_enum_list[encoder_type].name,
+ encoder->base.id);
+   if (!encoder->name) {
+   ret = -ENOMEM;
+   goto out_put;
+   }

list_add_tail(>head, >mode_config.encoder_list);
dev->mode_config.num_encoder++;

- out:
+out_put:
+   if (ret)
+   drm_mode_object_put(dev, >base);
+
+out_unlock:
drm_modeset_unlock_all(dev);

return ret;
@@ -1013,6 +1014,8 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
struct drm_device *dev = encoder->dev;
drm_modeset_lock_all(dev);
drm_mode_object_put(dev, >base);
+   kfree(encoder->name);
+   encoder->name = NULL;
list_del(>head);
dev->mode_config.num_encoder--;
drm_modeset_unlock_all(dev);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d4cd7e513280..219b533a2c15 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -400,6 +400,7 @@ struct drm_encoder_funcs {
  * @dev: parent DRM device
  * @head: list management
  * @base: base KMS object
+ * @name: encoder name
  * @encoder_type: one of the %DRM_MODE_ENCODER_ types in drm_mode.h
  * @possible_crtcs: bitmask of potential CRTC bindings
  * @possible_clones: bitmask of potential sibling encoders for cloning
@@ -416,6 +417,7 @@ struct drm_encoder {
struct list_head head;

struct drm_mode_object base;
+   char *name;
int encoder_type;
uint32_t possible_crtcs;
uint32_t possible_clones;
-- 
1.9.1



[RFC PATCH 1/2] drm: store connector name in connector struct

2014-05-14 Thread Jani Nikula
This makes drm_get_connector_name() thread safe.

Reference: http://lkml.kernel.org/r/645ee6e22cad47d38a2b35c21c8d5fe3 at 
DC1-MBX-01.ptsecurity.ru
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/drm_crtc.c | 36 
 include/drm/drm_crtc.h |  2 ++
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 461d19bd14ee..5781130b4126 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -277,21 +277,11 @@ EXPORT_SYMBOL(drm_get_encoder_name);

 /**
  * drm_get_connector_name - return a string for connector
- * @connector: connector to compute name of
- *
- * Note that the buffer used by this function is globally shared and owned by
- * the function itself.
- *
- * FIXME: This isn't really multithreading safe.
+ * @connector: the connector to get name for
  */
 const char *drm_get_connector_name(const struct drm_connector *connector)
 {
-   static char buf[32];
-
-   snprintf(buf, 32, "%s-%d",
-drm_connector_enum_list[connector->connector_type].name,
-connector->connector_type_id);
-   return buf;
+   return connector->name;
 }
 EXPORT_SYMBOL(drm_get_connector_name);

@@ -824,7 +814,7 @@ int drm_connector_init(struct drm_device *dev,

ret = drm_mode_object_get(dev, >base, 
DRM_MODE_OBJECT_CONNECTOR);
if (ret)
-   goto out;
+   goto out_unlock;

connector->base.properties = >properties;
connector->dev = dev;
@@ -834,9 +824,17 @@ int drm_connector_init(struct drm_device *dev,
ida_simple_get(connector_ida, 1, 0, GFP_KERNEL);
if (connector->connector_type_id < 0) {
ret = connector->connector_type_id;
-   drm_mode_object_put(dev, >base);
-   goto out;
+   goto out_out;
}
+   connector->name =
+   kasprintf(GFP_KERNEL, "%s-%d",
+ drm_connector_enum_list[connector_type].name,
+ connector->connector_type_id);
+   if (!connector->name) {
+   ret = -ENOMEM;
+   goto out_put;
+   }
+
INIT_LIST_HEAD(>probed_modes);
INIT_LIST_HEAD(>modes);
connector->edid_blob_ptr = NULL;
@@ -853,7 +851,11 @@ int drm_connector_init(struct drm_device *dev,
drm_object_attach_property(>base,
  dev->mode_config.dpms_property, 0);

- out:
+out_put:
+   if (ret)
+   drm_mode_object_put(dev, >base);
+
+out_unlock:
drm_modeset_unlock_all(dev);

return ret;
@@ -881,6 +883,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
   connector->connector_type_id);

drm_mode_object_put(dev, >base);
+   kfree(connector->name);
+   connector->name = NULL;
list_del(>head);
dev->mode_config.num_connector--;
 }
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c061bb372199..d4cd7e513280 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -444,6 +444,7 @@ struct drm_encoder {
  * @attr: sysfs attributes
  * @head: list management
  * @base: base KMS object
+ * @name: connector name
  * @connector_type: one of the %DRM_MODE_CONNECTOR_ types from drm_mode.h
  * @connector_type_id: index into connector type enum
  * @interlace_allowed: can this connector handle interlaced modes?
@@ -482,6 +483,7 @@ struct drm_connector {

struct drm_mode_object base;

+   char *name;
int connector_type;
int connector_type_id;
bool interlace_allowed;
-- 
1.9.1



[RFC PATCH 0/2] drm: make drm_get_{connector, encoder}_name thread safe

2014-05-14 Thread Jani Nikula
Hi all -

This series stores connector/encoder names in the relevant structs to
make the name getters thread safe.

What say you, is the wasted memory too high a price to pay for the
thread safety and implementation simplicity of this approach? I think
making drm_get_connector_name and drm_get_encoder_name return allocated
buffers makes a lot of code really ugly and error prone.

I am assuming connector_type, connector_type_id, encoder_type, and
encoder.base.id remain unchanged for the lifetime of the
connector/encoder - is that a correct assumption?

BR,
Jani.


N.B. I did not actually test this...


Jani Nikula (2):
  drm: store connector name in connector struct
  drm: store encoder name in encoder struct

 drivers/gpu/drm/drm_crtc.c | 67 +-
 include/drm/drm_crtc.h |  4 +++
 2 files changed, 41 insertions(+), 30 deletions(-)

-- 
1.9.1



[RFC PATCH v1 09/16] drm/qxl: rework to new fence interface

2014-05-14 Thread Maarten Lankhorst
Final driver! \o/

This is not a proper dma_fence because the hardware may never signal
anything, so don't use dma-buf with qxl, ever.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/qxl/Makefile  |2 
 drivers/gpu/drm/qxl/qxl_cmd.c |5 -
 drivers/gpu/drm/qxl/qxl_debugfs.c |   12 ++-
 drivers/gpu/drm/qxl/qxl_drv.h |   22 ++---
 drivers/gpu/drm/qxl/qxl_fence.c   |   87 ---
 drivers/gpu/drm/qxl/qxl_kms.c |2 
 drivers/gpu/drm/qxl/qxl_object.c  |2 
 drivers/gpu/drm/qxl/qxl_release.c |  166 -
 drivers/gpu/drm/qxl/qxl_ttm.c |   97 --
 9 files changed, 220 insertions(+), 175 deletions(-)
 delete mode 100644 drivers/gpu/drm/qxl/qxl_fence.c

diff --git a/drivers/gpu/drm/qxl/Makefile b/drivers/gpu/drm/qxl/Makefile
index ea046ba691d2..ac0d74852e11 100644
--- a/drivers/gpu/drm/qxl/Makefile
+++ b/drivers/gpu/drm/qxl/Makefile
@@ -4,6 +4,6 @@

 ccflags-y := -Iinclude/drm

-qxl-y := qxl_drv.o qxl_kms.o qxl_display.o qxl_ttm.o qxl_fb.o qxl_object.o 
qxl_gem.o qxl_cmd.o qxl_image.o qxl_draw.o qxl_debugfs.o qxl_irq.o qxl_dumb.o 
qxl_ioctl.o qxl_fence.o qxl_release.o
+qxl-y := qxl_drv.o qxl_kms.o qxl_display.o qxl_ttm.o qxl_fb.o qxl_object.o 
qxl_gem.o qxl_cmd.o qxl_image.o qxl_draw.o qxl_debugfs.o qxl_irq.o qxl_dumb.o 
qxl_ioctl.o qxl_release.o

 obj-$(CONFIG_DRM_QXL)+= qxl.o
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index 45fad7b45486..97823644d347 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -620,11 +620,6 @@ static int qxl_reap_surf(struct qxl_device *qdev, struct 
qxl_bo *surf, bool stal
if (ret == -EBUSY)
return -EBUSY;

-   if (surf->fence.num_active_releases > 0 && stall == false) {
-   qxl_bo_unreserve(surf);
-   return -EBUSY;
-   }
-
if (stall)
mutex_unlock(>surf_evict_mutex);

diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c 
b/drivers/gpu/drm/qxl/qxl_debugfs.c
index c3c2bbdc6674..0d144e0646d6 100644
--- a/drivers/gpu/drm/qxl/qxl_debugfs.c
+++ b/drivers/gpu/drm/qxl/qxl_debugfs.c
@@ -57,11 +57,21 @@ qxl_debugfs_buffers_info(struct seq_file *m, void *data)
struct qxl_device *qdev = node->minor->dev->dev_private;
struct qxl_bo *bo;

+   spin_lock(>release_lock);
list_for_each_entry(bo, >gem.objects, list) {
+   struct reservation_object_list *fobj;
+   int rel;
+
+   rcu_read_lock();
+   fobj = rcu_dereference(bo->tbo.resv->fence);
+   rel = fobj ? fobj->shared_count : 0;
+   rcu_read_unlock();
+
seq_printf(m, "size %ld, pc %d, sync obj %p, num releases %d\n",
   (unsigned long)bo->gem_base.size, bo->pin_count,
-  bo->tbo.sync_obj, bo->fence.num_active_releases);
+  bo->tbo.sync_obj, rel);
}
+   spin_unlock(>release_lock);
return 0;
 }

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 36ed40ba773f..d547cbdebeb4 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -31,6 +31,7 @@
  * Definitions taken from spice-protocol, plus kernel driver specific bits.
  */

+#include 
 #include 
 #include 
 #include 
@@ -95,13 +96,6 @@ enum {
QXL_INTERRUPT_IO_CMD |\
QXL_INTERRUPT_CLIENT_MONITORS_CONFIG)

-struct qxl_fence {
-   struct qxl_device *qdev;
-   uint32_t num_active_releases;
-   uint32_t *release_ids;
-   struct radix_tree_root tree;
-};
-
 struct qxl_bo {
/* Protected by gem.mutex */
struct list_headlist;
@@ -113,13 +107,13 @@ struct qxl_bo {
unsignedpin_count;
void*kptr;
int type;
+
/* Constant after initialization */
struct drm_gem_object   gem_base;
bool is_primary; /* is this now a primary surface */
bool hw_surf_alloc;
struct qxl_surface surf;
uint32_t surface_id;
-   struct qxl_fence fence; /* per bo fence  - list of releases */
struct qxl_release *surf_create;
 };
 #define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base)
@@ -191,6 +185,8 @@ enum {
  * spice-protocol/qxl_dev.h */
 #define QXL_MAX_RES 96
 struct qxl_release {
+   struct fence base;
+
int id;
int type;
uint32_t release_offset;
@@ -284,7 +280,11 @@ struct qxl_device {
uint8_t slot_gen_bits;
uint64_tva_slot_mask;

+   /* XXX: when rcu becomes available, release_lock can be killed */
+   spinlock_t  release_lock;
+   spinlock_t  fence_lock;
struct idr  release_idr;
+   uint32_trelease_seqno;
spinlock_t release_idr_lock;
struct mutexasync_io_mutex;

[RFC PATCH v1 08/16] drm/radeon: use common fence implementation for fences

2014-05-14 Thread Maarten Lankhorst
Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/radeon/radeon.h|   15 +--
 drivers/gpu/drm/radeon/radeon_device.c |1 
 drivers/gpu/drm/radeon/radeon_fence.c  |  189 +---
 3 files changed, 153 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 68528619834a..a7d839a158ae 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -64,6 +64,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
@@ -113,9 +114,6 @@ extern int radeon_hard_reset;
 #define RADEONFB_CONN_LIMIT4
 #define RADEON_BIOS_NUM_SCRATCH8

-/* fence seq are set to this number when signaled */
-#define RADEON_FENCE_SIGNALED_SEQ  0LL
-
 /* internal ring indices */
 /* r1xx+ has gfx CP ring */
 #define RADEON_RING_TYPE_GFX_INDEX 0
@@ -347,12 +345,15 @@ struct radeon_fence_driver {
 };

 struct radeon_fence {
+   struct fence base;
+
struct radeon_device*rdev;
-   struct kref kref;
/* protected by radeon_fence.lock */
uint64_tseq;
/* RB, DMA, etc. */
unsignedring;
+
+   wait_queue_t fence_wake;
 };

 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
@@ -2256,6 +2257,7 @@ struct radeon_device {
struct radeon_mman  mman;
struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
wait_queue_head_t   fence_queue;
+   unsignedfence_context;
struct mutexring_lock;
struct radeon_ring  ring[RADEON_NUM_RINGS];
boolib_pool_ready;
@@ -2346,11 +2348,6 @@ u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 
index);
 void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v);

 /*
- * Cast helper
- */
-#define to_radeon_fence(p) ((struct radeon_fence *)(p))
-
-/*
  * Registers read & write functions.
  */
 #define RREG8(reg) readb((rdev->rmmio) + (reg))
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 0e770bbf7e29..501d0cf9eb8b 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1175,6 +1175,7 @@ int radeon_device_init(struct radeon_device *rdev,
for (i = 0; i < RADEON_NUM_RINGS; i++) {
rdev->ring[i].idx = i;
}
+   rdev->fence_context = fence_context_alloc(RADEON_NUM_RINGS);

DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 
0x%04X:0x%04X).\n",
radeon_family_name[rdev->family], pdev->vendor, pdev->device,
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index a77b1c13ea43..bc844f300d3f 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -39,6 +39,15 @@
 #include "radeon.h"
 #include "radeon_trace.h"

+static const struct fence_ops radeon_fence_ops;
+
+#define to_radeon_fence(p) \
+   ({  \
+   struct radeon_fence *__f;   \
+   __f = container_of((p), struct radeon_fence, base); \
+   __f->base.ops == _fence_ops ? __f : NULL;\
+   })
+
 /*
  * Fences
  * Fences mark an event in the GPUs pipeline and are used
@@ -111,30 +120,55 @@ int radeon_fence_emit(struct radeon_device *rdev,
  struct radeon_fence **fence,
  int ring)
 {
+   u64 seq = ++rdev->fence_drv[ring].sync_seq[ring];
+
/* we are protected by the ring emission mutex */
*fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
if ((*fence) == NULL) {
return -ENOMEM;
}
-   kref_init(&((*fence)->kref));
-   (*fence)->rdev = rdev;
-   (*fence)->seq = ++rdev->fence_drv[ring].sync_seq[ring];
(*fence)->ring = ring;
+   __fence_init(&(*fence)->base, _fence_ops,
+>fence_queue.lock, rdev->fence_context + ring, seq);
+   (*fence)->rdev = rdev;
+   (*fence)->seq = seq;
radeon_fence_ring_emit(rdev, ring, *fence);
trace_radeon_fence_emit(rdev->ddev, ring, (*fence)->seq);
return 0;
 }

 /**
- * radeon_fence_process - process a fence
+ * radeon_fence_check_signaled - callback from fence_queue
  *
- * @rdev: radeon_device pointer
- * @ring: ring index the fence is associated with
- *
- * Checks the current fence value and wakes the fence queue
- * if the sequence number has increased (all asics).
+ * this function is called with fence_queue lock held, which is also used
+ * for the fence locking itself, so unlocked variants are used for
+ * fence_signal, and remove_wait_queue.
  */
-void 

[RFC PATCH v1 07/16] drm/nouveau: rework to new fence interface

2014-05-14 Thread Maarten Lankhorst
From: Maarten Lankhorst 

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/nouveau/core/core/event.c |4 
 drivers/gpu/drm/nouveau/nouveau_bo.c  |6 
 drivers/gpu/drm/nouveau/nouveau_display.c |4 
 drivers/gpu/drm/nouveau/nouveau_fence.c   |  434 -
 drivers/gpu/drm/nouveau/nouveau_fence.h   |   20 +
 drivers/gpu/drm/nouveau/nouveau_gem.c |   17 -
 drivers/gpu/drm/nouveau/nv04_fence.c  |4 
 drivers/gpu/drm/nouveau/nv10_fence.c  |4 
 drivers/gpu/drm/nouveau/nv17_fence.c  |2 
 drivers/gpu/drm/nouveau/nv50_fence.c  |2 
 drivers/gpu/drm/nouveau/nv84_fence.c  |   11 -
 11 files changed, 329 insertions(+), 179 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/core/core/event.c 
b/drivers/gpu/drm/nouveau/core/core/event.c
index 3f3c76581a9e..167408b72099 100644
--- a/drivers/gpu/drm/nouveau/core/core/event.c
+++ b/drivers/gpu/drm/nouveau/core/core/event.c
@@ -118,14 +118,14 @@ nouveau_event_ref(struct nouveau_eventh *handler, struct 
nouveau_eventh **ref)
 void
 nouveau_event_trigger(struct nouveau_event *event, int index)
 {
-   struct nouveau_eventh *handler;
+   struct nouveau_eventh *handler, *next;
unsigned long flags;

if (WARN_ON(index >= event->index_nr))
return;

spin_lock_irqsave(>list_lock, flags);
-   list_for_each_entry(handler, >index[index].list, head) {
+   list_for_each_entry_safe(handler, next, >index[index].list, 
head) {
if (test_bit(NVKM_EVENT_ENABLE, >flags) &&
handler->func(handler->priv, index) == NVKM_EVENT_DROP)
nouveau_event_put(handler);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index e98af2e9a1cb..84aba3fa1bd0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -959,7 +959,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int 
evict, bool intr,
}

mutex_lock_nested(>cli->mutex, SINGLE_DEPTH_NESTING);
-   ret = nouveau_fence_sync(bo->sync_obj, chan);
+   ret = nouveau_fence_sync(nouveau_bo(bo), chan);
if (ret == 0) {
ret = drm->ttm.move(chan, bo, >mem, new_mem);
if (ret == 0) {
@@ -1432,10 +1432,12 @@ nouveau_bo_fence_unref(void **sync_obj)
 void
 nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
 {
-   lockdep_assert_held(>bo.resv->lock.base);
+   struct reservation_object *resv = nvbo->bo.resv;

nouveau_bo_fence_unref(>bo.sync_obj);
nvbo->bo.sync_obj = nouveau_fence_ref(fence);
+
+   reservation_object_add_excl_fence(resv, >base);
 }

 static void *
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index 6a0ca004bd19..eeb8762feaf0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -660,7 +660,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
spin_unlock_irqrestore(>event_lock, flags);

/* Synchronize with the old framebuffer */
-   ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan);
+   ret = nouveau_fence_sync(old_bo, chan);
if (ret)
goto fail;

@@ -721,7 +721,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct 
drm_framebuffer *fb,
goto fail_unpin;

/* synchronise rendering channel with the kernel's channel */
-   ret = nouveau_fence_sync(new_bo->bo.sync_obj, chan);
+   ret = nouveau_fence_sync(new_bo, chan);
if (ret) {
ttm_bo_unreserve(_bo->bo);
goto fail_unpin;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c 
b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 90074d620e31..9a9e04985826 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -32,91 +32,139 @@
 #include "nouveau_drm.h"
 #include "nouveau_dma.h"
 #include "nouveau_fence.h"
+#include 

 #include 

-struct fence_work {
-   struct work_struct base;
-   struct list_head head;
-   void (*func)(void *);
-   void *data;
-};
+static const struct fence_ops nouveau_fence_ops_uevent;
+static const struct fence_ops nouveau_fence_ops_legacy;

 static void
 nouveau_fence_signal(struct nouveau_fence *fence)
 {
-   struct fence_work *work, *temp;
+   __fence_signal(>base);
+   list_del(>head);
+
+   if (fence->base.ops == _fence_ops_uevent &&
+   fence->event.head.next) {
+   struct nouveau_event *event;

-   list_for_each_entry_safe(work, temp, >work, head) {
-   schedule_work(>base);
-   list_del(>head);
+   list_del(>event.head);
+   fence->event.head.next = NULL;
+
+   event = container_of(fence->base.lock, typeof(*event), 
list_lock);
+   nouveau_event_put(>event);
}

- 

[RFC PATCH v1 06/16] drm/ttm: kill fence_lock

2014-05-14 Thread Maarten Lankhorst
No users are left, kill it off! :D
Conversion to the reservation api is next on the list, after
that the functionality can be restored with rcu.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c  |   25 +++---
 drivers/gpu/drm/nouveau/nouveau_display.c |6 --
 drivers/gpu/drm/nouveau/nouveau_gem.c |   16 +-
 drivers/gpu/drm/qxl/qxl_cmd.c |2 -
 drivers/gpu/drm/qxl/qxl_fence.c   |4 --
 drivers/gpu/drm/qxl/qxl_object.h  |2 -
 drivers/gpu/drm/qxl/qxl_release.c |2 -
 drivers/gpu/drm/radeon/radeon_display.c   |2 -
 drivers/gpu/drm/radeon/radeon_object.c|2 -
 drivers/gpu/drm/ttm/ttm_bo.c  |   75 +++--
 drivers/gpu/drm/ttm/ttm_bo_util.c |5 --
 drivers/gpu/drm/ttm/ttm_bo_vm.c   |3 -
 drivers/gpu/drm/ttm/ttm_execbuf_util.c|2 -
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c|4 --
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c  |   17 ++-
 include/drm/ttm/ttm_bo_api.h  |5 --
 include/drm/ttm/ttm_bo_driver.h   |3 -
 17 files changed, 36 insertions(+), 139 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 33eb7164525a..e98af2e9a1cb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1196,9 +1196,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, 
bool intr,
}

/* Fallback to software copy. */
-   spin_lock(>bdev->fence_lock);
ret = ttm_bo_wait(bo, true, intr, no_wait_gpu);
-   spin_unlock(>bdev->fence_lock);
if (ret == 0)
ret = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem);

@@ -1425,26 +1423,19 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
ttm_pool_unpopulate(ttm);
 }

+static void
+nouveau_bo_fence_unref(void **sync_obj)
+{
+   nouveau_fence_unref((struct nouveau_fence **)sync_obj);
+}
+
 void
 nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
 {
-   struct nouveau_fence *new_fence = nouveau_fence_ref(fence);
-   struct nouveau_fence *old_fence = NULL;
-
lockdep_assert_held(>bo.resv->lock.base);

-   spin_lock(>bo.bdev->fence_lock);
-   old_fence = nvbo->bo.sync_obj;
-   nvbo->bo.sync_obj = new_fence;
-   spin_unlock(>bo.bdev->fence_lock);
-
-   nouveau_fence_unref(_fence);
-}
-
-static void
-nouveau_bo_fence_unref(void **sync_obj)
-{
-   nouveau_fence_unref((struct nouveau_fence **)sync_obj);
+   nouveau_bo_fence_unref(>bo.sync_obj);
+   nvbo->bo.sync_obj = nouveau_fence_ref(fence);
 }

 static void *
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index 61b8c3375135..6a0ca004bd19 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -721,11 +721,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct 
drm_framebuffer *fb,
goto fail_unpin;

/* synchronise rendering channel with the kernel's channel */
-   spin_lock(_bo->bo.bdev->fence_lock);
-   fence = nouveau_fence_ref(new_bo->bo.sync_obj);
-   spin_unlock(_bo->bo.bdev->fence_lock);
-   ret = nouveau_fence_sync(fence, chan);
-   nouveau_fence_unref();
+   ret = nouveau_fence_sync(new_bo->bo.sync_obj, chan);
if (ret) {
ttm_bo_unreserve(_bo->bo);
goto fail_unpin;
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c 
b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 6e1c58a880fe..6cd5298cbb53 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -105,9 +105,7 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct 
nouveau_vma *vma)
list_del(>head);

if (mapped) {
-   spin_lock(>bo.bdev->fence_lock);
fence = nouveau_fence_ref(nvbo->bo.sync_obj);
-   spin_unlock(>bo.bdev->fence_lock);
}

if (fence) {
@@ -432,17 +430,11 @@ retry:
 static int
 validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo)
 {
-   struct nouveau_fence *fence = NULL;
+   struct nouveau_fence *fence = nvbo->bo.sync_obj;
int ret = 0;

-   spin_lock(>bo.bdev->fence_lock);
-   fence = nouveau_fence_ref(nvbo->bo.sync_obj);
-   spin_unlock(>bo.bdev->fence_lock);
-
-   if (fence) {
+   if (fence)
ret = nouveau_fence_sync(fence, chan);
-   nouveau_fence_unref();
-   }

return ret;
 }
@@ -661,9 +653,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
data |= r->vor;
}

-   spin_lock(>bo.bdev->fence_lock);
ret = ttm_bo_wait(>bo, false, false, false);
-   spin_unlock(>bo.bdev->fence_lock);
if (ret) {
NV_ERROR(cli, "reloc 

[RFC PATCH v1 05/16] drm/ttm: call ttm_bo_wait while inside a reservation

2014-05-14 Thread Maarten Lankhorst
This is the last remaining function that doesn't use the reservation
lock completely to fence off access to a buffer.
---
 drivers/gpu/drm/ttm/ttm_bo.c |   25 -
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 4ab9f7171c4f..d7d34336f108 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -502,17 +502,6 @@ static int ttm_bo_cleanup_refs_and_unlock(struct 
ttm_buffer_object *bo,
if (ret)
return ret;

-   /*
-* remove sync_obj with ttm_bo_wait, the wait should be
-* finished, and no new wait object should have been added.
-*/
-   spin_lock(>fence_lock);
-   ret = ttm_bo_wait(bo, false, false, true);
-   WARN_ON(ret);
-   spin_unlock(>fence_lock);
-   if (ret)
-   return ret;
-
spin_lock(>lru_lock);
ret = __ttm_bo_reserve(bo, false, true, false, 0);

@@ -528,8 +517,16 @@ static int ttm_bo_cleanup_refs_and_unlock(struct 
ttm_buffer_object *bo,
spin_unlock(>lru_lock);
return 0;
}
-   } else
-   spin_unlock(>fence_lock);
+
+   /*
+* remove sync_obj with ttm_bo_wait, the wait should be
+* finished, and no new wait object should have been added.
+*/
+   spin_lock(>fence_lock);
+   ret = ttm_bo_wait(bo, false, false, true);
+   WARN_ON(ret);
+   }
+   spin_unlock(>fence_lock);

if (ret || unlikely(list_empty(>ddestroy))) {
__ttm_bo_unreserve(bo);
@@ -1539,6 +1536,8 @@ int ttm_bo_wait(struct ttm_buffer_object *bo,
void *sync_obj;
int ret = 0;

+   lockdep_assert_held(>resv->lock.base);
+
if (likely(bo->sync_obj == NULL))
return 0;




[RFC PATCH v1 04/16] drm/nouveau: require reservations for nouveau_fence_sync and nouveau_bo_fence

2014-05-14 Thread Maarten Lankhorst
This will ensure we always hold the required lock when calling those functions.
---
 drivers/gpu/drm/nouveau/nouveau_bo.c  |2 ++
 drivers/gpu/drm/nouveau/nouveau_display.c |   17 +
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index b6dc85c614be..33eb7164525a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1431,6 +1431,8 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
struct nouveau_fence *new_fence = nouveau_fence_ref(fence);
struct nouveau_fence *old_fence = NULL;

+   lockdep_assert_held(>bo.resv->lock.base);
+
spin_lock(>bo.bdev->fence_lock);
old_fence = nvbo->bo.sync_obj;
nvbo->bo.sync_obj = new_fence;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index da764a4ed958..61b8c3375135 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -716,6 +716,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct 
drm_framebuffer *fb,
}

mutex_lock(>cli->mutex);
+   ret = ttm_bo_reserve(_bo->bo, true, false, false, NULL);
+   if (ret)
+   goto fail_unpin;

/* synchronise rendering channel with the kernel's channel */
spin_lock(_bo->bo.bdev->fence_lock);
@@ -723,12 +726,18 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct 
drm_framebuffer *fb,
spin_unlock(_bo->bo.bdev->fence_lock);
ret = nouveau_fence_sync(fence, chan);
nouveau_fence_unref();
-   if (ret)
+   if (ret) {
+   ttm_bo_unreserve(_bo->bo);
goto fail_unpin;
+   }

-   ret = ttm_bo_reserve(_bo->bo, true, false, false, NULL);
-   if (ret)
-   goto fail_unpin;
+   if (new_bo != old_bo) {
+   ttm_bo_unreserve(_bo->bo);
+
+   ret = ttm_bo_reserve(_bo->bo, true, false, false, NULL);
+   if (ret)
+   goto fail_unpin;
+   }

/* Initialize a page flip struct */
*s = (struct nouveau_page_flip_state)



[RFC PATCH v1 03/16] drm/nouveau: add reservation to nouveau_gem_ioctl_cpu_prep

2014-05-14 Thread Maarten Lankhorst
Apart from some code inside ttm itself and nouveau_bo_vma_del,
this is the only place where ttm_bo_wait is used without a reservation.
Fix this so we can remove the fence_lock later on.

After the switch to rcu the reservation lock will be
removed again.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/nouveau/nouveau_gem.c |   22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c 
b/drivers/gpu/drm/nouveau/nouveau_gem.c
index c90c0dc0afe8..6e1c58a880fe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -886,17 +886,31 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void 
*data,
struct drm_gem_object *gem;
struct nouveau_bo *nvbo;
bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
-   int ret = -EINVAL;
+   int ret;
+   struct nouveau_fence *fence = NULL;

gem = drm_gem_object_lookup(dev, file_priv, req->handle);
if (!gem)
return -ENOENT;
nvbo = nouveau_gem_object(gem);

-   spin_lock(>bo.bdev->fence_lock);
-   ret = ttm_bo_wait(>bo, true, true, no_wait);
-   spin_unlock(>bo.bdev->fence_lock);
+   ret = ttm_bo_reserve(>bo, true, false, false, 0);
+   if (!ret) {
+   spin_lock(>bo.bdev->fence_lock);
+   ret = ttm_bo_wait(>bo, true, true, true);
+   if (!no_wait && ret)
+   fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+   spin_unlock(>bo.bdev->fence_lock);
+
+   ttm_bo_unreserve(>bo);
+   }
drm_gem_object_unreference_unlocked(gem);
+
+   if (fence) {
+   ret = nouveau_fence_wait(fence, true, no_wait);
+   nouveau_fence_unref();
+   }
+
return ret;
 }




[RFC PATCH v1 02/16] drm/ttm: kill off some members to ttm_validate_buffer

2014-05-14 Thread Maarten Lankhorst
This reorders the list to keep track of what buffers are reserved,
so previous members are always unreserved.

This gets rid of some bookkeeping that's no longer needed,
while simplifying the code some.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/qxl/qxl_release.c   |1 
 drivers/gpu/drm/ttm/ttm_execbuf_util.c  |  142 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c |1 
 include/drm/ttm/ttm_execbuf_util.h  |3 -
 4 files changed, 50 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_release.c 
b/drivers/gpu/drm/qxl/qxl_release.c
index 2b43e5deb051..e85c4d274dc0 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -350,7 +350,6 @@ void qxl_release_fence_buffer_objects(struct qxl_release 
*release)

ttm_bo_add_to_lru(bo);
__ttm_bo_unreserve(bo);
-   entry->reserved = false;
}
spin_unlock(>fence_lock);
spin_unlock(>lru_lock);
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c 
b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index 39a11bbd2bac..6db47a72667e 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -32,20 +32,12 @@
 #include 
 #include 

-static void ttm_eu_backoff_reservation_locked(struct list_head *list)
+static void ttm_eu_backoff_reservation_reverse(struct list_head *list,
+ struct ttm_validate_buffer *entry)
 {
-   struct ttm_validate_buffer *entry;
-
-   list_for_each_entry(entry, list, head) {
+   list_for_each_entry_continue_reverse(entry, list, head) {
struct ttm_buffer_object *bo = entry->bo;
-   if (!entry->reserved)
-   continue;

-   entry->reserved = false;
-   if (entry->removed) {
-   ttm_bo_add_to_lru(bo);
-   entry->removed = false;
-   }
__ttm_bo_unreserve(bo);
}
 }
@@ -56,27 +48,9 @@ static void ttm_eu_del_from_lru_locked(struct list_head 
*list)

list_for_each_entry(entry, list, head) {
struct ttm_buffer_object *bo = entry->bo;
-   if (!entry->reserved)
-   continue;
+   unsigned put_count = ttm_bo_del_from_lru(bo);

-   if (!entry->removed) {
-   entry->put_count = ttm_bo_del_from_lru(bo);
-   entry->removed = true;
-   }
-   }
-}
-
-static void ttm_eu_list_ref_sub(struct list_head *list)
-{
-   struct ttm_validate_buffer *entry;
-
-   list_for_each_entry(entry, list, head) {
-   struct ttm_buffer_object *bo = entry->bo;
-
-   if (entry->put_count) {
-   ttm_bo_list_ref_sub(bo, entry->put_count, true);
-   entry->put_count = 0;
-   }
+   ttm_bo_list_ref_sub(bo, put_count, true);
}
 }

@@ -91,11 +65,18 @@ void ttm_eu_backoff_reservation(struct ww_acquire_ctx 
*ticket,

entry = list_first_entry(list, struct ttm_validate_buffer, head);
glob = entry->bo->glob;
+
spin_lock(>lru_lock);
-   ttm_eu_backoff_reservation_locked(list);
+   list_for_each_entry(entry, list, head) {
+   struct ttm_buffer_object *bo = entry->bo;
+
+   ttm_bo_add_to_lru(bo);
+   __ttm_bo_unreserve(bo);
+   }
+   spin_unlock(>lru_lock);
+
if (ticket)
ww_acquire_fini(ticket);
-   spin_unlock(>lru_lock);
 }
 EXPORT_SYMBOL(ttm_eu_backoff_reservation);

@@ -121,64 +102,55 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
if (list_empty(list))
return 0;

-   list_for_each_entry(entry, list, head) {
-   entry->reserved = false;
-   entry->put_count = 0;
-   entry->removed = false;
-   }
-
entry = list_first_entry(list, struct ttm_validate_buffer, head);
glob = entry->bo->glob;

if (ticket)
ww_acquire_init(ticket, _ww_class);
-retry:
+
list_for_each_entry(entry, list, head) {
struct ttm_buffer_object *bo = entry->bo;

-   /* already slowpath reserved? */
-   if (entry->reserved)
-   continue;
-
ret = __ttm_bo_reserve(bo, intr, (ticket == NULL), true,
   ticket);
+   if (!ret && unlikely(atomic_read(>cpu_writers) > 0)) {
+   __ttm_bo_unreserve(bo);

-   if (ret == -EDEADLK) {
-   /* uh oh, we lost out, drop every reservation and try
-* to only reserve this buffer, then start over if
-* this succeeds.
-*/
-   BUG_ON(ticket == NULL);
-   spin_lock(>lru_lock);
-  

[RFC PATCH v1 01/16] drm/ttm: add interruptible parameter to ttm_eu_reserve_buffers

2014-05-14 Thread Maarten Lankhorst
It seems some drivers really want this as a parameter,
like vmwgfx.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/qxl/qxl_release.c|2 +-
 drivers/gpu/drm/radeon/radeon_object.c   |2 +-
 drivers/gpu/drm/radeon/radeon_uvd.c  |2 +-
 drivers/gpu/drm/radeon/radeon_vm.c   |2 +-
 drivers/gpu/drm/ttm/ttm_execbuf_util.c   |   22 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c  |7 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |2 +-
 include/drm/ttm/ttm_execbuf_util.h   |9 +
 8 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_release.c 
b/drivers/gpu/drm/qxl/qxl_release.c
index 14e776f1d14e..2b43e5deb051 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -159,7 +159,7 @@ int qxl_release_reserve_list(struct qxl_release *release, 
bool no_intr)
if (list_is_singular(>bos))
return 0;

-   ret = ttm_eu_reserve_buffers(>ticket, >bos);
+   ret = ttm_eu_reserve_buffers(>ticket, >bos, !no_intr);
if (ret)
return ret;

diff --git a/drivers/gpu/drm/radeon/radeon_object.c 
b/drivers/gpu/drm/radeon/radeon_object.c
index 19bec0dbfa38..51bf80cdce5c 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -438,7 +438,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
u64 bytes_moved = 0, initial_bytes_moved;
u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev);

-   r = ttm_eu_reserve_buffers(ticket, head);
+   r = ttm_eu_reserve_buffers(ticket, head, true);
if (unlikely(r != 0)) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c 
b/drivers/gpu/drm/radeon/radeon_uvd.c
index 1b65ae2433cd..2f93fef15aab 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -620,7 +620,7 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev,
INIT_LIST_HEAD();
list_add(, );

-   r = ttm_eu_reserve_buffers(, );
+   r = ttm_eu_reserve_buffers(, , true);
if (r)
return r;

diff --git a/drivers/gpu/drm/radeon/radeon_vm.c 
b/drivers/gpu/drm/radeon/radeon_vm.c
index 2aae6ce49d32..f4fd72477a71 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -364,7 +364,7 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev,
 INIT_LIST_HEAD();
 list_add(, );

-r = ttm_eu_reserve_buffers(, );
+r = ttm_eu_reserve_buffers(, , true);
 if (r)
return r;

diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c 
b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index e8dac8758528..39a11bbd2bac 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -112,7 +112,7 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation);
  */

 int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
-  struct list_head *list)
+  struct list_head *list, bool intr)
 {
struct ttm_bo_global *glob;
struct ttm_validate_buffer *entry;
@@ -140,7 +140,7 @@ retry:
if (entry->reserved)
continue;

-   ret = __ttm_bo_reserve(bo, true, (ticket == NULL), true,
+   ret = __ttm_bo_reserve(bo, intr, (ticket == NULL), true,
   ticket);

if (ret == -EDEADLK) {
@@ -153,13 +153,17 @@ retry:
ttm_eu_backoff_reservation_locked(list);
spin_unlock(>lru_lock);
ttm_eu_list_ref_sub(list);
-   ret = ww_mutex_lock_slow_interruptible(>resv->lock,
-  ticket);
-   if (unlikely(ret != 0)) {
-   if (ret == -EINTR)
-   ret = -ERESTARTSYS;
-   goto err_fini;
-   }
+
+   if (intr) {
+   ret = 
ww_mutex_lock_slow_interruptible(>resv->lock,
+  ticket);
+   if (unlikely(ret != 0)) {
+   if (ret == -EINTR)
+   ret = -ERESTARTSYS;
+   goto err_fini;
+   }
+   } else
+   ww_mutex_lock_slow(>resv->lock, ticket);

entry->reserved = true;
if (unlikely(atomic_read(>cpu_writers) > 0)) {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 87df0b3674fd..5d7d2e00296b 100644
--- 

[RFC PATCH v1 00/16] Convert all ttm drivers to use the new reservation interface

2014-05-14 Thread Maarten Lankhorst
This series depends on the previously posted reservation api patches.
2 of them are not yet in for-next-fences branch of
git://git.linaro.org/people/sumit.semwal/linux-3.x.git

The missing patches are still in my vmwgfx_wip branch at
git://people.freedesktop.org/~mlankhorst/linux

All ttm drivers are converted to the fence api, fence_lock is removed
and rcu is used in its place.

qxl is the first driver to use shared fence slots, but when these patches
are applied it's easy to convert nouveau too. I've done it as part of the
cross-device gpu synchronization patch series.

---

Maarten Lankhorst (16):
  drm/ttm: add interruptible parameter to ttm_eu_reserve_buffers
  drm/ttm: kill off some members to ttm_validate_buffer
  drm/nouveau: add reservation to nouveau_gem_ioctl_cpu_prep
  drm/nouveau: require reservations for nouveau_fence_sync and 
nouveau_bo_fence
  drm/ttm: call ttm_bo_wait while inside a reservation
  drm/ttm: kill fence_lock
  drm/nouveau: rework to new fence interface
  drm/radeon: use common fence implementation for fences
  drm/qxl: rework to new fence interface
  drm/vmwgfx: get rid of different types of fence_flags entirely
  drm/vmwgfx: rework to new fence interface
  drm/ttm: flip the switch, and convert to dma_fence
  drm/nouveau: use rcu in nouveau_gem_ioctl_cpu_prep
  drm/radeon: use rcu waits in some ioctls
  drm/vmwgfx: use rcu in vmw_user_dmabuf_synccpu_grab
  drm/ttm: use rcu in core ttm

 drivers/gpu/drm/nouveau/core/core/event.c |4 
 drivers/gpu/drm/nouveau/nouveau_bo.c  |   59 +---
 drivers/gpu/drm/nouveau/nouveau_display.c |   25 +-
 drivers/gpu/drm/nouveau/nouveau_fence.c   |  430 +++--
 drivers/gpu/drm/nouveau/nouveau_fence.h   |   22 +
 drivers/gpu/drm/nouveau/nouveau_gem.c |   55 +---
 drivers/gpu/drm/nouveau/nv04_fence.c  |4 
 drivers/gpu/drm/nouveau/nv10_fence.c  |4 
 drivers/gpu/drm/nouveau/nv17_fence.c  |2 
 drivers/gpu/drm/nouveau/nv50_fence.c  |2 
 drivers/gpu/drm/nouveau/nv84_fence.c  |   11 -
 drivers/gpu/drm/qxl/Makefile  |2 
 drivers/gpu/drm/qxl/qxl_cmd.c |7 
 drivers/gpu/drm/qxl/qxl_debugfs.c |   16 +
 drivers/gpu/drm/qxl/qxl_drv.h |   20 -
 drivers/gpu/drm/qxl/qxl_fence.c   |   91 --
 drivers/gpu/drm/qxl/qxl_kms.c |1 
 drivers/gpu/drm/qxl/qxl_object.c  |2 
 drivers/gpu/drm/qxl/qxl_object.h  |6 
 drivers/gpu/drm/qxl/qxl_release.c |  172 ++--
 drivers/gpu/drm/qxl/qxl_ttm.c |   93 --
 drivers/gpu/drm/radeon/radeon.h   |   15 -
 drivers/gpu/drm/radeon/radeon_cs.c|   10 +
 drivers/gpu/drm/radeon/radeon_device.c|1 
 drivers/gpu/drm/radeon/radeon_display.c   |   20 +
 drivers/gpu/drm/radeon/radeon_fence.c |  191 ++---
 drivers/gpu/drm/radeon/radeon_gem.c   |   19 +
 drivers/gpu/drm/radeon/radeon_object.c|8 -
 drivers/gpu/drm/radeon/radeon_ttm.c   |   34 --
 drivers/gpu/drm/radeon/radeon_uvd.c   |   10 -
 drivers/gpu/drm/ttm/ttm_bo.c  |  187 ++---
 drivers/gpu/drm/ttm/ttm_bo_util.c |   28 --
 drivers/gpu/drm/ttm/ttm_bo_vm.c   |3 
 drivers/gpu/drm/ttm/ttm_execbuf_util.c|  146 +++---
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c|   47 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |1 
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c   |   24 --
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |  329 --
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.h |   35 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c  |   43 +--
 include/drm/ttm/ttm_bo_api.h  |7 
 include/drm/ttm/ttm_bo_driver.h   |   29 --
 include/drm/ttm/ttm_execbuf_util.h|   22 +
 43 files changed, 1107 insertions(+), 1130 deletions(-)
 delete mode 100644 drivers/gpu/drm/qxl/qxl_fence.c

-- 
Signature


[RFC V3 2/3] drm/bridge: add a dummy panel driver to support lvds bridges

2014-05-14 Thread Thierry Reding
ontrols inside
> bridge! :(

What makes you think that I would suddenly be any more convinced by this
solution than by your prior proposal? I didn't say outright no to what
you proposed earlier. What I said was that I didn't like it and that I
thought we could come up with a better solution. Part of getting to a
better solution is trying to understand the problems involved. You don't
solve a problem by simply moving code into a different driver.

Thierry
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140514/6d0ed490/attachment.sig>


[PATCH v2 4/7] drivers/base: Add interface framework

2014-05-14 Thread Daniel Vetter
On Tue, May 13, 2014 at 05:32:15PM -0700, Greg Kroah-Hartman wrote:
> On Tue, May 13, 2014 at 07:57:13PM +0200, Daniel Vetter wrote:
> > On Tue, May 13, 2014 at 05:30:47PM +0200, Thierry Reding wrote:
> > > From: Thierry Reding 
> > > 
> > > Some drivers, such as graphics drivers in the DRM subsystem, do not have
> > > a real device that they can bind to. They are often composed of several
> > > devices, each having their own driver. The master/component framework
> > > can be used in these situations to collect the devices pertaining to one
> > > logical device, wait until all of them have registered and then bind
> > > them all at once.
> > > 
> > > For some situations this is only a partial solution. An implementation
> > > of a master still needs to be registered with the system somehow. Many
> > > drivers currently resort to creating a dummy device that a driver can
> > > bind to and register the master against. This is problematic since it
> > > requires (and presumes) knowledge about the system within drivers.
> > > 
> > > Furthermore there are setups where a suitable device already exists, but
> > > is already bound to a driver. For example, on Tegra the following device
> > > tree extract (simplified) represents the host1x device along with child
> > > devices:
> > > 
> > >   host1x {
> > >   display-controller {
> > >   ...
> > >   };
> > > 
> > >   display-controller {
> > >   ...
> > >   };
> > > 
> > >   hdmi {
> > >   ...
> > >   };
> > > 
> > >   dsi {
> > >   ...
> > >   };
> > > 
> > >   csi {
> > >   ...
> > >   };
> > > 
> > >   video-input {
> > >   ...
> > >   };
> > >   };
> > > 
> > > Each of the child devices is in turn a client of host1x, in that it can
> > > request resources (command stream DMA channels and syncpoints) from it.
> > > To implement the DMA channel and syncpoint infrastructure, host1x comes
> > > with its own driver. Children are implemented in separate drivers. In
> > > Linux this set of devices would be exposed by DRM and V4L2 drivers.
> > > 
> > > However, neither the DRM nor the V4L2 drivers have a single device that
> > > they can bind to. The DRM device is composed of the display controllers
> > > and the various output devices, whereas the V4L2 device is composed of
> > > one or more video input devices.
> > > 
> > > This patch introduces the concept of an interface and drivers that can
> > > bind to a given interface. An interface can be exposed by any device,
> > > and interface drivers can bind to these interfaces. Multiple drivers can
> > > bind against a single interface. When a device is removed, interfaces
> > > exposed by it will be removed as well, thereby removing the drivers that
> > > were bound to those interfaces.
> > > 
> > > In the example above, the host1x device would expose the "tegra-host1x"
> > > interface. DRM and V4L2 drivers can then bind to that interface and
> > > instantiate the respective subsystem objects from there.
> > > 
> > > Signed-off-by: Thierry Reding 
> > > ---
> > > Note that I'd like to merge this through the Tegra DRM tree so that the
> > > changes to the Tegra DRM driver later in this series can be merged at
> > > the same time and are not delayed for another release cycle.
> > > 
> > > In particular that means that I'm looking for an Acked-by from Greg.
> > > 
> > >  drivers/base/Makefile |   2 +-
> > >  drivers/base/interface.c  | 186 
> > > ++
> > >  include/linux/interface.h |  40 ++
> > >  3 files changed, 227 insertions(+), 1 deletion(-)
> > >  create mode 100644 drivers/base/interface.c
> > >  create mode 100644 include/linux/interface.h
> > 
> > Hm, this interface stuff smells like bus drivers light. Should we instead
> > have a pile of helpers to make creating new buses with match methods more
> > trivial? There's a fairly big pile of small use-cases where this might be
> > useful. In your case here all the host1x children would sit on a host1x
> > bus. Admittedly I didn't look into the details.
> 
> I have no problem adding such "bus-light" functions, to make it easier
> to create and implement a bus in the driver core, as I know it's really
> heavy.  That's been on my "todo" list for over a decade now...

Hm, I've victimized^Wvolunteered a few internal people to look into a
hdmi/dp sink bus type of thing so that we can move away from all those
ad-hoc hacks currently used to coordinate between drm display drivers and
the audio side of things. So I'm interested.

Do you have some ideas somewhere already about how you think this should
look like? Or is this more a "hey, this would be really cool, eventually"
kind of thing?

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH v2 4/7] drivers/base: Add interface framework

2014-05-14 Thread Daniel Vetter
On Tue, May 13, 2014 at 11:31:07PM +0200, Thierry Reding wrote:
> A different solution, which seems to be fairly common for DRM drivers
> for SoCs, is to instantiate a dummy device so that the DRM driver can
> bind to it. This can happen in two forms: add the dummy device directly
> in device tree (which goes against pretty much everything that's been
> preached about device tree in the past) or the dummy device can be
> instantiated in code, which is what the current Tegra DRM/host1x driver
> does.

Actually the dummy device seems to be an acceptable solution and iirc was
even acked by DT maintainers in the last KS. I'm not on top of things, but
iirc the thinking was that a dummy device which just pulls in all the
relevant real bits with phandles is justified in the board file since it
tells you how the board is intended to be used. The justification was that
on SoCs where assigning stuff between v4l and drm is really flexible (e.g.
on omap or so where you can assign the display pipes essentially freely)
the use-case of the board is what matters, and that's a somewhat physical
property of it (i.e. in what kind of device it's sitting.)

So in your case you'd have a fake display and a fake video device which
pulls everything the drm/v4l driver need together. So if the issue is how
to get at a master device I think that's simple to solve.

If the issue otoh is how the various drivers can get at the bus-like
services host1x exposes, then I think a real bus driver makes a lot more
sense. And Greg seems to have ideas about that already.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH] drm/panel: Add support for EDT ETM0700G0DH6 panel

2014-05-14 Thread Philipp Zabel
The EDT ETM0700G0DH6 is a 7" 800x480 panel, which can be
supported by the simple panel driver.

Signed-off-by: Philipp Zabel 
---
 drivers/gpu/drm/panel/panel-simple.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 309f29e..c10ebb5 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -328,6 +328,29 @@ static const struct panel_desc chunghwa_claa101wb01 = {
},
 };

+static const struct drm_display_mode edt_etm0700g0dh6_mode = {
+   .clock = 33260,
+   .hdisplay = 800,
+   .hsync_start = 800 + 40,
+   .hsync_end = 800 + 40 + 128,
+   .htotal = 800 + 40 + 128 + 88,
+   .vdisplay = 480,
+   .vsync_start = 480 + 10,
+   .vsync_end = 480 + 10 + 2,
+   .vtotal = 480 + 10 + 2 + 33,
+   .vrefresh = 60,
+   .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
+static const struct panel_desc edt_etm0700g0dh6 = {
+   .modes = _etm0700g0dh6_mode,
+   .num_modes = 1,
+   .size = {
+   .width = 152,
+   .height = 91,
+   },
+};
+
 static const struct drm_display_mode lg_lp129qe_mode = {
.clock = 285250,
.hdisplay = 2560,
@@ -383,6 +406,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "chunghwa,claa101wb01",
.data = _claa101wb01
}, {
+   .compatible = "edt,etm0700g0dh6",
+   .data = _etm0700g0dh6,
+   }, {
.compatible = "lg,lp129qe",
.data = _lp129qe,
}, {
-- 
2.0.0.rc2



[Bug 78669] [r600g with -O3] layered-rendering/clear-color-all-types 3d single_level fails

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=78669

--- Comment #5 from Marek Ol??k  ---
I always compile with -O2 and the test result is random pass/fail.

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


[PATCH 18/18] ARM: dts: exynos5420: add dsi node

2014-05-14 Thread YoungJun Cho
This patch adds common part of dsi node.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 arch/arm/boot/dts/exynos5420.dtsi |   14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index 6fde5fd..43b6852 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -478,6 +478,20 @@
#phy-cells = <1>;
};

+   dsi at 1450 {
+   compatible = "samsung,exynos5420-mipi-dsi";
+   reg = <0x1450 0x1>;
+   interrupts = <0 82 0>;
+   samsung,power-domain = <_pd>;
+   phys = <_phy 1>;
+   phy-names = "dsim";
+   clocks = < CLK_DSIM1>, < CLK_SCLK_MIPI1>;
+   clock-names = "bus_clk", "pll_clk";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
fimd at 1440 {
samsung,power-domain = <_pd>;
clocks = < CLK_SCLK_FIMD1>, < CLK_FIMD1>;
-- 
1.7.9.5



[PATCH 17/18] ARM: dts: exynos5420: add mipi-phy node

2014-05-14 Thread YoungJun Cho
This patch adds mipi-phy node for MIPI-DSI device.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 arch/arm/boot/dts/exynos5420.dtsi |6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index c3a9a66..6fde5fd 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -472,6 +472,12 @@
phy-names = "dp";
};

+   mipi_phy: video-phy at 10040714 {
+   compatible = "samsung,s5pv210-mipi-video-phy";
+   reg = <0x10040714 12>;
+   #phy-cells = <1>;
+   };
+
fimd at 1440 {
samsung,power-domain = <_pd>;
clocks = < CLK_SCLK_FIMD1>, < CLK_FIMD1>;
-- 
1.7.9.5



[PATCH 16/18] ARM: dts: exynos5: add system register support

2014-05-14 Thread YoungJun Cho
This patch adds sysreg device node, and sysreg property to fimd device node
which is required to use I80 interface.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 arch/arm/boot/dts/exynos5.dtsi |6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 79d0608..95ee496 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -81,12 +81,18 @@
status = "disabled";
};

+   sys_reg: syscon at 1005 {
+   compatible = "samsung,exynos5-sysreg", "syscon";
+   reg = <0x1005 0x500>;
+   };
+
fimd at 1440 {
compatible = "samsung,exynos5250-fimd";
interrupt-parent = <>;
reg = <0x1440 0x4>;
interrupt-names = "fifo", "vsync", "lcd_sys";
interrupts = <18 4>, <18 5>, <18 6>;
+   samsung,sysreg = <_reg>;
status = "disabled";
};

-- 
1.7.9.5



[PATCH 15/18] ARM: dts: exynos4: add system register node

2014-05-14 Thread YoungJun Cho
This patch adds sysreg property to fimd device node which is required
to use I80 interface.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 arch/arm/boot/dts/exynos4.dtsi |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 2f8bcd0..abfcbe2 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -534,6 +534,7 @@
clocks = < CLK_SCLK_FIMD0>, < CLK_FIMD0>;
clock-names = "sclk_fimd", "fimd";
samsung,power-domain = <_lcd0>;
+   samsung,sysreg = <_reg>;
status = "disabled";
};
 };
-- 
1.7.9.5



[PATCH 14/18] drm/panel: add S6E3FA0 driver

2014-05-14 Thread YoungJun Cho
This patch adds MIPI-DSI command mode based S6E3FA0 AMOLED LCD Panel driver.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/panel/Kconfig |7 +
 drivers/gpu/drm/panel/Makefile|1 +
 drivers/gpu/drm/panel/panel-s6e3fa0.c |  570 +
 3 files changed, 578 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-s6e3fa0.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4ec874d..fa51237 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -30,4 +30,11 @@ config DRM_PANEL_S6E8AA0
select DRM_MIPI_DSI
select VIDEOMODE_HELPERS

+config DRM_PANEL_S6E3FA0
+   tristate "S6E3FA0 DSI command mode panel"
+   depends on DRM && DRM_PANEL
+   depends on OF
+   select DRM_MIPI_DSI
+   select CMDMODE_HELPERS
+
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 8b92921..85c6738 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
 obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
 obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
+obj-$(CONFIG_DRM_PANEL_S6E3FA0) += panel-s6e3fa0.o
diff --git a/drivers/gpu/drm/panel/panel-s6e3fa0.c 
b/drivers/gpu/drm/panel/panel-s6e3fa0.c
new file mode 100644
index 000..a3b2d7e
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-s6e3fa0.c
@@ -0,0 +1,570 @@
+/*
+ * MIPI-DSI based s6e3fa0 AMOLED LCD 5.7 inch panel driver.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *
+ * YoungJun Cho 
+ *
+ * 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.
+*/
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/* Manufacturer Command Set */
+#define MCS_GLOBAL_PARAMETER   0xb0
+#define MCS_AID0xb2
+#define MCS_ELVSSOPT   0xb6
+#define MCS_TEMPERATURE_SET0xb8
+#define MCS_PENTILE_CTRL   0xc0
+#define MCS_GAMMA_MODE 0xca
+#define MCS_VDDM   0xd7
+#define MCS_ALS0xe3
+#define MCS_ERR_FG 0xed
+#define MCS_KEY_LEV1   0xf0
+#define MCS_PANEL_UPDATE   0xf7
+#define MCS_KEY_LEV2   0xfc
+#define MCS_RE 0xfe
+#define MCS_TOUT2_HSYNC0xff
+
+/* Content Adaptive Brightness Control */
+#define DCS_WRITE_CABC 0x55
+
+#define MTP_ID_LEN 3
+#define GAMMA_LEVEL_NUM30
+
+#define DEFAULT_VDDM_VAL   0x15
+
+struct s6e3fa0 {
+   struct device   *dev;
+   struct drm_panelpanel;
+
+   struct regulator_bulk_data  supplies[2];
+   struct gpio_desc*reset_gpio;
+   struct gpio_desc*det_gpio;
+   struct gpio_desc*te_gpio;
+   struct cmdmode  cm;
+
+   unsigned intpower_on_delay;
+   unsigned intreset_delay;
+   unsigned intinit_delay;
+   unsigned intwidth_mm;
+   unsigned intheight_mm;
+
+   unsigned char   id;
+   unsigned char   vddm;
+   unsigned intbrightness;
+};
+
+#define panel_to_s6e3fa0(p) container_of(p, struct s6e3fa0, panel)
+
+/* VDD Memory Lookup Table contains paires of {ReadValue, WriteValue} */
+static const unsigned char s6e3fa0_vddm_lut[][2] = {
+   {0x00, 0x0d}, {0x01, 0x0d}, {0x02, 0x0e}, {0x03, 0x0f}, {0x04, 0x10},
+   {0x05, 0x11}, {0x06, 0x12}, {0x07, 0x13}, {0x08, 0x14}, {0x09, 0x15},
+   {0x0a, 0x16}, {0x0b, 0x17}, {0x0c, 0x18}, {0x0d, 0x19}, {0x0e, 0x1a},
+   {0x0f, 0x1b}, {0x10, 0x1c}, {0x11, 0x1d}, {0x12, 0x1e}, {0x13, 0x1f},
+   {0x14, 0x20}, {0x15, 0x21}, {0x16, 0x22}, {0x17, 0x23}, {0x18, 0x24},
+   {0x19, 0x25}, {0x1a, 0x26}, {0x1b, 0x27}, {0x1c, 0x28}, {0x1d, 0x29},
+   {0x1e, 0x2a}, {0x1f, 0x2b}, {0x20, 0x2c}, {0x21, 0x2d}, {0x22, 0x2e},
+   {0x23, 0x2f}, {0x24, 0x30}, {0x25, 0x31}, {0x26, 0x32}, {0x27, 0x33},
+   {0x28, 0x34}, {0x29, 0x35}, {0x2a, 0x36}, {0x2b, 0x37}, {0x2c, 0x38},
+   {0x2d, 0x39}, {0x2e, 0x3a}, {0x2f, 0x3b}, {0x30, 0x3c}, {0x31, 0x3d},
+   {0x32, 0x3e}, {0x33, 0x3f}, {0x34, 0x3f}, {0x35, 0x3f}, {0x36, 0x3f},
+   {0x37, 0x3f}, {0x38, 0x3f}, {0x39, 0x3f}, {0x3a, 0x3f}, {0x3b, 0x3f},
+   {0x3c, 0x3f}, {0x3d, 0x3f}, {0x3e, 0x3f}, {0x3f, 0x3f}, {0x40, 0x0c},
+   {0x41, 0x0b}, {0x42, 0x0a}, {0x43, 0x09}, {0x44, 0x08}, {0x45, 0x07},
+   {0x46, 0x06}, {0x47, 0x05}, {0x48, 0x04}, {0x49, 0x03}, {0x4a, 

[PATCH 13/18] ARM: dts: s6e3fa0: add DT bindings

2014-05-14 Thread YoungJun Cho
This patch adds DT bindings for s6e3fa0 panel.
The bindings describes panel resources, display timings and cpu mode timings.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt

diff --git a/Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt 
b/Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
new file mode 100644
index 000..c9a3fbd
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
@@ -0,0 +1,45 @@
+Samsung S6E3FA0 AMOLED LCD 5.7 inch panel
+
+Required properties:
+  - compatible: "samsung,s6e3fa0"
+  - reg: the virtual channel number of a DSI peripheral
+  - vdd3-supply: core voltage supply
+  - vci-supply: voltage supply for analog circuits
+  - reset-gpios: a GPIO spec for the reset pin
+  - det-gpios: a GPIO spec for the OLED detection pin
+  - te-gpios: a GPIO spec for the TE pin
+  - cmdmode-display-timings: command mode interface timings for the connected
+  panel as described by [1]
+
+Optional properties:
+
+The device node can contain one 'port' child node with one child 'endpoint'
+node, according to the bindings defined in [2]. This node should describe
+panel's video bus.
+
+[1]: Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
+[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+   panel at 0 {
+   compatible = "samsung,s6e3fa0";
+   reg = <0>;
+   vdd3-supply = <_reg>;
+   vci-supply = <_reg>;
+   reset-gpios = < 4 0>;
+   det-gpios = < 6 0>;
+   te-gpios = < 7 0>;
+
+   cmdmode-display-timings {
+   timing-0 {
+   clock-frequency = <0>;
+   hactive = <1080>;
+   vactive = <1920>;
+   cs-setup = <0>;
+   wr-setup = <0>;
+   wr-active = <1>;
+   wr-hold = <0>;
+   };
+   };
+   };
-- 
1.7.9.5



[PATCH 12/18] drm/exynos: dsi: add driver data to support Exynos5420

2014-05-14 Thread YoungJun Cho
The offset of register DSIM_PLLTMR_REG in Exynos5420 is different
from the one in Exynos4 SoC.

In case of Exynos5420 SoC, there is no frequency band bit in DSIM_PLLCTRL_REG,
and it uses DSIM_PHYCTRL_REG and DSIM_PHYTIMING*_REG instead.
So this patch adds driver data to distinguish it.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c |  157 ++-
 1 file changed, 135 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 783d7a5..35d636b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -17,6 +17,7 @@

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -55,9 +56,12 @@

 /* FIFO memory AC characteristic register */
 #define DSIM_PLLCTRL_REG   0x4c/* PLL control register */
-#define DSIM_PLLTMR_REG0x50/* PLL timer register */
 #define DSIM_PHYACCHR_REG  0x54/* D-PHY AC characteristic register */
 #define DSIM_PHYACCHR1_REG 0x58/* D-PHY AC characteristic register1 */
+#define DSIM_PHYCTRL_REG   0x5c
+#define DSIM_PHYTIMING_REG 0x64
+#define DSIM_PHYTIMING1_REG0x68
+#define DSIM_PHYTIMING2_REG0x6c

 /* DSIM_STATUS */
 #define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
@@ -201,6 +205,24 @@
 #define DSIM_PLL_M(x)  ((x) << 4)
 #define DSIM_PLL_S(x)  ((x) << 1)

+/* DSIM_PHYCTRL */
+#define DSIM_PHYCTRL_ULPS_EXIT(x)  (((x) & 0x1ff) << 0)
+
+/* DSIM_PHYTIMING */
+#define DSIM_PHYTIMING_LPX(x)  ((x) << 8)
+#define DSIM_PHYTIMING_HS_EXIT(x)  ((x) << 0)
+
+/* DSIM_PHYTIMING1 */
+#define DSIM_PHYTIMING1_CLK_PREPARE(x) ((x) << 24)
+#define DSIM_PHYTIMING1_CLK_ZERO(x)((x) << 16)
+#define DSIM_PHYTIMING1_CLK_POST(x)((x) << 8)
+#define DSIM_PHYTIMING1_CLK_TRAIL(x)   ((x) << 0)
+
+/* DSIM_PHYTIMING2 */
+#define DSIM_PHYTIMING2_HS_PREPARE(x)  ((x) << 16)
+#define DSIM_PHYTIMING2_HS_ZERO(x) ((x) << 8)
+#define DSIM_PHYTIMING2_HS_TRAIL(x)((x) << 0)
+
 #define DSI_MAX_BUS_WIDTH  4
 #define DSI_NUM_VIRTUAL_CHANNELS   4
 #define DSI_TX_FIFO_SIZE   2048
@@ -234,6 +256,12 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_INITIALIZED BIT(1)
 #define DSIM_STATE_CMD_LPM BIT(2)

+struct exynos_dsi_driver_data {
+   unsigned int plltmr_reg;
+
+   unsigned int has_freqband:1;
+};
+
 struct exynos_dsi {
struct mipi_dsi_host dsi_host;
struct drm_connector connector;
@@ -263,11 +291,39 @@ struct exynos_dsi {

spinlock_t transfer_lock; /* protects transfer_list */
struct list_head transfer_list;
+
+   struct exynos_dsi_driver_data *driver_data;
 };

 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)

+static struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
+   .plltmr_reg = 0x50,
+   .has_freqband = 1,
+};
+
+static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
+   .plltmr_reg = 0x58,
+};
+
+static struct of_device_id exynos_dsi_of_match[] = {
+   { .compatible = "samsung,exynos4210-mipi-dsi",
+ .data = _dsi_driver_data },
+   { .compatible = "samsung,exynos5420-mipi-dsi",
+ .data = _dsi_driver_data },
+   { }
+};
+
+static inline struct exynos_dsi_driver_data *exynos_dsi_get_driver_data(
+   struct platform_device *pdev)
+{
+   const struct of_device_id *of_id =
+   of_match_device(exynos_dsi_of_match, >dev);
+
+   return (struct exynos_dsi_driver_data *)of_id->data;
+}
+
 static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)
 {
if (wait_for_completion_timeout(>completed, msecs_to_jiffies(300)))
@@ -341,14 +397,9 @@ static unsigned long exynos_dsi_pll_find_pms(struct 
exynos_dsi *dsi,
 static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
unsigned long freq)
 {
-   static const unsigned long freq_bands[] = {
-   100 * MHZ, 120 * MHZ, 160 * MHZ, 200 * MHZ,
-   270 * MHZ, 320 * MHZ, 390 * MHZ, 450 * MHZ,
-   510 * MHZ, 560 * MHZ, 640 * MHZ, 690 * MHZ,
-   770 * MHZ, 870 * MHZ, 950 * MHZ,
-   };
+   struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
unsigned long fin, fout;
-   int timeout, band;
+   int timeout;
u8 p, s;
u16 m;
u32 reg;
@@ -369,18 +420,30 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi 
*dsi,
"failed to find PLL PMS for requested frequency\n");
return -EFAULT;
}
+   dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);

-   for (band = 0; band < ARRAY_SIZE(freq_bands); 

[PATCH 11/18] ARM: dts: exynos_dsim: add exynos5420 compatible to DT bindings

2014-05-14 Thread YoungJun Cho
This patch adds relevant to exynos5420 compatible for exynos5420 SoC support.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 .../devicetree/bindings/video/exynos_dsim.txt  |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt 
b/Documentation/devicetree/bindings/video/exynos_dsim.txt
index 33b5730..29bf3b2 100644
--- a/Documentation/devicetree/bindings/video/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
@@ -1,7 +1,9 @@
 Exynos MIPI DSI Master

 Required properties:
-  - compatible: "samsung,exynos4210-mipi-dsi"
+  - compatible: value should be one of the following
+   "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
+   "samsung,exynos5420-mipi-dsi" /* for Exynos5420 SoCs */
   - reg: physical base address and length of the registers set for the device
   - interrupts: should contain DSI interrupt
   - clocks: list of clock specifiers, must contain an entry for each required
-- 
1.7.9.5



[PATCH 10/18] drm/exynos: fimd: support I80 interface

2014-05-14 Thread YoungJun Cho
To support MIPI DSI command mode interface, FIMD should do followings:
- Sets LCD block configuration for I80 interface.
- Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
- Implements trigger feature which transfers image date if there is
  page flip request, and implements TE handler to call trigger function.
- Sets command mode timings configuration.
- Sets ideal(pixel) clock is 2 times faster than the original one to
  generate frame done IRQ prior to the next TE signal.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig   |1 +
 drivers/gpu/drm/exynos/exynos_drm_fimd.c |  277 +-
 include/video/samsung_fimd.h |3 +-
 3 files changed, 237 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 5bf5bca..f4d34f0 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
bool "Exynos DRM FIMD"
depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
select FB_MODE_HELPERS
+   select MFD_SYSCON
help
  Choose this option if you want to use Exynos FIMD for DRM.

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 173ee97..9d585f9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -20,11 +20,14 @@
 #include 
 #include 
 #include 
+#include 
+#include 

 #include 
 #include 
 #include 
 #include 
+#include 

 #include "exynos_drm_drv.h"
 #include "exynos_drm_fbdev.h"
@@ -60,6 +63,24 @@
 /* color key value register for hardware window 1 ~ 4. */
 #define WKEYCON1_BASE(x)   ((WKEYCON1 + 0x140) + ((x - 1) * 8))

+/* i80 / RGB trigger control register */
+#define TRIGCON0x1A4
+#define TRGMODE_I80_RGB_ENABLE_I80 (1 << 0)
+#define SWTRGCMD_I80_RGB_ENABLE(1 << 1)
+
+/* display mode change control register except exynos4 */
+#define VIDOUT_CON 0x000
+#define VIDOUT_CON_F_I80_LDI0  (0x2 << 8)
+
+/* i80 interface control for main LDI register */
+#define I80IFCONFAx(x) (0x1B0 + (x) * 4)
+#define I80IFCONFBx(x) (0x1B8 + (x) * 4)
+#define LCD_CS_SETUP(x)((x) << 16)
+#define LCD_WR_SETUP(x)((x) << 12)
+#define LCD_WR_ACT(x)  ((x) << 8)
+#define LCD_WR_HOLD(x) ((x) << 4)
+#define I80IFEN_ENABLE (1 << 0)
+
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR 5

@@ -67,10 +88,14 @@

 struct fimd_driver_data {
unsigned int timing_base;
+   unsigned int lcdblk_off;
+   unsigned int lcdblk_vt_shift;
+   unsigned int lcdblk_bypass_shift;

unsigned int has_shadowcon:1;
unsigned int has_clksel:1;
unsigned int has_limited_fmt:1;
+   unsigned int has_vidoutcon:1;
 };

 static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -81,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {

 static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
+   .lcdblk_off = 0x210,
+   .lcdblk_vt_shift = 10,
+   .lcdblk_bypass_shift = 1,
.has_shadowcon = 1,
 };

 static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x2,
+   .lcdblk_off = 0x214,
+   .lcdblk_vt_shift = 24,
+   .lcdblk_bypass_shift = 15,
.has_shadowcon = 1,
+   .has_vidoutcon = 1,
 };

 struct fimd_win_data {
@@ -111,15 +143,23 @@ struct fimd_context {
struct clk  *bus_clk;
struct clk  *lcd_clk;
void __iomem*regs;
+   struct regmap   *sysreg;
struct drm_display_mode mode;
struct fimd_win_datawin_data[WINDOWS_NR];
unsigned intdefault_win;
unsigned long   irq_flags;
+   u32 vidcon0;
u32 vidcon1;
+   u32 vidout_con;
+   u32 i80ifcon;
+   booli80_if;
boolsuspended;
int pipe;
wait_queue_head_t   wait_vsync_queue;
atomic_twait_vsync_event;
+   atomic_twin_updated;
+   atomic_ttriggering;
+   spinlock_t  win_updated_lock;

struct exynos_drm_panel_info panel;
struct fimd_driver_data *driver_data;
@@ -242,6 +282,14 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
unsigned long ideal_clk = mode->htotal * 

[PATCH 09/18] drm/exynos: dsi: add TE handler to support command mode interface

2014-05-14 Thread YoungJun Cho
To support command mode interface, the DSI host calls this handler
to notify the panel tearing effect synchronization signal to the
CRTC device manager to trigger to transfer video image.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c |   13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0a4e3ce..783d7a5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -24,6 +24,7 @@
 #include 
 #include 

+#include "exynos_drm_crtc.h"
 #include "exynos_drm_drv.h"

 /* returns true iff both arguments logically differs */
@@ -1033,10 +1034,22 @@ static ssize_t exynos_dsi_host_transfer(struct 
mipi_dsi_host *host,
return (ret < 0) ? ret : xfer.rx_done;
 }

+static int exynos_dsi_host_te_handler(struct mipi_dsi_host *host)
+{
+   struct exynos_dsi *dsi = host_to_dsi(host);
+   struct drm_encoder *encoder = dsi->encoder;
+
+   if (!(dsi->state & DSIM_STATE_ENABLED))
+   return -EPERM;
+
+   return exynos_drm_crtc_te_handler(encoder->crtc);
+}
+
 static const struct mipi_dsi_host_ops exynos_dsi_ops = {
.attach = exynos_dsi_host_attach,
.detach = exynos_dsi_host_detach,
.transfer = exynos_dsi_host_transfer,
+   .te_handler = exynos_dsi_host_te_handler,
 };

 static int exynos_dsi_poweron(struct exynos_dsi *dsi)
-- 
1.7.9.5



[PATCH 08/18] drm/exynos: add TE handler to support MIPI DSI command mode interface

2014-05-14 Thread YoungJun Cho
To support MIPI DSI command mode interface, the panel should generates
Tearing Effect synchronization signal between MCU and FB to display
video images.
And the display controller should trigger to transfer video image at
this signal.
So the panel receives the TE IRQ, then calls this handler chains
to notify it to the display controller.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c |   11 +++
 drivers/gpu/drm/exynos/exynos_drm_crtc.h |7 +++
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |3 +++
 include/drm/drm_mipi_dsi.h   |8 
 4 files changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 485fa26..2567ae0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -509,3 +509,14 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device 
*drm_dev,

return -EPERM;
 }
+
+int exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
+{
+   struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
+   int ret = 0;
+
+   if (manager->ops->te_handler)
+   ret = manager->ops->te_handler(manager);
+
+   return ret;
+}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index 9f74b10..875d93d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -36,4 +36,11 @@ void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, 
int zpos);
 int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
unsigned int out_type);

+/*
+ * This function calls the crtc device(manager)'s te_handler() callback
+ * to trigger to transfer video image at the tearing effect synchronization
+ * signal.
+ */
+int exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
+
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index e82e620..54b08d7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -181,6 +181,8 @@ struct exynos_drm_display {
  * @win_commit: apply hardware specific overlay data to registers.
  * @win_enable: enable hardware specific overlay.
  * @win_disable: disable hardware specific overlay.
+ * @te_handler: trigger to transfer video image at the tearing effect
+ * synchronization signal if there is a page flip request.
  */
 struct exynos_drm_manager;
 struct exynos_drm_manager_ops {
@@ -199,6 +201,7 @@ struct exynos_drm_manager_ops {
void (*win_commit)(struct exynos_drm_manager *mgr, int zpos);
void (*win_enable)(struct exynos_drm_manager *mgr, int zpos);
void (*win_disable)(struct exynos_drm_manager *mgr, int zpos);
+   int (*te_handler)(struct exynos_drm_manager *mgr);
 };

 /*
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 7209df1..f6d4c85 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -49,6 +49,13 @@ struct mipi_dsi_msg {
  * @detach: detach DSI device from DSI host
  * @transfer: send and/or receive DSI packet, return number of received bytes,
  *   or error
+ * @te_handler: call the crtc te_handler() callback from DSI host.
+ * The panel generates tearing effect synchronization signal
+ * between MCU and FB to display video images.
+ * And the display controller should trigger to transfer video
+ * image at this signal.
+ * So the panel receives the TE IRQ, then calls this handler
+ * to notify it to the display controller.
  */
 struct mipi_dsi_host_ops {
int (*attach)(struct mipi_dsi_host *host,
@@ -57,6 +64,7 @@ struct mipi_dsi_host_ops {
  struct mipi_dsi_device *dsi);
ssize_t (*transfer)(struct mipi_dsi_host *host,
struct mipi_dsi_msg *msg);
+   int (*te_handler)(struct mipi_dsi_host *host);
 };

 /**
-- 
1.7.9.5



[PATCH 07/18] ARM: dts: samsung-fimd: add I80 specific properties

2014-05-14 Thread YoungJun Cho
In case of using MIPI command mode interface panel,
the relevant registers should be set.
So this patch adds relevant DT bindings.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 .../devicetree/bindings/video/samsung-fimd.txt |2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/video/samsung-fimd.txt 
b/Documentation/devicetree/bindings/video/samsung-fimd.txt
index 2dad41b..6bf93e9 100644
--- a/Documentation/devicetree/bindings/video/samsung-fimd.txt
+++ b/Documentation/devicetree/bindings/video/samsung-fimd.txt
@@ -44,6 +44,8 @@ Optional Properties:
 - display-timings: timing settings for FIMD, as described in document [1].
Can be used in case timings cannot be provided otherwise
or to override timings provided by the panel.
+- samsung,sysreg: handle to syscon used to control the system registers
+- vidout-i80-ldi: boolean to support i80 interface instead of rgb one

 The device node can contain 'port' child nodes according to the bindings 
defined
 in [2]. The following are properties specific to those nodes:
-- 
1.7.9.5



[PATCH 06/18] ARM: dts: sysreg: add exynos5 compatible to DT bindings

2014-05-14 Thread YoungJun Cho
This patch adds relevant to exynos5 compatible for exynos5 SoCs.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 .../devicetree/bindings/arm/samsung/sysreg.txt |1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt 
b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
index 0ab3251..fd71581 100644
--- a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
@@ -3,6 +3,7 @@ SAMSUNG S5P/Exynos SoC series System Registers (SYSREG)
 Properties:
  - compatible : should contain "samsung,-sysreg", "syscon";
For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon";
+   For Exynos5 SoC series it should be "samsung,exynos5-sysreg", "syscon";
  - reg : offset and length of the register set.

 Example:
-- 
1.7.9.5



[PATCH 05/18] drm_modes: add command mode helpers

2014-05-14 Thread YoungJun Cho
This patch adds helper functions to convert cmdmode
to drm_display_mode

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/drm_modes.c |   59 +++
 include/drm/drm_modes.h |   12 +
 2 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index bedf189..8977381 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -37,6 +37,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 

 #include "drm_crtc_internal.h"
@@ -651,6 +653,63 @@ EXPORT_SYMBOL_GPL(of_get_drm_display_mode);
 #endif /* CONFIG_OF */
 #endif /* CONFIG_VIDEOMODE_HELPERS */

+#ifdef CONFIG_CMDMODE_HELPERS
+int drm_display_mode_from_cmdmode(const struct cmdmode *cm,
+   struct drm_display_mode *dmode)
+{
+   dmode->hdisplay = cm->hactive;
+   dmode->htotal = dmode->hsync_end = dmode->hsync_start = dmode->hdisplay;
+
+   dmode->vdisplay = cm->vactive;
+   dmode->vtotal = dmode->vsync_end = dmode->vsync_start = dmode->vdisplay;
+
+   dmode->clock = cm->pixelclock / 1000;
+
+   dmode->cs_setup = cm->cs_setup;
+   dmode->wr_setup = cm->wr_setup;
+   dmode->wr_active = cm->wr_active;
+   dmode->wr_hold = cm->wr_hold;
+
+   dmode->flags = 0;
+   drm_mode_set_name(dmode);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(drm_display_mode_from_cmdmode);
+
+#ifdef CONFIG_OF
+/**
+ * of_get_drm_cmdmode_display_mode - get a drm_display_mode from devicetree
+ * @np: device_node with the timing specification
+ * @dmode: will be set to the return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * This function is expensive and should only be used, if only one mode is to 
be
+ * read from DT. To get multiple modes start with
+ * of_get_cmdmode_display_timings and work with that instead.
+ */
+int of_get_drm_cmdmode_display_mode(struct device_node *np,
+   struct drm_display_mode *dmode, int index)
+{
+   struct cmdmode cm;
+   int ret;
+
+   ret = of_get_cmdmode(np, , index);
+   if (ret)
+   return ret;
+
+   drm_display_mode_from_cmdmode(, dmode);
+
+   pr_debug("%s: got %dx%d display mode from %s\n",
+   of_node_full_name(np), cm.hactive, cm.vactive, np->name);
+   drm_mode_debug_printmodeline(dmode);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_drm_cmdmode_display_mode);
+#endif /* CONFIG_OF */
+#endif /* CONFIG_CMDMODE_HELPERS */
+
 /**
  * drm_mode_set_name - set the name on a mode
  * @mode: name will be set in this mode
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 91d0582..0d29754 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -144,6 +144,12 @@ struct drm_display_mode {
int vrefresh;   /* in Hz */
int hsync;  /* in kHz */
enum hdmi_picture_aspect picture_aspect_ratio;
+
+   /* Command mode info - refers to video/cmdmode.h */
+   int cs_setup;
+   int wr_setup;
+   int wr_active;
+   int wr_hold;
 };

 /* mode specified on the command line */
@@ -176,6 +182,7 @@ static inline bool drm_mode_is_stereo(const struct 
drm_display_mode *mode)

 struct drm_connector;
 struct drm_cmdline_mode;
+struct cmdmode;

 struct drm_display_mode *drm_mode_create(struct drm_device *dev);
 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
@@ -200,6 +207,11 @@ void drm_display_mode_from_videomode(const struct 
videomode *vm,
 int of_get_drm_display_mode(struct device_node *np,
struct drm_display_mode *dmode,
int index);
+extern int drm_display_mode_from_cmdmode(const struct cmdmode *cm,
+  struct drm_display_mode *dmode);
+extern int of_get_drm_cmdmode_display_mode(struct device_node *np,
+  struct drm_display_mode *dmode,
+  int index);

 void drm_mode_set_name(struct drm_display_mode *mode);
 int drm_mode_hsync(const struct drm_display_mode *mode);
-- 
1.7.9.5



[PATCH 04/18] video: add command mode and command mode display timing

2014-05-14 Thread YoungJun Cho
This patch is based on videomode and display_timing relevant codes.
To support command mode panel, it does not need to guide its timing
information to the display controller like video mode panel,
but it requires signal timings to transfer video data.
So this patch adds cmdmode struct, cmdmode_display_timing struct and
the according helper functions to convert cmdmode_display_timing
to a generic cmdmode.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/video/Kconfig |3 +
 drivers/video/Makefile|2 +
 drivers/video/cmdmode.c   |   42 ++
 drivers/video/cmdmode_display_timing.c|   26 
 drivers/video/of_cmdmode.c|   55 
 drivers/video/of_cmdmode_display_timing.c |  212 +
 include/video/cmdmode.h   |   67 +
 include/video/cmdmode_display_timing.h|   59 
 include/video/of_cmdmode.h|   19 +++
 include/video/of_cmdmode_display_timing.h |   26 
 10 files changed, 511 insertions(+)
 create mode 100644 drivers/video/cmdmode.c
 create mode 100644 drivers/video/cmdmode_display_timing.c
 create mode 100644 drivers/video/of_cmdmode.c
 create mode 100644 drivers/video/of_cmdmode_display_timing.c
 create mode 100644 include/video/cmdmode.h
 create mode 100644 include/video/cmdmode_display_timing.h
 create mode 100644 include/video/of_cmdmode.h
 create mode 100644 include/video/of_cmdmode_display_timing.h

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c7b4f0f..7090ee5 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -38,6 +38,9 @@ config VGASTATE
 config VIDEOMODE_HELPERS
bool

+config CMDMODE_HELPERS
+   bool
+
 config HDMI
bool

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 9ad3c17..619dd99 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -8,6 +8,8 @@ obj-y += backlight/
 obj-y+= fbdev/

 obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
+obj-$(CONFIG_CMDMODE_HELPERS) += cmdmode_display_timing.o cmdmode.o
 ifeq ($(CONFIG_OF),y)
 obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
+obj-$(CONFIG_CMDMODE_HELPERS) += of_cmdmode_display_timing.o of_cmdmode.o
 endif
diff --git a/drivers/video/cmdmode.c b/drivers/video/cmdmode.c
new file mode 100644
index 000..3d3eeb8
--- /dev/null
+++ b/drivers/video/cmdmode.c
@@ -0,0 +1,42 @@
+/*
+ * generic cmdmode display timing functions
+ *
+ * Copyright (c) 2014 YoungJun Cho 
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+void cmdmode_from_timing(const struct cmdmode_display_timing *cmdt,
+   struct cmdmode *cm)
+{
+   cm->pixelclock = cmdt->pixelclock;
+   cm->hactive = cmdt->hactive;
+   cm->vactive = cmdt->vactive;
+   cm->cs_setup = cmdt->cs_setup;
+   cm->wr_setup = cmdt->wr_setup;
+   cm->wr_active = cmdt->wr_active;
+   cm->wr_hold = cmdt->wr_hold;
+}
+EXPORT_SYMBOL_GPL(cmdmode_from_timing);
+
+int cmdmode_from_timings(const struct cmdmode_display_timings *cmdts,
+   struct cmdmode *cm, unsigned int index)
+{
+   struct cmdmode_display_timing *cmdt;
+
+   cmdt = cmdmode_display_timings_get(cmdts, index);
+   if (!cmdt)
+   return -EINVAL;
+
+   cmdmode_from_timing(cmdt, cm);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(cmdmode_from_timings);
diff --git a/drivers/video/cmdmode_display_timing.c 
b/drivers/video/cmdmode_display_timing.c
new file mode 100644
index 000..88bab08
--- /dev/null
+++ b/drivers/video/cmdmode_display_timing.c
@@ -0,0 +1,26 @@
+/*
+ * generic cmdmode display timing functions
+ *
+ * Copyright (c) 2014 YoungJun Cho 
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+
+void cmdmode_display_timings_release(struct cmdmode_display_timings *cmdts)
+{
+   if (cmdts->timings) {
+   unsigned int i;
+
+   for (i = 0; i < cmdts->num_timings; i++)
+   kfree(cmdts->timings[i]);
+   kfree(cmdts->timings);
+   }
+   kfree(cmdts);
+}
+EXPORT_SYMBOL_GPL(cmdmode_display_timings_release);
diff --git a/drivers/video/of_cmdmode.c b/drivers/video/of_cmdmode.c
new file mode 100644
index 000..d63294e
--- /dev/null
+++ b/drivers/video/of_cmdmode.c
@@ -0,0 +1,55 @@
+/*
+ * generic cmdmode helper
+ *
+ * Copyright (c) 2014 YoungJun Cho 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under 

[PATCH 03/18] ARM: dts: video: add command mode display timing DT bindings

2014-05-14 Thread YoungJun Cho
This patch adds DT bindings for command mode display timing.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 .../bindings/video/cmdmode-display-timing.txt  |   64 
 1 file changed, 64 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/video/cmdmode-display-timing.txt

diff --git a/Documentation/devicetree/bindings/video/cmdmode-display-timing.txt 
b/Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
new file mode 100644
index 000..7cedfe4
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
@@ -0,0 +1,64 @@
+cmdmode-display-timing bindings
+===
+
+cmdmode-display-timings node
+
+
+required properties:
+ - none
+
+optional properties:
+ - native-mode: The native mode for the display, in case multiple modes are
+   provided. When omitted, assume the first node is the native.
+
+timing subnode
+--
+
+required properties:
+ - clock-frequency: display clock in Hz
+ - hactive, vactive: display resolution
+ - cs-setup: clock cycles for the active period of address signal is enabled
+   until chip select is enabled.
+ - wr-setup: clock cycles for the active period of CS signal is enabled until
+   write signal is enabled.
+ - wr-active: clock cycles for the active period of CS is enabled.
+ - wr-hold: clock cycles for the active period of CS is disabled until write
+   signal is disabled.
+
+optional properties:
+
+There are different ways of describing the capabilities of a display. The
+devicetree representation corresponds to the one commonly found in datasheets
+for displays. If a display supports multiple signal timings, the native-mode
+can be specified.
+
+The parameters are defined as:
+
+  VCLK(internal)  __|??|_|??|_|??|_|??|_|??
+:::::
+  Address Output  --:|:::
+  Chip Select ???|::|??
+ | WR-SETUP+1 || WR-HOLD+1  |
+ |<-->||<-->|
+  Write Enable||???
+  | WR-ACTIVE+1|
+  |<-->|
+  Video Data  --
+
+Example:
+
+   cmdmode-display-timings {
+   native-mode = <>;
+   timing0: 1080p24 {
+   /* 1920x1080p24 */
+   clock-frequency = <5200>;
+   hactive = <1920>;
+   vactive = <1080>;
+   cs-setup = <0>;
+   wr-setup = <0>;
+   wr-active = <1>;
+   wr-hold = <0>;
+   };
+   };
-- 
1.7.9.5



[PATCH 02/18] drm/exynos: use wait_event_timeout() for safety usage

2014-05-14 Thread YoungJun Cho
There could be the case that the page flip operation isn't finished correctly
with some abnormal condition such as panel reset. So this patch replaces
wait_event() with wait_event_timeout() to avoid waiting for page flip completion
infinitely.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 95c9435..485fa26 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -69,8 +69,9 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int 
mode)

if (mode > DRM_MODE_DPMS_ON) {
/* wait for the completion of page flip. */
-   wait_event(exynos_crtc->pending_flip_queue,
-   atomic_read(_crtc->pending_flip) == 0);
+   wait_event_timeout(exynos_crtc->pending_flip_queue,
+   !atomic_read(_crtc->pending_flip),
+   HZ/20);
drm_vblank_off(crtc->dev, exynos_crtc->pipe);
}

-- 
1.7.9.5



[PATCH 01/18] drm/exynos: dsi: move the EoT packets configuration point

2014-05-14 Thread YoungJun Cho
This configuration could be used in MIPI DSI command mode also.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 84661fe..0a4e3ce 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -473,8 +473,6 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)

if (!(dsi->mode_flags & MIPI_DSI_MODE_VSYNC_FLUSH))
reg |= DSIM_MFLUSH_VS;
-   if (!(dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
-   reg |= DSIM_EOT_DISABLE;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
reg |= DSIM_SYNC_INFORM;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
@@ -491,6 +489,9 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
reg |= DSIM_HSA_MODE;
}

+   if (!(dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
+   reg |= DSIM_EOT_DISABLE;
+
switch (dsi->format) {
case MIPI_DSI_FMT_RGB888:
reg |= DSIM_MAIN_PIX_FORMAT_RGB888;
-- 
1.7.9.5



[PATCH 00/18] drm/exynos: support MIPI DSI command mode display

2014-05-14 Thread YoungJun Cho
Hi,

This series is for the Exynos DRM driver to support MIPI DSI command mode
display and based on exynos-drm-next branch.

The previous patches,
RFC: http://www.spinics.net/lists/dri-devel/msg58898.html

Patches 1 and 2 fix trivial bugs.

Patches 3 and 4 introduce command mode and command mode display timing.
These are based on video mode and (video mode) display timing.
The MIPI DSI command mode interface panel does not require (video mode) display
timing, but it requires signal timings to distinguish command data and video
data so command mode and command mode display timing are used for it.

Patch 5 converts command mode to drm display mode.

Patches 6, 7, 8, 9 and 10 implement FIMD(display controller) I80 interface.
The MIPI DSI command mode interface panel generates Tearing Effect
synchronization signal between MCU and FB to display video image,
and FIMD should trigger to transfer video image at this signal.
So the panel should receive the TE IRQ then calls TE handler chains to notify
it to the FIMD.

Patches 11 and 12 implement to use Exynos5420 SoC DSI driver which is different
from previous Exynos4 SoCs for some registers control.

Patches 13 and 14 introduce MIPI DSI command interface Samsung S6E3FA0 AMOLED
5.7" LCD panel driver.

Patch 15 is device tree source file for Exynos4 SoCs to support MIPI DSI
command mode.

The others are device tree source files for Exynos5420 to support MIPI DSI
(command mode) driver.

I welcome any comments.

Thank you.
Best regards YJ

YoungJun Cho (18):
  drm/exynos: dsi: move the EoT packets configuration point
  drm/exynos: use wait_event_timeout() for safety usage
  ARM: dts: video: add command mode display timing DT bindings
  video: add command mode and command mode display timing
  drm_modes: add command mode helpers
  ARM: dts: sysreg: add exynos5 compatible to DT bindings
  ARM: dts: samsung-fimd: add I80 specific properties
  drm/exynos: add TE handler to support MIPI DSI command mode interface
  drm/exynos: dsi: add TE handler to support command mode interface
  drm/exynos: fimd: support I80 interface
  ARM: dts: exynos_dsim: add exynos5420 compatible to DT bindings
  drm/exynos: dsi: add driver data to support Exynos5420
  ARM: dts: s6e3fa0: add DT bindings
  drm/panel: add S6E3FA0 driver
  ARM: dts: exynos4: add system register node
  ARM: dts: exynos5: add system register support
  ARM: dts: exynos5420: add mipi-phy node
  ARM: dts: exynos5420: add dsi node

 .../devicetree/bindings/arm/samsung/sysreg.txt |1 +
 .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++
 .../bindings/video/cmdmode-display-timing.txt  |   64 +++
 .../devicetree/bindings/video/exynos_dsim.txt  |4 +-
 .../devicetree/bindings/video/samsung-fimd.txt |2 +
 arch/arm/boot/dts/exynos4.dtsi |1 +
 arch/arm/boot/dts/exynos5.dtsi |6 +
 arch/arm/boot/dts/exynos5420.dtsi  |   20 +
 drivers/gpu/drm/drm_modes.c|   59 ++
 drivers/gpu/drm/exynos/Kconfig |1 +
 drivers/gpu/drm/exynos/exynos_drm_crtc.c   |   16 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.h   |7 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h|3 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c|  175 +-
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   |  277 --
 drivers/gpu/drm/panel/Kconfig  |7 +
 drivers/gpu/drm/panel/Makefile |1 +
 drivers/gpu/drm/panel/panel-s6e3fa0.c  |  570 
 drivers/video/Kconfig  |3 +
 drivers/video/Makefile |2 +
 drivers/video/cmdmode.c|   42 ++
 drivers/video/cmdmode_display_timing.c |   26 +
 drivers/video/of_cmdmode.c |   55 ++
 drivers/video/of_cmdmode_display_timing.c  |  212 
 include/drm/drm_mipi_dsi.h |8 +
 include/drm/drm_modes.h|   12 +
 include/video/cmdmode.h|   67 +++
 include/video/cmdmode_display_timing.h |   59 ++
 include/video/of_cmdmode.h |   19 +
 include/video/of_cmdmode_display_timing.h  |   26 +
 include/video/samsung_fimd.h   |3 +-
 31 files changed, 1722 insertions(+), 71 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
 create mode 100644 
Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
 create mode 100644 drivers/gpu/drm/panel/panel-s6e3fa0.c
 create mode 100644 drivers/video/cmdmode.c
 create mode 100644 drivers/video/cmdmode_display_timing.c
 create mode 100644 drivers/video/of_cmdmode.c
 create mode 100644 drivers/video/of_cmdmode_display_timing.c
 create mode 100644 include/video/cmdmode.h
 create mode 100644 include/video/cmdmode_display_timing.h
 

[RFC PATCH 0/2] drm: make drm_get_{connector, encoder}_name thread safe

2014-05-14 Thread Chris Wilson
On Wed, May 14, 2014 at 04:58:18PM +0300, Jani Nikula wrote:
> Hi all -
> 
> This series stores connector/encoder names in the relevant structs to
> make the name getters thread safe.
> 
> What say you, is the wasted memory too high a price to pay for the
> thread safety and implementation simplicity of this approach? I think
> making drm_get_connector_name and drm_get_encoder_name return allocated
> buffers makes a lot of code really ugly and error prone.

I thought we could use dev_set_name(connector->kdev, "foo").
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[Bug 78537] no anisotropic filtering in a native Half-Life 2

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=78537

Michel D?nzer  changed:

   What|Removed |Added

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

--- Comment #6 from Michel D?nzer  ---
Commit: c5828b0599a5c00ebab488b795c63a21f1dc53cd
URL:   
http://cgit.freedesktop.org/mesa/mesa/commit/?id=c5828b0599a5c00ebab488b795c63a21f1dc53cd

Author: Michel D?nzer 
Date:   Wed May 14 16:30:33 2014 +0900

radeonsi: Fix anisotropic filtering state setup

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


CIK hangs with kernel 3.15, bisected

2014-05-14 Thread Christian König
Crap, any chance you can narrow it down a bit more?

I've just tried a piglit quick test on my Bonaire and it seems to work 
perfectly fine.

What hw do you test on?

Regards,
Christian.

Am 13.05.2014 23:21, schrieb Marek Ol??k:
> Hi Christian,
>
> Even though some regressions are fixed by these patches:
>
> drm/radeon: fix page directory update size estimation
> drm/radeon: fix buffer placement under memory pressure v2
>
> and indeed, the texelFetch tests no longer hang, there is one more
> hang which needs to be fixed. :( All I know is the exact same commit
> causes it and it can only be reproduced by running whole piglit with
> concurrency enabled.
>
> My kernel git log:
>
> * 2ba22c8 - drm/radeon: fix buffer placement under memory pressure v2
> (10 hours ago) 
> * 3af91e5 - drm/radeon: fix page directory update size estimation (21
> hours ago) 
> * 6d2f294 - drm/radeon: use normal BOs for the page tables v4 (2
> months ago) 
> * fa68834 - drm/radeon: further cleanup vm flushing & fencing (2
> months ago) 
>
> fa68834 doesn't hang, but 2ba22c8 hangs, which means 6d2f294 or either
> of the two fixes is the first bad commit.
>
> Marek
>
> On Fri, May 9, 2014 at 8:03 PM, Marek Ol??k  wrote:
>> Hi Christian,
>>
>> This commit which first appeared in 3.15-rc1 causes hangs on Bonaire:
>>
>> commit 6d2f2944e95e504a7d33385eeeb9bb7fcca72592
>> Author: Christian K?nig 
>> Date:   Thu Feb 20 13:42:17 2014 +0100
>>
>>  drm/radeon: use normal BOs for the page tables v4
>>
>>  No need to make it more complicated than necessary,
>>  just allocate the page tables as normal BO and
>>  flush whenever the address change.
>>
>>  v2: update comments and function name
>>  v3: squash bug fixes, page directory and tables patch
>>  v4: rebased on Mareks changes
>>
>>  Signed-off-by: Christian K?nig 
>>
>>
>> Reverting the commit gives me a lot of merge conflicts.
>>
>> The simplest way to reproduce the hangs is to run piglit with these 
>> parameters:
>> -t texelFetch.fs
>>
>> Some of the tests allocate a lot of MSAA textures and the tests also
>> run in parallel, which creates a lot of memory pressure and probably
>> causes buffer evictions.
>>
>> Any idea what is wrong with it?
>>
>> Thanks,
>>
>> Marek



[Bug 78669] [r600g with -O3] layered-rendering/clear-color-all-types 3d single_level fails

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=78669

--- Comment #4 from David Heidelberger (okias)  
---
it's random with -O3 or just random?

if you want some more testing on 6550D, let me know

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


[Bug 75992] Display freezes & corruption with an r7 260x on 3.14-rc6

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=75992

--- Comment #56 from Alexander Tsoy  ---
(In reply to comment #55)

Without commit [1] new microcode (BONAIRE_mc2.bin) is not loaded. This commit
is currently included only in >=3.15-rc2

[1]
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=277babc374f6ecab6af182554f5d9f35a7768755

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


[PATCH 2/2] drm/radeon: fix buffer placement under memory pressure v2

2014-05-14 Thread Christian König
Am 13.05.2014 21:47, schrieb Marek Ol??k:
> For the patch:
>
> Reviewed-by: Marek Ol??k 
>
> It would be clearer if alt_domain was renamed to allowed_domains.

Yeah, already had the same idea. Going to rename "domain" to 
"prefered_domains" and "alt_domain" to "allowed_domains" for 3.16.

Thanks,
Christian.

>
> Marek
>
> On Mon, May 12, 2014 at 3:30 PM, Christian K?nig
>  wrote:
>> From: Christian K?nig 
>>
>> Some buffers (UVD/VM page tables) must be placed in VRAM,
>> but the byte restriction for moving buffers didn't took this
>> into account.
>>
>> v2: keep closer to the original code
>>
>> Signed-off-by: Christian K?nig 
>> ---
>>   drivers/gpu/drm/radeon/radeon_object.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/radeon_object.c 
>> b/drivers/gpu/drm/radeon/radeon_object.c
>> index 72705fb..4faa4d6 100644
>> --- a/drivers/gpu/drm/radeon/radeon_object.c
>> +++ b/drivers/gpu/drm/radeon/radeon_object.c
>> @@ -458,7 +458,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
>>   * into account. We don't want to disallow buffer 
>> moves
>>   * completely.
>>   */
>> -   if (current_domain != RADEON_GEM_DOMAIN_CPU &&
>> +   if ((lobj->alt_domain & current_domain) != 0 &&
>>  (domain & current_domain) == 0 && /* will be 
>> moved */
>>  bytes_moved > bytes_moved_threshold) {
>>  /* don't move it */
>> --
>> 1.9.1
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel



[Intel-gfx] [PATCH] drm,drm/i915: Export cmdline mode parsing

2014-05-14 Thread Jani Nikula
On Tue, 13 May 2014, Chris Wilson  wrote:
> i915.ko has a custom fbdev initialisation routine that aims to preserve
> the current mode set by the BIOS, unless overruled by the user. The
> user's wishes are determined by what, if any, mode is specified on the
> command line (via the video= parameter). However, that command line mode
> is first parsed by drm_fb_helper_initial_config() which is called after
> i915.ko's custom initial_config() as a fallback method. So in order for
> us to honour it, we need to export the routine out of the helper and
> call it first.

Is this an answer to https://bugs.freedesktop.org/show_bug.cgi?id=73154?

Jani.


>
> Signed-off-by: Chris Wilson 
> Cc: Jesse Barnes 
> Cc: Ville Syrj?l? 
> Cc: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_crtc.c | 58 
> ++
>  drivers/gpu/drm/drm_fb_helper.c| 47 +++---
>  drivers/gpu/drm/i915/intel_fbdev.c |  2 ++
>  include/drm/drm_crtc.h |  3 +-
>  4 files changed, 66 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 656788a9bf4b..853804277921 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -852,6 +852,64 @@ int drm_connector_init(struct drm_device *dev,
>  EXPORT_SYMBOL(drm_connector_init);
>  
>  /**
> + * drm_connector_get_cmdline_mode - reads the user's cmdline mode
> + * @connector: connector to quwery
> + * @mode: returned mode
> + *
> + * The kernel supports per-connector configration of its consoles through
> + * use of the video= parameter. This function parses that option and
> + * extracts the user's specified mode (or enable/disable status) for a
> + * particular connector. This is typically only used during the early fbdev
> + * setup.
> + */
> +void drm_connector_get_cmdline_mode(struct drm_connector *connector,
> + struct drm_cmdline_mode *mode)
> +{
> + char *option = NULL;
> +
> + if (mode->specified)
> + return;
> +
> + if (fb_get_options(drm_get_connector_name(connector), ))
> + return;
> +
> + if (!drm_mode_parse_command_line_for_connector(option,
> +connector,
> +mode))
> + return;
> +
> + if (mode->force) {
> + const char *s;
> +
> + switch (mode->force) {
> + case DRM_FORCE_OFF:
> + s = "OFF";
> + break;
> + case DRM_FORCE_ON_DIGITAL:
> + s = "ON - dig";
> + break;
> + default:
> + case DRM_FORCE_ON:
> + s = "ON";
> + break;
> + }
> +
> + DRM_INFO("forcing %s connector %s\n",
> +  drm_get_connector_name(connector), s);
> + connector->force = mode->force;
> + }
> +
> + DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
> +   drm_get_connector_name(connector),
> +   mode->xres, mode->yres,
> +   mode->refresh_specified ? mode->refresh : 60,
> +   mode->rb ? " reduced blanking" : "",
> +   mode->margins ? " with margins" : "",
> +   mode->interlace ?  " interlaced" : "");
> +}
> +EXPORT_SYMBOL(drm_connector_get_cmdline_mode);
> +
> +/**
>   * drm_connector_cleanup - cleans up an initialised connector
>   * @connector: connector to cleanup
>   *
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index e95ed5805f07..f61a6c02101c 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -107,55 +107,16 @@ EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
>  
>  static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
>  {
> - struct drm_fb_helper_connector *fb_helper_conn;
>   int i;
>  
>   for (i = 0; i < fb_helper->connector_count; i++) {
> - struct drm_cmdline_mode *mode;
> - struct drm_connector *connector;
> - char *option = NULL;
> + struct drm_fb_helper_connector *fb_helper_conn;
>  
>   fb_helper_conn = fb_helper->connector_info[i];
> - connector = fb_helper_conn->connector;
> - mode = _helper_conn->cmdline_mode;
> -
> - /* do something on return - turn off connector maybe */
> - if (fb_get_options(drm_get_connector_name(connector), ))
> - continue;
> -
> - if (drm_mode_parse_command_line_for_connector(option,
> -   connector,
> -   mode)) {
> - if (mode->force) {
> - const char *s;
> -

[Bug 75992] Display freezes & corruption with an r7 260x on 3.14-rc6

2014-05-14 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=75992

--- Comment #55 from nicolas.laplante at gmail.com ---
Regression on 3.14.3. Screen corruption is back. Using Radeon microcode from
2014-04-30.

dmesg is full of messages like this:

[  658.696174] radeon :01:00.0: GPU fault detected: 147 0x0ee20808
[  658.696175] radeon :01:00.0:   VM_CONTEXT1_PROTECTION_FAULT_ADDR  
0x
[  658.696177] radeon :01:00.0:   VM_CONTEXT1_PROTECTION_FAULT_STATUS
0x
[  658.696178] VM fault (0x00, vmid 0) at page 0, read from '' (0x) (0)

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


[Intel-gfx] [PATCH 09/10] i915: add DP 1.2 MST support (v0.3)

2014-05-14 Thread Daniel Vetter
On Wed, May 14, 2014 at 08:05:11AM +0200, David Herrmann wrote:
> Hi
> 
> On Wed, May 14, 2014 at 2:03 AM, Dave Airlie  wrote:
> > Since any objects you get with find are only valid under mode_config.mutex,
> > yes some drivers mess this up, but they should be fixed.
> 
> Didn't know that we have such a rule. Then it's fine, of course. The
> page-flip code is what worried me, but drivers ought to cancel that
> when destroying connectors, anyway.

i915 cancels/stalls for any pageflips when we switch off the crtc, so I
think we should be fine.

And the above rule is for all modeset objects except framebuffers, since
those are separately protected with refcounting and you don't even need
the big mode_config mutex to do the idr lookup.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH v2 4/7] drivers/base: Add interface framework

2014-05-14 Thread Greg Kroah-Hartman
On Wed, May 14, 2014 at 04:37:19PM +0200, Daniel Vetter wrote:
> On Tue, May 13, 2014 at 05:32:15PM -0700, Greg Kroah-Hartman wrote:
> > On Tue, May 13, 2014 at 07:57:13PM +0200, Daniel Vetter wrote:
> > > On Tue, May 13, 2014 at 05:30:47PM +0200, Thierry Reding wrote:
> > > > From: Thierry Reding 
> > > > 
> > > > Some drivers, such as graphics drivers in the DRM subsystem, do not have
> > > > a real device that they can bind to. They are often composed of several
> > > > devices, each having their own driver. The master/component framework
> > > > can be used in these situations to collect the devices pertaining to one
> > > > logical device, wait until all of them have registered and then bind
> > > > them all at once.
> > > > 
> > > > For some situations this is only a partial solution. An implementation
> > > > of a master still needs to be registered with the system somehow. Many
> > > > drivers currently resort to creating a dummy device that a driver can
> > > > bind to and register the master against. This is problematic since it
> > > > requires (and presumes) knowledge about the system within drivers.
> > > > 
> > > > Furthermore there are setups where a suitable device already exists, but
> > > > is already bound to a driver. For example, on Tegra the following device
> > > > tree extract (simplified) represents the host1x device along with child
> > > > devices:
> > > > 
> > > > host1x {
> > > > display-controller {
> > > > ...
> > > > };
> > > > 
> > > > display-controller {
> > > > ...
> > > > };
> > > > 
> > > > hdmi {
> > > > ...
> > > > };
> > > > 
> > > > dsi {
> > > > ...
> > > > };
> > > > 
> > > > csi {
> > > > ...
> > > > };
> > > > 
> > > > video-input {
> > > > ...
> > > > };
> > > > };
> > > > 
> > > > Each of the child devices is in turn a client of host1x, in that it can
> > > > request resources (command stream DMA channels and syncpoints) from it.
> > > > To implement the DMA channel and syncpoint infrastructure, host1x comes
> > > > with its own driver. Children are implemented in separate drivers. In
> > > > Linux this set of devices would be exposed by DRM and V4L2 drivers.
> > > > 
> > > > However, neither the DRM nor the V4L2 drivers have a single device that
> > > > they can bind to. The DRM device is composed of the display controllers
> > > > and the various output devices, whereas the V4L2 device is composed of
> > > > one or more video input devices.
> > > > 
> > > > This patch introduces the concept of an interface and drivers that can
> > > > bind to a given interface. An interface can be exposed by any device,
> > > > and interface drivers can bind to these interfaces. Multiple drivers can
> > > > bind against a single interface. When a device is removed, interfaces
> > > > exposed by it will be removed as well, thereby removing the drivers that
> > > > were bound to those interfaces.
> > > > 
> > > > In the example above, the host1x device would expose the "tegra-host1x"
> > > > interface. DRM and V4L2 drivers can then bind to that interface and
> > > > instantiate the respective subsystem objects from there.
> > > > 
> > > > Signed-off-by: Thierry Reding 
> > > > ---
> > > > Note that I'd like to merge this through the Tegra DRM tree so that the
> > > > changes to the Tegra DRM driver later in this series can be merged at
> > > > the same time and are not delayed for another release cycle.
> > > > 
> > > > In particular that means that I'm looking for an Acked-by from Greg.
> > > > 
> > > >  drivers/base/Makefile |   2 +-
> > > >  drivers/base/interface.c  | 186 
> > > > ++
> > > >  include/linux/interface.h |  40 ++
> > > >  3 files changed, 227 insertions(+), 1 deletion(-)
> > > >  create mode 100644 drivers/base/interface.c
> > > >  create mode 100644 include/linux/interface.h
> > > 
> > > Hm, this interface stuff smells like bus drivers light. Should we instead
> > > have a pile of helpers to make creating new buses with match methods more
> > > trivial? There's a fairly big pile of small use-cases where this might be
> > > useful. In your case here all the host1x children would sit on a host1x
> > > bus. Admittedly I didn't look into the details.
> > 
> > I have no problem adding such "bus-light" functions, to make it easier
> > to create and implement a bus in the driver core, as I know it's really
> > heavy.  That's been on my "todo" list for over a decade now...
> 
> Hm, I've victimized^Wvolunteered a few internal people to look into a
> hdmi/dp sink bus type of thing so that we can move away from all those
> ad-hoc hacks currently used to coordinate 

[Bug 76131] Regression: Wake up after suspend broken with Radeon R7 260x (BONAIRE, radeonsi)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76131

--- Comment #5 from Felix Homann  ---
OK, 3.14.x kernels will resume fine if I suspend before the screen freezes.

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


[PATCH 09/10] i915: add DP 1.2 MST support (v0.3)

2014-05-14 Thread Dave Airlie
>
> So we leak all dynamically created objects? There's no
> kfree(intel_connector) here and we cannot add it because
> drm_mode_object_find() is not ref-counted. So we keep the connector in
> the mode_group and wait until the final drm_mode_config_cleanup()? But
> drm_connector_cleanup() already removes the connector from the
> mode-group, so we eventually leak the object.
>

Seems like freeing it should be fine, it was just an oversight,

Since any objects you get with find are only valid under mode_config.mutex,
yes some drivers mess this up, but they should be fixed.

Dave.


[Bug 76131] Regression: Wake up after suspend broken with Radeon R7 260x (BONAIRE, radeonsi)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76131

--- Comment #4 from Felix Homann  ---
I'll do (*). But bisecting will not be that easy as the R7 260x is mostly
broken on 3.14.x anyway, see
https://bugzilla.redhat.com/show_bug.cgi?id=1094153 and the corresponding
report on freedesktop.org. The bisect result might get wrong due to the overall
3.14.x issues.


(*) I probably won't find any time for a bisect session before May 26.

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


[Intel-gfx] [PATCH] drm,drm/i915: Export cmdline mode parsing

2014-05-14 Thread Chris Wilson
On Wed, May 14, 2014 at 11:31:47AM +0300, Jani Nikula wrote:
> On Tue, 13 May 2014, Chris Wilson  wrote:
> > i915.ko has a custom fbdev initialisation routine that aims to preserve
> > the current mode set by the BIOS, unless overruled by the user. The
> > user's wishes are determined by what, if any, mode is specified on the
> > command line (via the video= parameter). However, that command line mode
> > is first parsed by drm_fb_helper_initial_config() which is called after
> > i915.ko's custom initial_config() as a fallback method. So in order for
> > us to honour it, we need to export the routine out of the helper and
> > call it first.
> 
> Is this an answer to https://bugs.freedesktop.org/show_bug.cgi?id=73154?

Yes. Not in this patch, but we can also use in that case as well.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[Bug 76131] Regression: Wake up after suspend broken with Radeon R7 260x (BONAIRE, radeonsi)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76131

--- Comment #3 from Christian K?nig  ---
Then please bisect what commit broke it for you.

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


[PATCH] drm: Missed clflushopt in drm_clflush_virt_range

2014-05-14 Thread Ross Zwisler
With this commit:

2a0788dc9bc4 x86: Use clflushopt in drm_clflush_virt_range

If clflushopt is available on the system, we use it instead of clflush
in drm_clflush_virt_range.  There were two calls to clflush in this
function, but only one was changed to clflushopt.  This patch changes
the other clflush call to clflushopt.

Signed-off-by: Ross Zwisler 
Reported-by: Matthew Wilcox 

Cc: David Airlie 
Cc: dri-devel at lists.freedesktop.org
Cc: H Peter Anvin 
Cc: Ingo Molnar 
Cc: Thomas Gleixner 

---
 drivers/gpu/drm/drm_cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 534cb89..041b73b 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -138,7 +138,7 @@ drm_clflush_virt_range(char *addr, unsigned long length)
char *end = addr + length;
mb();
for (; addr < end; addr += boot_cpu_data.x86_clflush_size)
-   clflush(addr);
+   clflushopt(addr);
clflushopt(end - 1);
mb();
return;
-- 
1.9.0



[Bug 76131] Regression: Wake up after suspend broken with Radeon R7 260x (BONAIRE, radeonsi)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76131

--- Comment #2 from Felix Homann  ---
The proposed patch https://bugzilla.kernel.org/attachment.cgi?id=135881 doesn't
fix the issue on my machine.

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


[PATCH] Documentation/dma-buf-sharing.txt: update API descriptions

2014-05-14 Thread Gioh Kim
Thank you for advice.
I will send a fixed patch soon.

> -Original Message-
> From: Thierry Reding [mailto:thierry.reding at gmail.com]
> Sent: Tuesday, May 13, 2014 5:45 PM
> To: gioh.kim
> Cc: Sumit Semwal; Randy Dunlap; linux-media at vger.kernel.org; dri-devel at 
> lists.freedesktop.org; linux-
> doc at vger.kernel.org; linux-kernel at vger.kernel.org; gunho.lee at lge.com
> Subject: Re: [PATCH] Documentation/dma-buf-sharing.txt: update API 
> descriptions
> 
> On Mon, May 12, 2014 at 08:48:12PM +0900, gioh.kim wrote:
> > From: "gioh.kim" 
> 
> It might be good to fix your setup to make this be the same as the name
> and email used in the Signed-off-by line below.
> 
> > update some descriptions for API arguments and descriptions.
> 
> Nit: "Update" since it's the beginning of a sentence.
> 
> > Signed-off-by: Gioh Kim 
> > ---
> >  Documentation/dma-buf-sharing.txt |   10 ++
> >  1 file changed, 6 insertions(+), 4 deletions(-)
> >
> > diff --git a/Documentation/dma-buf-sharing.txt 
> > b/Documentation/dma-buf-sharing.txt
> > index 505e711..1ea89b8 100644
> > --- a/Documentation/dma-buf-sharing.txt
> > +++ b/Documentation/dma-buf-sharing.txt
> > @@ -56,7 +56,7 @@ The dma_buf buffer sharing API usage contains the 
> > following steps:
> >  size_t size, int flags,
> >  const char *exp_name)
> >
> > -   If this succeeds, dma_buf_export allocates a dma_buf structure, and 
> > returns a
> > +   If this succeeds, dma_buf_export_named allocates a dma_buf structure, 
> > and returns a
> 
> Perhaps reformat this so that the lines don't exceed 80 characters?
> 
> > pointer to the same. It also associates an anonymous file with this 
> > buffer,
> > so it can be exported. On failure to allocate the dma_buf object, it 
> > returns
> > NULL.
> > @@ -66,7 +66,7 @@ The dma_buf buffer sharing API usage contains the 
> > following steps:
> >
> > Exporting modules which do not wish to provide any specific name may 
> > use the
> > helper define 'dma_buf_export()', with the same arguments as above, but
> > -   without the last argument; a __FILE__ pre-processor directive will be
> > +   without the last argument; a KBUILD_MODNAME pre-processor directive 
> > will be
> > inserted in place of 'exp_name' instead.
> 
> This was already fixed in commit 2e33def0339c (dma-buf: update exp_name
> when using dma_buf_export()). Perhaps you should rebase this patch on
> top of the latest linux-next.
> 
> Otherwise looks good.
> 
> Thierry



[PATCH] Documentation/dma-buf-sharing.txt: update API descriptions

2014-05-14 Thread Gioh Kim
Update some descriptions for API arguments and descriptions.

Signed-off-by: Gioh Kim 
---
 Documentation/dma-buf-sharing.txt |   14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Documentation/dma-buf-sharing.txt 
b/Documentation/dma-buf-sharing.txt
index 505e711..aadd901 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -56,10 +56,10 @@ The dma_buf buffer sharing API usage contains the following 
steps:
 size_t size, int flags,
 const char *exp_name)

-   If this succeeds, dma_buf_export allocates a dma_buf structure, and returns 
a
-   pointer to the same. It also associates an anonymous file with this buffer,
-   so it can be exported. On failure to allocate the dma_buf object, it returns
-   NULL.
+   If this succeeds, dma_buf_export_named allocates a dma_buf structure, and
+   returns a pointer to the same. It also associates an anonymous file with 
this
+   buffer, so it can be exported. On failure to allocate the dma_buf object,
+   it returns NULL.

'exp_name' is the name of exporter - to facilitate information while
debugging.
@@ -76,7 +76,7 @@ The dma_buf buffer sharing API usage contains the following 
steps:
drivers and/or processes.

Interface:
-  int dma_buf_fd(struct dma_buf *dmabuf)
+  int dma_buf_fd(struct dma_buf *dmabuf, int flags)

This API installs an fd for the anonymous file associated with this buffer;
returns either 'fd', or error.
@@ -157,7 +157,9 @@ to request use of buffer for allocation.
"dma_buf->ops->" indirection from the users of this interface.

In struct dma_buf_ops, unmap_dma_buf is defined as
-  void (*unmap_dma_buf)(struct dma_buf_attachment *, struct sg_table *);
+  void (*unmap_dma_buf)(struct dma_buf_attachment *,
+struct sg_table *,
+enum dma_data_direction);

unmap_dma_buf signifies the end-of-DMA for the attachment provided. Like
map_dma_buf, this API also must be implemented by the exporter.
-- 
1.7.9.5



[Bug 76131] Regression: Wake up after suspend broken with Radeon R7 260x (BONAIRE, radeonsi)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76131

Christian K?nig  changed:

   What|Removed |Added

 CC||deathsimple at vodafone.de

--- Comment #1 from Christian K?nig  ---
Sounds like a duplicate of https://bugzilla.kernel.org/show_bug.cgi?id=75651

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


[Bug 76131] Regression: Wake up after suspend broken with Radeon R7 260x (BONAIRE, radeonsi)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76131

Felix Homann  changed:

   What|Removed |Added

 CC||linuxaudio at showlabor.de
 Regression|No  |Yes

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


[Bug 76131] New: Regression: Wake up after suspend broken with Radeon R7 260x (BONAIRE, radeonsi)

2014-05-14 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=76131

Bug ID: 76131
   Summary: Regression: Wake up after suspend broken with Radeon
R7 260x (BONAIRE, radeonsi)
   Product: Drivers
   Version: 2.5
Kernel Version: 3.15.0-rc5+ (commit
14186fea0cb06bc43181ce239efe0df6f1af260a)
  Hardware: x86-64
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-dri at kernel-bugs.osdl.org
  Reporter: linuxaudio at showlabor.de
Regression: No

My sytem won't wake up (properly) after suspend when using a Radeon R7 260x:
The screen stays black and the system cannot be reached over ssh. Using the
onboard Intel graphics adapter the system will wake up properly with the same
kernel.

This has not been a problem with 3.13.x kernels. I have not tested with 3.14
kernels.

I am using the MESA driver, the BONAIRE_mc2.bin firmware is present. Overall
performance of the driver is great.


The kernel I'm using is commit 14186fea0cb06bc43181ce239efe0df6f1af260a from
Linus' tree.

Here's the output of ver_linux:

Linux yerbouti.fritz.box 3.15.0-rc5+ #1 SMP Tue May 13 16:34:21 CEST 2014
x86_64 x86_64 x86_64 GNU/Linux

Gnu C  4.8.2
Gnu make   3.82
binutils   2.23.2
util-linux 2.24.2
mount  assert
module-init-tools  15
e2fsprogs  1.42.8
jfsutils   1.1.15
reiserfsprogs  3.6.21
pcmciautils018
PPP2.4.5
Linux C Library2.18
Dynamic linker (ldd)   2.18
Procps 3.3.8
Net-tools  2.10-alpha
Kbd1.15.5
oprofile   0.9.9
Sh-utils   8.21
wireless-tools 29
Modules Loaded rfcomm ipt_MASQUERADE fuse xt_CHECKSUM tun
nf_conntrack_netbios_ns nf_conntrack_broadcast ip6t_rpfilter ip6t_REJECT
xt_conntrack cfg80211 ebtable_nat ebtable_broute bridge stp llc ebtable_filter
ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6
ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables
iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack
iptable_mangle iptable_security iptable_raw bnep it87 hwmon_vid vfat fat btusb
bluetooth 6lowpan_iphc rfkill iTCO_wdt iTCO_vendor_support uas usb_storage
x86_pkg_temp_thermal coretemp kvm_intel kvm bcache crct10dif_pclmul
crc32_pclmul crc32c_intel ghash_clmulni_intel snd_hda_codec_via
snd_hda_codec_generic microcode snd_hda_codec_hdmi serio_raw snd_hda_intel
pcspkr snd_hda_controller i2c_i801 snd_hda_codec snd_hwdep snd_seq
snd_seq_device snd_pcm mei_me tpm_infineon mei tpm_tis tpm video snd_timer snd
lpc_ich mfd_core shpchp soundcore binfmt_misc radeon btrfs xor raid1
i2c_algo_bit drm_kms_helper ttm raid6_pq drm firewire_ohci alx firewire_core
r8169 i2c_core mii crc_itu_t mdio

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


  1   2   >